查看: 4912|回复: 5

卢老师请看一下STM32在UCOSII下进TIM2中断异常

[复制链接]
  • TA的每日心情
    开心
    2014-10-5 15:14
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2014-10-5 15:13:42 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 lj250668420 于 2014-10-5 15:21 编辑

    用的是ST3.5的库函数,uCOS-II是用的是2.91版本.在程序中创建了一个LED-red+500ms延时取反的任务,另外还想做一个TIM2的定时器,每个1秒进一次定时器中断取反另一个小灯.也就是一个任务用延时来控制小灯亮灭,另外在写一个定时器2的定时中断函数来控制另一个小灯的亮灭.现在的情况时两个小灯,A闪烁,B不闪烁,然后过一会儿(时间不固定但肯定是超过了我设定的0.5秒和1秒的)变成A不闪烁B闪烁.好苦恼已经看了几天的资料了没有解决办法.下面贴出源码
    1. int main(void)
    2. {
    3.           BSP_Init();
    4.         OSInit();
    5.         OSTaskCreate(Task_LED_RED,(void *)0,
    6.            &Task_LED_RED_SKT[Task_LED_RED_STK_SIZE-1], Task_LED_RED_PRIO);
    7.         OSStart();
    8.     return 0;
    9. }
    复制代码
    1. void Task_LED_RED(void *p_arg)
    2. {
    3.     (void)p_arg;                                // 'p_arg' 并没有用到,防止编译器提示警告

    4.     while (1)
    5.     {
    6.                 printf("\r\n 小灯 \r\n");
    7.                 LED_RED=!LED_RED;
    8.         OSTimeDlyHMSM(0, 0,0,500);
    9.     }
    10. }
    复制代码
    1. void BSP_Init(void)
    2. {        
    3.         RCC_Configuration();                //配置系统时钟为72M  
    4.         TIM2_Configuration();                //定时器2配置
    5.         SysTick_init();                                //初始化并使能SysTick定时器  
    6.     LED_GPIO_Config();                  //LED 端口初始化
    7.         USART1_Config();
    8. }

    9. /*
    10. * 函数名:SysTick_init
    11. * 描述  :配置SysTick定时器
    12. * 输入  :无
    13. * 输出  :无
    14. */
    15. void SysTick_init(void)
    16. {
    17.     SysTick_Config(SystemCoreClock/OS_TICKS_PER_SEC);//初始化并使能SysTick定时器
    18. }
    19. void RCC_Configuration(void)
    20. {
    21.         ErrorStatus     HSEStartUpStatus;                                                        //定义枚举类型变量HSEStartUpStatus
    22.         RCC_DeInit();                                                                                                  //复位系统时钟
    23.         RCC_HSEConfig(RCC_HSE_ON);                                                                          //开启HSE
    24.         HSEStartUpStatus=RCC_WaitForHSEStartUp();                                         //等待HSE稳定起振
    25.         
    26.         if(HSEStartUpStatus==SUCCESS)                                                                //如果HSE稳定起振                                                                 
    27.         {                 
    28.                 RCC_HCLKConfig(RCC_SYSCLK_Div1);                                    //选择HCLK(AHB)时钟源为SYSCLK 1分频                 
    29.                 RCC_PCLK2Config(RCC_HCLK_Div1);                                   //选择PCLK2时钟源为HCLK(AHB) 1分频                 
    30.                 RCC_PCLK1Config(RCC_HCLK_Div2);                                   //选择PLCK1时钟源为HCLK(AHB) 2分频         
    31.                 FLASH_SetLatency(FLASH_Latency_2);                                   //设置FLASH延时周期数为2                  
    32.                 FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);         //使能FLASH预取缓存               
    33.                 RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_6);           //选择PLL时钟源为HSE 1分频,倍频数为6,则PLL=12MHz*6=72MHz         
    34.                 RCC_PLLCmd(ENABLE);                                                                           //使能PLL
    35.                 while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);                  //等待PLL输出稳定         
    36.                 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);                                   //以PLL作为系统时钟                  
    37.                 while(RCC_GetSYSCLKSource()!=0x08);                                    //等待PLL成为有效系统时钟源
    38.         }         
    39.         
    40.         RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);                          //各外设时钟使能  RCC_APB1Periph_USART3|
    41.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|
    42.                                                    RCC_APB2Periph_GPIOD|RCC_APB2Periph_ADC1|RCC_APB2Periph_ADC2|RCC_APB2Periph_USART1 ,ENABLE);                        
    43.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2|RCC_APB1Periph_USART2|RCC_APB1Periph_BKP|RCC_APB1Periph_PWR , ENABLE);
    44. }
    45. void TIM2_Configuration(void)
    46. {
    47.         TIM_TimeBaseInitTypeDef          TIM_TimeBaseStructure;                        //定义TIM_TimeBase初始化结构体TIM_TimeBaseStructure
    48.         TIM_OCInitTypeDef                        TIM_OCInitStructure;                        //定义TIM_OCInit初始化结构体TIM_OCInitStructure
    49.         NVIC_InitTypeDef NVIC_InitStructure;                                                //定义NVIC初始化结体NVIC_InitStructure     
    50.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);                         //选择NVIC优先级分组0

    51.         NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;                                //使能TIM2全局中断,0级先占优先级,3级次占有先机         
    52.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    53.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    54.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    55.         NVIC_Init(&NVIC_InitStructure);        
    56.         
    57.         TIM_TimeBaseStructure.TIM_Period=65535;                                                 /* 自动重装载寄存器周期的值(计数值) */
    58.     TIM_TimeBaseStructure.TIM_Prescaler=7199;                                        /* 时钟预分频数*/
    59.     TIM_TimeBaseStructure.TIM_ClockDivision=0;                                         /* 时钟分割 */
    60.     TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;         /* 向上计数模式 */
    61.     TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);
    62.         
    63.         TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_Timing;                        //选择定时器模式为TIM输出比较时间模式
    64.         TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable;        //使能输出比较状态
    65.         TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High;                //TIM输出比较极性高
    66.         TIM_OCInitStructure.TIM_Pulse=10;                                                        //设置了待装入捕获比较寄存器的脉冲值
    67.         TIM_OC1Init(TIM2,&TIM_OCInitStructure);                                                //根据TIM_OCInitStruct中指定的参数初始化TIM2通道1
    68.         TIM_OCInitStructure.TIM_Pulse=100;
    69.         TIM_OC2Init(TIM2,&TIM_OCInitStructure);
    70.         TIM_OCInitStructure.TIM_Pulse=1000;
    71.         TIM_OC3Init(TIM2,&TIM_OCInitStructure);
    72.         TIM_OCInitStructure.TIM_Pulse=10000;
    73.         TIM_OC3Init(TIM2,&TIM_OCInitStructure);

    74.         TIM_OC1PreloadConfig(TIM2,TIM_OCPreload_Disable);                        //失能TIM2在CCR1上的预装载寄存器
    75.         TIM_OC2PreloadConfig(TIM2,TIM_OCPreload_Disable);
    76.         TIM_OC3PreloadConfig(TIM2,TIM_OCPreload_Disable);
    77.         TIM_OC4PreloadConfig(TIM2,TIM_OCPreload_Disable);
    78.         TIM_ITConfig(TIM2,TIM_IT_CC1|TIM_IT_CC2|
    79.                                           TIM_IT_CC3|TIM_IT_CC4,ENABLE);                                        //使能TIM2中断         
    80.         TIM_Cmd(TIM2, ENABLE);                                                                            //定时器2启动
    81. }
    82. void USART1_Config(void)
    83. {
    84.     USART_InitTypeDef  USART_InitStructure;                                                        //定义USART初始化结构体USART_InitStructure
    85.         GPIO_InitTypeDef GPIO_InitStructure;                                                        //定义GPIO初始化结构体GPIO_InitStructure
    86.         NVIC_InitTypeDef NVIC_InitStructure;                                                        //定义NVIC初始化结体NVIC_InitStructure     
    87.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);                                 //选择NVIC优先级分组0

    88.         NVIC_InitStructure.NVIC_IRQChannel =USART1_IRQn ;                                 //使能USART1全局中断,0级先占优先级,0级次占有先机
    89.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    90.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;   
    91.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    92.         NVIC_Init(&NVIC_InitStructure);

    93.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                                                //设置USART1的Tx脚(PA.9)为第二功能推挽输出模式
    94.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    95.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    96.         GPIO_Init(GPIOA, &GPIO_InitStructure);

    97.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;                                                //设置USART1的Rx脚(PA.10)为悬空输入
    98.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    99.         GPIO_Init(GPIOA, &GPIO_InitStructure);

    100.         USART_InitStructure.USART_BaudRate = 115200;                                        //波特率设置
    101.         USART_InitStructure.USART_WordLength = USART_WordLength_8b;                //8位数据长度
    102.         USART_InitStructure.USART_StopBits = USART_StopBits_1;                        //1个停止位
    103.         USART_InitStructure.USART_Parity = USART_Parity_No;                                //奇偶失能
    104.         USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;        //硬件流控制失能
    105.         USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;        //使能发送和接收模式        
    106.         USART_Init(USART1, &USART_InitStructure);                                                //根据USART_InitStruct中指定的参数初始化外设USART1寄存器

    107.         USART_ITConfig(USART1, USART_IT_RXNE,ENABLE);                                        //使能USART1中断        
    108.         USART_ITConfig(USART1, USART_IT_TXE,DISABLE);                                        //失能USART1中断               
    109.     USART_Cmd(USART1, ENABLE);                                                                                //使能USART1
    110.         USART_ClearITPendingBit(USART1, USART_IT_RXNE);
    111.         USART_ClearITPendingBit(USART1, USART_IT_TXE);
    112.         USART_ClearFlag(USART1, USART_FLAG_TXE);                                                //清除发送标志位
    113.         USART_ClearFlag(USART1, USART_FLAG_RXNE);                                                //清除发送标志位
    114. }
    复制代码
    1. void SysTick_Handler(void)
    2. {
    3.         OSIntEnter();
    4.     OSTimeTick();
    5.     OSIntExit();
    6. }

    7. void TIM2_IRQHandler(void)
    8. {         
    9.         vu16 capture=0;                                                                                //当前捕获计数值局部变量
    10.         
    11.         OSIntEnter();

    12.         if(TIM_GetITStatus(TIM2,TIM_IT_CC1)!=RESET)                        //检查TIM2中TIM捕获/比较1中断源发生
    13.         {        
    14.                 capture=TIM_GetCapture1(TIM2);                                        //读取当前计数值
    15.                 TIM_SetCompare1(TIM2,capture+10);                                //根据当前计数值更新输出捕获寄存器
    16.                 TIM_ClearITPendingBit(TIM2,TIM_IT_CC1);
    17.         }else if(TIM_GetITStatus(TIM2,TIM_IT_CC2)!=RESET)
    18.         {
    19.                 capture=TIM_GetCapture2(TIM2);
    20.                 TIM_SetCompare2(TIM2,capture+100);
    21.                 TIM_ClearITPendingBit(TIM2,TIM_IT_CC2);               
    22.         }else if(TIM_GetITStatus(TIM2,TIM_IT_CC3)!=RESET)
    23.         {
    24.                 capture=TIM_GetCapture3(TIM2);
    25.                 TIM_SetCompare3(TIM2,capture+1000);
    26.                 TIM_ClearITPendingBit(TIM2,TIM_IT_CC3);               
    27.         }else if(TIM_GetITStatus(TIM2,TIM_IT_CC3)!=RESET)
    28.         {
    29.                 LED_GREEN=!LED_GREEN;                                                        //小灯控制
    30.                 capture=TIM_GetCapture3(TIM2);
    31.                 TIM_SetCompare3(TIM2,capture+10000);
    32.                 TIM_ClearITPendingBit(TIM2,TIM_IT_CC3);               
    33.         }
    34.         OSIntExit();        
    35. }

    36. void USART1_IRQHandler(void)                                                                //串口1中断函数
    37. {
    38.         OSIntEnter();
    39.         if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)        //检查USART2中接收中断发生与否
    40.         {
    41. //                LED_GREEN=!LED_GREEN;
    42. //                getchar1 = USART_ReceiveData(USART1);
    43. //                Usart_TransData(2,getchar1);
    44.                 USART_ClearITPendingBit(USART1, USART_IT_RXNE);
    45.         }
    46. //        else if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET)
    47. //        {
    48. //                USART_ClearITPendingBit(USART1, USART_IT_TXE);
    49. //        }
    50.         OSIntExit();
    51. }
    复制代码
    程序的串口中断都可以正常的进入,但是定时器这边就出问题.两个小灯,A闪烁,B不闪烁,然后过一会儿(时间不固定但肯定是超过了我设定的0.5秒和1秒的)变成A不闪烁B闪烁.总感觉像是定时器2的配置这里出了问题,是不是中断向量表我弄错了?麻烦大家给指点一下
    回复

    使用道具 举报

  • TA的每日心情

    2021-12-7 12:35
  • 签到天数: 1354 天

    连续签到: 1 天

    [LV.10]以坛为家III

    发表于 2014-10-6 22:32:36 | 显示全部楼层
    下载下来,好好学习,写的好
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2014-10-15 08:59
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2014-10-15 19:07:38 | 显示全部楼层
      学习了,谢谢分享
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2015-1-20 09:02
  • 签到天数: 45 天

    连续签到: 1 天

    [LV.5]常住居民I

    发表于 2014-12-7 18:56:24 | 显示全部楼层
    我是来赚铜板的
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    2015-7-1 15:49
  • 签到天数: 1 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2015-12-4 16:07:34 | 显示全部楼层
    版主是问题,下面都是学习。。。
    神奇
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2018-1-8 15:51
  • 签到天数: 22 天

    连续签到: 1 天

    [LV.4]偶尔看看III

    发表于 2015-12-14 17:07:28 | 显示全部楼层
    我觉得原理上没问题的,可以分部解决
    1.写定时器2的裸奔程序,直到正常
    2. 在带UCOS的程序中,先完成延时部分,直到正常
    3.再加入中断处理,直到正常
    建议在ISR中POST信号量让任务来点灯
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条



    手机版|小黑屋|与非网

    GMT+8, 2024-11-23 22:27 , Processed in 0.181211 second(s), 25 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.