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

📄 uart.c

📁 SEP3203_DTU
💻 C
📖 第 1 页 / 共 2 页
字号:
{
    uint16 i;

    for(i=0; i<Size; i++,Ret++)
    {
        if((Uart0Getch((uint8 *)Ret, QUEUE_ACCEPT))!=SYS_ERR_OK)
        {
            return i;
        }
    }
    return i;    
}
/*********************************************************************************************************
** 函数名称: UART0Getch
** 功能描述: 接收一个字节
** 输 入: 无
** 输 出: SYS_ERR_OK:接收到的数据
**                   SYS_ERR_FAIL:没有接收到数据
** 全局变量: 无
** 调用模块: 无
**
** 作 者: 陈明计
** 日 期: 2003年7月4日
**-------------------------------------------------------------------------------------------------------
** 修改人: Zbj
** 日 期: 2007.11.27
**-------------------------------------------------------------------------------------------------------
********************************************************************************************************/
        sys_err Uart0Getch(uint8 *Ret, q_mod Mod)
{
    if(QueueRead(Ret, (void *)Uart0RecvBuf,Mod)==QUEUE_OK)
    {
        return SYS_ERR_OK;
    }
    return SYS_ERR_FAIL;    
} 

int UartStart(void)
{
     
   U32 sysclk      = 70000000;  //;系统时钟 20MHz, 30MHz, 40MHz, 50MHz, 60MHz
   
 
   int recie = 1;               //;接收中断使能 0 disable, 1 enble
   int thrie = 0;	            //;发送中断使能  0 disable, 1 enble
  
	
	/* open uart0 interrrupt mask */
	//unmask_irq(INT_UART0);//;根据参数中断号判断出uart0屏蔽打开
      
   Uart0Init(sysclk, uart_baudrate, uart_databit, uart_trigerlevel);//;初始化uart0

   unmask_irq(INT_UART0);//根据参数中断号判断出uart0屏蔽打开
   Uart0_Int_En(recie, thrie);				 
  // *(RP)INTC_IEN = 0X01800000;					//第23,24位置1,打开uart1 uart0		

    if (QueueCreate((void *)Uart0SendBuf,
                     UART0_SEND_QUEUE_LENGTH,
                     NULL,
                     (uint8 (*)())UartWriteFull)
                     == NOT_OK)
    {
        return FALSE;
    }

    //建立接收数据队列
    if (QueueCreate((void *)Uart0RecvBuf,
                     UART0_RECV_QUEUE_LENGTH,                     
                     (uint8 (*)())UartReadEmpty,
                     NULL)
                     == NOT_OK)
    {
        return FALSE;
    }

    return 0;
}

int Uart0Init(U32 sysclk, U32 baudrate, U32 databit, U32 trigerlevel)
{
    U32 baud, bit, triger, baudh, baudl;
    baud  = sysclk/16/baudrate;//?
    baudh = baud >> 8;//;波特率高8位赋值
    baudl = baud & 0xff;//;波特率低8位赋值
    
    switch(databit)//;根据数据位大小判断,
    //;四种情况对应不同的数据比特数:00(5bits),01(6bits),10(7bits),11(8bits)
    {
    	case 5: bit = 0x80;
    	     break;
    	     
    	case 6: bit = 0x81;
    	     break;
    	       
    	case 7: bit = 0x82;
    	     break;
    	     
    	case 8: bit = 0x83;
    	     break;
    	
    	default: ;
    	     break;             	  	
    }	
    
    write_reg(UART0_LCR, bit);  //divisor latch被访问,通过输入的数据bit第8位为1配置
    
    write_reg(UART0_DLH, baudh);//将计算后的波特率写入高8位
    write_reg(UART0_DLL, baudl);//将计算后的波特率写入低8位
    
    read_reg(UART0_LCR) &= (~(0x1 << 7));  //通过UART0_LCR第7位和0相与置0,关闭波特率访问,
    //转到普通寄存器的访问,至此完成的数据的初始化
    
    switch(trigerlevel)//触发级初始化,定义transmitter FIFO的trigger level:00(0byte),
    //01(2byte),10(4byte),11(8byte)
    {
    	case 1:  triger = 0x0;
    	     break;
    	     
    	case 4:  triger = 0x1;
    	     break;
    	     
    	case 8:  triger = 0x2;
    	     break;
    	     
    	case 14: triger = 0x3;
    	     break;
    	
    }
    
    triger = (triger << 6);
    
    write_reg(UART0_FCR, triger);
    //这个函数同样方法可以定义receiver FIFO的trigger level。
    
    write_reg(UART0_IER, 0x00);//关闭Uart中断
    //	
    return E_OK;
}

