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

📄 uart.c

📁 在ARM平台上开发的LCD驱动程序,具有很强的通用性.
💻 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 + -