硬件:AC7811通用开发板
软件:Keil 5.23
PWM模块功能很强大,在很多应用场景中非常常见。AC7811的PWM支持输入捕获、输出比较、PWM信号生成。每种功能都有例程帮助学习,但例程是使用接口函数实现的,这里介绍一下操作寄存器实现各个功能。
一、PWM信号生成
以下实现PWM1的CH0生成PWM
1.首先,AC7811的每个模块都有独立的时钟开关,未用到的模块可关闭时钟,节省功耗。在需要使用时需先打开相应的时钟。
CKGEN_Enable(CLK_PWM1_APB, 1);
CKGEN_Enable(CLK_PWM1_TIMER,1);
CKGEN_SoftReset(SRST_PWM1_APB, 1);
CKGEN_SoftReset(SRST_PWM1_TIMER, 1);
2.PWM功能实现,500HZ
PWM1->INIT = 0;
PWM1->INIT |= 1<<3; //PWM时钟选择系统时钟,不使能中断
PWM1->INIT |= (PWM_PRESCALE)<<8; //分频,PWM_PRESCALE为宏定义分频系数
PWM1->CNT = 0;
PWM1->MCVR = PWM_FRE; //最大计数值,决定PWM的频率
PWM1->CHANNELS[0].CHSCR = PWM_CHSCR_MSR1_Msk | PWM_CHSCR_ELSR1_Msk; //CH0为边沿对齐PWM模式,高有效脉冲
PWM1->CHANNELS[0].CHV = PWM1_CH0_duty;//PWM1_CH0_duty;//占空比数值
其中,PWM_PRESCALE和 PWM_FRE为宏定义,
#define PWM_PRESCALE (48-1) //PWM时钟分频
#define PWM_FRE (2000-1) //PWM频率值,fre=48M/48/2000= 500hz
可通过修改PWM1->CHANNELS[0].CHV的值来改变占空比。
二、PWM输入捕获
用PWM2捕获PWM1生成波形的频率和占空比,硬件上需将PD3与PB15相连
1.打开PWM2模块时钟
CKGEN_Enable(CLK_PWM2_APB, 1);
CKGEN_Enable(CLK_PWM2_TIMER,1);
CKGEN_SoftReset(SRST_PWM2_APB, 1);
CKGEN_SoftReset(SRST_PWM2_TIMER, 1);
2.配置PWM2为输入捕获
PWM2->INIT = 0;
PWM2->INIT |= 1<<3;//PWM时钟选择系统时钟,不使能中断
PWM2->INIT |= (100-1)<<8; //分频 48M/4800 =10K
PWM2->MCVR = 0XFFFF; //最大计数值
PWM2->FUNCSEL |=1;//PWM使能
PWM2->MODESEL =0;
PWM2->MODESEL |=(1<<2);//CH0双边沿捕获使能
PWM2->CHANNELS[0].CHSCR &= ~PWM_CHSCR_CHIF_Msk;
PWM2->CHANNELS[1].CHSCR &= ~PWM_CHSCR_CHIF_Msk;
PWM2->CHANNELS[0].CHSCR = PWM_CHSCR_MSR0_Msk | PWM_CHSCR_ELSR0_Msk; //CH0双边沿捕获,上升沿
PWM2->CHANNELS[1].CHSCR = PWM_CHSCR_MSR0_Msk | PWM_CHSCR_ELSR1_Msk; //CH1双边沿捕获,连续捕获,下降沿
/*把CH2N设为上升沿,CH2N+1设为下降沿,当出现上升沿时,CH2N记录当前的count值;
当出现下降沿,CH2N+1记录当前的count值,并在CH2N+1捕获到下降沿时产生通道中断*/
PWM2->MODESEL |= 1<<3;//双边沿捕获有效
PWM_SetCallback(PWM2, PWM2_CaptureCallBack); //设置中断回调函数
NVIC_EnableIRQ(PWM2_IRQn); //使能中断
PWM_EnableChannelInt(PWM2, PWM_CHANNEL_CHANNEL1);
3.捕获PWM数据
void PWM2_CaptureCallBack(void)
{
if(PWM_GetOverFlowFlag(PWM2)) //计数器溢出中断
{
PWM_ClrOverFlowFlag(PWM2);
}
else
{
//判断CH1是否产生中断
if (PWM_GetChannelIntFlag(PWM2, PWM_CHANNEL_CHANNEL1))
{
PWM_ClrChannelIntFlag(PWM2, PWM_CHANNEL_CHANNEL1);//清除中断标志位
//获取CH0/CH1对应的计数值
PWM_Capture.CH0value = PWM2->CHANNELS[0].CHV;
PWM_Capture.CH1value = PWM2->CHANNELS[1].CHV;
PWM2->CNT =0; //读取完数据后,必须将计数寄存器清零
//如果CH1计数值小于CH0计数值,说明CH1有溢出,计算前需加上溢出值
if (PWM_Capture.CH1value < PWM_Capture.CH0value)
{
PWM_Capture.CH1value = PWM_Capture.CH1value + 0xffff;
}
//PWM时钟 = 48M/100 = 480000HZ
PWM_Capture.fre = 480000/PWM_Capture.CH1value;
PWM_Capture.duty = (PWM_Capture.CH1value-PWM_Capture.CH0value)*100/PWM_Capture.CH1value;
}
}
}
通过在线调试,可观察到捕获得到的频率与占空比值与实际对应
pwm.rar
(1.37 MB)
|