用的是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的配置这里出了问题,是不是中断向量表我弄错了?麻烦大家给指点一下 |