📄 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.
*
**************************************************************************************/
#include "garfield.h"
int i=0;
//#define CSMODE
#undef CSMODE
#define ESRAM_Test_BASE 0x1fff0000
#define LCDCOM 0x34000000
#define LCDDATA 0x3400ffff
#define delay10ms() do{for(i=0;i<200000;i++);}while(0)
#define delay100us() do{for(i=0;i<2000;i++);}while(0) //延时100us
#define delay() delay100us()
#define show()
#define showStop()
unsigned char initda[]={0x08,0x01,0x02,0x10,0x38,0x0c,0x80};
unsigned char initda2[]={0x0c,0x34,0x06,0x03,0x40};
unsigned char disdata1[]={0xba,0xc0,0xba,0xc1,0xba,0xc2,0xba,0xc3,0xba,0xc4,0xba,0xc5,0xba,0xc6,0xbf,0xc0,0xba,0xc7,0xba,0xc8,0xba,0xc3,0xba,0xc4,0xba,0xc5,0xba,0xc6};
unsigned char disdata2[]={0xb9,0xe6,0xbc,0xc1,0xbc,0xc2,0xbc,0xc3,0xbc,0xc4,0xbc,0xc5,0xbc,0xc6,0xbe,0xc0,0xba,0xc9,0xba,0xca,0xba,0xc3,0xba,0xc4,0xba,0xc5,0xba,0xc6};
/*-----------------------------------------------------------------------
延时函数
系统时钟:10M
-----------------------------------------------------------------------*/
void delay_1us(void) //1us延时函数
{
for (i=10;i>0;i--);
}
void delay_nus(unsigned int n) //N us延时函数
{
for (i=0;i<n;i++)
delay_1us();
}
void delay_1ms(void) //1ms延时函数
{
for (i=0;i<10000;i++);
}
void delay_nms(unsigned int n) //N ms延时函数
{
for (i=0;i<n;i++)
delay_1ms();
}
/*
R/W --> PD5
RS --> PD3
E -->PA0
*/
//读
void R(void)
{
*(RP)0x1000b02c |= 0x20; // sel pd5
*(RP)0x1000b030 |= 0x20; // data pd5 -> 1
*(RP)0x1000b028 &= ~0x20; // dir pd5 out
}
//写
void W(void)
{
*(RP)0x1000b02c |= 0x20; // sel pd5
*(RP)0x1000b030 &= ~0x20; // data pd5 -> 0
*(RP)0x1000b028 &= ~0x20; // dir pd5 out
}
//数据写入或者读取
void D(void)
{
*(RP)0x1000b02c |= 0x8; // sel pd3
*(RP)0x1000b030 |= 0x8; // data pd3 -> 1
*(RP)0x1000b028 &= ~0x8; // dir pd3 out
}
//命令写入
void C(void)
{
*(RP)0x1000b02c |= 0x8; // sel pd3
*(RP)0x1000b030 &= ~0x8; // data pd3 -> 0
*(RP)0x1000b028 &= ~0x8; // dir pd3 out
}
//背光亮
void lingtOn(void)
{
*(RP)0x1000b02c |= 0x10; // sel pd4
*(RP)0x1000b030 |= 0x10; // data pd4 -> 1
*(RP)0x1000b028 &= ~0x10; // dir pd4
}
//背光灭
void lingtOff(void)
{
*(RP)0x1000b02c |= 0x10; // sel pd4
*(RP)0x1000b030 &= ~0x10; // data pd4 -> 1
*(RP)0x1000b028 &= ~0x10; // dir pd4
}
//e使能
void E(void)
{
*(RP)0x1000b008 |= 0x1; // sel pa0
*(RP)0x1000b00c |= 0x1; // data pa0 -> 1
*(RP)0x1000b004 &= ~0x1; // dir pa0
}
//e 不使能
void disE(void)
{
*(RP)0x1000b008 |= 0x1; // sel pa0
*(RP)0x1000b00c &= ~0x1; // data pa0 -> 0
*(RP)0x1000b004 &= ~0x1; // dir pa0
}
//检测忙标志
void check_busy(void)
{
char x;
C(); //RS = 0; //指令
R(); //RW = 1; //读取端口的状态
//E(); //E = 1; //开通读写信号
disE();
x = *(RP16)LCDDATA;
printf("x = %d\n",x);
while(x &= 0x80)
{
E();
x = *(RP16)LCDDATA;
disE(); //E = 0;
}
}
void com(char a)
{
#ifdef CSMODE
*(RP16)LCDCOM = a;
show();
delay();
showStop();
#else
check_busy();
C(); //RS = 0; //开通写指令
W(); //RW = 0; //写
disE();
*(RP16)LCDCOM = a;
E(); //E = 1; //开通读写信号
delay();
disE();
#endif
}
void data(char a)
{
#ifdef CSMODE
*(RP16)LCDDATA = a;
show();
delay();
showStop();
#else
check_busy();
D(); //RS = 0; //开通写指令
W(); //RW = 0; //写
disE();
*(RP16)LCDDATA = a;
E(); //E = 1; //开通读写信号
delay();
disE();
#endif
}
//画水漆直线子函数
void draw_xline(char x, char y, char line_data, char icount)
{
com(0x34);
com(y);
delay100us();
com(x);
com(0x30);
while(icount--)
{
data(line_data);
}
com(0x36);
com(0x30);
/*write_code(0x34);
write_code(y);
delay(1);
write_code(x);
write_code(0x30);
while(icount--)
{
write_data(line_data);
//delay(1);
}
write_code(0x36);
write_code(0x30);
*/
}
//清屏子函数
void clc(void)
{
com(0x01);
com(0x34);
com(0x30);
}
//LCD初始化
void init(void)
{
#if 1
com(0x30);
delay100us();
com(0x30);
delay100us();
com(0x3f);
delay100us();
com(0x1);
delay10ms();
com(0x6);
delay100us();
#endif
#if 0
com(0x30);
com(0x30);
com(0x20);
com(0x80);
com(0x34);
com(0x30);
com(0x1);
com(0x6);
com(0xc);
#endif
}
int main(void)
{
int j = 0;
system_init();
*(RP)0x10000000 = 0;
*(RP16)0x24000000 = 0x30;
init();
lingtOn();
delay10ms();
draw_xline(0x90,0x90,0xff,16);
while(1);
for(j=0;j<16;j++)
{
data( disdata1[j]);
}
#if 0
for(j=3;j>0;j--)
{
show();
*(RP16)LCDCOM = 0x30; //基本指令集
delay();
showStop();
}
/////////////////////////////////////////////////////////////
delay();
*(RP16)LCDCOM = 0x30; //基本指令集
show();
delay();
showStop();
delay();
*(RP16)LCDCOM = 0x30; //基本指令集
show();
delay();
showStop();
delay();
*(RP16)LCDCOM = 0x3f; //整体显示、光标显示、光标反显
show();
delay();
showStop();
delay();
*(RP16)LCDCOM = 0x1; //清屏
show();
delay();
showStop();
for(i=0;i<0x100000;i++);
delay();
*(RP16)LCDCOM = 0x7; //光标移动的方向
show();
delay();
showStop();
delay();
*(RP16)LCDCOM = 0x30; //基本指令集
show();
delay();
showStop();
///////////////////////////////////////////////////////////////
delay();
*(RP16)LCDCOM = 0x20; // 位置归0
show();
delay();
showStop();
delay();
*(RP16)LCDCOM = 0x80; // ddram位置选择
show();
delay();
showStop();
//////////////////////////////////////////////////////////////
for(j=0;j<16;j++)
{
delay();
*(RP16)LCDDATA = disdata1[j];
show();
delay();
showStop();
}
for(j=0;j<7;j++)
{
delay();
*(RP16)LCDDATA = initda[j];
show();
delay();
showStop();
}
#endif
while(1);
}
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);
*(RP)INTC_IEN = 0X01800000; //第23,24位置1,打开uart1 uart2
unmask_all_irq();
prints("ESCo1");
prints("27 69 10 100 10 5 6 8 7 2 0");
return 0;
}
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("%d\n",a);//把接收的数据在lcd上打印
}
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中数据,清除这个中断
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 + -