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

📄 uart.c

📁 关于ucos下的 UART串口驱动实现 硬件平台是LPC2114
💻 C
📖 第 1 页 / 共 2 页
字号:
								recvQueue.start =   0;
									U0IER &=(~0x01);			
									//IO0SET = R485;
								break;
								}								
							}
						} //for
					}else{
						for(i=8; i!=0; i--){                             // 12月4日修改
							temp = U0RBR;
						}  
						U0IER &=(~0x01);
					}
					recvQueue.DataNum = dataNum;
                break;
            case 0x06:                                  /* 接收线状态   */
                temp = U0LSR;
                break;
            case 0x0c:                                  /* 字符超时指示 */
                if(recvQueue.RBuff != NULL){
                dataNum = recvQueue.DataNum;
                for(i=8;i!=0;i--){
		                if(0==U0LSR&0x01){
		             	   			break;
		             	   		}
						temp = U0RBR;
						if(temp == 0x68){
							recvQueue.start = 1;
							}
						if(recvQueue.start==1){
							*recvQueue.pData++ = temp;
						 	dataNum++;
						}
						if((0 == g_Uart0_Func)&&(0x16==temp)&&(*(recvQueue.RBuff+2)==(uint8)(dataNum-5))){
							OSSemPost(Uart0recvSem);			/*通知任务拿数据*/
							                       			    /*释放UART0 一次帧发送和帧返回作为一次串口占用 如果 表具无响应的话
												 				 那么 Uart0recvSem和 Uart0Sem 就得不到释放 所以等待超时后 先释放信号量 */
							UART0_OWN_Flag = 0 ;
							
							U0_Post_flag = 1   ;
							g_meter_wait = MANI_METER_WAIT  ;
							
							recvQueue.RBuff = NULL;       		//重置接收缓存控制结构
							recvQueue.pData = NULL;
							recvQueue.DataNum = 0;
							recvQueue.start =   0;
							U0IER &=(~0x01);			
								//IO0SET = R485;
							break;
							}
						if((1 == g_Uart0_Func)&&(0x16==temp)){  	 //用于扫描仪接收时的判断
							dataLen = *(recvQueue.RBuff+5)*100 + *(recvQueue.RBuff+6) ;
							if(dataLen == (dataNum-9)){
								OSSemPost(Uart0recvSem);			 /*通知任务拿数据*/
								
								recvQueue.RBuff = NULL;      		 //重置接收缓存控制结构
								recvQueue.pData = NULL;
								recvQueue.DataNum = 0;
								recvQueue.start =   0;
									U0IER &=(~0x01);			
									//IO0SET = R485;
								break;
								}
							}
						}//for
				}else{
					for(i=8; i!=0;i--){                             // 12月4日修改
							temp = U0RBR;
							if(0 == (U0LSR&0x01)){
							break;
							}
						}  
					U0IER &=(~0x01);
					}
				recvQueue.DataNum = dataNum;
                break;
            default :
                break;
        }
   
   
    VICVectAddr = 0;               	// 通知中断控制器中断结束
    OS_EXIT_CRITICAL();
}
//---------------------------------------//
//---------------------------------------//

/*********************************************************************************************************
** 函数名称: UART1Init
** 功能描述: 初始化UART0 
** 输 入: bps:波特率
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
  uint8 UART1Init(uint32 bps)
  {
 	uint16 Fdiv;

    U1LCR = 0x80;                               /* 允许访问分频因子寄存器 */
    Fdiv = (Fpclk / 16) / bps;                  /* 设置波特率 */
    U1DLM = Fdiv / 256;							
	U1DLL = Fdiv % 256;						
    U1LCR = 0x03;                               /* 禁止访问分频因子寄存器 */
                                                /* 且设置为8,1,n */
    U1FCR = 0x87;                               /* 初始化FIFO */
    Uart1Sem = OSSemCreate(1);
    Uart1_Mbox = OSMboxCreate(NULL);
					
    	g_Mbox_Complete = 1;            /*初始化 邮箱信息已经完成处理 数组可用*/ 
    
    recvQueue_U1.RBuff = (QUEUE_DATA_TYPE *)Uart1_recv; /*初始化 邮箱信息接受控制模块 */
	recvQueue_U1.pData = recvQueue_U1.RBuff;
	recvQueue_U1.DataNum = 0;
	recvQueue_U1.start = 0;
	
    U1IER = U1IER & (~0x07)	;                              
    U1IER = U1IER | 0x01	;/*允许接收中断*/
    
    if ((Uart1Sem != NULL)&&(Uart1_Mbox!=NULL))
    {
        return TRUE;
    }
    else
    {
        return FALSE;
    }
  }
/*********************************************************************************************************
** 函数名称: UART1_SendQ
** 功能描述: 发送一组数据
** 输 入: 无
** 输 出: 接收到的数据
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/

	void UART1_SendQ(const void * DQ_head, uint16 DataN)
	{
		uint8 err;
		OSSemPend(Uart1Sem,0,&err);
		
		OS_ENTER_CRITICAL();
		sendQueue_U1.DQ_head = (QUEUE_DATA_TYPE *)DQ_head;
		sendQueue_U1.pData =  (QUEUE_DATA_TYPE *)DQ_head;
		sendQueue_U1.DataNum = DataN;
		OS_EXIT_CRITICAL();
		
	if(1 == g_GPRS_recv){             /* 发送GPRS AT指令,不发送前导(FE FE)字节*/
		U1THR = *sendQueue_U1.pData++ ;
		sendQueue_U1.DataNum -- ;
		U1IER = U1IER | 0x02 ;
		return ;
	} 
		U1THR = 0xFE;
		U1THR = 0xFE;                                   			/*启动THR中断 需前导字节初始化 FIFO*/
		U1IER = U1IER | 0x02;                            			 /*使能发送中断*/
	}
