📄 wuart.c
字号:
/**************************************************************************
NAME:wUart.C
copyright:wzz at Qingdao University 2008.11
ps:receiving function is modified from ARM3000 driver
**************************************************************************/
#include "..\inc\WOPTIONS.H"
#include "..\ucos\includes.h"
#include "..\porting\port.h"
OS_EVENT *Uart0_Rxd_mbox=NULL; //Uart0 receive mail box
//OS_EVENT *Uart0_Txd_sem=NULL; //uart0 tx sem because of the fast speed,no use
U8 Uart0_Rxd_Buffer[UART0_REVBUFFER_SIZE]; //Uart0 接受缓冲区
U8 Uart0_Txd_Buffer[UART0_REVBUFFER_SIZE]; //Uart0 发送缓冲区
static U8* pUart0_Rxd=Uart0_Rxd_Buffer, //Uart0 接收缓冲区指针
*pUart0_read=Uart0_Rxd_Buffer; //Uart0 读缓冲区指针
static U8* pUart0_Txd=Uart0_Txd_Buffer, //Uart0 发送缓冲区指针
*pUart0_send=Uart0_Txd_Buffer; //Uart0 读缓冲区指针
static int nRxd_Uart0=1; //设定的Uart接收字符数
//static int nTxd_Uart0=5; //设定的Uart发送字符数;
//**************************************************************************/
//1.1 接收&发送中断服务程序
//Attention!!
//虽然uart0的接收和发送都采用的中断方式
//但两个的中断的 ---触发方式--- 和ucos的时钟中断是不同的!!
//----------------------------------------------------------------------
//UCON0 0x01D00004 R/W UART channel 0 control register 0x00
//Tx interrupt type [9] Interrupt request type
//0 = Pulse (Interrupt is requested the instant Tx buffer becomes empty)
//1 = Level (Interrupt is requested while Tx buffer is empty)
//----------------------------------------------------------------------
//Rx interrupt type [8] Interrupt request type
//0 = Pulse (Interrupt is requested the instant Rx buffer receives the data)
//1 = Level (Interrupt is requested while Rx buffer is receiving data)
//----------------------------------------------------------------------
//in the WSFRCDEF.h UCON0 is define as below
//#define crUCON0 0x305(0x205 also works)
//即Tx发送中断在发送缓冲器为空时一直申请中断
//而Rx接收中断在接收缓冲器为满时一直申请中断
//不然由于ucos操作系统的时钟中断,且该时钟中断优先级高于uart中断
//采用Pulse方式可能无法正常响应uart中断
/**************************************************************************/
//1.1.1 Uart0接收中断服务程序
//------------------------------------------------------------------
void irq_OSRxdUart0()
{
int nrev;
if(!(rUTRSTAT0 & 0x1))
return;//is it turn recieve buffer
*pUart0_Rxd=RdURXH0();//Receive data
pUart0_Rxd++;
if(pUart0_Rxd==Uart0_Rxd_Buffer+UART0_REVBUFFER_SIZE)
pUart0_Rxd=Uart0_Rxd_Buffer;//循环缓冲区调整
nrev=pUart0_Rxd-pUart0_read; //判断读取的数据个数
if(nrev>=nRxd_Uart0)
{ CloseUart0Rxd();
OSMboxPost(Uart0_Rxd_mbox, (void*)nrev);//是否达到读取个数要求
}
}
//1.1.2 Uart0发送中断服务程序
//-------------------------------------------------------------------
void irq_OSTxdUart0()
{
WrUTXH0(*pUart0_send); //写发送缓冲寄存器
if (*pUart0_send==0x0d) //若收到回车符号0x0d,再给超级终端补一个换行0x0a
{*pUart0_send=0x0a;}
else
pUart0_send++;
if(pUart0_send==Uart0_Txd_Buffer+UART0_REVBUFFER_SIZE)
pUart0_send=Uart0_Txd_Buffer;//循环缓冲区调整
if(pUart0_Txd==pUart0_send)
CloseUart0Txd(); //判断发送是否完成,关闭uart0发送中断
//OSSemPost(Uart0_Txd_sem);
}
//**************************************************************************/
//2.2 初始化程序
//**************************************************************************/
void OSInitUart()
{
if(Uart0_Rxd_mbox==NULL)
Uart0_Rxd_mbox=OSMboxCreate((void*)NULL);
// if(Uart0_Txd_sem==NULL)
// Uart0_Txd_sem=OSSemCreate(0);
// if(Uart0_Txd_sem==(void *)0)
// Uart_Printf("sem create error\n");
}
//**************************************************************************/
//3.3 操作集
//**************************************************************************/
//3.3.1 开启串口0的接收中断
//------------------------------------------------------------------
void OpenUart0Rxd()
{
SetISR_Interrupt(INT_URXD0_OFFSET,irq_OSRxdUart0, 0);
}
//3.3.2 关闭串口0的接收中断
//------------------------------------------------------------------
void CloseUart0Rxd()
{
ClearISR_Interrupt(INT_URXD0_OFFSET);
}
//3.3.3 开启串口0的接收中断
//------------------------------------------------------------------
void OpenUart0Txd()
{
SetISR_Interrupt(INT_UTXD0_OFFSET,irq_OSTxdUart0, 0);
}
//3.3.4 关闭串口0的接收中断
//------------------------------------------------------------------
void CloseUart0Txd()
{
ClearISR_Interrupt(INT_UTXD0_OFFSET);
}
//3.3.5 读串口0的数据--返回值,实际读取的数据
//------------------------------------------------------------------
int OSReadUart0(U8 data[], int num, int ntimeout)
{
//U8 data[] 存放字符空间
//int num 要求得到的字符数
//int ntimeout 忍耐时间
//function:
//将读取的数据先放入接受缓冲区,
//待达到要求的个数就拷贝到用户数据指定的数据区
int i;
INT8U err;
int nrev;
nRxd_Uart0=num; //设置Uart0接收数据数
nrev=pUart0_Rxd-pUart0_read;
if(nrev<0)//循环缓冲区调整
nrev+=UART0_REVBUFFER_SIZE;
if(nrev<num){
while((nrev=(int)OSMboxPend(Uart0_Rxd_mbox, ntimeout,&err))<num){
if(err==OS_TIMEOUT){
num=nrev;
break;//若消息邮箱等待超时返回实际接收到的字符数
}
}
}
for(i=0;i<num;i++){
data[i]=*pUart0_read;//将接收到的字符拷贝到用户数组中
pUart0_read++;
if(pUart0_read==Uart0_Rxd_Buffer+UART0_REVBUFFER_SIZE)
pUart0_read=Uart0_Rxd_Buffer;//循环缓冲区调整
}
return nrev;//返回接收到的字符数
}
//3.3.6 写串口0数据
//------------------------------------------------------------------
int OSWriteUart0(U8 data[], int num)
{
//U8 data[] 用户数据区
//int num 要发送的字符数
//put into Txbuffer
//then open the Tx interrupt
//先将要求发送的字符放到发送缓冲区,
//然后打开uart0的发送中断
//让uart0的发送中断服务程序完成发送工作
int i;
// nTxd_Uart0=num;
for(i=0;i<num;i++)
{
*pUart0_Txd=data[i];
pUart0_Txd++;//将用户数据放入发送缓冲区
if(pUart0_Txd==Uart0_Txd_Buffer+UART0_REVBUFFER_SIZE)
pUart0_Txd=Uart0_Txd_Buffer;//循环缓冲区调整
}
OpenUart0Txd();//待发送数据已经就绪,打开uart0的发送中断
// OSSemPend(Uart0_Txd_sem,0,0);
// CloseUart0Txd();
return 0;
//
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -