一:AI8051的PWM定时器知识分享:
Ai8051U 系列的单片机内部集成了8通道 16 位高级 PWM 定时器,分成两组周期可不同的PWM,分别命名为 PWMA 和 PWMB,可分别单独设置。第一组 PWM/PWMA 可配置成4组互补/对称/死区控制的 PWM 或捕捉外部信号,第二组 PWM/PWMB 可配置成4路 PWM 输出或捕捉外部信号。
第一组 PWM/PWMA 的时钟频率可以是系统时钟经过寄存器 PWMA PSCRH 和 PWMA PSCRL 进行分频后的时钟,分频值可以是 1~65535 之间的任意值。第二组PWMPWMB 的时钟频率可以是系统时钟经过寄存器 PWMB PSCRH 和 PWMB PSCRL 进行分频后的时钟,分频值可以是 1~65535 之间的任意值。两组 PWM 的时钟频率可分别独立设置。
第一组 PWM 定时器/PWMA有4个通道(PWMIP/PWMIN、PWM2P/PWM2N、PWM3P/PWM3N.PWM4P/PWM4N),每个通道都可独立实现 PWM 输出(可设置带死区的互补对称 PWM 输出)、捕获和比较功能:第二组PWM定时器/PWMB有4个通道(PWM5、PWM6、PWM7、PWM8),每个通道也可独立实现 PWM 输出、捕获和比较功能。两组 PWM 定时器唯一的区别是第一组可输出带死区的互补对称 PWM,而第二组只能输出单端的 PWM,其他功能完全相同。下面关于高级 PWM 定时器的介绍只以第一组为例进行说明。
当使用第一组 PWM 定时器输出 PWM 波形时,可单独使能 PWMIP/PWM2P/PWM3P/PWVM4P 输出,也可单独使能 PWMIN/PWM2N/PWM3N/PWM4N 输出。例如:若单独使能了PWM1P 输出,则 PWMIN就不能再独立输出,除非 PWM1P 和PWM1N 组成一组互补对称输出。PWMA的4路输出是可分别独立设置的,例如:可单独使能 PWMIP 和PWM2N 输出,也可单独使能PWM2N 和 PWM3N 输出。若需要使用第一组 PWM 定时器进行捕获功能或者测量脉宽时,输入信号只能从每路的正端输入,即只有PWM1P/PWM2P/PWM3P/PWM4P 才有捕获功能和测量脉宽功能。
两组高级 PWM 定时器对外部信号进行捕获时,可选择上升沿捕获或者下降沿捕获。如果需要同时捕获上升沿和下降沿,则可将输入信号同时接入到两路 PWM,使能其中一路捕获上升沿,另外一路捕获下降沿即可。更强悍的是,将外部输入信号同时接入到两路PWM 时,可同时捕获信号的周期值和占空比值。
二:PWMA内部的结构框图:

主要特性:
16 位向上、向下、向上/下自动装载计数器;
允许在指定数目的计数器周期之后更新定时器寄存器的重复计数器
16 位可编程(可以实时修改)预分频器,计数器时钟频率的分频系数为 1~65535 之间的任意数值
同步电路,用于使用外部信号控制定时器以及定时器互联
多达4个独立通道可以配置成:输入捕获、输出比较、PWM 输出(边缘或中间对齐模式)、六步 PWM 输出、单脉冲模式输出、支持4个死区时间可编程的通道上互补输出;
刹车输入信号(PWMFLT)可以将定时器输出信号置于复位状态或者一个确定状态
外部触发输入引脚(PWMETI)
产生中断的事件包括:
更新:计数器向上溢出/向下溢出,计数器初始化(通过软件或者内部/外部触发)触发事件(计数器启动、停止、初始化或者由内部/外部触发计数)、输入捕获、输出比较、刹车信号输入
三:软件代码如下所示:
3.1 PWM初始化配置:
PWMA_CCER1 = 0x00; //写 CCMRx 前必须先清零 CCxE 关闭通道 PWMA_CCER2 = 0x00; PWMA_CCMR1 = 0x60; //通道模式配置 PWMA_CCMR2 = 0x60; PWMA_CCMR3 = 0x60; PWMA_CCMR4 = 0x60; PWMA_CCER1 = 0x55; //配置通道输出使能和极性 PWMA_CCER2 = 0x55; PWMA_CCMR1 |= 0x08; //开启PWMA_CCR1预装载功能(需要CC1E=1才可写) PWMA_CCMR2 |= 0x08; PWMA_CCMR3 |= 0x08; PWMA_CCMR4 |= 0x08; PWMA_ARRH = (u8)(PWM_PERIOD >> 8); //设置周期时间 PWMA_ARRL = (u8)PWM_PERIOD; PWMA_ENO = 0x00; PWMA_ENO |= ENO1P; //使能输出 PWMA_ENO |= ENO1N; //使能输出 PWMA_ENO |= ENO2P; //使能输出 PWMA_ENO |= ENO2N; //使能输出 PWMA_ENO |= ENO3P; //使能输出 PWMA_ENO |= ENO3N; //使能输出 PWMA_ENO |= ENO4P; //使能输出 PWMA_ENO |= ENO4N; //使能输出 PWMA_PS = 0x00; //高级 PWM 通道输出脚选择位 PWMA_PS |= PWM1_1; //选择 PWM1_1 通道 PWMA_PS |= PWM2_1; //选择 PWM2_1 通道 PWMA_PS |= PWM3_1; //选择 PWM3_1 通道 PWMA_PS |= PWM4_1; //选择 PWM4_1 通道 PWMA_BKR = 0x80; //使能主输出 PWMA_CR1 |= 0x81; //使能ARR预装载,开始计时 P40 = 0; //给LED供电 EA = 1; //打开总中断
3.2 更新PWM的占空比函数:
void UpdatePwm(void)
{
PWMA_CCR1H = (u8)(PWM1_Duty >> 8); //设置占空比时间
PWMA_CCR1L = (u8)(PWM1_Duty);
PWMA_CCR2H = (u8)(PWM2_Duty >> 8); //设置占空比时间
PWMA_CCR2L = (u8)(PWM2_Duty);
PWMA_CCR3H = (u8)(PWM3_Duty >> 8); //设置占空比时间
PWMA_CCR3L = (u8)(PWM3_Duty);
PWMA_CCR4H = (u8)(PWM4_Duty >> 8); //设置占空比时间
PWMA_CCR4L = (u8)(PWM4_Duty);
}3.3 定时器0的处理函数:
void timer0(void) interrupt 1
{
if(!PWM1_Flag)
{
PWM1_Duty++;
if(PWM1_Duty > PWM_PERIOD) PWM1_Flag = 1;
}
else
{
PWM1_Duty--;
if(PWM1_Duty <= 0) PWM1_Flag = 0;
}
if(!PWM2_Flag)
{
PWM2_Duty++;
if(PWM2_Duty > PWM_PERIOD) PWM2_Flag = 1;
}
else
{
PWM2_Duty--;
if(PWM2_Duty <= 0) PWM2_Flag = 0;
}
if(!PWM3_Flag)
{
PWM3_Duty++;
if(PWM3_Duty > PWM_PERIOD) PWM3_Flag = 1;
}
else
{
PWM3_Duty--;
if(PWM3_Duty <= 0) PWM3_Flag = 0;
}
if(!PWM4_Flag)
{
PWM4_Duty++;
if(PWM4_Duty > PWM_PERIOD) PWM4_Flag = 1;
}
else
{
PWM4_Duty--;
if(PWM4_Duty <= 0) PWM4_Flag = 0;
}
UpdatePwm();
}四:实物测试图片如下所示:

我要赚赏金
