/*定时器iopwm程序*/
typedef unsigned char uint8;
typedef unsigned int uint16;
sfr AUXR = 0x8E; //0000,0000 辅助寄存器
//按键和led接口定义
sbit LED =P3^4;
//定时器重装值
#define SYSTEM_CLOCK 11059200 //时钟频率
#define TIMER0_OVERFLOW_FREQ (25600) //定时器溢出频率
//定时器重装值,指定类型避免浮点错误
#define TIMER0_RELOAD_VALUE (65535-(uint16)((unsigned long)SYSTEM_CLOCK/(unsigned long)TIMER0_OVERFLOW_FREQ)+1)
#define PWM_DUTY_MASK 0x3f //pwm控制深度级的掩位(1的个数)
#define PWM_OVERFLOW (PWM_DUTY_MASK+1) //pwm溢出的位值
//#define PWM_CYCLE //pwm周期
uint8 Time0_Counter=0; //定时器0溢出计数
uint8 PWM_Value=0; //PWM占空比值
uint16 Time_400HZ_Counter=0; //高位计数,计数频率与PWM_DUTY_MASK定义相关
/****************400HZ,64级pwm(0x3F)******************************/
void Timer0_Service (void) interrupt 1 {//F0=1出错,中断服务函数保存了psw状态寄存器
Time0_Counter++;
if ((Time0_Counter&PWM_DUTY_MASK)==0) { //计数回0,置无效电平(led灭)
LED=1; //25600/64=400HZ
} else {
//低六位有效(Time0_Counter&PWM_DUTY_MASK优化),比较符号和置位值决定输出
if ((Time0_Counter&PWM_DUTY_MASK)>=(PWM_Value&PWM_DUTY_MASK))
LED=0; //比较输出有效电平
}
}
/**********************主函数**************************************/
int main(void) {
//初始化T0为TIMER0_OVERFLOW_FREQ指定的溢出频率
AUXR |=0x80; //t0 1t
TMOD=0x00; //选择定时器0,工作模式0(stc15:16位自动重装模式0)
TL0=(uint8)TIMER0_RELOAD_VALUE;
TH0=(uint8)(TIMER0_RELOAD_VALUE>>8);
TR0=1; //开启控制端
ET0=1; //开启定时器0中断允许,允许定时器0中断。
EA=1; //总中断控制
while(1) {
if ((Time0_Counter & PWM_OVERFLOW)) {
Time0_Counter &= ~PWM_OVERFLOW; //不重复
Time_400HZ_Counter++; //400HZ累加
//使用计数变量改变占空比 //4分频的变化速率
PWM_Value=(uint8)(Time_400HZ_Counter/4);
if (Time_400HZ_Counter&(4*PWM_OVERFLOW)) PWM_Value=~PWM_Value;
}//end if (
}//end while(1)
}
|