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

📄 ocmj15x20d(ads7843).c

📁 液晶驱动程序Ra8803控制器带触摸屏ADS7843驱动程序
💻 C
字号:
/**********************************
☆型号:OCMJ15X20D(ADS7843)
☆单片机:ATmega16(L)
☆内部RC振荡:4M
☆邮箱:roger_cwf@yahoo.com.cn
☆日期:2007/11/02
**********************************/

#include <iom16v.h>
#include <macros.h>

#define uchar      unsigned char
#define uint       unsigned int

#define sbit(X,Y)   (X|=(1<<Y))       //Set Bit y of Byte x 
#define cbit(X,Y)   (X&=~(1<<Y))      //Clear Bit y of Byte x 
#define chkbit(X,Y)   (X&(1<<Y))      //Check Bit y of Byte x 
#define invbit(X,Y)   (X^=(1<<Y))     //Invert Bit y of Byte x

#define LCD_RS   PORTD		//D0
#define LCD_WR   PORTD		//D1
#define LCD_RD   PORTD		//D2
#define LCD_CS1  PORTD		//D3
#define LCD_CS2  PORTD		//D4
#define LCD_BUSY PORTD		//D5
#define LCD_RST  PORTD		//D6

#define DCLK       PORTA        //A0
#define CS         PORTA        //A1
#define DIN        PORTA        //A2
#define STA        PORTA        //A3
#define DOUT       PORTA        //A4
#define IP         PORTA        //A5  

#define data_ora   PORTB        //MCU PROTB<------> LCM

#define lcd_regname  PORTB
#define lcd_regdata  PORTB
#define lcd_regnada  PORTB
#define lcd_data     PORTB
#define lcd_control  PORTD

#define TOUCH_MSR_X  0x90   //读X轴坐标指令
#define TOUCH_MSR_Y  0xD0   //读Y轴坐标指令

uchar taby[4];
uchar tabx[4];
uint x[4],y[4];
uchar r;

const uchar chn[]={
"             触摸屏坐标测试             "
"                 X=                     "
"                 Y=                     "
};

/*延时子程序*/
void Delay_Ns(void)
{
	asm("nop");
}

//Nus延时
void Delay_Nus(uint n)
{
	uint i=0;
	for (i=0;i<n;i++)
	Delay_Ns();
}

void Delay_Ms(void)
{
 	uint i;
	for (i=0;i<1140;i++);
}

//Nms延时函数
void Delay_Nms(uint n)
{
	uint i=0;
	for (i=0;i<n;i++)
	Delay_Ms();
}

//端口初始化
void Port_Init(void)
{
	PORTA=0xff;
	DDRA=0xC7;
	PORTB=0xff;
	DDRB=0xff;
	PORTD=0xff;
	DDRD=0xdf;
}

//送数据子函数
void SendData(uchar regnada)
{
	lcd_regnada = regnada;
	
	cbit(LCD_CS1,PORTD3);
	sbit(LCD_RD,PORTD2);
	cbit(LCD_RS,PORTD0);
	cbit(LCD_WR,PORTD1);
	//Delay_Nus(5);
	sbit(LCD_WR,PORTD1);
	sbit(LCD_RS,PORTD0);
	sbit(LCD_CS1,PORTD3);
/*	
	LCD_CS1 =0; // chip enable.
	LCD_RD = 1; //
	LCD_RS = 0; // rs = 0;
	LCD_WR = 0; // wr = 0;
	;
	LCD_WR = 1; // wr = 1;
	LCD_RS = 1; // rs = 1;
	LCD_CS1 =1; // chip disable.
*/
}

//写资料到缓存器
void WriteDataToREG(uchar regname,uchar regdata)
{                                   
	SendData(regname);
	//Delay_Nus(5);
	SendData(regdata);
}

//写资料到DDRAM
void WiteDataToDDRAM(uchar wrdata)
{	

	while(chkbit(PIND,PIND5));
	lcd_data = wrdata;
	cbit(LCD_CS1,PORTD3);
	sbit(LCD_RD,PORTD2);
	sbit(LCD_RS,PORTD0);
	cbit(LCD_WR,PORTD1);
	//Delay_Nus(5);
	sbit(LCD_WR,PORTD1);
	sbit(LCD_RS,PORTD0);
	sbit(LCD_CS1,PORTD3);	
/*					
	while(LCD_BUSY == 1);
	lcd_data = wrdata;
	LCD_CS1 =0; // chip enable.
	LCD_RD = 1; //
	LCD_RS = 1; // rs = 1;
	LCD_WR = 0; // wr = 0;
	;
	LCD_WR = 1; // wr = 1;
	LCD_RS = 1; // rs = 1;
	LCD_CS1 =1; // chip disable.
*/
}

