OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 3108|回复: 3

4个通道的PWM输入捕获,其中一个有影响

[复制链接]

2

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
94
金钱
94
注册时间
2016-3-24
在线时间
28 小时
发表于 2016-3-28 17:12:05 | 显示全部楼层 |阅读模式
本人最近在做四轴飞行器,用天地飞6A来做遥控器,通过PWM输入捕获来采集接收机过来的4个PWM信号。采集程序是改了原子哥的输入捕获例程而来的程序,开了TIM5的四个通道(A0、A1、A2、A3)来采集。今天在测试的时候发现一个问题,作了仿真等等试验手段还是暂时没有找到问题,现在也是一头雾水,不知道从何下手。故发帖来问问大神们看能不能帮小弟找出问题所在,不胜感激。故障说明:能正确的采集各个通道的PWM,同时通过LED灯(TIM1->CCR1),来知晓PWM的大小。即我通过遥控的摇杆能改变LED灯的强弱,说明一切都是正常的。就是不知道为什么,通道4的信号居然会影响到通道3的信号而通道3的信号却不会影响到通道4的信号。同时,通道1跟通道2是不会有互相影响的情况就出现。就是不知道为什么通道4的信号会影响通道3,其他正常的。本人配置寄存器的时候是查手册一个一个配置的,出现问题后也是检查过几次,确保硬件跟寄存器配置是没问题(或者是有问题暂时还没有发现)。所以发帖想让大家帮我看看,希望能够有所点拨,让我明白问题所在,谢谢各位了!现在附上程序:
//定时器5通道1、通道2、通道3、通道4输入捕获配置
//arr:自动重装值
//psc:时钟预分频数
void TIM5_Cap_Init(u16 arr,u16 psc)
{                 
        RCC->APB1ENR|=1<<3;           //TIM5 时钟使能
        RCC->APB2ENR|=1<<2;            //使能PORTA时钟  
         
        GPIOA->CRL&=0XFFFF0000;        //PA0、PA1、PA2、PA3清除之前设置  
        GPIOA->CRL|=0X00008888;        //PA0、PA1、PA2、PA3 输入   
        GPIOA->ODR|=0<<0;                //PA0 下拉
        GPIOA->ODR|=0<<1;                //PA1 下拉
        GPIOA->ODR|=0<<2;                //PA2 下拉
        GPIOA->ODR|=0<<3;                //PA3 下拉

        TIM5->ARR=arr;                  //设定计数器自动重装值   
        TIM5->PSC=psc;                  //预分频器

        TIM5->CCMR1|=1<<0;                //CC1S=01         选择输入端 IC1映射到TI1上
        TIM5->CCMR1|=0<<4;                 //IC1F=0000 配置输入滤波器 不滤波
        TIM5->CCMR1|=0<<10;         //IC2PS=00         配置输入分频,不分频
        TIM5->CCMR1|=1<<8;                //CC2S=01         选择输入端 IC2映射到TI2上       
        TIM5->CCMR1|=0<<12;         //IC2F=0000 配置输入滤波器 不滤波
        TIM5->CCMR1|=0<<10;         //IC2PS=00         配置输入分频,不分频
        TIM5->CCMR2|=1<<0;                //CC3S=01         选择输入端 IC3映射到TI3上       
        TIM5->CCMR2|=0<<4;                 //IC3F=0000 配置输入滤波器 不滤波
        TIM5->CCMR2|=0<<2;           //IC3PS=00         配置输入分频,不分频
        TIM5->CCMR2|=1<<8;                //CC4S=01         选择输入端 IC4映射到TI4上       
        TIM5->CCMR2|=0<<12;         //IC4F=0000 配置输入滤波器 不滤波
        TIM5->CCMR2|=0<<10;         //IC4PS=00         配置输入分频,不分频

        TIM5->CCER|=0<<1;                 //CC1P=0        上升沿捕获
        TIM5->CCER|=1<<0;                 //CC1E=1         允许捕获计数器的值到捕获寄存器中
        TIM5->CCER|=0<<5;                 //CC2P=0        上升沿捕获
        TIM5->CCER|=1<<4;                 //CC2E=1         允许捕获计数器的值到捕获寄存器中
        TIM5->CCER|=0<<9;                 //CC3P=0        上升沿捕获
        TIM5->CCER|=1<<8;                 //CC3E=1         允许捕获计数器的值到捕获寄存器中
        TIM5->CCER|=0<<13;                 //CC4P=0        上升沿捕获
        TIM5->CCER|=1<<12;                 //CC4E=1         允许捕获计数器的值到捕获寄存器中

        TIM5->DIER|=1<<1;           //允许捕获1中断                               
        TIM5->DIER|=1<<2;           //允许捕获2中断               
        TIM5->DIER|=1<<3;           //允许捕获3中断               
        TIM5->DIER|=1<<4;           //允许捕获4中断               
        TIM5->DIER|=1<<0;           //允许更新中断       
        TIM5->CR1|=0x01;            //使能定时器5
        MY_NVIC_Init(2,0,TIM5_IRQn,2);//抢占2,子优先级0,组2          
}

