OpenEdv-开源电子网

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

求助,PWM和ADC中断转换,PWM不正常

[复制链接]

1

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
130
金钱
130
注册时间
2019-5-4
在线时间
40 小时
发表于 2019-6-1 10:11:46 | 显示全部楼层 |阅读模式
10金钱
       我刚学STM32,板子是F103mini,这个困扰我好几天了,麻烦解答一下,感激不尽!!!

       PWM、ADC单独使用都没问题。我是用定时器1输出PWM来控制舵机,ADC转换传感器的模拟量(ADC中断读取,禁止扫描模式,连续转换,ADC时钟9MHZ)。通过ADC转换后的数值来判断情况,再调PWM占空比。但两个一起用就不行,原本舵机我让它0~180度来回转动,加了ADC初始化后,舵机就一卡一卡的。用示波器看PWM的波形,它变化幅度、频率都不稳定。(是不是我的ADC采样时间有问题)

      同样PWM加上个基本定时器中断之后(500ms输出一次串口,输出操作是写在主函数里的),PWM和串口都用不了,单独使用没问题。基本定时器初始化用了就立马不行。是定时器中断太频繁了影响PWM吗?还是PWM的定时器初始化和基本定时器初始化哪里冲突了?刚学32,好多不懂,求解答!谢谢了

最佳答案

