//p1.0读输入电平,p3.7输出pwm值
//本程序输出的pwm频率为50Hz
#include
sfr CCON = 0xd8; //PCA控制寄存器CCON
sfr CMOD = 0xd9; //PCA工作模式寄存器
sfr CCAPM2 = 0xdc; //PCA比较/捕获寄存器CCAPM0、CCAPM1和CCAPM2
sfr CL = 0xe9; //PCA的16位计数器 — 低8位CL和高8位CH
sfr CH = 0xf9;
sfr CCAP2L = 0xec;
sfr CCAP2H = 0xfc;
/*PCA捕捉/比较寄存器 — CCAPnL(低位字节)和CCAPnH(高位字节)
当PCA模块用于捕获或比较时,它们用于保存各个模块的16位捕捉计数值;当PCA模块用于PWM模式时,它们用来控制输出的占空比。
其中,n = 0、1、2,分别对应模块0、模式1和模块2。复位值均为00H。它们对应的地址分别为:
CCAP0L — EAH、CCAP0H — FAH:模块0的捕捉/比较寄存器。
CCAP1L — EBH、CCAP1H — FBH:模块1的捕捉/比较寄存器。
CCAP2L — ECH、CCAP2H — FCH:模块2的捕捉/比较寄存器。*/
sfr P1M1 = 0x91; //配置IO输出输入模式
sfr P1M0 = 0x92;
sfr PCA_PMW2 = 0xf4; //PCA模块2的PWM寄存器 地址 为0xf4。
sfr AUXR = 0x8e; //辅助寄存器
sbit HL=P1^0;
void timer0_isr(void) interrupt 1 {
TH0= (65536 - 936) / 256; //重装初值
TL0= (65536 - 936) % 256; //重装初值
}
/*********************Timer0初始化函数***********************/
void timer0_init(void)
{
AUXR |= 0x80; //定时器时钟1T模式,|=0x80 就是将最高位置1。AUXR &= 0xBF;定时器时钟12T模式 ,&=0xBF就是只操作AUXR的第7位,其他位不动。
TMOD= 0x01; //T0工作方式1,16位自动重载
TH0= (65536 - 936) / 256; //对机器脉冲计数936个计满溢出引发中断
TL0= (65536 - 936) % 256;
EA= 1; //开总中断
ET0= 1; //开T0中断
TR0= 1; //启动定时器T0
}
void pwm0_init(void)
{
P1M0 = 0x00; //P1口用传统51准双向口模式
P1M1 = 0x00;
CCAP2L = 0xF4;//低电平的占空比:CCAP2L/256,高电平的站控比:1-CCAP2L/256。
//CCAP2H = 0xF4; //由于工作模式是8位PMW,所以CCAP2H是不参与计数匹配
CMOD = 0x84; // 空闲模式下PCA计数器停止工作;定时器0溢出做PCA模块的时钟源
CCON= 0x00;
CL= 0x00; //当计数数值与CCAP2L匹配,电平翻转
CH= 0x00;
PCA_PMW2= 0x00; //8位PMW,占空比的第九位EPC0L为0
CCAPM2= 0x42; //允许比较,P3.7输出,CCAPM2:PCA模块2的比较/捕获寄存器,不允许中断
//要使能PWM模式,模块CCAPMn寄存器的PWMn和ECOMn位必须置位。
CCON= 0x40; //允许PAC计数
}
void main(void)
{
timer0_init();
pwm0_init();
while(1) {
if(HL== 1) { //如果P1.0输入高电平
CCAP2L = 0xEC;//低电平的占空比:CCAP2L/256,高电平的占控比:1 - CCAP2L/256。
}
if(HL== 0){ //如果P1.0输入低电平
CCAP2L = 0xF4;//低电平的占空比:CCAP2L/256,高电平的占控比:1 - CCAP2L/256。
}
}
}
定时器的配置可以参考以下链接,http://blog.csdn.net/sjong/article/details/73380499,定时器需要重载初值,定时器要工作在1T模式下。