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