查看完整内容[请看2#楼]

今天换了个ADC+DMA读取就没影响了。虽然不知道为什么ADC中断不行,但不管了
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

1

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
130
金钱
130
注册时间
2019-5-4
在线时间
40 小时
 楼主| 发表于 2019-6-1 10:11:47 来自手机 | 显示全部楼层
edmund1234 发表于 2019-6-2 15:32
unsigned char x=45;
改为
unsigned short x=45;

今天换了个ADC+DMA读取就没影响了。虽然不知道为什么ADC中断不行,但不管了
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-6-1 17:33:05 | 显示全部楼层
把代码贴出来吧
回复

使用道具 举报

1

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
130
金钱
130
注册时间
2019-5-4
在线时间
40 小时
 楼主| 发表于 2019-6-1 17:53:43 | 显示全部楼层
PWM、ADC、串口.zip (7.34 MB, 下载次数: 36)
回复

使用道具 举报

1

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
130
金钱
130
注册时间
2019-5-4
在线时间
40 小时
 楼主| 发表于 2019-6-1 17:56:11 | 显示全部楼层
本帖最后由 ExtremeHoly 于 2019-7-10 20:35 编辑

        #include "stm32f10x.h"
        #include "bsp_usart.h"
        #include "bsp_adc.h"
        #include "pwm.h"
        #include "bsp_TiMbase.h"
        #include "led.h"
        #include "delay.h"

    void ALL_Init(void);                        /*  多个模块初始化*/
        void PWM_around(void);                        /*  循环转动舵机*/
        void Scan_fire(void);                        /*  扫描到目标时操作*/
        void Usart_printf(void);                /*  串口定时器中断输出AD值*/        
        void delay__ms(u16 time);                /*  简易延时     */

        extern __IO uint16_t ADC_ConvertedValue;        
        float ADC_ConvertedValueLocal;         /* 局部变量,用于保存转换计算后的电压值 */
        volatile uint32_t time = 0;                /* ms 定时器中断计时变量*/        
        unsigned char x=45;


        



        /*主函数*/
/************************************************************************************************/
        
/************************************************************************************************/


        int main(void)
        {        
               
                ALL_Init();                                        //  多个模块初始化

               
                while (1)
                {
                        PWM_around();                        //  循环转动舵机
                                       
                        Usart_printf();                        //  定时器中断串口输出AD值
               
                        Scan_fire();                        //  扫描到目标时操作
                        
                }
        }

        
/************************************************************************************************/
        
/************************************************************************************************/

        

        
        
        
        
        
        
        

        /*模块初始化*/
/************************************************************************************************/
        void ALL_Init(void)
        {
        
                USART_Config();                                        // 配置串口                                
                ADCx_Init();                                        // ADC 初始化                                
                TIM1_PWM_Init(1799,799);                //分频。PWM频率 = 72000,000/(7199+1)/(199+1) = 50 hz =0.02s=20ms
                LED_Init ();
                delay_init();
                BASIC_TIM_Init();                                //基本定时器



        }
/************************************************************************************************/


        

        
        /*舵机来回转动*/
/************************************************************************************************/
        
        void PWM_around(void)
        {
                        TIM1->CCR1=x;
                        x+=2;
                        delay__ms(17);
//                while(time%25!=0);
                                       
                                       
                        if(x>=225)
                         {
                                                
                                for(x=225;x>=45;x-=2)
                                 {
                                       
                                        TIM1->CCR1=x;
                                        delay__ms(17);
//                                        while(time%25!=0);
                                         
                                 }
                                                        
                         }

        }
/************************************************************************************************/

        
        

        /*扫描目标时*/
/************************************************************************************************/

        void Scan_fire(void)
         {

                if(ADC_ConvertedValueLocal<=3000)
                  {
                        
                        GPIO_ResetBits(GPIOD,GPIO_Pin_2);        //低电平点亮LED
                        
                        
                        printf("\r\n已扫描到目标\r\n");                          
                        printf("\r\n\r\n");
                  }        
        
                else

                 {
                        GPIO_SetBits(GPIOD,GPIO_Pin_2);  //设置高电平

               
                 }
                                       

        }        
/************************************************************************************************/
        

        
        

        
        
        
        
        
        
        /*串口输出AD值*/
/************************************************************************************************/

        void Usart_printf(void)
        {

                if ( time == 500 )                 //        定时器中断   ms
                {
                          time = 0;

                        ADC_ConvertedValueLocal =(float) ADC_ConvertedValue;        //        ADC_ConvertedValueLocal        值最高4096        
                        printf("\r\n The current AD value = 0x%04X \r\n",  ADC_ConvertedValue);
                        printf("\r\n The current AD value = %f V \r\n", ADC_ConvertedValueLocal);
                        printf("\r\n\r\n");               
                }         
        

        
        }

/************************************************************************************************/

        
        
        
        
        
        /*基本定时器中断        */
/************************************************************************************************/
        
                void  BASIC_TIM_IRQHandler (void)
        {


                if ( TIM_GetITStatus( BASIC_TIM, TIM_IT_Update) != RESET )
                {        
                        time++;
                        TIM_ClearITPendingBit(BASIC_TIM , TIM_FLAG_Update);  


                }                        
        }
        
/************************************************************************************************/
        
        
        
        
               
        
        
                        /*简单延时ms*/
/************************************************************************************************/

        void delay__ms(u16 time)
        {   
           u16 i=0;  
           while(time--)
           {
                  i=12000;  
                  while(i--) ;   
           }
        }
/************************************************************************************************/

        
        
        
        

回复

使用道具 举报

1

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
130
金钱
130
注册时间
2019-5-4
在线时间
40 小时
 楼主| 发表于 2019-6-1 17:59:32 | 显示全部楼层

嗯,我把main放下面了,完整的下面也上传了附件,麻烦看看
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-6-1 20:01:54 | 显示全部楼层
ExtremeHoly 发表于 2019-6-1 17:59
嗯,我把main放下面了,完整的下面也上传了附件,麻烦看看


uint16_t        PwmC=17;


int main(void)
    {   
        
        ALL_Init();                    //  多个模块初始化

        
        while (1)
        {
            if (!PwmC) {
                PwmC=17;

                PWM_around();            //  循环转动舵机
            }
                    
            Usart_printf();            //  定时器中断串口输出AD值
        
            Scan_fire();            //  扫描到火焰时操作
            
        }
    }



  void PWM_around(void)
    {
            static u8 Mode=0;
        
            TIM1->CCR1=x;
        
            if (!Mode){        // 45 to 255
                    x+=2;
                    if (x>=255) {
                        Mode=1;
                        x=255;
                    }
            }
            else{
                x-=2;
                if (x<=45){
                    Mode=0;
                    x=45;
                }
            }

    }

    void  BASIC_TIM_IRQHandler (void)
    {


        if ( TIM_GetITStatus( BASIC_TIM, TIM_IT_Update) != RESET )
        {   
            time++;
            if (PwmC)
                PwmC--;

            TIM_ClearITPendingBit(BASIC_TIM , TIM_FLAG_Update);  
        }            
    }


只改了红色标记处, 加了一个全局变量, 试一下吧




回复

使用道具 举报

1

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
130
金钱
130
注册时间
2019-5-4
在线时间
40 小时
 楼主| 发表于 2019-6-2 08:40:22 | 显示全部楼层
edmund1234 发表于 2019-6-1 20:01
uint16_t        PwmC=17;

    原本用网上找的  for延时  或者  原子哥例程里拿的delay,都和 定时器中断 串口输出 有冲突。现在PWM和串口输出延时都用定时器中断,好多了。
     不过ADC用了还是不行,用了ADC之后,转动速度快了好多(像是直接从 0度占空比 到 180度占空比 转动)。转动范围也逐渐减小,之后又逐渐增大,就这样循环增大减小。
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-6-2 14:00:02 | 显示全部楼层
ExtremeHoly 发表于 2019-6-2 08:40
原本用网上找的  for延时  或者  原子哥例程里拿的delay,都和 定时器中断 串口输出 有冲突。现在PWM ...

什么意思?还是不正常?
回复

使用道具 举报

1

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
130
金钱
130
注册时间
2019-5-4
在线时间
40 小时
 楼主| 发表于 2019-6-2 14:26:12 来自手机 | 显示全部楼层
edmund1234 发表于 2019-6-2 14:00
什么意思?还是不正常?

不正常,简单说转动速度变快,转完一次来回停顿一两秒,转动范围时大时小
回复

使用道具 举报

3

主题

1907

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4106
金钱
4106
注册时间
2018-8-14
在线时间
696 小时
发表于 2019-6-2 15:32:57 | 显示全部楼层
ExtremeHoly 发表于 2019-6-2 14:26
不正常,简单说转动速度变快,转完一次来回停顿一两秒,转动范围时大时小

unsigned char x=45;
改为
unsigned short x=45;
回复

使用道具 举报

1

主题

29

帖子

0

精华

初级会员

Rank: 2

积分
130
金钱
130
注册时间
2019-5-4
在线时间
40 小时
 楼主| 发表于 2019-6-2 22:42:50 | 显示全部楼层
edmund1234 发表于 2019-6-2 15:32
unsigned char x=45;
改为
unsigned short x=45;

改了还是一样.....这个好消磨耐心和信心啊,真是太麻烦你了
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-17 10:01

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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