OpenEdv-开源电子网

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

关于通过按键中断控制输出pwm波形,哪位大神好心帮忙看一下,弄了好几天了。。。就是出不来

[复制链接]

5

主题

15

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2017-6-30
在线时间
6 小时
发表于 2017-7-4 17:29:58 | 显示全部楼层 |阅读模式
6金钱
要实现的功能是:通过EXTIX_Init();函数,按键产生中断,在中断服务函数里 EXTI3_IRQHandler();增加pwm的占空比,现在有两个问题:
1.我用按键控制pwm波形,不过总是调不出pwm波,单独做按键和输出pwm波形实验都可以,组合起来按按键,没有反应,产生不了pwm波。2.还有TIM3_PWM_Init(799,199);放在主函数里输出的是20ms的pwm波,放在中断服务函数里产生的就是2ms的pwm波形


下面是主要具体的函数代码(在标准例程上修改的,全部程序在附件中):
主函数:
int main(void)
{               

        delay_init();                     //延时函数初始化          
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
        uart_init(115200);         //串口初始化为115200
        TIM3_PWM_Init(799,199);
        LED_Init();                                  //初始化与LED连接的硬件接口
        //BEEP_Init();                         //初始化蜂鸣器IO
        EXTIX_Init();                 //初始化外部中断输入
        LED0=0;                                        //先点亮红灯
        while(1)
        {            
                printf("OK\r\n");       
                delay_ms(1000);          
        }         
}

中断初始化:
void EXTIX_Init(void)
{

           EXTI_InitTypeDef EXTI_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        KEY_Init();         //        按键端口初始化函数(代码在最后面)

          RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);        //使能复用功能时钟



   //GPIOE.3          中断线以及中断初始化配置 下降沿触发 //KEY1
          GPIO_EXTILineConfig(GPIO_PortSourceGPIOE,GPIO_PinSource3);
          EXTI_InitStructure.EXTI_Line=EXTI_Line3;
          EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;       
          EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
          EXTI_Init(&EXTI_InitStructure);                  //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器

NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;                        //使能按键KEY1所在的外部中断通道
          NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;        //抢占优先级2
          NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01;                                        //子优先级1
          NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                                                //使能外部中断通道
          NVIC_Init(&NVIC_InitStructure);            //根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器

外部中断3服务程序:
void EXTI3_IRQHandler(void)
{
         u16 indexwave[] = {50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,
                            200,210,220,230,240,250,260,270,280,290,300};
                                                                                       
         u16 led0pwmval=0;
         u8 dir=1;       
        delay_ms(10);//消抖
        if(KEY1==0)         //按键KEY1
        {                                 
                delay_ms(10);
                if(dir)led0pwmval++;
                else led0pwmval--;

                if(led0pwmval>26)dir=0;
                if(led0pwmval==0)dir=1;                                                                                 
                TIM_SetCompare2(TIM3,indexwave[led0pwmval]);
        }                 
        EXTI_ClearITPendingBit(EXTI_Line3);  //清除LINE3上的中断标志位  
}

PWM产生函数:
void TIM3_PWM_Init(u16 arr,u16 psc)
{  
        GPIO_InitTypeDef GPIO_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_OCInitTypeDef  TIM_OCInitStructure;
       

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);        //使能定时器3时钟
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB  | RCC_APB2Periph_AFIO, ENABLE);  //使能GPIO外设和AFIO复用功能模块时钟
       
        GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); //Timer3部分重映射  TIM3_CH2->PB5   

   //设置该引脚为复用输出功能,输出TIM3 CH2的PWM脉冲波形        GPIOB.5
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //TIM_CH2
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //复用推挽输出
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化GPIO

   //初始化TIM3
        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
        TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseInitStruct中指定的参数初始化TIMx的时间基数单位
       
        //初始化TIM3 Channel2 PWM模式         
        TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择定时器模式:TIM脉冲宽度调制模式2
        TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
        TIM_OCInitStructure.TIM_Pulse = 0;
        TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
        TIM_OC2Init(TIM3, &TIM_OCInitStructure);  //根据T指定的参数初始化外设TIM3 OC2

        TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);  //使能TIM3在CCR2上的预装载寄存器

        TIM_Cmd(TIM3, ENABLE);  //使能TIM3

}



按键初始化函数
void KEY_Init(void) //IO初始化
{
        GPIO_InitTypeDef GPIO_InitStructure;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE);//使能PORTA,PORTE时钟

        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_4|GPIO_Pin_3;//KEY0-KEY1
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //设置成上拉输入
        GPIO_Init(GPIOE, &GPIO_InitStructure);//初始化GPIOE4,3

        //初始化 WK_UP-->GPIOA.0          下拉输入
        GPIO_InitStructure.GPIO_Pin  = GPIO_Pin_0;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0设置成输入,默认下拉          
        GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.0
}

实验5 外部中断实验.rar

2.72 MB, 下载次数: 459

按键控制pwm波

最佳答案

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

第二、static u16 led0pwmval=0; static u8 dir=1; 把中断里这两个参数改为静态变量。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

21

主题

146

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
467
金钱
467
注册时间
2013-7-12
在线时间
86 小时
发表于 2017-7-4 17:29:59 | 显示全部楼层
第二、static u16 led0pwmval=0;          static u8 dir=1;        把中断里这两个参数改为静态变量。
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165538
金钱
165538
注册时间
2010-12-1
在线时间
2117 小时
发表于 2017-7-5 00:27:43 | 显示全部楼层
再搞几天先
回复

使用道具 举报

21

主题

146

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
467
金钱
467
注册时间
2013-7-12
在线时间
86 小时
发表于 2017-7-5 11:16:34 | 显示全部楼层
第一、你把TIM3_PWM_Init(799,199);放在EXTIX_Init();的后面。(不要问我为什么)
回复

使用道具 举报

5

主题

15

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2017-6-30
在线时间
6 小时
 楼主| 发表于 2017-7-5 15:27:02 | 显示全部楼层
SR_LI 发表于 2017-7-5 11:16
第一、你把TIM3_PWM_Init(799,199);放在EXTIX_Init();的后面。(不要问我为什么)

好的,谢谢,我试一下
回复

使用道具 举报

5

主题

15

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2017-6-30
在线时间
6 小时
 楼主| 发表于 2017-7-5 15:41:54 | 显示全部楼层
SR_LI 发表于 2017-7-5 11:16
第一、你把TIM3_PWM_Init(799,199);放在EXTIX_Init();的后面。(不要问我为什么)

按你说的真的可以了,非常感谢!我查查为什么要这么搞
回复

使用道具 举报

5

主题

15

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2017-6-30
在线时间
6 小时
 楼主| 发表于 2017-7-5 16:30:47 | 显示全部楼层

哈哈,已经搞出来了
回复

使用道具 举报

57

主题

1680

帖子

3

精华

资深版主

Rank: 8Rank: 8

积分
4306
金钱
4306
注册时间
2018-6-30
在线时间
808 小时
发表于 2018-7-13 15:00:33 | 显示全部楼层
哥们,你这程序能够通过按键不停按,灯变得越来越亮吗
业精于勤荒于嬉;行成于思毁于随!
回复

使用道具 举报

20

主题

450

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
4920
金钱
4920
注册时间
2017-7-6
在线时间
721 小时
发表于 2018-7-13 15:20:50 | 显示全部楼层
fucha2 发表于 2017-7-5 15:41
按你说的真的可以了,非常感谢!我查查为什么要这么搞

楼主,知道为啥这么做吗?
我是小白,很白很白的小白!!!
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-15 13:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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