* 內容簡述:緩存
本例程操做系統採用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 統計運行時間的任務-------優先級次低 app
一、主任務創建:ide
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 }
二、其餘任務創建:函數
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 }
三、硬件初始化部分spa
說了這麼多,居然忘了說硬件初始化的部分啦!這裏包括系統時鐘設置、引腳使能、中斷使能...放在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/ code
工程代碼:http://pan.baidu.com/s/1jG850X4blog