P1.0口模拟量输入 P3.5口 PWM信号输出
求大神指导下 应该是我的程序没有嵌套上占空比 求赐教
单片机源程序如下:
#include <reg51.h>
#include "intrins.h"
#define FOSC 10240000L
#define BAUD 9600
typedef unsigned char BYTE; //这是重新定义一个新的变量类型byte
typedef unsigned int WORD; //定义了一个unsigned int的同义词,名字为WORD
#define URMD 0 //0:使用定时器2做波特率发生器
//1:使用定时器1的模式0(16位自动重载模式)作为波特率发生器
//2:使用定时器1的模式2(8位自动重载模式)作为波特率发生器
sfr T2H = 0xd6; //定时器2高8位
sfr T2L = 0xd7; //定时器2低8位
sfr ADC_CONTR=0xBC; //定义ad转换电源,周期,标致,开启,转换口,数据存储位置
sfr ADC_RES=0xBD; //定义转换完毕数据高高八位数据位置
sfr ADC_LOW2=0xBE; //定义转换完毕的低2位数据存放位置
sfr P1ASP=0x9D; //定义ad转换的总开关位置
sfr CLK_DIV=0x97; //定义时钟分频寄存器地址
/*ADC操作定义常量*/
#define ADC_POWER 0x80 //ADC的电源控制位,打开,10000000
#define ADC_FLAG 0x10 //ADC完成标志,10000,一定要软件清零
#define ADC_START 0x08 //ADC的启动控制点,1000,开始转换
#define ADC_SPEEDLL 0x00 //540 clocks,00,,00,540个时钟周期转换一次
#define ADC_SPEEDL 0x20 //360 clocks,100000,01
#define ADC_SPEEDH 0x40 //180 clocks,1000000,10
#define ADC_SPEEDHH 0x60 //90 clocks,1100000,11
void InitUart(); //初始化Uart,通用异步接收器/发送器,就是通常所说的串行口,
void SendData(BYTE dat); //byte=char
void delay_ms(WORD n); //word=int
void InitADC();
BYTE ch = 0; //ADC通道号,指定p1.0作为A/D输入来用
/*PWM操作定义常量*/
#define PWM_DUTY 512 //定义PWM的周期,数值为时钟周期数,假如使用10.24MHZ的主频,则PWM频率为10240/512kHZ.
#define PWM_HIGH_MIN 32 //限制PWM 输出的最小占空比. 用户请勿修改.
#define PWM_HIGH_MAX(PWM_DUTY-PWM_HIGH_MIN) //限制PWM 输出的最大占空比.
typedef unsigned char u8;
typedef unsigned int u16;
typedef unsigned long u32;
sfr P3M1 = 0xB1; //1011 0001
sfr P3M0 = 0xB2; //1011 0010
sfr AUXR = 0xBE; // 10 00 11 10
sfr INT_CLKO = 0xBF; // 10 00 11 11
BYTE GBTADCResult(BYTE ch);
sbit P_PWM = P3*5; //定义PWM 输出引脚.
u16 pwm; //定义PWM 输出高电平的时间的变量. 用户操作PWM 的变量.
u16 PWM_high,PWM_low; //中间变量,用户请勿修改.
void delay_ms(unsigned char ms);
void LoadPWM(u16 i);
/********************主函数**************************/
void main(void)
{
P_PWM = 0; //中断过程中装载低电平
P3M1 &=~(1<<5); //P3.5设置为推挽输出
P3M0 |= (1<<5); //p3口为准双向模式
TR0 = 0; //停止计时器T0计数,TCON
BT0 = 1; //允许T0溢出中断,IE
PT0 = 1; //高优先级中断,IP
TMOD &=~0x03; //工作模式,0:16位自动重装,~0x03=11111100,
//与运算这保证后两位一直为零,16位自动重装 将RL_THO和RL_TLO分别自动装入THO和TLO;
AUXR |= 0x80; //1T;10000000,定时器 0,不分频
TMOD &=~0x04; //定时,~0x04=11111011,与运算这保证后第三位一直为零,
//即保证定时器 0 当作定时器而不是计数器
INT_CLKO|= 0x01; //输出时钟,或运算保证最后一位一定是1,即运行输出
TH0 = 0; //定时器 0 高八位为零
TL0 = 0; //定时器 0 低八位为零
TR0 = 1; //开始运行,允许定时器 0 开始计数
EA = 1; //cpu开放中断,中断程序将16为PWM_high和PWM_low 的高8位和低8位分别赋给TH0和TL0;
pwm = PWM_DUTY*0.4678; //给PWM 一个初值
LoadPWM(pwm); //计算PWM 的高电平时间和低电平时间然后通过中断将高8位和低8位分别赋给TH0和TL0
delay_ms(800);
InitADC(); //初始化ADC
}
while(1)
{
ADC_CONTR = ADC_POWER | ADC_SPEEDLL |ADC_START | ch;
_nop_();
_nop_();
_nop_();
_nop_(); //等待4个nop
while(!(ADC_CONTR&ADC_FLAG)); //等待ADC转换完成
if((ADC_RES*4+ADC_LOW2)<507)
pwm=PWM_DUTY*0.4678571
if((ADC_RES*4+ADC_LOW2)>531)
pwm=PWM_DUTY*0.4678571*531.948/(ADC_RES*4+ADC_LOW2);
LoadPWM(pwm);
delay_ms(8);
}
}
//=======================================================================
//函数:voiddelay_ms(unsigned char ms)
//描述:延时函数.
//参数:ms,要延时的 ms 数,这里只支持1~255ms,自动适应主时钟.
=======================================================================
void delay_ms(unsigned char ms)
{
unsigned int i;
do{
i = POSC / 13000;
while(-i);
}while(-ms);
}
/****************计算PWM重装值函数*******************/
void LoadPWM(u16 i)
{
u16 j;
if(i>PWM_HIGH_MAX) i = PWM_HIGH_MAX; //如果写入大于最大占空比数据,则强制为最大占空比.
if(i<PWM_HIGH_MIN) i = PWM_HIGH_MIN; //如果写入小于最小占空比数据,则强制为最小占空比.
j = 65536UL - PWM_DUTY + i; //计算PWM 低电平时间
i = 65536UL - i; //计算PWM 高电平时间
BA = 0;
PWM_high = i; //装载PWM 高电平时间
PWM_low = j; //装载PWM 低电平时间
EA = 1;
}
/*********************Timer0 中断函数************************/
void timer0_int (void) interrupt 1
{
if(P_PWM)
{
TH0= (u8)(PWM_low>>8); //如果是输出高电平,则装载低电平时间,即TH0等于PWM_low的高八位
//(U8)为强制取低八位
TL0= (u8)PWM_low;
}
else
{
TH0= (u8)(PWM_high>>8); //如果是输出低电平,则装载高电平时间.
TL0= (u8)PWM_high;
}
}
/*-----------------------------
初始ADC函数
-----------------------------*/
void InitADC( )
{
P1ASF = 0x01; //设置P1口为模拟输入端口
ADC_RES = 0; //清除先前的结果
ADC_LOW2 = 0; //清除先前的结果
ADC_CONTR = ADC_POWER | ADC_SPEEDLL |ADC_START | ch;
delay_ms(2); //ADC上电并延迟
}
|