//读缓存器
uchar ReadDataFromREG(uchar regname)
{                           
	uchar reg_rddata;

	SendData(regname);
	lcd_data = 0xff;
	DDRB=0x00;            //设置为输入
	cbit(LCD_CS1,PORTD3); // chip enable.
	sbit(LCD_WR,PORTD1);  // wr = 1;
	cbit(LCD_RS,PORTD0);  // rs = 0;
	cbit(LCD_RD,PORTD2);  // rd = 0;
	//Delay_Nus(5);
	reg_rddata = lcd_data;
	sbit(LCD_RD,PORTD2);  // rd = 1;
	sbit(LCD_RS,PORTD0);  // rs = 1;
	sbit(LCD_CS1,PORTD3); // chip disable.
	DDRB=0xff;            //设置为输出
	return(reg_rddata);
/*
	lcd_data = 0xff;
	LCD_CS1 =0; // chip enable.
	LCD_WR = 1; // wr = 1;
	LCD_RS = 0; // rs = 0;
	LCD_RD = 0; // rd = 0;
	;
	reg_rddata = lcd_data;
	LCD_RD = 1; // rd = 1;
	LCD_RS = 1; // rs = 1;
	LCD_CS1 =1; // chip disable.
	return(reg_rddata);
*/
}

//上电复位
void LCD_Reset(void)
{               
	Delay_Nms(100);     // Delay_Nus 120ms 等待上电复位
	lcd_control = 0xff; // LCD_RS/WR/RD/CS1/CS2 normal - skeep high.
}

//设定坐标
void SetXY(uchar x,uchar y)
{                                
	WriteDataToREG(0x60,x); // active window top register(awtr)
	WriteDataToREG(0x70,y); // active window top register(awtr)
}

//初始化
void LCD_Initial(void)
{                   
	WriteDataToREG(0x00,0xc9); // lcd control register(lcr)
	WriteDataToREG(0x01,0xf2); // misc.register(mir)
	WriteDataToREG(0x02,0x10); // advance power setup register(apsr)	
	WriteDataToREG(0x03,0x80); // advance display setup regiser(adsr)
	WriteDataToREG(0x10,0x6b); // cursor control register(ccr)
	WriteDataToREG(0x11,0x00); // distance of word or lines register(dwlr)
	WriteDataToREG(0x12,0x91); // memory access mode register(awrr)
	WriteDataToREG(0x21,0x27); // display window right register(dwrr)
	WriteDataToREG(0x31,0xef); // display window bottom register(dwbr)
	WriteDataToREG(0x41,0x00); // display window left register(dwlr)
	WriteDataToREG(0x51,0x00); // display window top register(dwtr)
	WriteDataToREG(0x20,0x27); // active window right register(awrr)
	WriteDataToREG(0x30,0xef); // active window bottom register(awbr)
	WriteDataToREG(0x40,0x00); // active window left register(awlr)
	WriteDataToREG(0x50,0x00); // active window top register(awtr)
	WriteDataToREG(0x60,0x00); // cursor position x register(cpxr)
	WriteDataToREG(0x61,0x00); // begin segment position register(bgsg)
	WriteDataToREG(0x70,0x00); // cursor position y register(cpyr)
	WriteDataToREG(0x71,0x00); // shift action range,begin commom register(bgcm)
	WriteDataToREG(0x72,0xef); // shift action range,end commom register(edcm)
	WriteDataToREG(0x80,0xaa); // blink time register(btr)
	WriteDataToREG(0x81,0x00); // frame rate polarity change at common_fa register(fdca)
	WriteDataToREG(0x91,0x00); // frame rate polarity change at common_fb register(fdcb)
	WriteDataToREG(0x90,0x06); // shift clock control register(sccr)
	WriteDataToREG(0xa0,0x11); // interrupt setup & status register(frcb)
	WriteDataToREG(0xa1,0x00); // key scan control register(kscr)
	WriteDataToREG(0xa2,0x00); // key scan data register(ksdr)
	WriteDataToREG(0xa3,0x00); // key scan data expand register(kser)
	WriteDataToREG(0xb0,0x27); // interrupt column setup register(intx)
	WriteDataToREG(0xb1,0xef); // interrupt row setup register(inty)
	WriteDataToREG(0xc0,0x00); // touch panel control register(tpcr)
	WriteDataToREG(0xc1,0x0a); // adc status register(adcs)
	WriteDataToREG(0xc8,0x80); // touch panel segment high byte data register(tpxr)
	WriteDataToREG(0xc9,0x80); // touch panel common high byte data register(tpyr)
	WriteDataToREG(0xca,0x00); // touch panel segment/common low byte data register(tpzr)
	WriteDataToREG(0xd0,0x80); // lcd contrast control register (lccr)
	WriteDataToREG(0xe0,0x00); // pattern data register(pdr)
	WriteDataToREG(0xf0,0xa0); // font control register(fcr)
	WriteDataToREG(0xf1,0x0f); // font size control register
}

