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

📄 uart.c

📁 ucos ii串口通讯程序
💻 C
字号:
/***************************************************************************\
	Copyright (c) 2004-2007 threewater@up-tech.com, All rights reserved.
	by threewter	2004.4.26
\***************************************************************************/
	

/***************************************************************************\
    #说明: 串口抽象层函数
	----------------------------------  Bug  --------------------------------------

	----------------------------------  TODO list  --------------------------------------

	----------------------------------修正--------------------------------------
	2004-5-26	创建

\***************************************************************************/

#include "../inc/marco.h"
#include "../ucos-ii/includes.h"
#include "../ucos-ii/uhal/isr.h"
#include "uart.h"
#include "sys/lib.h"

extern struct_Uart_Buffer Uart_Buffer[];
extern serial_driver_t* serial_drv[];
extern int NumberOfUartDrv;

/*********************************\
	有数据收到,
	填充接收缓冲区数据
\**********************************/
void Put_RevBuffer(int ndev, U8 data)
{
	int nrev;
	struct_Uart_Buffer *pUart_Buffer;

#if OS_ARG_CHK_EN > 0
	if(ndev>=NumberOfUartDrv)
		return;
#endif
	pUart_Buffer=&Uart_Buffer[ndev];

	//Receive data
	pUart_Buffer->revBuffer[pUart_Buffer->nUart_rev]=data;
	RoundINC(pUart_Buffer->nUart_rev, UART_REVBUFFER_SIZE);

	nrev=RoundCount(pUart_Buffer->nUart_rev, pUart_Buffer->nUart_read, UART_REVBUFFER_SIZE);
	if(nrev>=pUart_Buffer->nRev_Uart)
		OSSemPost(pUart_Buffer->Uart_Rev_sem);
}

/*********************************\
	获得发送缓冲区的数据
	成功返回数据
	没有数据,则返回-1
\**********************************/
int Get_SndBuffer(int ndev)
{
	int data;
	int n;
	struct_Uart_Buffer *pUart_Buffer;

#if OS_ARG_CHK_EN > 0
	if(ndev>=NumberOfUartDrv)
		return;
#endif
	pUart_Buffer=&Uart_Buffer[ndev];

	//get data
	n=RoundCount(pUart_Buffer->nUart_write, pUart_Buffer->nUart_send, UART_SNDBUFFER_SIZE);
	if(n==0)
		return -1;

	data=pUart_Buffer->sndBuffer[pUart_Buffer->nUart_send];
	RoundINC(pUart_Buffer->nUart_send, UART_SNDBUFFER_SIZE);

	n=UART_SNDBUFFER_SIZE-n;

	if(n>=UART_SNDBUFFER_SIZE/2)
		OSSemPost(pUart_Buffer->Uart_Snd_sem);

	return data;
}

/*
void irq_OSRevUart(int vector, int ndev)
{
	int nrev;
	struct_Uart_Buffer *pUart_Buffer=&Uart_Buffer[ndev];

	if(ndev>=NumberOfUartDrv)
		return;

	while(serial_drv[ndev]->poll()){
		//Receive data
		*(pUart_Buffer->pUart_rev)=(U8)serial_drv[ndev]->read();
		pUart_Buffer->pUart_rev++;
		if(pUart_Buffer->pUart_rev==pUart_Buffer->Buffer+UART_REVBUFFER_SIZE)
			pUart_Buffer->pUart_rev=pUart_Buffer->Buffer;

		nrev=pUart_Buffer->pUart_rev-pUart_Buffer->pUart_read;
		if(nrev<0)//循环缓冲区调整
			nrev+=UART_REVBUFFER_SIZE;
	}

	if(nrev>=pUart_Buffer->nRev_Uart)
		OSMboxPost(pUart_Buffer->Uart_Rev_mbox, (void*)nrev);
}*/

/*************************
	读串口n的数据
	返回值,实际读取的数据数目
****************************/
int OSReadUart(int ndev, U8 data[], int num, int ntimeout)
{
	INT8U err;
	int nrev, n, snum;
	struct_Uart_Buffer *pUart_Buffer;
#if OS_CRITICAL_METHOD == 3
	OS_CPU_SR  cpu_sr;
#endif

#if OS_ARG_CHK_EN > 0
	if(ndev>=NumberOfUartDrv)
		return 0;
#endif
	pUart_Buffer=&Uart_Buffer[ndev];

	snum=num;
	for(; num>0;num-=n){
		OS_ENTER_CRITICAL();
		//设置Uart接收数据数
		n=min(num, UART_REVBUFFER_SIZE);
		pUart_Buffer->nRev_Uart=n;
		nrev=RoundCount(pUart_Buffer->nUart_rev, pUart_Buffer->nUart_read, UART_REVBUFFER_SIZE);
		OS_EXIT_CRITICAL();

		while(nrev<n){
			OSSemPend(pUart_Buffer->Uart_Rev_sem, ntimeout,&err);
			if(err==OS_TIMEOUT){
				goto end;
			}
			nrev=RoundCount(pUart_Buffer->nUart_rev, pUart_Buffer->nUart_read, UART_REVBUFFER_SIZE);
		}

		OS_ENTER_CRITICAL();
		RoundmemCpyFrom(data, pUart_Buffer->revBuffer, 
			pUart_Buffer->nUart_read, n, UART_REVBUFFER_SIZE);
		OS_EXIT_CRITICAL();
		data+=n;
	}
//	for(i=0;i<num;i++){
//		data[i]=*(pUart_Buffer->revBuffer[pUart_Buffer->nUart_read]);
//		RoundINC(pUart_Buffer->nUart_read, UART_REVBUFFER_SIZE);
//	}
end:
	return snum-num;
}

