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

📄 uart.c

📁 USART的驱动程序
💻 C
字号:
/*************************************************************************************
*	Copyright (c) 2005 by National ASIC System Engineering Research Center.
*	PROPRIETARY RIGHTS of ASIC are involved in the subject matter of this 
*	material.  All manufacturing, reproduction, use, and sales rights 
*	pertaining to this subject matter are governed by the license agreement.
*	The recipient of this software implicitly accepts the terms of the license.
*
*	File Name: uart.c
*
*	File Description:
*			The file consists of the function used to config uart
*
*	Function Description:
*		uart_reset_value_test()			
*								check uart registers reset value
*
*		HA_InitUart1(U32 clk, U32 baud, U32 bits, U32 triger)
*								 initiate UART
*								
*
*		ER en_re_int(U32)
*								enable and disable the recieve int and the transmit int
*               thr_isr_uart0(void)
                                                                interrupt handler for UART1
                rda_isr_uart0(void) 
                                                                interrupt handler
                int_serv_uart0()
                                                                UART0 interrupt service
*	Created by Michael <yuyu_zh@seu.edu.cn>, 2005-03-21
**************************************************************************************/


#include "garfield.h"

#define ESRAM_Test_BASE  0x1fff0000
 
STATUS ModuleUart(void)
{
     
   U32 sysclk      = 70000000;  //;系统时钟 20MHz, 30MHz, 40MHz, 50MHz, 60MHz
   U32 baudrate    = 9600;      //;波特率 57600, 56000, 38400, 19200, 9600
   U32 databit     = 8;         //; 数据位6, 7, 8 
   U32 trigerlevel = 8;         //;触发级 4, 8, 14
   
 
   int recie = 1;               //;接收中断使能 0 disable, 1 enble
   int thrie = 0;	            //;发送中断使能  0 disable, 1 enble
  
   
	/* system initialized */
	system_init();//;PMU_init() INT_init()系统时钟功耗初始化 中断初始化(屏蔽所有中断
	//;同时使能所有中断,等待打开屏蔽)
	
	/* open uart0 interrrupt mask */
	unmask_irq(INT_UART0);//;根据参数中断号判断出uart0屏蔽打开
      
   init_uart0(sysclk, baudrate, databit, trigerlevel);//;初始化uart0
      
   uart0_int_en(recie, thrie);
   
   prints("test Garfield !\n");
   
   *(RP)INTC_IEN = 0X01800000;					//;第23,24位置1,打开uart1 uart2				 
   
   unmask_all_irq();

   while(1);                                    //;等待中断
                       
}

   void init_esram(void)
 {
    int i;
 
   volatile int *esram_base1 = ( int  *)ESRAM_Test_BASE;
   volatile int *esram_base2 = ( int  *)ESRAM_Test_BASE;
   //*(esram_base1) = "test string!";
   for(i = 0; i<0x1000; i++)
   {
      *(esram_base1)=0;
      esram_base1 ++;
    }

   for(i=0;i<0x40;i++)
   {
 	*(esram_base2)=i;
 	esram_base2 ++;
   }
 
 }


int init_uart0(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第8位和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);//打开接收FIFO触发级中断使能
    //	
    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) |= (0x1 << 1);//开发送FIFO触发级空中断使能    /*transmitter holding register empty interrupt enable*/
        
     else
        if(thrie == 0)//uart0没准备好发送数据
          read_reg(UART0_IER) &= ~(0x1 << 1); //关闭发送FIFO触发级空中断使能/*transmitter holding register empty interrupt disable*/	
   	
     return E_OK; 
}

int thr_isr_uart0(void)
{
     U32 i;
     U32 a = 0x30;
     
     prints("UART transmiter holding register handler!\n");
     
     for(i=0; i<100; i++,a++)
         write_reg(UART1_THR,a);//把要发送的数据放入传输FIFO
         
     return E_OK;
}

ER rda_isr_uart0(void)
{
     U32 i;
     U32 a;
     
     prints("UART receive data available handler!\n");
     
     for(i=0; i<8; i++)
     {
         a = read_reg(UART0_RBR);//读取接收FIFO里的数据
         printf("%c",a);//把接收的数据在lcd上打印 
     }
     printf("\n");
     return E_OK;
}
/*中断服务程序*/
void int_serv_uart0(void)
{
	//a =  (*(RP)UART0_IIR & 0XE ) >> 1;
	switch(( read_reg(UART0_IIR) & 0XE ) >> 1 )//判断bit【3:1】中断源标号
 	//switch(a)
 	{
 	case 3 :	
 		rls_isr();	//receiver line status interrupt接收数据状态中断
 		return ;
 		break;	
	case 2 :
		rda_isr_uart0();	//receiver data available interrupt接收FIFO中的数据达到触发级中断
		return ;
		break;	
	case 6 :	
		tmo_isr_uart0();	//time out interrupt超时中断
		return ;
		break;	
	case 1 :	
		thr_isr_uart0();	//transmit holding register empty interrupt 传输FIFO中断
		return ;
		break;
	case 0 :	
		mds_isr();	//modem status intertupt modem状态发生变化中断
		return ;
		break;

	default :
		return ;
	}
}
extern ER rls_isr(void)//出现硬件错误
{
	return E_HA;	
}

extern ER mds_isr(void)//出现硬件错误
{
	return E_HA;	
}	
ER tmo_isr_uart0(void)
{
	volatile U32 a;
	
	a = read_reg(UART0_RBR);//读取接收FIFO中数据,清除这个中断
	//print_num(HA_ERRORBASE_UART + 40, a); 

	return E_OK;
	
}


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 + -