/*********************************************************************************************************
** 函数名称: UART1_Reset()
** 功能描述: 用于重置UART1接收缓存
** 输 入: 无
** 输 出: 接收到的数据
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/	
void UART1_RecvReset(void)
{

OS_ENTER_CRITICAL();
	g_Mbox_Complete = 1;
	recvQueue_U1.pData = recvQueue_U1.RBuff;
	recvQueue_U1.DataNum = 0;
	recvQueue_U1.start =   0;
OS_EXIT_CRITICAL();
	memset((uint8 *)Uart1_recv, 0, sizeof(Uart1_recv)); 			 /* 08-12-1日增加*/
}
	
/*********************************************************************************************************
** 函数名称: UART1_Exception
** 功能描述: UART1中断服务程序
** 修改 08-12-27 :GPRS返回数据不用中断接收,去掉相关内容;但AT指令仍用中断发送;
**------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        void UART1_Exception(void)
{
    uint8 IIR, temp , i;  
    uint16 dataNum = 0;
    
    OS_ENTER_CRITICAL();
        IIR = U1IIR	;
					                                   
        switch (IIR & 0x0e) 									/* 有中断未处理完 */
        {
            case 0x02: 
            	dataNum = sendQueue_U1.DataNum;                                
             	if(sendQueue_U1.DQ_head == NULL){
             		U1IER = U1IER&(~0x02);               		/* THRE中断    */
             	}else{
             		  for(i=16;i!=0;i--)                 			/*如果发送允许(U0THR为空)*/
             			{
             				U1THR = *sendQueue_U1.pData++;
							if(0 == --dataNum)  break;             				
             			}
             		  if(!dataNum){                       		 /*数据发送完毕*/
             				sendQueue_U1.DQ_head = NULL;
             				sendQueue_U1.pData = NULL;
             				recvQueue_U1.start = 0;
             					g_GPRS_recv = 0;	
             				U1IER &=(~0x02);            		/*如果发送的是AT指令 则标识复位  */
             				OSSemPost(Uart1Sem);         
             					                                  
             		  }else{
             				sendQueue_U1.DataNum = dataNum;
             		  }
             	    }		
                break;
            case 0x04:                           			   /* 接收数据可用 */                                               
                if(1 == g_Mbox_Complete){
                   dataNum = recvQueue_U1.DataNum;
             	   for(i=8;i!=0;i--){
						temp = U1RBR;
						if(temp == 0x68){
							recvQueue_U1.start = 1;
							}
						if(recvQueue_U1.start==1){
							*recvQueue_U1.pData++ = temp;
						 	dataNum++;
							}
						if((0x16==temp)&&(*(recvQueue_U1.RBuff+6)==(uint8)(dataNum-9))){
							OSMboxPost(Uart1_Mbox, Uart1_recv);			/*通知任务拿数据*/
							g_Mbox_Complete = 0;                        /*等待任务来处理邮箱里信息桢*/
							break;
							} 
						if(dataNum > 50){    				/*考虑到:如果桢错误,有0X68 但无结束0X16 接受字符超过50 怎么办*/
							dataNum = 0 ; 					 //recvQueue_U1.DataNum = 0;  跳出FOR后,可将 recvQueue_U1.DataNum  赋值为 0;
							recvQueue_U1.pData = recvQueue_U1.RBuff ;
							recvQueue_U1.start = 0 ;
							U1FCR |= 0x02 ;               
							break;
							}
						} //for                                              
					}else{                       			 /*上次桢还没处理完 复位清空 RXFIFO  U1FCR |=0x02 ( 这样会引起数据预取中止 有待解决); */
						for(i=8; i!=0;i--){      			 //12月4日修改
							temp = U1RBR;
						}						
						break;
					}
				recvQueue_U1.DataNum = dataNum;
                break;
            case 0x06:                                  /* 接收线状态   */
                temp = U1LSR;
                break;
            case 0x0c:                                  /* 字符超时指示 */
                if( 1 == g_Mbox_Complete){
                   dataNum = recvQueue_U1.DataNum;
             	   for(i=8;i!=0;i--){
             	   		if(0==U1LSR&0x01){
             	   			break;
             	   		}
						temp = U1RBR;
						if((temp == 0x68)&&(0 == recvQueue_U1.start)){
							recvQueue_U1.start=1;
							}
						if(recvQueue_U1.start==1){
							*recvQueue_U1.pData++ = temp;
						 	dataNum++;
						}
						if((0x16==temp)&&(*(recvQueue_U1.RBuff+6)==(uint8)(dataNum-9))){
							OSMboxPost(Uart1_Mbox, Uart1_recv);			/*通知任务取邮箱信息*/
							g_Mbox_Complete = 0;                        /*等待任务来处理完毕邮箱里信息桢*/
							break;
							}
						if(dataNum > 50){ 								/*考虑到:如果桢错误,有0X68 但无结束0X16 接受字符超过50 怎么办*/
							dataNum = 0 ;
							recvQueue_U1.pData = recvQueue_U1.RBuff;
							recvQueue_U1.start = 0   ;
							                          					//recvQueue_U1.DataNum = 0 ;
								U1FCR |= 0x02;
							break;
							}
						}		 //for
					}else{												/*上次桢还没处理完 复位 RXFIFO   U1FCR |= 0x02 ; */
						for(i=8; i!=0;i--){                             // 12月4日修改
							temp = U1RBR;
							if(0 == (U1LSR&0x01)){
							break;
							}
						}  													
						break ;
					}
					recvQueue_U1.DataNum = dataNum;
                break;
            default :
                break;
        }
    VICVectAddr = 0;               										// 通知中断控制器中断结束
    OS_EXIT_CRITICAL();
}
/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

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