OpenEdv-开源电子网

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

STM32跑uCOU-II中定时器2进中断遇到的问题!原子哥看过来啊看过来

[复制链接]

6

主题

12

帖子

0

精华

初级会员

Rank: 2

积分
72
金钱
72
注册时间
2014-1-8
在线时间
2 小时
发表于 2014-10-5 15:01:03 | 显示全部楼层 |阅读模式
5金钱
用的是ST3.5的库函数,uCOS-II是用的是2.91版本.在程序中创建了一个LED-red+500ms延时取反的任务,另外还想做一个TIM2的定时器,每个1秒进一次定时器中断取反另一个小灯.也就是一个任务用延时来控制小灯亮灭,另外在写一个定时器2的定时中断函数来控制另一个小灯的亮灭.现在的情况时两个小灯,A闪烁,B不闪烁,然后过一会儿(时间不固定但肯定是超过了我设定的0.5秒和1秒的)变成A不闪烁B闪烁.好苦恼已经看了几天的资料了没有解决办法.下面贴出源码
[mw_shl_code=c,true]int main(void) { BSP_Init(); OSInit(); OSTaskCreate(Task_LED_RED,(void *)0, &Task_LED_RED_SKT[Task_LED_RED_STK_SIZE-1], Task_LED_RED_PRIO); OSStart(); return 0; } void BSP_Init(void) { RCC_Configuration(); //配置系统时钟为72M TIM2_Configuration(); //定时器2配置 SysTick_init(); //初始化并使能SysTick定时器 LED_GPIO_Config(); //LED 端口初始化 USART1_Config(); } /* * 函数名:SysTick_init * 描述 :配置SysTick定时器 * 输入 :无 * 输出 :无 */ void SysTick_init(void) { SysTick_Config(SystemCoreClock/OS_TICKS_PER_SEC);//初始化并使能SysTick定时器 } void RCC_Configuration(void) { ErrorStatus HSEStartUpStatus; //定义枚举类型变量HSEStartUpStatus RCC_DeInit(); //复位系统时钟 RCC_HSEConfig(RCC_HSE_ON); //开启HSE HSEStartUpStatus=RCC_WaitForHSEStartUp(); //等待HSE稳定起振 if(HSEStartUpStatus==SUCCESS) //如果HSE稳定起振 { RCC_HCLKConfig(RCC_SYSCLK_Div1); //选择HCLK(AHB)时钟源为SYSCLK 1分频 RCC_PCLK2Config(RCC_HCLK_Div1); //选择PCLK2时钟源为HCLK(AHB) 1分频 RCC_PCLK1Config(RCC_HCLK_Div2); //选择PLCK1时钟源为HCLK(AHB) 2分频 FLASH_SetLatency(FLASH_Latency_2); //设置FLASH延时周期数为2 FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //使能FLASH预取缓存 RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_6); //选择PLL时钟源为HSE 1分频,倍频数为6,则PLL=12MHz*6=72MHz RCC_PLLCmd(ENABLE); //使能PLL while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET); //等待PLL输出稳定 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //以PLL作为系统时钟 while(RCC_GetSYSCLKSource()!=0x08); //等待PLL成为有效系统时钟源 } RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); //各外设时钟使能 RCC_APB1Periph_USART3| RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC| RCC_APB2Periph_GPIOD|RCC_APB2Periph_ADC1|RCC_APB2Periph_ADC2|RCC_APB2Periph_USART1 ,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2|RCC_APB1Periph_USART2|RCC_APB1Periph_BKP|RCC_APB1Periph_PWR , ENABLE); } void TIM2_Configuration(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; //定义TIM_TimeBase初始化结构体TIM_TimeBaseStructure TIM_OCInitTypeDef TIM_OCInitStructure; //定义TIM_OCInit初始化结构体TIM_OCInitStructure NVIC_InitTypeDef NVIC_InitStructure; //定义NVIC初始化结体NVIC_InitStructure NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //选择NVIC优先级分组0 NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //使能TIM2全局中断,0级先占优先级,3级次占有先机 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); TIM_TimeBaseStructure.TIM_Period=65535; /* 自动重装载寄存器周期的值(计数值) */ TIM_TimeBaseStructure.TIM_Prescaler=7199; /* 时钟预分频数*/ TIM_TimeBaseStructure.TIM_ClockDivision=0; /* 时钟分割 */ TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; /* 向上计数模式 */ TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure); TIM_OCInitStructure.TIM_OCMode=TIM_OCMode_Timing; //选择定时器模式为TIM输出比较时间模式 TIM_OCInitStructure.TIM_OutputState=TIM_OutputState_Enable; //使能输出比较状态 TIM_OCInitStructure.TIM_OCPolarity=TIM_OCPolarity_High; //TIM输出比较极性高 TIM_OCInitStructure.TIM_Pulse=10; //设置了待装入捕获比较寄存器的脉冲值 TIM_OC1Init(TIM2,&TIM_OCInitStructure); //根据TIM_OCInitStruct中指定的参数初始化TIM2通道1 TIM_OCInitStructure.TIM_Pulse=100; TIM_OC2Init(TIM2,&TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse=1000; TIM_OC3Init(TIM2,&TIM_OCInitStructure); TIM_OCInitStructure.TIM_Pulse=10000; TIM_OC3Init(TIM2,&TIM_OCInitStructure); TIM_OC1PreloadConfig(TIM2,TIM_OCPreload_Disable); //失能TIM2在CCR1上的预装载寄存器 TIM_OC2PreloadConfig(TIM2,TIM_OCPreload_Disable); TIM_OC3PreloadConfig(TIM2,TIM_OCPreload_Disable); TIM_OC4PreloadConfig(TIM2,TIM_OCPreload_Disable); TIM_ITConfig(TIM2,TIM_IT_CC1|TIM_IT_CC2| TIM_IT_CC3|TIM_IT_CC4,ENABLE); //使能TIM2中断 TIM_Cmd(TIM2, ENABLE); //定时器2启动 } void USART1_Config(void) { USART_InitTypeDef USART_InitStructure; //定义USART初始化结构体USART_InitStructure GPIO_InitTypeDef GPIO_InitStructure; //定义GPIO初始化结构体GPIO_InitStructure NVIC_InitTypeDef NVIC_InitStructure; //定义NVIC初始化结体NVIC_InitStructure NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //选择NVIC优先级分组0 NVIC_InitStructure.NVIC_IRQChannel =USART1_IRQn ; //使能USART1全局中断,0级先占优先级,0级次占有先机 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //设置USART1的Tx脚(PA.9)为第二功能推挽输出模式 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //设置USART1的Rx脚(PA.10)为悬空输入 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 115200; //波特率设置 USART_InitStructure.USART_WordLength = USART_WordLength_8b; //8位数据长度 USART_InitStructure.USART_StopBits = USART_StopBits_1; //1个停止位 USART_InitStructure.USART_Parity = USART_Parity_No; //奇偶失能 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流控制失能 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //使能发送和接收模式 USART_Init(USART1, &USART_InitStructure); //根据USART_InitStruct中指定的参数初始化外设USART1寄存器 USART_ITConfig(USART1, USART_IT_RXNE,ENABLE); //使能USART1中断 USART_ITConfig(USART1, USART_IT_TXE,DISABLE); //失能USART1中断 USART_Cmd(USART1, ENABLE); //使能USART1 USART_ClearITPendingBit(USART1, USART_IT_RXNE); USART_ClearITPendingBit(USART1, USART_IT_TXE); USART_ClearFlag(USART1, USART_FLAG_TXE); //清除发送标志位 USART_ClearFlag(USART1, USART_FLAG_RXNE); //清除发送标志位 } void Task_LED_RED(void *p_arg) { (void)p_arg; // 'p_arg' 并没有用到,防止编译器提示警告 STARTUP_TASK_PRIO2); while (1) { printf("\r\n 小灯 \r\n"); LED_RED=!LED_RED; OSTimeDlyHMSM(0, 0,0,500); } } void TIM2_IRQHandler(void) { vu16 capture=0; //当前捕获计数值局部变量 OSIntEnter(); if(TIM_GetITStatus(TIM2,TIM_IT_CC1)!=RESET) //检查TIM2中TIM捕获/比较1中断源发生 { capture=TIM_GetCapture1(TIM2); //读取当前计数值 TIM_SetCompare1(TIM2,capture+10); //根据当前计数值更新输出捕获寄存器 TIM_ClearITPendingBit(TIM2,TIM_IT_CC1); }else if(TIM_GetITStatus(TIM2,TIM_IT_CC2)!=RESET) { capture=TIM_GetCapture2(TIM2); TIM_SetCompare2(TIM2,capture+100); TIM_ClearITPendingBit(TIM2,TIM_IT_CC2); }else if(TIM_GetITStatus(TIM2,TIM_IT_CC3)!=RESET) { capture=TIM_GetCapture3(TIM2); TIM_SetCompare3(TIM2,capture+1000); TIM_ClearITPendingBit(TIM2,TIM_IT_CC3); }else if(TIM_GetITStatus(TIM2,TIM_IT_CC3)!=RESET) { LED_GREEN=!LED_GREEN; //小灯控制 capture=TIM_GetCapture3(TIM2); TIM_SetCompare3(TIM2,capture+10000); TIM_ClearITPendingBit(TIM2,TIM_IT_CC3); } OSIntExit(); } void USART1_IRQHandler(void) //串口1中断函数 { OSIntEnter(); if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //检查USART2中接收中断发生与否 { // LED_GREEN=!LED_GREEN; // getchar1 = USART_ReceiveData(USART1); // Usart_TransData(2,getchar1); USART_ClearITPendingBit(USART1, USART_IT_RXNE); } // else if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET) // { // USART_ClearITPendingBit(USART1, USART_IT_TXE); // } OSIntExit(); } [/mw_shl_code]
程序的串口中断都可以正常的进入,但是定时器这边就出问题.两个小灯,A闪烁,B不闪烁,然后过一会儿(时间不固定但肯定是超过了我设定的0.5秒和1秒的)变成A不闪烁B闪烁.总感觉像是定时器2的配置这里出了问题,是不是中断向量表我弄错了?麻烦大家给指点一下

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

使用道具 举报

28

主题

1489

帖子

0

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1656
金钱
1656
注册时间
2013-7-24
在线时间
1 小时
发表于 2014-10-5 16:06:31 | 显示全部楼层
没有推演,看了代码。如下:

1、在main()中进行初始化,需确保不会在任务启动前触发系统调用;
2、不清楚TIM2的时序,但如果是可能同时发生的中断,用[else if]是不妥的;
于20150522停用该账号:http://www.microstar.club
回复

使用道具 举报

4

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
163
金钱
163
注册时间
2016-4-30
在线时间
26 小时
发表于 2016-8-18 10:00:36 | 显示全部楼层
应该是定时器2中断函数的 问题你先把定时器中断去掉看RED灯是否正常  然后再开中断,还有就是 TIM_IT_CC4你开了但中断里面没有
回复

使用道具 举报

5

主题

121

帖子

0

精华

高级会员

Rank: 4

积分
615
金钱
615
注册时间
2016-1-26
在线时间
149 小时
发表于 2016-8-18 15:28:50 | 显示全部楼层
肯定是这样的啊!定时器中断1s进一次,但是你的任务并不是标准的500ms执行一次,因为你只是做了一个500ms的延时,这个过程中的cpu处理其他任务或中断,简单的说就是500ms取反一次并不标准,这也使得两个灯的闪烁是不成比例的,就会出现你这种情况
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-1 20:25

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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