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

📄 uart1.c

📁 基于ARM7处理器的中断与串口在ucos下切换的演示程序
💻 C
字号:
/* ----------------------------------------------------
   模块名: Uart1.c:
   描  述: 串口1接口函数  
--------------------------------------------------------*/
#include "config.h"


#define USE_SEMAPHORE_RX  1              /* 打开后不稳定问题解决 */





static OS_EVENT *Uart1TxSem;

#if USE_SEMAPHORE_RX
static OS_EVENT *Uart1RxSem;
#else
volatile uint8 uart1_inbufsign;          /* 接收缓冲区非空标志-有=1 */
#endif



//volatile char  RxBuf12[uart1_LenRxBuf];	/* just test */
volatile char  RxBuf1[uart1_LenRxBuf];
volatile int  rxHead1;         /* 收发缓冲区读写指针 */
volatile int  rxTail1;
volatile int   nUart1RxLen;

volatile char  TxBuf1[uart1_LenTxBuf]; /* 收发缓冲区实体 */
volatile int  txHead1;         /* 收发缓冲区读写指针 */
volatile int  txTail1;
volatile int  nUart1TxLen;	


void UART1_data_transfer(void*);
/*------------------------------------------------------------
名    称:UART1_Ini()
功    能:初始化串口0。设置其工作模式及波特率。
入口参数:set  模式设置(UARTMODE数据结构)
出口参数:返回值为1时表示初化成功,为0表除参数出错
------------------------------------------------------------*/
uint8  UART1_Ini(UARTMODE *set)
{  
	uint32  bak;
	
    VICIntEnClr = 1 << 7;   //禁止uart1中断

    /* 参数过滤 */
    if((0 == set->baudrate)||(set->baudrate > 115200) ) return(0);
    if((set->datab < 5) ||(set->datab > 8) ) return(0);
    if((0 == set->stopb)||(set->stopb > 2) ) return(0);
    if( set->parity > 2 ) return(0);

    /* 设置I/O连接到UART1 */
    PINSEL0 = (PINSEL0 & 0xfff0ffff) | 0x00050000;
    //PINSEL0 = (PINSEL0 & 0x0000ffff) | 0x55550000;

    /* 设置串口波特率 */
    U1LCR = 0x80;                    // DLAB位置1
    bak = (FPCLK>>4)/set->baudrate;
    U1DLM = bak>>8;
    U1DLL = bak&0xff;
     
    /* 设置串口模式 */
    bak = set->datab - 5;            // 设置字长度
    if(2 == set->stopb) bak |= 0x04; // 判断是否为2位停止位  
    
    if(0 != set->parity) 
    {
		if(set->parity == 1)
		{
            bak |= 0x08;             // 设置为奇校验
		}
		else
		{
			bak |= 0x18;             // 设置为偶校验
		}
    }
    U1LCR = bak;	
    //U1FCR = 0x01;                    	// 每接收到一个字符就产生一次中断   
	U1FCR = 0xc1;
    U1IER = 0x03;                    	// 允许RBR和THRE中断,即接收中断
    
    /* 初始化串口所用到的全局变量 */   
	nUart1RxLen = 0;
    rxHead1 = 0;
    rxTail1 = 0;

	nUart1TxLen = 0;
    txHead1 = 0;
    txTail1 = 0;

    //memset(RxBuf12, 0, sizeof(RxBuf12));
    
    Uart1TxSem = OSSemCreate(1);     // 信号量用于发送缓冲区满后等待发送
	
#if USE_SEMAPHORE_RX
    Uart1RxSem = OSSemCreate(0);     // 信号量用于等待串口接收字符中断
#else
    uart1_inbufsign = 0;
#endif
    
    //VICIntEnable = 1 << 7;           // 允许uart0中断
    
    return 0;
}

//
// 向硬件发送一个字节
//
void uart1PhySend(void)
{
	
    if( nUart1TxLen )
	{      	
		if( txHead1 == uart1_LenTxBuf)
		{
			txHead1 = 0;
		}

		OS_ENTER_CRITICAL();
		if( LSR_TEMT & U1LSR )
		{           
		   U1THR = TxBuf1[txHead1++] ;
		   nUart1TxLen--;          
		}
	    OS_EXIT_CRITICAL();	
	}
}

//
// 从硬件获取数据
//
void uart1PhyRecv(void)
{
	char c;
	//int i;

	//for( i = 0; i < 16; i++ )
	while(1)
	{
		if( U1LSR & LSR_RDR )	// 有数据
		{
			c = U1RBR;
			OS_ENTER_CRITICAL();
			if( nUart1RxLen < uart1_LenRxBuf )
			{
				// if reach the end, turn round
				if( rxTail1 == uart1_LenRxBuf)
				{
					rxTail1 = 0;
				}
				RxBuf1[rxTail1++] = c;
				nUart1RxLen++;
			}
		    OS_EXIT_CRITICAL();	
		}
		else break;
	}
}

