
LZ 迷糊的只是 应该 先 En=1 再 P0=DATA, 还是 先 P0=DATA 再 En=1;
En 是 LCD 使能端,En=1 表示 使能 LCD *** 作,En=0 表示 禁止 LCD *** 作。
程序前面 已经 对 RS 跟 RW 进行了选择(写指令),如果 这时候 开启 En 使能端,那么 LCD 将 允许 该 *** 作(写指令),同时 将 数据端P0 的数据 读取到 LCD,这个过程的时间 是 ns 级别 的,程序还没来得及 将 DATA 的 数据 送到 P0 ,就已经发生了 数据被读取的 *** 作,也就是说,LCD 读进去的数据,并不是 LZ 想要的 DATA 数据,而是 之前 的数据,很可能是随机的。这将导致LCD 执行了错误 的命令,或是 无法识别命令。
所以 ,要在使能端 En=1 前,先将 数据 DATA 放到 数据口P0,再 使能 En,如此 LCD 就会 读取到 正确 的命令数据了。
①问,RS,RW,E 的设置为 读状态时序 的过程,读出来的数据(数据口P1) 的最高位 刚好即为 液晶的 忙碌 标志位。
②问,writecontrol(unsigned condata) 函数 是个 写指令 函数;
③问,空 *** 作 是为了让数据稳定后,才使能 液晶接收数据;
④问,写指令有时间 间隔要求,太频繁的读写会丢码,所以要加延时,三条38指令,是因为安全起见,上电后马上初始化会出现液晶电源不稳而丢码;
⑤问,液晶显示 只在 更新数据 的时候刷新一次即可,液晶会维持内容,无需重复刷新。
⑥附送,③和④问,都是驱动太恶心而造成的结果,好的驱动程序不需如此 *** 作。液晶的时序要求为ns级,单片机的指令周期普遍为us级,根本不需过多累赘。
#include"reg52h" //包含52头文件
#include"SMC1602Ah" //包含SMC1602A宏定义文件
#define BusyReadCount 10 //读忙标志等待次数
#define SMC1602_Data P0 //定义 数据接口
//sbit SMC1602_VO=P2^4; //定义 VO对比度接口
sbit SMC1602_RW=P2^5; //定义 R/W接口25
sbit SMC1602_RS=P2^6; //定义 RS接口26
sbit SMC1602_E=P2^7; //定义 E接口27
#define SMC1602_En SMC1602_E=1 //使能
#define SMC1602_Dis SMC1602_E=0 //禁止
uchar SMC1602_Read(bit read_type) //1602液晶屏读函数
{
uchar read_data;
SMC1602_Dis; //禁止使能
SMC1602_RW=ReadOperate; //读 *** 作
SMC1602_RS=read_type; //读类型:0状态,1数据
SMC1602_En; //开启使能
read_data=SMC1602_Data; //存储结果
SMC1602_Dis; //禁止使能
return read_data; //返回结果
}
void SMC1602_WriteByte(bit write_type,uchar write_data) //1602液晶屏读函数
{
uchar i=BusyReadCount;
for(;i;i--); //延时 *** 作,为写 *** 作预留回复时间
while((SMC1602_Read(CommOperate)&BusyState) &&(++i<=BusyReadCount)); //读取忙标志(BusyReadCount次),若均忙中,则不再读取忙标志,直接执行写 *** 作
//while(SMC1602_Read(CommOperate)&BusyState) if(++i>BusyReadCount) return; //读取忙标志,若BusyReadCount次均忙中,则不进行写 *** 作
//while(SMC1602_Read(CommOperate)&BusyState); //等待空闲(死等)
SMC1602_Dis; //禁止使能
SMC1602_RW=WriteOperate; //写 *** 作
SMC1602_RS=write_type; //写类型:0指令,1数据
SMC1602_Data=write_data; //写 *** 作,将 *** 作数送的数据口
SMC1602_En; //开启使能
SMC1602_Dis; //禁止使能
}
void SMC1602_WriteCGRAM(uchar write_buf,uchar start_loca,uchar word_num,uchar start_addr) //SMC1602写CGRAM函数,用于自定义字符
{
uchar i,j;
write_buf+=start_loca; //指向"需写入数据数组"的起始位置
SMC1602_WriteByte(CommOperate,CGRAMAddr|start_addr<<3); //写CGRAM *** 作,并将CGRAM起始地址设为 start_addr
for(j=0;j<word_num;j++) //自定义字符数量
for(i=0;i<8;i++) SMC1602_WriteByte(DataOperate,write_buf++); //写入一个自定义字符8个字节数据
}
void SMC1602_Init() //1602液晶屏初始化函数
{
uint i;
SMC1602_WriteByte(CommOperate,DisplayMode); //显示模式设置:16×2显示,5×7点阵,8位数据接口
SMC1602_WriteByte(CommOperate,ScreenMode|ScreenOn); //光标模式设置:开启整体显示,开启光标显示,开启光标闪烁
SMC1602_WriteByte(CommOperate,InputMode); //输入方式设置:关闭整屏移动,开启光标正移动(+1)
SMC1602_WriteByte(CommOperate,CleanLCD); //清屏,复位光标
SMC1602_WriteByte(CommOperate,FirstCol); //定位第一行
for(i=150;i;i--); //等待电源稳定,否则写CGRAM数据(自定义字符)时容易丢失,uint执行周期长,用uchar将会缩短时间,不足以稳定LCD
}
首先,你的程序连着仿真器能在Flash中运行;
用软件复位cpu后可以运行;
去掉GEL后也能运行;
掉电能运行。
经过以上几步检查才能映证。大部分情况是在去掉GEL文件后就不能运行了,可以查看GEL中的初始化部分都做了些什么工作,而你的程序没做的(一般是寄存器、存储区的初始化),补上即可。
//端口定义 诺基亚5110显示屏
int LCD_CE=2;
int LCD_RST=3;
int SCLK=4;
int SDIN=5;
int LCD_DC=6;
int inputPin=8; // 定义超声波信号接收接口
int outputPin=9; // 定义超声波信号发出接口
//
void setup()
{
pinMode(inputPin, INPUT);
pinMode(outputPin, OUTPUT);
}
//定义ASCII字符//
/
6 x 8 font
1 pixel space at left and bottom
index = ASCII - 32
/
const unsigned char font6x8[][6] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // sp
{ 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00 }, // !
{ 0x00, 0x00, 0x07, 0x00, 0x07, 0x00 }, // "
{ 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // #
{ 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $
{ 0x00, 0x62, 0x64, 0x08, 0x13, 0x23 }, // %
{ 0x00, 0x36, 0x49, 0x55, 0x22, 0x50 }, // &
{ 0x00, 0x00, 0x05, 0x03, 0x00, 0x00 }, // '
{ 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00 }, // (
{ 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00 }, // )
{ 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14 }, //
{ 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08 }, // +
{ 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00 }, // ,
{ 0x00, 0x08, 0x08, 0x08, 0x08, 0x08 }, // -
{ 0x00, 0x00, 0x60, 0x60, 0x00, 0x00 }, //
{ 0x00, 0x20, 0x10, 0x08, 0x04, 0x02 }, // /
{ 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E }, // 0
{ 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00 }, // 1
{ 0x00, 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2
{ 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31 }, // 3
{ 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10 }, // 4
{ 0x00, 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5
{ 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30 }, // 6
{ 0x00, 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7
{ 0x00, 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8
{ 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E }, // 9
{ 0x00, 0x00, 0x36, 0x36, 0x00, 0x00 }, // :
{ 0x00, 0x00, 0x56, 0x36, 0x00, 0x00 }, // ;
{ 0x00, 0x08, 0x14, 0x22, 0x41, 0x00 }, // <
{ 0x00, 0x14, 0x14, 0x14, 0x14, 0x14 }, // =
{ 0x00, 0x00, 0x41, 0x22, 0x14, 0x08 }, // >
{ 0x00, 0x02, 0x01, 0x51, 0x09, 0x06 }, //
{ 0x00, 0x32, 0x49, 0x59, 0x51, 0x3E }, // @
{ 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C }, // A
{ 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36 }, // B
{ 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22 }, // C
{ 0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C }, // D
{ 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41 }, // E
{ 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01 }, // F
{ 0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A }, // G
{ 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F }, // H
{ 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00 }, // I
{ 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01 }, // J
{ 0x00, 0x7F, 0x08, 0x14, 0x22, 0x41 }, // K
{ 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40 }, // L
{ 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F }, // M
{ 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F }, // N
{ 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E }, // O
{ 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06 }, // P
{ 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E }, // Q
{ 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46 }, // R
{ 0x00, 0x46, 0x49, 0x49, 0x49, 0x31 }, // S
{ 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01 }, // T
{ 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F }, // U
{ 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F }, // V
{ 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F }, // W
{ 0x00, 0x63, 0x14, 0x08, 0x14, 0x63 }, // X
{ 0x00, 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y
{ 0x00, 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z
{ 0x00, 0x00, 0x7F, 0x41, 0x41, 0x00 }, // [
{ 0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55 }, // 55
{ 0x00, 0x00, 0x41, 0x41, 0x7F, 0x00 }, // ]
{ 0x00, 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^
{ 0x00, 0x40, 0x40, 0x40, 0x40, 0x40 }, // _
{ 0x00, 0x00, 0x01, 0x02, 0x04, 0x00 }, // '
{ 0x00, 0x20, 0x54, 0x54, 0x54, 0x78 }, // a
{ 0x00, 0x7F, 0x48, 0x44, 0x44, 0x38 }, // b
{ 0x00, 0x38, 0x44, 0x44, 0x44, 0x20 }, // c
{ 0x00, 0x38, 0x44, 0x44, 0x48, 0x7F }, // d
{ 0x00, 0x38, 0x54, 0x54, 0x54, 0x18 }, // e
{ 0x00, 0x08, 0x7E, 0x09, 0x01, 0x02 }, // f
{ 0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C }, // g
{ 0x00, 0x7F, 0x08, 0x04, 0x04, 0x78 }, // h
{ 0x00, 0x00, 0x44, 0x7D, 0x40, 0x00 }, // i
{ 0x00, 0x40, 0x80, 0x84, 0x7D, 0x00 }, // j
{ 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00 }, // k
{ 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00 }, // l
{ 0x00, 0x7C, 0x04, 0x18, 0x04, 0x78 }, // m
{ 0x00, 0x7C, 0x08, 0x04, 0x04, 0x78 }, // n
{ 0x00, 0x38, 0x44, 0x44, 0x44, 0x38 }, // o
{ 0x00, 0xFC, 0x24, 0x24, 0x24, 0x18 }, // p
{ 0x00, 0x18, 0x24, 0x24, 0x18, 0xFC }, // q
{ 0x00, 0x7C, 0x08, 0x04, 0x04, 0x08 }, // r
{ 0x00, 0x48, 0x54, 0x54, 0x54, 0x20 }, // s
{ 0x00, 0x04, 0x3F, 0x44, 0x40, 0x20 }, // t
{ 0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C }, // u
{ 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C }, // v
{ 0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C }, // w
{ 0x00, 0x44, 0x28, 0x10, 0x28, 0x44 }, // x
{ 0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C }, // y
{ 0x00, 0x44, 0x64, 0x54, 0x4C, 0x44 }, // z
{ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14 } // horiz lines
};
/LCD初始化函数/
void LCD_init(void)
{
//先设置为输出
pinMode(SCLK,OUTPUT);
pinMode(SDIN,OUTPUT);
pinMode(LCD_DC,OUTPUT);
pinMode(LCD_CE,OUTPUT);
pinMode(LCD_RST,OUTPUT);
// 产生一个让LCD复位的低电平脉冲
digitalWrite( LCD_RST, LOW);
delayMicroseconds(1);
digitalWrite( LCD_RST, HIGH);
// 关闭LCD
digitalWrite( LCD_CE, LOW);
delayMicroseconds(1);
// 使能LCD
digitalWrite( LCD_CE, HIGH); //LCD_CE = 1;
delayMicroseconds(1);
LCD_write_byte(0x21, 0); // 使用扩展命令设置LCD模式
LCD_write_byte(0xc8, 0); // 设置偏置电压
LCD_write_byte(0x06, 0); // 温度校正
LCD_write_byte(0x13, 0); // 1:48
LCD_write_byte(0x20, 0); // 使用基本命令
LCD_clear(); // 清屏
LCD_write_byte(0x0c, 0); // 设定显示模式,正常显示
// 关闭LCD
digitalWrite( LCD_CE, LOW); //LCD_CE = 0;
}
/LCD清屏函数/
void LCD_clear(void)
{
unsigned int i;
LCD_write_byte(0x0c, 0);
LCD_write_byte(0x80, 0);
for (i=0; i<504; i++)
{
LCD_write_byte(0, 1);
}
}
/设置字符位置函数/
void LCD_set_XY(unsigned char X, unsigned char Y)
{
LCD_write_byte(0x40 | Y, 0);// column
LCD_write_byte(0x80 | X, 0);// row
}
/ASCII字符显示函数/
void LCD_write_char(unsigned char c)
{
unsigned char line;
c -= 32;
for (line=0; line<6; line++)
{
LCD_write_byte(font6x8[c][line], 1);
}
}
//
/-------------------------------------------------
LCD_write_english_String : 英文字符串显示函数
输入参数:s :英文字符串指针;
X、Y : 显示字符串的位置,x 0-83 ,y 0-5
--------------------------------------------------/
void LCD_write_english_string(unsigned char X,unsigned char Y,char s)
{
LCD_set_XY(X,Y);
while (s)
{
LCD_write_char(s);
s++;
}
}
//
/---------------------------------------------
LCD_write_byte : 写数据到LCD
输入参数:data :写入的数据;
command :写数据/命令选择;
---------------------------------------------/
void LCD_write_byte(unsigned char dat, unsigned char command)
{
unsigned char i;
digitalWrite( LCD_CE, LOW); // 使能LCD_CE = 0
if (command == 0)
{
digitalWrite( LCD_DC, LOW);// 传送命令 LCD_DC = 0;
}
else
{
digitalWrite( LCD_DC, HIGH);// 传送数据LCD_DC = 1;
}
for(i=0;i<8;i++)
{
if(dat&0x80)
{
digitalWrite( SDIN, HIGH);//SDIN = 1;
}
else
{
digitalWrite( SDIN, LOW);//SDIN = 0;
}
digitalWrite( SCLK, LOW);//SCLK = 0;
dat = dat << 1;
digitalWrite( SCLK, HIGH);//SCLK = 1;
}
digitalWrite( LCD_CE, HIGH);//LCD_CE = 1;
}
/以下为主函数/
void loop()
{
LCD_init();//初始化液晶
LCD_clear();
LCD_write_english_string(0,0," --Arduino-- ");
LCD_write_english_string(0,2,"Renge:");
LCD_write_english_string(0,4,"DESIGN BY KENT");
LCD_write_english_string(0,5," 20106 ");
while(1)
{
digitalWrite(outputPin, LOW); // 使发出发出超声波信号接口低电平2μs
delayMicroseconds(2);
digitalWrite(outputPin, HIGH); // 使发出发出超声波信号接口高电平10μs,这里是至少10μs
delayMicroseconds(10);
digitalWrite(outputPin, LOW); // 保持发出超声波信号接口低电平
int distance = pulseIn(inputPin, HIGH); // 读出脉冲时间
distance= distance/58; // 将脉冲时间转化为距离(单位:厘米)
if(distance>120)
{
LCD_write_english_string(35,2,"");
}
else
{
LCD_write_english_string(60,2,"cm");
LCD_set_XY(35, 2);
LCD_write_char( 0x30+distance%1000/100); //显示百位数
LCD_write_char( 0x30+distance%100/10); //显示十位数
LCD_write_char( 0x30+distance%10); //显示个位数
}
delay(10);
}
}
#include <reg51h>
#define uchar unsigned char
#define uint unsigned int
#define LCD_DATA P2
sbit LCD_BL=P1^0;
sbit LCD_RS=P1^1;
sbit LCD_RW=P1^2;
sbit LCD_EN=P1^3;
//uchar code smg_data[]={0x15,0x15,0x15,0x0E,0x0E,0x15,0x15,0x15};
//uchar code smg_data[]={0x15,0x0A,0x15,0x0A,0x15,0x0A,0x15,0x00};
//uchar code smg_data[]={0x1B,0x0A,0x11,0x15,0x11,0x0A,0x1B,0x00};
//uchar code smg_data[]={0x0E,0x15,0x15,0x00,0x15,0x00,0x15,0x00};
//uchar code smg_data[]={0x1F,0x11,0x15,0x1B,0x15,0x11,0x1F,0x00};
//uchar code smg_data[]={0x11,0x15,0x15,0x0A,0x15,0x15,0x11,0x00};
//uchar code smg_data[]={0x1F,0x15,0x15,0x1F,0x15,0x15,0x1F,0x00};
//uchar code smg_data[]={0x1F,0x11,0x11,0x11,0x11,0x0A,0x04,0x00};
void delay(uint z);
void write_com(uchar com);
void write_data(uchar da);
void init();
void main()
{
// uchar i;
LCD_RW=0;
LCD_EN=0;
LCD_BL=0;
init();
// write_com(0x40);
// for(i=0;i<8;i++)
// {
// write_data(smg_data[i]);
// }
write_com(0x80);
write_data('a');
while(1);
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void write_com(uchar com)
{
LCD_DATA=com;
LCD_RS=0;
LCD_EN=1;
delay(5);
LCD_EN=0;
}
void write_data(uchar da)
{
LCD_DATA=da;
LCD_RS=1;
LCD_EN=1;
delay(5);
LCD_EN=0;
}
void init()
{
write_com(0x38); //设置8位格式,2行5x7点阵
write_com(0x0c); //开显示,关光标,不闪烁
write_com(0x06); //文字不动,光标自动右移
write_com(0x01); //清屏并光标复位
}
1602液晶第一行第一位显示个 a
哥们儿,你没有达到目标啊
你没有写按键程序
你的location函数可以不用,准确地说不用这么复杂,用一循环就好了
还有你显示的那句话完全可以用数组啊,这样你的程序就不用这么繁琐了!
以上就是关于单片机中lcd12864的时序程序全部的内容,包括:单片机中lcd12864的时序程序、lcd1602液晶显示的程序、您好!请问你的“DSP2812烧写LCD程序到flash中,断电重启程序无法运行”这个问题最后是怎么解决的谢谢等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)