//清屏
void LCD_Clear(void)
{                   
	uchar reg_rddata;
	WriteDataToREG(0xe0,0x00);
	WriteDataToREG(0xf0,0xa8);
	Delay_Nms(10);
}
/*
//显示图形
void Display_Picture(const uchar *pho)
{                          
	uchar i,j,k;
	const uchar *pp;
	SetXY(0,0);
	for(k=0;k<4;k++)
	{
		pp=pho;
		for(j=0;j<60;j++)
		{
			for(i=0;i<40;i++)
			{
				WiteDataToDDRAM(*pp);
				++pp;
			}
		}
	}
}

//显示点阵
void Display_Grid(uchar data1,uchar data2)
{                                    
	uchar i,j;
	SetXY(0,0);
	for(j=0;j<60;j++)
	{
		for(i=0;i<80;i++)
		{
			WiteDataToDDRAM(data1);
		}
		for(i=0;i<80;i++)
		{
			WiteDataToDDRAM(data2);
		}
	}
}
*/
//显示中文或字符
void Display_Chinese(const uchar *cha,unsigned int count)
{                                    
	int i;
	for(i=0;i<count;i++)
	{
		WiteDataToDDRAM(*cha);
		++cha;
	}
}

//显示中文或字符
void Display_Chinese1(uint count)
{                                 
	WiteDataToDDRAM(count);
}

//SPI写数据
WriteDataTo7843(unsigned char num) 
{
	unsigned char count=0;
	cbit(DCLK,PORTA0);                //DCLK=0
	for(count=0;count<8;count++)
	{
		if(num&0x80)
			sbit(DIN,PORTA2);        //进位标志位为1时 DIN=1
		else
			cbit(DIN,PORTA2);
		num<<=1;
		cbit(DCLK,PORTA0);           //上升沿有效 
		Delay_Nus(4); 
		sbit(DCLK,PORTA0);
		Delay_Nus(4); 
	}
}

//SPI 读数据
ReadDataFrom7843() 
{
	unsigned char count=0;
	unsigned int Num=0;
	for(count=0;count<12;count++)
	{
		Num<<=1;
		sbit(DCLK,PORTA0); 
		Delay_Nus(4); 
		cbit(DCLK,PORTA0); 
		Delay_Nus(4); 
		if(chkbit(PINA,PINA4)) Num++;
	}
	return(Num);
}

//SPI开始
void start() 
{
	cbit(DCLK,PORTA0);
	sbit(CS,PORTA1);
	sbit(DIN,PORTA2);
	sbit(DCLK,PORTA0);
	cbit(CS,PORTA1);
}

//触摸处理
void Go_Touch(void)
{
	unsigned int X=0,Y=0;

	start();                              //启动SPI
	Delay_Nus(2);

	for(r=0;r<4;r++)
	{
		WriteDataTo7843(TOUCH_MSR_X);     //送控制字 10010000 即用差分方式读X坐标 详细请见有关资料
		Delay_Nus(4); 
		cbit(DCLK,PORTA0);
		Delay_Nus(4); 
		x[r]=ReadDataFrom7843();          //读X轴坐标
		WriteDataTo7843(TOUCH_MSR_Y);     //送控制字 11010000 即用差分方式读Y坐标 详细请见有关资料
		sbit(DCLK,PORTA0);
		Delay_Nus(4); 
		cbit(DCLK,PORTA0);
		Delay_Nus(4);  
		y[r]=ReadDataFrom7843();          //读Y轴坐标
	}
	
	sbit(CS,PORTA1);
	sbit(IP,PORTA5);

	X=(x[0]+x[1]+x[2]+x[3])/4;
	Y=(y[0]+y[1]+y[2]+y[3])/4;

	tabx[0]=X/1000;
	tabx[1]=X%1000/100;
	tabx[2]=X%100/10;
	tabx[3]=X%10;
	taby[0]=Y/1000;
	taby[1]=Y%1000/100;
	taby[2]=Y%100/10;
	taby[3]=Y%10;
	
	WriteDataToREG(0x10,0x00);//反相存入
	WriteDataToREG(0x00,0xcd);
 	for(r=0;r<4;r++)
	{    
		SetXY(19+r,64);
		Display_Chinese1(0x30+tabx[r]);
	}
	for(r=0;r<4;r++)
	{     
		SetXY(19+r,80);
		Display_Chinese1(0x30+taby[r]);
	}
	Delay_Nms(100);
}

//!!!!!!!主程序!!!!!!!!!!!
void main (void)
{ 
	CLI();
	MCUCR = 0x00;
	GICR  = 0x00;
	TIMSK = 0x00; //timer interrupt sources
	Port_Init();
	
	LCD_Reset();
	LCD_Initial();
	LCD_Clear();
	
	WriteDataToREG(0x10,0x29);
	WriteDataToREG(0x00,0xcd);
	SetXY(0,48);
	Display_Chinese(chn,120);
	while(1)
	{
		if(!chkbit(PINA,PINA5))
		{
			Delay_Nms(20);             //延时以消抖
			if(!chkbit(PINA,PINA5))    //检测触摸屏是否被按下
			{
				Go_Touch();
			}
		}
	}
}

⌨️ 快捷键说明

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