串口發送部分代碼:
//通過信號量的方法發送數據 void usart1SendData(CPU_INT08U ch) { OS_ERR err; CPU_INT08U isTheFirstCh; OSSemPend(&Usart1Sem, 0, OS_OPT_PEND_BLOCKING, NULL, &err);//阻塞型等待串口發送資源 OSSemPend(&Usart1TxBufSem, 0, OS_OPT_PEND_BLOCKING, NULL, &err);//阻塞型等待發送 isTheFirstCh = 0; if(pTxBufRead == pTxBufWrite){ //若讀指針等於寫指針,表明要寫入緩沖區的為當前第一個數據 isTheFirstCh = 1; //置位第一個數據標志 } *pTxBufWrite = ch;//向當前寫指針對應的地址寫入數據 if((pTxBufWrite++) == &Usart1TxBuf[USART1_TX_BUFFER_LEN - 1]){ //若當前寫指針寫到緩沖區最后一個地址,否則地址自增1 pTxBufWrite = Usart1TxBuf; //寫指針更新為緩沖區第一個地址,環形隊列 } if(isTheFirstCh){ //寫入的是第一個數據 USART_ITConfig(USART1, USART_IT_TXE, ENABLE);//開啟緩沖區發送空中斷,下一步將會進入中斷處理數據 } OSSemPost(&Usart1Sem, OS_OPT_POST_1, &err); }
串口接收部分代碼:
//串口1中斷處理程序 void USART1_IRQHandler(void) //串口1中斷服務程序 { OS_ERR err; OSIntEnter(); //通知UCOS進入中斷 //發送緩沖區空中斷 if(USART_GetITStatus(USART1, USART_IT_TXE) != RESET) { USART_SendData(USART1, *pTxBufRead);//向串口發送緩沖區寫入一個字節 if((pTxBufRead++) == &Usart1TxBuf[USART1_TX_BUFFER_LEN - 1]){ //讀到最后一個字節 pTxBufRead = Usart1TxBuf; //移動讀指針到第首地址 } if(pTxBufRead == pTxBufWrite){ //若讀寫指針相等,表明本次緩沖區數據已經讀完 USART_ITConfig(USART1, USART_IT_TXE, DISABLE);//關閉中斷 } OSSemPost(&Usart1TxBufSem, OS_OPT_POST_1, &err); //釋放緩沖區信號量 } //串口接收到數據中斷 if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET){ *pRxBufWrite = USART_ReceiveData(USART1); //讀取一個字節到緩沖區 OSTaskQPost(&Usart1RxTaskTCB, pRxBufWrite, 1, OS_OPT_POST_FIFO, &err); //發送該字節所在緩沖區的地址到消息隊列,等待任務處理 if((pRxBufWrite++) == &Usart1RxBuf[USART1_RX_BUFFER_LEN - 1]){ //若當前寫指針寫到緩沖區最后一個地址 pRxBufWrite = Usart1RxBuf; //寫指針更新為緩沖區第一個地址,環形隊列 } } OSIntExit(); //通知UCOS退出中斷 }
例程:
http://www.openedv.com/forum.php?mod=attachment&aid=Njg0MnxmMzFkMzdmN3wxNTQ1MDQ0NjE5fDB8MzM2MTE%3D