/*------------------------------------------------------------
名    称:UART1_Exception()
功    能:串口UART1接收中断。
入口参数:无
出口参数:无
------------------------------------------------------------*/
void   Uart1_Exception(void)
{
    uint8 Uart1Int;	

	OS_ENTER_CRITICAL();
    if(((Uart1Int = U1IIR)&0x01) == 0)
    {
        switch(Uart1Int & 0x0e)
        {
            case 0x02:  /* 发送中断处理 */           
                OSSemPost(Uart1TxSem);                
                //uart1PhySend();
          
            	break;

            case 0x04:  /* 接收中断处理 */
            {
            	uart1PhyRecv();
				
				//if(nUart1RxLen!=1)
				//	OSUntimeout(UART1_data_transfer, NULL);
				//OSTimeout(UART1_data_transfer, NULL, 1);													
            }
            break;
            
            case 0x06: /* 串口接收线路状态错误中断 */
            {
                Uart1Int = U1LSR; /* 一定要进行该操作,用以清除中断标志,否则串口会死掉! */       

            }
            break;
            
            case 0x0c: /* 串口字符超时指示(CTI)中断 */
            {
            	uart1PhyRecv();
				//OSUntimeout(UART1_data_transfer, NULL);
            	//UART1_data_transfer((void*)0);

                //Uart1Int = U1RBR; /* 一定要进行该操作,用以清除中断标志,否则串口会死掉! */

            }
            break;
            
            default:
                Uart1Int = U1LSR;

            break;
        }
    }
    OS_EXIT_CRITICAL();
    
    VICVectAddr = 0x00;                          // 中断处理结束
}               

/*------------------------------------------------------------
** 函数名称: UART1_PutChar
** 功能描述: 从UART1往外发送一字节
** 输   入: 待发送数据
** 输   出: 无
** 返    回: 待发送数据 
------------------------------------------------------------*/

char UART1_PutChar(char c)
{
	UART1_PutData( &c, 1 );
	return c;
}

/*------------------------------------------------------------
** 函数名称: UART1_PutChar
** 功能描述: 从UART1往外发送一指定长度字符串
** 输   入: 待发送数据
** 输   出: 无
** 返    回: 无 
------------------------------------------------------------*/
int UART1_PutData(char *str, int len)
{
	int i;
	int nTempLen;
	//int nNeedToSend = FALSE;
	//uint8 err;

	if( nUart1TxLen >= uart1_LenTxBuf )
		return 0;
	
    OS_ENTER_CRITICAL();

	nTempLen = min(len, uart1_LenTxBuf - nUart1TxLen );
	for( i = 0; i < nTempLen; i++ )
	{
		if( txTail1 == uart1_LenTxBuf )
			txTail1 = 0;
		TxBuf1[txTail1++] = str[i];
		nUart1TxLen ++;
	}

    OS_EXIT_CRITICAL();
    return len;
}

//
// read data direct
//
int ReadDataNowait(char *buffer,int limit)
{
	int i;
	int templen;

	templen = min(limit, nUart1RxLen);
	for( i = 0; i < templen; i++ )
	{
		if( rxHead1 == uart1_LenRxBuf )
			rxHead1 = 0;
		buffer[i] = RxBuf1[rxHead1++];
	}
	
	OS_ENTER_CRITICAL();
	nUart1RxLen -= templen;
	OS_EXIT_CRITICAL();

	return templen;
}

//
// 读取串口数据
// buf: 缓冲地址
// len: 缓冲长度
// timeout: 超时时间
// 返回: 数据长度
//
int ReadData(char *buffer,int limit,int timeout)
{	
	//uint8 err;	
	
	//OSSemPend(Uart1RxSem, timeout, &err);
	//if(OS_NO_ERR != err)
   	//{
   	//    return 0;
   	//}		

	return ReadDataNowait(buffer, limit);
}

//
// check if there any data to read
//
int ReadDataWaiting(void)
{
	return nUart1RxLen;	
}

//
// notify the application to read data
//
void UART1_data_transfer(void* p)
{
	OSSemPost(Uart1RxSem);	
}

//
// 发送数据
// buffer: 数据缓冲地址
// size:   缓冲大小
// 返回: 已发送数据长度
//
int SendData(char* buffer, int size)
{
	UART1_PutData( buffer, size );	
	return size;
}

//
// 清空串口缓冲
//
void ClearComm(void)
{
	OS_ENTER_CRITICAL();	
	nUart1RxLen = 0;
    rxHead1 = 0;
    rxTail1 = 0;

	nUart1TxLen = 0;
    txHead1 = 0;
    txTail1 = 0;	
	OS_EXIT_CRITICAL();
}

unsigned char IsOpened(void)
{
	return 0;
}


//
// set the DTR control line
//
void uart1_set_dtr( int value )
{
	/*IODIR = IODIR | UART1_DTR;
	if( value )
		IOSET = IOSET | UART1_DTR;	// 置1 无效
	else		
		IOCLR = IOCLR | UART1_DTR;	// 置0, 有效 
		*/
}

int uart1_get_dcd(void)
{
   //P1.22
   if ((IO1PIN & 0x00400000) != 0)
   {
       return 1;
   }
   else
   {
       return 0;
   }
}

int uart1_get_cts(void)
{
   //P0.11

   if ((IO0PIN & 0x00000800) != 0)
   {
   	   return 1;
   }
   else
   {
   	   return 0;
   }
}

⌨️ 快捷键说明

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