标签:style blog http color 使用 os io strong
* 内容简述:
本例程操作系统采用ucos2.86a版本, 建立了5个任务
任务名 优先级
APP_TASK_START_PRIO 2 主任务
Task_Com1_PRIO 4 COM1通信任务
Task_Led1_PRIO 7 LED1 闪烁任务
Task_Led2_PRIO 8 LED2 闪烁任务
Task_Led3_PRIO 9 LED3 闪烁任务
当然还包含了系统任务:
OS_TaskIdle 空闲任务-----------------优先级最低
OS_TaskStat 统计运行时间的任务-------优先级次低
1、主任务建立:
1 //建立主任务, 优先级最高 建立这个任务另外一个用途是为了以后使用统计任务 2 os_err = OSTaskCreate((void (*) (void *)) App_TaskStart, //指向任务代码的指针 3 (void *) 0, //任务开始执行时,传递给任务的参数的指针 4 (OS_STK *) &App_TaskStartStk[APP_TASK_START_STK_SIZE - 1], //分配给任务的堆栈的栈顶指针 从顶向下递减 5 (INT8U) APP_TASK_START_PRIO); //分配给任务的优先级
1 static void App_TaskStart(void* p_arg) 2 { 3 (void) p_arg; 4 //初始化ucos时钟节拍 5 OS_CPU_SysTickInit(); /* Initialize the SysTick. */ 6 7 //使能ucos 的统计任务 8 #if (OS_TASK_STAT_EN > 0) 9 //----统计任务初始化函数 10 OSStatInit(); /* Determine CPU capacity. */ 11 #endif 12 //建立其他的任务 13 App_TaskCreate(); 14 15 while (1) 16 { 17 //1秒一次循环 18 OSTimeDlyHMSM(0, 0,1, 0); 19 } 20 }
2、其他任务建立:
1 static void App_TaskCreate(void) 2 { 3 //CPU_INT08U os_err; 4 5 //Com1_SEM=OSSemCreate(1); //建立串口1中断的信号量 6 Com1_MBOX=OSMboxCreate((void *) 0); //建立串口1中断的消息邮箱 7 8 //串口1接收及发送任务--------------------------------------------------------- 9 OSTaskCreateExt(Task_Com1, //指向任务代码的指针 10 (void *)0, //任务开始执行时,传递给任务的参数的指针 11 (OS_STK *)&Task_Com1Stk[Task_Com1_STK_SIZE-1],//分配给任务的堆栈的栈顶指针 从顶向下递减 12 Task_Com1_PRIO, //分配给任务的优先级 13 Task_Com1_PRIO, //预备给以后版本的特殊标识符,在现行版本同任务优先级 14 (OS_STK *)&Task_Com1Stk[0], //指向任务堆栈栈底的指针,用于堆栈的检验 15 Task_Com1_STK_SIZE, //指定堆栈的容量,用于堆栈的检验 16 (void *)0, //指向用户附加的数据域的指针,用来扩展任务的任务控制块 17 OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR); //选项,指定是否允许堆栈检验,是否将堆栈清0,任务是否要进行浮点运算等等。 18 //LED1 闪烁任务------------------------------------------------------ 19 OSTaskCreateExt(Task_Led1,(void *)0,(OS_STK *)&Task_Led1Stk[Task_Led1_STK_SIZE-1],Task_Led1_PRIO,Task_Led1_PRIO,(OS_STK *)&Task_Led1Stk[0], 20 Task_Led1_STK_SIZE, 21 (void *)0, 22 OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR); 23 24 //LED2 闪烁任务------------------------------------------------------ 25 OSTaskCreateExt(Task_Led2,(void *)0,(OS_STK *)&Task_Led2Stk[Task_Led2_STK_SIZE-1],Task_Led2_PRIO,Task_Led2_PRIO,(OS_STK *)&Task_Led2Stk[0], 26 Task_Led2_STK_SIZE, 27 (void *)0, 28 OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR); 29 30 //LED3 闪烁任务------------------------------------------------------ 31 OSTaskCreateExt(Task_Led3,(void *)0,(OS_STK *)&Task_Led3Stk[Task_Led3_STK_SIZE-1],Task_Led3_PRIO,Task_Led3_PRIO,(OS_STK *)&Task_Led3Stk[0], 32 Task_Led3_STK_SIZE, 33 (void *)0, 34 OS_TASK_OPT_STK_CHK|OS_TASK_OPT_STK_CLR); 35 }
1 //LED1闪烁任务---------------------------------------- 2 static void Task_Led1(void* p_arg) 3 { 4 (void) p_arg; 5 while (1) 6 { 7 LED_LED1_ON(); 8 OSTimeDlyHMSM(0, 0, 0, milsec1); 9 10 LED_LED1_OFF(); 11 OSTimeDlyHMSM(0, 0, 0, milsec1); 12 } 13 }
1 #define APP_TASK_START_PRIO 2 2 #define APP_TASK_USER_IF_PRIO 13 3 #define APP_TASK_KBD_PRIO 12 4 #define Task_Com1_PRIO 4 5 #define Task_Led1_PRIO 7 6 #define Task_Led2_PRIO 8 7 #define Task_Led3_PRIO 9
1 static void Task_Com1(void *p_arg){ 2 INT8U err; 3 unsigned char * msg; 4 (void)p_arg; 5 while(1){ 6 7 //OSSemPend(Com1_SEM,0,&err); //等待串口接收指令成功的信号量 8 msg=(unsigned char *)OSMboxPend(Com1_MBOX,0,&err); //等待串口接收指令成功的邮箱信息 9 //USART_OUT(USART1,&TxBuffer1[0]); 10 if(msg[0]==‘L‘&&msg[1]==0x31){ 11 milsec1=atoi(&msg[3]); //LED1 的延时毫秒 (mini and V3) 12 USART_OUT(USART1,"\r\n"); 13 USART_OUT(USART1,"LED1: %d ms 间隔闪烁",milsec1); 14 } 15 else if(msg[0]==‘L‘&&msg[1]==0x32){ 16 milsec2=atoi(&msg[3]); //LED2 的延时毫秒 (only V3) 17 USART_OUT(USART1,"\r\n"); 18 USART_OUT(USART1,"LED2: %d ms 间隔闪烁",milsec2); 19 } 20 else if(msg[0]==‘L‘&&msg[1]==0x33){ 21 milsec3=atoi(&msg[3]); //LED3 的延时毫秒 (only V3) 22 USART_OUT(USART1,"\r\n"); 23 USART_OUT(USART1,"LED3: %d ms 间隔闪烁",milsec3); 24 } 25 } 26 }
1 void USART1_IRQHandler(void) 2 { 3 unsigned int i; 4 unsigned char msg[50]; 5 OS_CPU_SR cpu_sr; 6 7 OS_ENTER_CRITICAL(); //保存全局中断标志,关总中断// Tell uC/OS-II that we are starting an ISR 8 OSIntNesting++; 9 10 OS_EXIT_CRITICAL(); //恢复全局中断标志 11 12 //OSTimeTick(); // Call uC/OS-II‘s OSTimeTick(),在os_core.c文件里定义,主要判断延时的任务是否计时到 13 14 if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //判断读寄存器是否非空 15 { 16 // Read one byte from the receive data register 17 18 msg[RxCounter1++]= USART_ReceiveData(USART1); //将读寄存器的数据缓存到接收缓冲区里 19 20 if(msg[RxCounter1-1]==‘L‘){msg[0]=‘L‘; RxCounter1=1;} //判断起始标志 21 if(msg[RxCounter1-1]==‘F‘) //判断结束标志是否是"F" 22 23 { 24 for(i=0; i< RxCounter1; i++){ 25 TxBuffer1[i] =msg[i]; //将接收缓冲器的数据转到发送缓冲区,准备转发 26 27 } 28 29 TxBuffer1[RxCounter1]=0; //接收缓冲区终止符 30 RxCounter1=0; 31 //OSSemPost(Com1_SEM); 32 OSMboxPost(Com1_MBOX,(void *)&msg); 33 } 34 } 35 if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET) // 36 { 37 USART_ITConfig(USART1, USART_IT_TXE, DISABLE); 38 } 39 OSIntExit(); //在os_core.c文件里定义,如果有更高优先级的任务就绪了,则执行一次任务切换 40 }
3、硬件初始化部分
说了这么多,竟然忘了说硬件初始化的部分啦!这里包括系统时钟设置、引脚使能、中断使能...放在bsp.c文件里,在main函数开始直接调用BSP_Init();就可以。
1 void BSP_Init(void) 2 { 3 /* System Clocks Configuration --72M*/ 4 RCC_Configuration(); 5 GPIO_Configuration(); 6 /* NVIC configuration */ 7 /*嵌套向量中断控制器 8 说明了USART1抢占优先级级别0(最多1位) ,和子优先级级别0(最多7位) */ 9 NVIC_Configuration(); 10 USART_Config(USART1,115200); //串口1初始化 11 }
1 void RCC_Configuration(void) 2 { 3 SystemInit(); 4 }
1 void GPIO_Configuration(void) 2 { 3 GPIO_InitTypeDef GPIO_InitStructure; 4 5 /*对控制LED指示灯的IO口进行了初始化,将端口配置为推挽上拉输出,口线速度为50Mhz。PA9,PA10端口复用为串口1的TX,RX。 6 在配置某个口线时,首先应对它所在的端口的时钟进行使能。否则无法配置成功,由于用到了端口B,D,E, 因此要对这几个端口的时钟 7 进行使能,同时由于用到复用IO口功能用于配置串口。因此还要使能AFIO(复用功能IO)时钟。*/ 8 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOB , ENABLE); 9 10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1 11 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 12 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 13 GPIO_Init(GPIOB, &GPIO_InitStructure); 14 15 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_3; //LED2, LED3 16 GPIO_Init(GPIOD, &GPIO_InitStructure); 17 }
1 void NVIC_Configuration(void) 2 { 3 4 //EXTI_InitTypeDef EXTI_InitStructure; 5 NVIC_InitTypeDef NVIC_InitStructure; 6 7 /* Configure one bit for preemption priority */ 8 #if defined (VECT_TAB_RAM) 9 /* Set the Vector Table base location at 0x20000000 */ 10 NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); 11 #elif defined(VECT_TAB_FLASH_IAP) 12 NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x2000); 13 #else /* VECT_TAB_FLASH */ 14 /* Set the Vector Table base location at 0x08000000 */ 15 NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); 16 #endif 17 18 /* Configure the NVIC Preemption Priority Bits */ 19 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); 20 21 22 NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //设置串口1中断 23 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 24 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 25 NVIC_Init(&NVIC_InitStructure); 26 27 }
1 void USART_Config(USART_TypeDef* USARTx,u32 baud){ 2 USART_InitTypeDef USART_InitStructure; 3 GPIO_InitTypeDef GPIO_InitStructure; 4 5 //PA9,PA10 复用IO口功能用于配置串口。因此要使能AFIO(复用功能IO)时钟。 6 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); 7 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); 8 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); 9 10 //usart_init---------------------------------------------------- 11 /* Configure USART1 Rx (PA.10) as input floating */ 12 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 13 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //浮空输入模式 14 GPIO_Init(GPIOA, &GPIO_InitStructure); 15 16 /* Configure USART1 Tx (PA.09) as alternate function push-pull */ 17 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 18 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 19 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 20 GPIO_Init(GPIOA, &GPIO_InitStructure); 21 22 23 USART_InitStructure.USART_BaudRate =baud; //速率115200bps 24 USART_InitStructure.USART_WordLength = USART_WordLength_8b; //数据位8位 25 USART_InitStructure.USART_StopBits = USART_StopBits_1; //停止位1位 26 USART_InitStructure.USART_Parity = USART_Parity_No; //无校验位 27 USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //无硬件流控 28 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式 29 30 /* Configure USART1 */ 31 USART_Init(USARTx, &USART_InitStructure); //配置串口参数函数 32 33 34 /* Enable USART1 Receive and Transmit interrupts */ 35 USART_ITConfig(USARTx, USART_IT_RXNE, ENABLE); //使能接收中断 36 //USART_ITConfig(USARTx, USART_IT_TXE, ENABLE); //使能发送缓冲空中断 37 38 39 /* Enable the USART1 */ 40 USART_Cmd(USARTx, ENABLE); 41 42 //USART_ClearFlag(USARTx, USART_FLAG_TXE); /* 清发送完成标志,Transmission Complete flag */ 43 }
PS:相关链接
LZ blog:http://www.cnblogs.com/zjutlitao/
工程代码:http://pan.baidu.com/s/1jG850X4
[stm32][ucos] 1、基于ucos操作系统的LED闪烁、串口通信简单例程,布布扣,bubuko.com
[stm32][ucos] 1、基于ucos操作系统的LED闪烁、串口通信简单例程
标签:style blog http color 使用 os io strong
原文地址:http://www.cnblogs.com/zjutlitao/p/3917638.html