int Uart0_Int_En(int recie, int thrie)//判断uart0是否准备接收和发送数据,从而决定FIFO的使能控制
{
     if(recie == 1)//uart0准备好接收数据
        read_reg(UART0_IER) |= 0x1;//开接收FIFO触发级中断使能/*received data available interrupt enable*/
        
     else 
        if(recie == 0)//uart0没准备接收数据
          read_reg(UART0_IER) &= ~0x1;//关闭接收FIFO触发级中断使能/*interrupt disable*/
        
     if(thrie == 1)//uart0准备发送数据
        read_reg(UART0_IER) |= (0x02);//开发送FIFO触发级空中断使能    /*transmitter holding register empty interrupt enable*/
        
     else
        if(thrie == 0)//uart0没准备好发送数据
          read_reg(UART0_IER) &= ~(0x02); //关闭发送FIFO触发级空中断使能/*transmitter holding register empty interrupt disable*/	
   	
     return E_OK; 
}


/*中断服务程序*/
void Uart0_Exception(void)
{
    uint8 i,temp;
	
    	#if OS_CRITICAL_METHOD == 3                                /* Allocate storage for CPU status register */
    	OS_CPU_SR     cpu_sr;
	#endif

       OS_ENTER_CRITICAL();

	switch(( read_reg(UART0_IIR) & 0XE ) >> 1 )//判断bit【3:1】中断源标号
 	{		
	case 2 :              //receiver data available interrupt接收FIFO中的数据达到触发级中断
		for(i=0; i<UART_FIFO_LENGTH; i++)
     		{
     			if((read_reg(UART0_LSR)&0x01)==0x00)      //没有数据
                    {
                         break;
			}
         		temp = read_reg(UART0_RBR);//读取接收FIFO里的数据
         		QueueWrite((void *)Uart0RecvBuf,temp); 
    		}	
		break;	
		
	case 6 :	   		//time out interrupt超时中断
		for(i=0; i<UART_FIFO_LENGTH; i++)
     		{
     			if((read_reg(UART0_LSR)&0x01)==0x00)      //没有数据
                    {
                         break;
			}
         		temp = read_reg(UART0_RBR);//读取接收FIFO里的数据
         		QueueWrite((void *)Uart0RecvBuf,temp); 
    		}	
		break;	
		
	case 1 :	//transmit holding register empty interrupt 传输FIFO中断
		 for (i = 0; i < UART_FIFO_LENGTH; i++) /* 向发送FIFO填充数据 */
                {
                    if (QueueRead(&temp, Uart0SendBuf,QUEUE_ACCEPT) == QUEUE_OK)
                    {
                        write_reg(UART0_THR,temp);
                    }
                    else if(QueueRead(&temp, Uart0RecvBuf,QUEUE_ACCEPT) == QUEUE_OK)
                    	{
                    	    write_reg(UART0_THR,temp);
                    	}
			else
                    {
                        read_reg(UART0_IER) &= ~(0x02);        /* 队列空,则禁止发送中断 */
                    }
                }
                break;
				
	default :
		break ;
	}
	OS_EXIT_CRITICAL();
}

ER prints(char *s)//把数据打印到上位机超级终端
{
    int i;
   // U32 mask;
    while(*s != '\0')
    {
        {
           *(RP)UART0_THR = *s++;//利用指针传输数据,这个是硬件管理的,我们只要把指针指向首数据地址,并且建立循环
        }
        for(i=0; i<5000 ; i++) ;
    }
    *(RP)UART0_THR = '\n';   
       return E_OK;    
}

⌨️ 快捷键说明

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