[学习笔记]

AC7811的PWM模块捕获功能——寄存器实现

[复制链接]
801|2
手机看帖
扫描二维码
随时随地手机跟帖
wangjj19950516|  楼主 | 2020-9-9 19:55 | 显示全部楼层 |阅读模式
硬件: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)

使用特权

评论回复

相关帖子

zeshoufx| | 2020-9-10 09:25 | 显示全部楼层
谢谢分享【AC7811的PWM模块捕获功能——寄存器实现】

使用特权

评论回复
marginer| | 2020-9-14 10:12 | 显示全部楼层
手把手教大家用PWM,赞

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

24

主题

86

帖子

2

粉丝