第一次接触液晶屏(320*240, RA8835),用的CPU是ATmega16. 只想显示最简单的字母和数字,却怎么也调不通。。求大侠相助
下面是代码:
#include <avr/io.h>
#include <avr/interrupt.h>
#include <math.h>
#define F_CPU 1000000 //内部晶振1M
#include <util/delay.h>
//------------------------------------------------------------------------------
//Parameter Defines
#define dispoff 0x58 //显示关闭 后续参数1字节
#define dispon 0x59 //显示状态打开 后续参数1字节
#define hdotscr 0x5a //点位移量设置 后续参数1字节
#define ovlay 0x5b //显示合成设置 后续参数1字节
#define cgramadr 0x5c //CGRAM首地址设置 后续参数2字节
#define csrform 0x5d //光标形状设置 后续参数2字节
#define csrdirr 0x4c //光标向右方向移动 后续参数:无
#define csrdirl 0x4d //光标向左方向移动 后续参数:无
#define csrdiru 0x4e //光标向上方向移动 后续参数:无
#define csrdird 0x4f //光标向下方向移动 后续参数:无
#define csrw 0x46 //设置光标地址 后续参数2字节
#define csrr 0x47 //读出光标地址 后续参数2字节
#define mwrite 0x42 //显示数据写入 后续参数N字节
#define mread 0x43 //显示数据读取 后续参数N字节
/*--------------------------------------------------------------*/
//#define busy 0x40 //忙信号D6 0100 0000
#define AP 0x28 //一行所占显示存储单元的字节数
//------------------------------------------------------------------------------
//===== MCU Interface =====
#define lcd_bus PORTB //PORTB 数据口
//--------------------------------------
#define WR_H PORTD |= (1<<2) //WR 为高
#define WR_L PORTD &= ~(1<<2) //WR 为低
#define RD_H PORTD |= (1<<3) //RD 为高
#define RD_L PORTD &= ~(1<<3) // RD为低
#define CE_H PORTD |= (1<<4) //CE 为高 片选
#define CE_L PORTD &= ~(1<<4) //CE 为低
#define A0_H PORTD |= (1<<6) //A0 为高 命令数据选择
#define A0_L PORTD &= ~(1<<6) //A0 为低
#define RST_H PORTD |= (1<<7) //RST 为高 复位
#define RST_L PORTD &= ~(1<<7) //RST 为低
#define nBUSY (P3&0x08)
void wr_cmd80(unsigned char cmdx); ///写命令
void wr_dat1335(unsigned char datax); //写数据
void init1335(); //初始化1335函数
void Full1335(void);//全屏显示
void SetCursor1335(unsigned char lsb,unsigned char msb);//设置光标
void clear1335(void);//清屏
void lattice_1335(unsigned int pixelW,unsigned char pixelH,unsigned char dat1,unsigned char dat2);//指定范围内写入数据
void locate_xy1(unsigned char x, unsigned char y); //定位光标
void show_char(unsigned char x, unsigned char y, char *string); //字符串显示
////CPU初始化//////
void CPUInit( void )
{
DDRB = 0xff;
PORTB = 0x00; //B口输出 0, D0~D7
DDRD |= (1<<2)|(1<<3)|(1<<4)|(1<<6)|(1<<7);
PORTD |= (1<<2)|(1<<3)|(1<<4)|(1<<6)|(1<<7); //D口输出 ,1,PD2为/WR PD3为/RD PD4为CE PD6为A0 PD7为/RST
}
///// 标准8080时序写命令//////////////
unsigned char rd_status(void)
{
unsigned char datx;
A0_L;
WR_H;
RD_L;
datx = lcd_bus;
RD_H;
return datx;
}
void wr_cmd80(unsigned char cmdx) //写命令
{
CE_L;
A0_H;
RD_H;
//lcd_cmd = cmdx;
lcd_bus = cmdx;
WR_L;
WR_H;
CE_H;
}
////////////写数据///////////////////
void wr_dat1335(unsigned char datax)
{
CE_L;
while(rd_status()&0x80); //0x80???
A0_L;
RD_H;
//lcd_para = datax;
lcd_bus = datax;
WR_L;
WR_H;
CE_H;
}
////////初始化1335///////////////////////////////////
void init1335()
{
wr_cmd80(0x40); //SYSTEM SET
wr_dat1335(0x30); //p1
wr_dat1335(0x87); //p2 FX
wr_dat1335(0x07); //p3 FY
wr_dat1335(0x27); //p4 C/R 27
wr_dat1335(0x42); //p5 42 TC/R
wr_dat1335(0xEF); //p6 L/F ef
wr_dat1335(0x28); //p7 APL 28
wr_dat1335(0x00); //p8 APH
wr_cmd80(0x44); //SCROLL
wr_dat1335(0x00); //sa1-L
wr_dat1335(0x00); //sa1-H
wr_dat1335(0xF0); //sL1
wr_dat1335(0x00); //sa2-L
wr_dat1335(0x28); //sa2-H
wr_dat1335(0xF0); //sL2
wr_dat1335(0x00); //sa3-L
wr_dat1335(0x50); //sa3-H
wr_dat1335(0x00); //sa4-L
wr_dat1335(0x00); //sa4-H
wr_cmd80(0x5a); //HDOT SCR
wr_dat1335(0x00);
wr_cmd80(0x58); //DISP OFF
wr_dat1335(0x54);
wr_cmd80(0x5d); //CSR FORM
wr_dat1335(0x00); //CRX
wr_dat1335(0x00); //CRY
wr_cmd80(0x59); //DISP ON
wr_dat1335(0x54);
wr_cmd80(0x5b);
wr_dat1335(0x00);
}
//////////全屏//////////////////////////
void Full1335(void)
{
unsigned int i;
wr_cmd80(0x5b);
wr_dat1335(0x00);
SetCursor1335(0x00,0x00);
wr_cmd80(0x42);
for(i=0;i<0x2580;i++)
wr_dat1335(0x1F);
for(;i<0x7fff;i++)
wr_dat1335(0xFF);
}
///////清屏/////////////
void clear1335(void)
{
unsigned int i;
wr_cmd80(0x5b);
wr_dat1335(0x00);
SetCursor1335(0x00,0x00);
wr_cmd80(0x42);
for(i=0;i<0x2580;i++)
wr_dat1335(0x20);
for(;i<0x7fff;i++)
wr_dat1335(0x00);
}
///////设置光标//////////
void SetCursor1335(unsigned char lsb,unsigned char msb)
{
wr_cmd80(0x46); //设置光标地址
wr_dat1335(lsb);
wr_dat1335(msb);
wr_cmd80(0x42);
}
////////////指定范围内写入数据/////////////
void lattice_1335(unsigned int pixelW,unsigned char pixelH,unsigned char dat1,unsigned char dat2)
{
unsigned char i,k,tmp1,tmp2;
tmp1 = pixelH/2;
tmp2 = (unsigned char)(pixelW/8);
SetCursor1335(0x80,0x25);
for(k=0;k<tmp1;k++)
{
for(i=0;i<tmp2;i++)
wr_dat1335(dat1);
for(i=0;i<tmp2;i++)
wr_dat1335(dat2);
}
}
/*--------------------------------------------------------------*/
//光标定位
//x横坐标: 0~39 320/8=40
//y纵坐标: 0~29 240/8=30
void locate_xy1(unsigned char x, unsigned char y)
{
unsigned int addr;
addr =(unsigned int)(y) * AP + x;
wr_cmd80(csrw); //写入光标地址
wr_dat1335((unsigned char)(addr & 0xff)); //先写低八位
wr_dat1335((unsigned char)(addr >> 8)); //后写高八位
}
/*--------------------------------------------------------------*/
//显示字符串
//x横坐标: 0~39 320/8=40
//y纵坐标: 0~29 240/8=30
void show_char(unsigned char x, unsigned char y, char *string)
{
locate_xy1(x, y); //光标定位
wr_cmd80(csrform); //光标形状设置
wr_dat1335(0x07); //水平显示宽度6
wr_dat1335(0x07); //线状光标显示,高度8
wr_cmd80(csrdirr); //光标向右方向移动
wr_cmd80(dispon); //显示状态开启
wr_dat1335(0x57); //显示图像,光标1Hz闪烁
wr_cmd80(mwrite); //显示数据写入
while(*string)
{
wr_dat1335(*string);
string++;
}
}
//////////////主函数///////////////////
int main(void)
{
_delay_ms(50);
CPUInit(); //初始化CPU
_delay_ms(50); //CPU初始化
RST_L; //复位 //RESET
_delay_ms(50);
RST_H;
_delay_ms(50);
init1335(); //初始化液晶屏
//RD_H;
while(1)
{
Full1335(); //全屏
_delay_ms(1000);
clear1335(); //清屏
_delay_ms(1000);
/*lattice_1335(320,240,0x55,0xaa); //指定范围内写入数据
_delay_ms(1000);
lattice_1335(320,240,0xaa,0x55);
_delay_ms(1000);
lattice_1335(320,240,0xff,0x00);
_delay_ms(1000);
lattice_1335(320,240,0x00,0xff);
_delay_ms(1000); */
show_char(0, 0, "Hi"); //显示字符串
};
}
本文来自论坛,点击查看完整帖子内容。