串口发送部分代码:
//通过信号量的方法发送数据 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