📄 uart.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 + -