/********************************************************************************<br />*<br />* 文件名:uart0.c<br />*<br />* 功能:基于UC/OS-II操作系统串口驱动<br />*<br />*编写人:overfly<br />*<br />*日期:06/12/29<br />*<br />*版本:V2.0<br />*<br />*说明:由于水鸟水平有限,有些细节尚未考虑<br />********************************************************************************/<br /><br />#define IN_UART0<br />#include "config.h"<br /><br />/********************************************************************************<br />*<br />* 名称:UART0Init()<br />*<br />* 功能:初始化UART0<br />*<br />* 入口参数:bps 波特率<br />* <br />* data_lengh 字符长度<br />*<br />* stop_bit_num 停止位个数<br />*<br />* check_mode 奇偶校验类型<br />*<br />* 出口参数: 0 初始化失败<br />*<br />* 1 初始化成功<br />*<br />* 全局变量: 无<br />*<br />* 调用模块: OSSemCreate,OSSemPost<br />*<br />********************************************************************************/<br /><br /> <br />INT8U UART0Init(INT32U bps,INT8U data_lengh,INT8U stop_bit_num,INT8U check_mode)<br />{<br /> INT32U Fdiv;<br /> <br /> PINSEL0 = (PINSEL0 & 0xfffffff0) | 0x05; /* 选择管脚为UART0 */<br /> <br /> U0LCR = 0x80; /* 允许访问分频因子寄存器 */<br /> Fdiv = (Fpclk / 16) / bps; /* 设置波特率 */<br /> U0DLM = Fdiv / 256; <br /> U0DLL = Fdiv % 256;<br /> <br /> if(data_lengh==5)<br /> U0LCR=U0LCR|0x00;<br /> else if(data_lengh==6)<br /> U0LCR=U0LCR|0x01;<br /> else if(data_lengh==7)<br /> U0LCR=U0LCR|0x02;<br /> else if(data_lengh==8)<br /> U0LCR=U0LCR|0x03;<br /> else <br /> return 0;//选择失败<br /> if(stop_bit_num==1)<br /> U0LCR=U0LCR|0x00;<br /> else if(stop_bit_num==2)<br /> U0LCR=U0LCR|0x04;<br /> else <br /> return 0;<br /> <br /> if(check_mode==0) //<br /> U0LCR=U0LCR|0x00;<br /> else if(check_mode==1)//ji<br /> U0LCR=U0LCR|0x08;<br /> else if(check_mode==2)<br /> U0LCR=U0LCR|0x18;//ou<br /> else <br /> return 0;<br /> U0LCR=U0LCR&0x7f;//固定波特率<br /> U0FCR=0x87;//8BYTE 85<br /> U0IER=0x00;//发送中断<br /> <br /> ReMsgQeue=OSQCreate(&MsgQeueTb[0],20);<br /> UART0SendFree=OSSemCreate(0);//建立空闲信号量<br /> UART0SendEnd=OSSemCreate(0);//建立发送结束信号量<br /> // UART0SendContinue=OSSemCreate(0);//数据尚未发送完毕,继续发送<br /> OSSemPost(UART0SendFree);//发送空闲信号<br /> return 1;<br /> }<br /> <br />/********************************************************************************<br />*<br />* 名称: void UART0SendData(INT8U *dat,INT8U nbyte)<br />*<br />* 功能:发送8byte 数据<br />*<br />* 入口参数:*dat 发送的数据存储位置<br />* <br />* nbyte 发送的字节数<br />*<br />* 出口参数: 无<br />*<br />* 全局变量: 无<br />*<br />* 调用模块: OSSemPend,OSSemPost<br />*<br />********************************************************************************/<br /><br /> <br /> void UART0SendData(INT8U *dat,INT8U nbyte)//nbyte<=16<br /> {<br /> INT8U err,i;<br /> <br /> OSSemPend(UART0SendFree,0,&err);//判断发送器是否为空<br /> U0IER=U0IER|0x02;//开中断<br /> for(i=0;i<nbyte;i++)<br /> U0THR=*(dat+i);<br /> //UART0SendByte=nbyte;//已发送nbyte <br /> OSSemPend(UART0SendEnd,0,&err);//等待发送完毕<br /> OSSemPost(UART0SendFree);//发送器空闲<br /> U0IER=U0IER&~0x02;//禁止发送中断<br /> }<br /> <br />/********************************************************************************<br />*<br />* 名称: INT8U UART0ReadData(INT8U *ReceDat)<br />*<br />* 功能:读取串口数据<br />*<br />* 入口参数:*ReceDat 接收数据存储位置<br />* * UART0SendByte 从串口读取数据的个数(一定是4N个数据,N>0) <br />* *<br />* 出口参数: 1 读取成功<br />*<br />* 全局变量: 无<br />*<br />* 调用模块: OSSemPend<br />*<br />********************************************************************************/<br /> void UART0ReadData(INT8U *ReceDat,INT8U UART0SendByte)//读取串口数据<br /> {<br /> INT8U i,err;<br /> INT32U rec_data;<br /> U0IER=U0IER|0x01;//允许接收中断<br /> for(i=0;i<(UART0SendByte/4);i++)<br /> {<br /> rec_data=(INT32U)(INT32U *)OSQPend(ReMsgQeue,0,&err);<br /> for(err=0;err<4;err++)<br /> {<br /> ReceDat[4*i+3-err]=(INT8U)(rec_data&0xff);//<br /> rec_data>>=8;<br /> }<br /> }<br /> U0IER=U0IER&~0x01;//关闭接收中断<br /> }<br /> <br /> /********************************************************************************<br />*<br />* 名称: void UART0_Exception(void)<br />*<br />* 功能:IRQ中断<br />*<br />* 入口参数:无<br />* <br />*<br />* 出口参数: 无<br />*<br />* 全局变量: 无<br />*<br />* 调用模块: OSSemPost,OSQPost,OS_ENTER_CRITICAL,OS_EXIT_CRITICAL<br />*<br />********************************************************************************/<br /> void UART0_Exception(void)<br /> {<br /> INT8U IIR,i,temp;<br /> INT32U Tmp;<br /> <br /> OS_ENTER_CRITICAL();<br /> VICVectAddr=0;<br /> while(((IIR = U0IIR) & 0x01) == 0)<br /> { /* 有中断未处理完 */<br /> switch (IIR & 0x0f)<br /> {<br /> case 0x02: <br /> OSSemPost(UART0SendEnd); // <br /> break;<br /> case 0x04: <br /> temp=U0IIR;<br /> for(i=0;i<4;i++)<br /> Tmp=(Tmp<<8)|U0RBR;<br /> OSQPost(ReMsgQeue,(void *)Tmp);<br /> for(i=0;i<4;i++)<br /> Tmp=(Tmp<<8)|U0RBR;<br /> OSQPost(ReMsgQeue,(void *)Tmp);<br /> break;<br /> case 0x06: /* 接收线状态 */<br /> temp = U0LSR;<br /> break;<br /> case 0x0c: /* 字符超时指示 */<br /> temp=U0IIR;<br /> for(i=0;i<4;i++)<br /> Tmp=(Tmp<<8)|U0RBR;<br /> OSQPost(ReMsgQeue,(void *)Tmp);<br /> for(i=0;i<4;i++)<br /> Tmp=(Tmp<<8)|U0RBR;<br /> OSQPost(ReMsgQeue,(void *)Tmp);<br /> break; <br /> <br /> default :<br /> break;<br /> }<br /> } <br /> OS_EXIT_CRITICAL();<br /> } <br /> <br /><br />/********************************************************************************<br />*<br />* 文件名:uart0.h<br />*<br />* 功能:基于UC/OS-II操作系统串口驱动<br />*<br />*编写人:overfly<br />*<br />*日期:06/12/29<br />*<br />*版本:V2.0<br />*<br />*说明:由于水鸟水平有限,有些细节尚未考虑<br />********************************************************************************/<br /><br /><br />#ifdef IN_UART0<br /> OS_EVENT *UART0SendFree;//发送器空闲信号<br /> OS_EVENT *UART0SendEnd;//发送结束信号<br /> OS_EVENT *UART0SendContinue;//<br /> OS_EVENT *ReMsgQeue;//定义消息队列<br /> void *MsgQeueTb[20];//定义消息队列数组<br /> #endif<br /> <br /> #ifndef IN_UART0<br />/********************************************************************************<br />*<br />* 名称:UART0Init()<br />*<br />* 功能:初始化UART0<br />*<br />* 入口参数:bps 波特率<br />* <br />* data_lengh 字符长度<br />*<br />* stop_bit_num 停止位个数<br />*<br />* check_mode 奇偶校验类型<br />*<br />* 出口参数: 0 初始化失败<br />*<br />* 1 初始化成功<br />*<br />* 全局变量: 无<br />*<br />* 调用模块: OSSemCreate,OSSemPost<br />*<br />********************************************************************************/<br /><br />extern INT8U UART0Init(INT32U bps,INT8U data_lengh,INT8U stop_bit_num,INT8U check_mode);<br /> <br />/********************************************************************************<br />*<br />* 名称: void UART0SendData(INT8U *dat,INT8U nbyte)<br />*<br />* 功能:发送8byte 数据<br />*<br />* 入口参数:*dat 发送的数据存储位置<br />* <br />* nbyte 发送的字节数<br />*<br />* 出口参数: 无<br />*<br />* 全局变量: 无<br />*<br />* 调用模块: OSSemPend,OSSemPost<br />*<br />********************************************************************************/<br /><br />extern void UART0SendData(INT8U *dat,INT8U nbyte);<br /> /********************************************************************************<br />*<br />* 名称: void UART0_Exception(void)<br />*<br />* 功能:IRQ中断<br />*<br />* 入口参数:无<br />* <br />*<br />* 出口参数: 无<br />*<br />* 全局变量: 无<br />*<br />* 调用模块: OSSemPost,OSQPost,OS_ENTER_CRITICAL,OS_EXIT_CRITICAL<br />*<br />********************************************************************************/<br />extern void UART0_Exception(void);<br />/********************************************************************************<br />*<br />* 名称: INT8U UART0ReadData(INT8U *ReceDat)<br />*<br />* 功能:读取串口数据<br />*<br />* 入口参数:*ReceDat 接收数据存储位置<br />* <br />*<br />* 出口参数: 1 读取成功<br />*<br />* 全局变量: 无<br />*<br />* 调用模块: OSSemPend<br />*<br />********************************************************************************/<br />extern INT8U UART0ReadData(INT8U *ReceDat,INT8U UART0SendByte);<br />#endif<br /><br />main.c<br /><br /><br />#include "config.h"<br />#include "stdlib.h" <br /><br />#define TaskStkLengh 64 //Define the Task0 stack length 定义用户任务0的堆栈长度<br /><br /> <br />OS_STK Task0Stk [TaskStkLengh]; //Define the Task0 stack 定义用户任务0的堆栈<br />OS_STK Task1Stk [TaskStkLengh];<br /><br />INT8U data_buffer[16];<br />void Task0(void *pdata); //Task0 任务0<br />void Task1(void *pdata); <br /><br />int main (void)<br />{<br /> <br /> OSInit (); <br /> <br /> OSTaskCreate (Task0,(void *)0, &Task0Stk[TaskStkLengh - 1], 2); //任务2:UART <br /> OSTaskCreate (Task1,(void *)0, &Task1Stk[TaskStkLengh - 1], 4); <br /> OSStart ();<br /> <br /> return 0; <br />}<br /><br />void Task0(void *pdata)<br />{<br /> pdata=pdata;<br /> TargetInit();<br /> UART0Init(115200,8,1,0);<br /> while(1)<br /> {<br /> UART0ReadData(data_buffer,16);<br /> UART0SendData(data_buffer,16);<br /> OSTimeDly(20);<br /> }<br />}<br /><br />void Task1(void *pdata)<br />{<br /> pdata=pdata;<br /> while(1)<br /> {<br /> OSTimeDly(20);<br /> }<br />}<br />
|