//TIM5捕获状态
//[7]:0,没有成功的捕获;1,成功捕获到一次.
//[6]:0,还没捕获到高电平;1,已经捕获到高电平了.
//[5:0]:捕获高电平后溢出的次数
u8  TIM5CH1_CAPTURE_STA=0;        //CH1输入捕获状态                                                   
u16        TIM5CH1_CAPTURE_VAL;          //CH1输入捕获值

u8  TIM5CH2_CAPTURE_STA=0;        //CH2输入捕获状态                                                   
u16        TIM5CH2_CAPTURE_VAL;          //CH2输入捕获值

u8  TIM5CH3_CAPTURE_STA=0;        //CH3输入捕获状态                                                   
u16        TIM5CH3_CAPTURE_VAL;          //CH3输入捕获值

u8  TIM5CH4_CAPTURE_STA=0;        //CH4输入捕获状态                                                   
u16        TIM5CH4_CAPTURE_VAL;          //CH4输入捕获值
u16 TIM5_duty_a;
u16 TIM5_duty_b;
//定时器5中断服务程序         
void TIM5_IRQHandler(void)
{                     
        u16 tsr;
        tsr=TIM5->SR;
        if((TIM5CH1_CAPTURE_STA&0X80)==0)//还未成功捕获       
        {
                if(tsr&0X01)//溢出
                {            
                        if(TIM5CH1_CAPTURE_STA&0X40)//已经捕获到高电平了
                        {
                                if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
                                {
                                        TIM5CH1_CAPTURE_STA|=0X80;//标记成功捕获了一次
                                        TIM5CH1_CAPTURE_VAL=0XFFFF;
                                }else TIM5CH1_CAPTURE_STA++;
                        }         
                }
        }
       
        if((TIM5CH2_CAPTURE_STA&0X80)==0)//还未成功捕获       
        {
                if(tsr&0X01)//溢出
                {            
                        if(TIM5CH2_CAPTURE_STA&0X40)//已经捕获到高电平了
                        {
                                if((TIM5CH2_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
                                {
                                        TIM5CH2_CAPTURE_STA|=0X80;//标记成功捕获了一次
                                        TIM5CH2_CAPTURE_VAL=0XFFFF;
                                }else TIM5CH2_CAPTURE_STA++;
                        }         
                }               
        }       

        if((TIM5CH3_CAPTURE_STA&0X80)==0)//还未成功捕获       
        {
                if(tsr&0X01)//溢出
                {            
                        if(TIM5CH3_CAPTURE_STA&0X40)//已经捕获到高电平了
                        {
                                if((TIM5CH3_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
                                {
                                        TIM5CH3_CAPTURE_STA|=0X80;//标记成功捕获了一次
                                        TIM5CH3_CAPTURE_VAL=0XFFFF;
                                }else TIM5CH3_CAPTURE_STA++;
                        }         
                }
        }
       
        if((TIM5CH4_CAPTURE_STA&0X80)==0)//还未成功捕获       
        {
                if(tsr&0X01)//溢出
                {            
                        if(TIM5CH4_CAPTURE_STA&0X40)//已经捕获到高电平了
                        {
                                if((TIM5CH4_CAPTURE_STA&0X3F)==0X3F)//高电平太长了
                                {
                                        TIM5CH4_CAPTURE_STA|=0X80;//标记成功捕获了一次
                                        TIM5CH4_CAPTURE_VAL=0XFFFF;
                                }else TIM5CH4_CAPTURE_STA++;
                        }         
                }               
        }       
       
                if(tsr&0x02)//捕获1(CH1)发生捕获事件
                {       
                        if(TIM5CH1_CAPTURE_STA&0X40)                //捕获到一个下降沿                
                        {                                 
                                TIM5CH1_CAPTURE_STA|=0X80;                //标记成功捕获到一次高电平脉宽
                          TIM5CH1_CAPTURE_VAL=TIM5->CCR1;        //获取当前的捕获值.
                                 TIM5->CCER&=~(1<<1);                        //CC1P=0 设置为上升沿捕获
                        }else                                                                  //还未开始,第一次捕获上升沿
                        {
                                TIM5CH1_CAPTURE_STA=0;                        //清空
                                TIM5CH1_CAPTURE_VAL=0;    //
                                TIM5CH1_CAPTURE_STA|=0X40;                //标记捕获到了上升沿
                                 TIM5->CNT=0;                                        //计数器清空
                                 TIM5->CCER|=1<<1;                                 //CC1P=1 设置为下降沿捕获
                        }                    
                }       

                if(tsr&0x04)//捕获2(CH2)发生捕获事件
                {       
                        if(TIM5CH2_CAPTURE_STA&0X40)                //捕获到一个下降沿                
                        {                                 
                                TIM5CH2_CAPTURE_STA|=0X80;                //标记成功捕获到一次高电平脉宽
                          TIM5CH2_CAPTURE_VAL=TIM5->CCR2;        //获取当前的捕获值.(采集PWM值)
                                TIM5->CCER&=~(1<<5);                        //CC2P=0 设置为上升沿捕获
                        }else                                                                  //还未开始,第一次捕获上升沿
                        {
                                TIM5CH2_CAPTURE_STA=0;                        //清空
                                TIM5CH2_CAPTURE_VAL=0;    //
                                TIM5CH2_CAPTURE_STA|=0X40;                //标记捕获到了上升沿
                                 TIM5->CNT=0;                                        //计数器清空
                                 TIM5->CCER|=1<<5;                                 //CC2P=1 设置为下降沿捕获
                        }                    
                }               
               
                if(tsr&0x08)//捕获3(CH3)发生捕获事件
                {       
                        if(TIM5CH3_CAPTURE_STA&0X40)                //捕获到一个下降沿                
                        {                                 
                                TIM5CH3_CAPTURE_STA|=0X80;                //标记成功捕获到一次高电平脉宽
                          TIM5CH3_CAPTURE_VAL=TIM5->CCR3;        //获取当前的捕获值.(采集PWM值)
                                TIM5->CCER&=~(1<<9);                        //CC3P=0 设置为上升沿捕获
                        }else                                                                  //还未开始,第一次捕获上升沿
                        {
                                TIM5CH3_CAPTURE_STA=0;                        //清空
                                TIM5CH3_CAPTURE_VAL=0;    //
                                TIM5CH3_CAPTURE_STA|=0X40;                //标记捕获到了上升沿
                                 TIM5->CNT=0;                                        //计数器清空
                                 TIM5->CCER|=1<<9;                                 //CC3P=1 设置为下降沿捕获
                        }                    
                }               
               
                if(tsr&0x10)//捕获4(CH4)发生捕获事件
                {       
                        if(TIM5CH4_CAPTURE_STA&0X40)                //捕获到一个下降沿                
                        {                                 
                                TIM5CH4_CAPTURE_STA|=0X80;                //标记成功捕获到一次高电平脉宽
                          TIM5CH4_CAPTURE_VAL=TIM5->CCR4;        //获取当前的捕获值.(采集PWM值)
                                TIM5->CCER&=~(1<<13);                        //CC4P=0 设置为上升沿捕获
                        }else                                                                  //还未开始,第一次捕获上升沿
                        {
                                TIM5CH4_CAPTURE_STA=0;                        //清空
                                TIM5CH4_CAPTURE_VAL=0;    //
                                TIM5CH4_CAPTURE_STA|=0X40;                //标记捕获到了上升沿
                                 TIM5->CNT=0;                                        //计数器清空
                                 TIM5->CCER|=1<<13;                                 //CC4P=1 设置为下降沿捕获
                        }                    
                }                                                                                                                                  
        TIM5->SR=0;//清除中断标志位             
}

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
94
金钱
94
注册时间
2016-3-24
在线时间
28 小时
 楼主| 发表于 2016-3-28 17:15:15 | 显示全部楼层
本人写的程序如下:程序是初版的测试程序,能看,以后还是得优化的,请强迫症者勿喷。恳求各位大神能帮我找出问题,让我好解决这个困扰,谢谢了!

CCS_天地飞遥控程序-4通道.rar

670.07 KB, 下载次数: 730

回复 支持 反对

使用道具 举报

2

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
94
金钱
94
注册时间
2016-3-24
在线时间
28 小时
 楼主| 发表于 2016-4-5 15:59:30 | 显示全部楼层
先跟大家道个歉先!之前自己所说的问题,其实是自己为了赶时间一时马虎,把一个寄存器的配置写错了所以才出现了干扰的问题。在做仿真的时候,比较烦躁没有用心看,才没发现问题所在。今天下午有时间就把之前的程序再拿出来检查下,就知道当时自己出的问题是多么幼稚跟可笑了!希望大家以我这件事为反例,以后能戒浮戒躁,细心打磨才能出好的产品。稳定的遥控程序如下,有需要的请下载。写得比较粗略,望勿喷。

CCS_天地飞遥控4通道_稳定操作.rar

671.33 KB, 下载次数: 675

回复 支持 反对

使用道具 举报

2

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
94
金钱
94
注册时间
2016-3-24
在线时间
28 小时
 楼主| 发表于 2016-4-19 15:05:43 | 显示全部楼层
这个才是对的,上次没看清楚把调试的版本发上去了,上次那个是有点问题的,不好意思啊~

CCS_天地飞遥控4通道_稳定操作.rar

676.8 KB, 下载次数: 747

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-18 00:17

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表