/*************************
	写串口n的数据
	返回值,实际写入的数据数目
****************************/
int OSWriteUart(int ndev, U8 data[], int num, int ntimeout)
{
	INT8U err;
	int n;
	struct_Uart_Buffer *pUart_Buffer;
#if OS_CRITICAL_METHOD == 3
	OS_CPU_SR  cpu_sr;
#endif

#if OS_ARG_CHK_EN > 0
	if(ndev>=NumberOfUartDrv)
		return 0;
#endif
	pUart_Buffer=&Uart_Buffer[ndev];

	OS_ENTER_CRITICAL();
	n=RoundFreeCount(pUart_Buffer->nUart_write, pUart_Buffer->nUart_send, UART_SNDBUFFER_SIZE);
	OS_EXIT_CRITICAL();

	do{
		if(n<num){
			if(n>0){
				OS_ENTER_CRITICAL();
				RoundmemCpyTo(pUart_Buffer->sndBuffer, data, pUart_Buffer->nUart_write, 
					n, UART_SNDBUFFER_SIZE);
				serial_drv[ndev]->write();
				OS_EXIT_CRITICAL();
				num-=n;
			}

			do{
				OSSemPend(pUart_Buffer->Uart_Snd_sem, ntimeout,&err);
				if(err==OS_TIMEOUT){
					return num;
				}
				n=RoundFreeCount(pUart_Buffer->nUart_write, 
					pUart_Buffer->nUart_send, UART_SNDBUFFER_SIZE);
			}while(n<=UART_SNDBUFFER_SIZE/2 && n<num);
			
		}else{
			OS_ENTER_CRITICAL();
			RoundmemCpyTo(pUart_Buffer->sndBuffer, data, pUart_Buffer->nUart_write, 
				num, UART_SNDBUFFER_SIZE);
			serial_drv[ndev]->write();
			OS_EXIT_CRITICAL();
			return 0;
		}		
	}while(num);

	return num;
}

/*************************
	写串口n的数据
	返回值,实际写入的数据数目
****************************/
int OSWritepollUart(int ndev, U8 data[], int num, int ntimeout)
{
	for(; num>0; num--){
		serial_drv[ndev]->writepoll(*data);
		data++;
	}
	
	return 0;
}


//发送缓冲区清空
void Uart_FlushTxBuffer(int ndev)
{
	struct_Uart_Buffer *pUart_Buffer;
#if OS_ARG_CHK_EN > 0
	if(ndev>=NumberOfUartDrv)
		return;
#endif
	pUart_Buffer=&Uart_Buffer[ndev];

	pUart_Buffer->nUart_send=pUart_Buffer->nUart_write=0;
	serial_drv[ndev]->flush_output();
}

//接收缓冲区清空
void Uart_FlushRxBuffer(int ndev)
{
	struct_Uart_Buffer *pUart_Buffer;
#if OS_ARG_CHK_EN > 0
	if(ndev>=NumberOfUartDrv)
		return;
#endif
	pUart_Buffer=&Uart_Buffer[ndev];

	pUart_Buffer->nUart_rev=pUart_Buffer->nUart_read=0;
	serial_drv[ndev]->flush_input();
}


void OSInitUart(void)
{
	int i;

	for(i=0;i<NumberOfUartDrv;i++){
		Uart_Buffer[i].nRev_Uart=1;		//设定的Uart接收字符数
		Uart_Buffer[i].nUart_rev=Uart_Buffer[i].nUart_read=0;
		Uart_Buffer[i].nUart_send=Uart_Buffer[i].nUart_write=0;
		Uart_Buffer[i].Uart_Rev_sem=OSSemCreate(0);
		Uart_Buffer[i].Uart_Snd_sem=OSSemCreate(0);
		Uart_Buffer[i].Uart_write = OSWritepollUart;
	}
}

/*************************
	开启串口n中断和缓冲模式
****************************/
int OpenUartRev(int ndev)
{
//	struct_Uart_Buffer *pUart_Buffer;
#if OS_ARG_CHK_EN > 0
	if(ndev>=NumberOfUartDrv)
		return FAIL;
#endif
//	pUart_Buffer=&Uart_Buffer[ndev];

	Uart_Buffer[ndev].Uart_write = OSWriteUart;
	serial_drv[ndev]->open();

//	SetISR_Interrupt(serial_drv[ndev]->nIsr, (Interrupt_func_t)irq_OSRevUart, (void*)ndev);

	return OK;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -