⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wuart.c

📁 基于S3C44b0的键盘LED接口设计
💻 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 + -