STC驱动LCD1602无果,求助
自己写的驱动程序,连个LCD都点不亮呀。贴出来,做回伸手党!{:lol:}#include<reg51.h>
#include<intrins.h>
sbit RSPIN = P2^6;
sbit RWPIN = P2^7;
sbit EPIN = P3^7;
unsigned char XPOS,YPOS;
void delay(unsigned int t)
{unsigned int i,j;
for(i=0;i<t;i++)
for(j=0;j<10;j++)
;
}
void lcdwaitidle(void)
{P0=0xff;
RSPIN=0;
RWPIN=1;
EPIN=1;
while((P0&0x80)==0x80);
EPIN=0;
}
void lcdwcn(unsigned char c)
{RSPIN=0;
RWPIN=0;
P0=c;
EPIN=1;
_nop_();
EPIN=0;
}
void lcdwc(unsigned char c)
{lcdwaitidle();
lcdwcn(c);
}
void lcdwd(unsigned char d)
{lcdwaitidle();
RSPIN=1;
RWPIN=0;
P0=d;
EPIN=1;
_nop_();
EPIN=0;
}
void lcdpos(void)
{XPOS&=0x0f;
YPOS&=0x03;
if(YPOS==0x00)
lcdwc(XPOS|0x80);
else if(YPOS==0x01)
lcdwc((XPOS+0x40)|0x80);
}
void lcdreset()
{delay(150); lcdwcn(0x38);
delay(50); lcdwcn(0x38);
delay(50); lcdwcn(0x38);
lcdwc(0x38);
lcdwc(0x08);
lcdwc(0x01);
lcdwc(0x06);
lcdwc(0x0c);
}
void lcdfill(unsigned char n)
{
for(YPOS=0;YPOS<2;YPOS++)
for(XPOS=0;XPOS<16;XPOS++)
{lcdpos();
lcdwd(n);}
}
void lcdwda(unsigned char x,unsigned char y,unsigned char *s)
{YPOS=y;
for(XPOS=x;XPOS<16;XPOS++)
{lcdpos();
lcdwd(*s);
s++;
delay(400);
}
}
main()
{unsigned char i;
EPIN=0;
while(1)
{lcdreset();
for(i=0x30;i<=0x3a;i++)
{lcdfill(i);
delay(3500);
}
lcdfill(' ');
delay(2000);
lcdwda(0,0,"ABCDEFGHIJKLMNOPQRSTUVWXYZ");
//lcdwda(0,1,"ZYXWVUTSRQPONMLKJIHGFEDCBA");
delay(2000);
}
} 看样子像是对比度不大对。 调一下对比度 对比度电位器用两个10K代替不行,还不如1个1K接地呢。另外你芯片是哪个,89系列的P0需要上拉电阻的。如果是你现在那个LE型号,液晶不一定在3V下驱动起来,一般都是5V的,仅供参考。 搞屁啊,你单片机根本没P0,你愣是在程序上写了P0,,,IO都不对应怎么显示? 饭桶 发表于 2014-8-11 23:35
对比度电位器用两个10K代替不行,还不如1个1K接地呢。另外你芯片是哪个,89系列的P0需要上拉电阻的。如果是 ...
芯片用的是STC12C5628AD对比度没调好?换成1K接地?{:lol:} “自己写的驱动程序,连个LCD都点不亮呀”
"代码是坛子里下载的" i7gly 发表于 2014-8-11 23:38
搞屁啊,你单片机根本没P0,你愣是在程序上写了P0,,,IO都不对应怎么显示?
复制坛子上的代码忘了改了,但是写的时候该成了P1 现象就是这样{:lol:} 电子喵星人 发表于 2014-8-11 23:44
“自己写的驱动程序,连个LCD都点不亮呀”
之前是自己写的,驱动不了。现在用坛子里下载的修改了 还是驱动部了{:lol:} 楼主的这个现象我碰到过
是因为rs,r/w,e的时序不对造成的 huangyiting1990 发表于 2014-8-11 23:51
复制坛子上的代码忘了改了,但是写的时候该成了P1 现象就是这样
#include <iostm8s208mb.h>
#include "lcd1602.h"
#include "main.h"
/************IO映射***********
RW-> PG6
RS-> PG7
E -> PG5
DATA -> PI
*****************************/
#define LCD_DATA PI_ODR
#define SET_RW PG_ODR |= BIT6
#define RESET_RWPG_ODR &= ~BIT6
#define SET_RS PG_ODR |= BIT7
#define RESET_RSPG_ODR &= ~BIT7
#define SET_EN PG_ODR |= BIT5
#define RESET_ENPG_ODR &= ~BIT5
const unsigned char num_table[]="0123456789ABCDEF";
/***********底层控制函数**************/
void LCD_Delay(unsigned char x)
{
while(x--);
}
void Write_Com(unsigned char wcom)
{
SET_EN;
RESET_RS;
RESET_RW;
LCD_DATA = wcom;
LCD_Delay(50);
RESET_EN;
}
void Write_Data(unsigned char wdata)
{
SET_EN;
SET_RS;
RESET_RW;
LCD_DATA = wdata;
LCD_Delay(50);
RESET_EN;
}
//LCD初始化函数
void Lcd1602_Init(void)
{
/************IO Init**************/
PG_DDR|= (BIT5 + BIT6 + BIT7);
PG_CR1|= (BIT5 + BIT6 + BIT7);
PG_CR2|= ~(BIT5 + BIT6 + BIT7);
PI_DDR= 0xff;
PI_CR1= 0xff;
PI_CR2= 0x00;
//Write_Com(0x01);
Write_Com(0x06);//
Write_Com(0x0c);//开显示屏
Write_Com(0x38);//8位传送数据 2行显示
}
//显示字符串
//起始位置x,y对应屏幕字符位置,字符串由指针带入
//y=0 or 1,大于则舍去,x>15则舍去
//自动换行,多出字符舍去
void Display_Char(unsigned char x , unsigned char y , unsigned char* pchar)
{
if(y>1 || x>15)return; //超出显示区域
if(y==1)x += 0x40; //计算换行地址
x += 0x80; //加上首地址
Write_Com(x); //写入地址
while(*pchar != '\0') //写入字符串
{
if((x > 0x8F) && (y != 1)) //0x8F = 0x80+15,也就是第一行最后一位
{
x= 0x80 + 0x40; //地址重新指向第二行
Write_Com(x); //写入第二行地址,显示从第二行重新开始
y=1; //已经显示到第二行了,防止重复判断
}
if(x > 0xCF)break; //0xCF = 0x80 + 0x40 + 15 第二行最后一位,超出后就退出了.
Write_Data(*pchar); //写入字符
pchar++; //指针递增
x++; //地址+1,用于计算自动换行或超长退出操作
}
}
//十进制显示1Byte的数字,占用3个字符位,想占用两位的去找Display_Hex_8bit()
//地址写入规则跟Display_Char()一样
//不自动换行
void Display_Number_8bit(unsigned char x , unsigned char y , unsigned char num)
{
if(y>1 || x>15)return; //超出显示区域
if(y==1)x += 0x40; //计算换行地址
Write_Com(0x80 + x); //写入地址
Write_Data(num_table);
Write_Data(num_table);
Write_Data(num_table);
}
//十进制显示2Byte的数字,占用5个字符位,想占用4位的去找Display_Hex_16bit()
//地址写入规则跟Display_Char()一样
//不自动换行
void Display_Number_16bit(unsigned char x , unsigned char y , unsigned int num)
{
if(y>1 || x>15)return; //超出显示区域
if(y==1)x += 0x40; //计算换行地址
Write_Com(0x80 + x); //写入地址
Write_Data(num_table);
Write_Data(num_table);
Write_Data(num_table);
Write_Data(num_table);
Write_Data(num_table);
}
//十六进制显示1Byte的数字,占用2个字符位置
//地址写入规则跟Display_Char()一样
//不自动换行
void Display_Hex_8bit(unsigned char x , unsigned char y , unsigned char num)
{
if(y>1 || x>15)return; //超出显示区域
if(y==1)x += 0x40; //计算换行地址
Write_Com(0x80 + x); //写入地址
Write_Data(num_table);
Write_Data(num_table);
}
//十六进制显示2Byte的数字,占用4个字符位置
//地址写入规则跟Display_Char()一样
//不自动换行
void Display_Hex_16bit(unsigned char x , unsigned char y , unsigned int num)
{
if(y>1 || x>15)return; //超出显示区域
if(y==1)x += 0x40; //计算换行地址
Write_Com(0x80 + x); //写入地址
Write_Data(num_table);
Write_Data(num_table);
Write_Data(num_table);
Write_Data(num_table);
}
//清除显示域
void LCD_Clear(void)
{
unsigned char x;
Write_Com(0x80);
for(x=0;x<16;x++)
Write_Data (' ');
Write_Com(0x80+0x40);
for(x=0;x<16;x++)
Write_Data (' ');
}
给你一份我写的,修改头文件,修改管脚宏定义,修改Init函数里面的管脚初始化就能用了 Display_Char(0,0,"Midy Studio !!!");
Display_Hex_8bit(0,0,temp);
Display_Number_8bit(0,1,temp);
Display_Hex_16bit(4,0,num);
Display_Number_16bit(4,1,num);
这样调用 i7gly 发表于 2014-8-11 23:55
这样调用
{:lol:} 行,我再试试 论坛上代码是12t速度单片机 你这个是1t速度单片机延时要调试 lxa0 发表于 2014-8-11 23:53
楼主的这个现象我碰到过
是因为rs,r/w,e的时序不对造成的
明天再用逻辑分析抓波试试{:lol:} 对比度的问题,最好用电位器调。 饭桶 发表于 2014-8-12 00:01
对比度的问题,最好用电位器调。
10K电位器? huangyiting1990 发表于 2014-8-11 23:58
明天再用逻辑分析抓波试试
我勒个去 还抓波 贴你个源代码 本帖最后由 lcl 于 2014-8-12 00:31 编辑
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit rs=P1^0;
sbit rw=P1^1;
sbit lcden=P2^5;
uchar table1[]="NI DA YE DE MAO";
uchar table2[]="WWW.BAIDU.COM";
void delay(uint x)
{
uint a,b;
for(a=x;a>0;a--)
for(b=10;b>0;b--);
}
void delay1(uint x)
{
uint a,b;
for(a=x;a>0;a--)
for(b=100;b>0;b--);
}
void write_com(uchar com)
{
P0=com;
rs=0;
lcden=0;
delay(10);
lcden=1;
delay(10);
lcden=0;
}
void write_date(uchar date)
{
P0=date;
rs=1;
lcden=0;
delay(10);
lcden=1;
delay(10);
lcden=0;
}
void init()
{
rw=0;
dula=0;
wela=0;
write_com(0x38); //显示模式设置:16×2显示,5×7点阵,8位数据接口
delay(20);
write_com(0x0f); //显示模式设置
delay(20);
write_com(0x06); //显示模式设置:光标右移,字符不移
delay(20);
write_com(0x01); //清屏幕指令,将以前的显示内容清除
delay(20);
}
void main()
{
uchar a;
init();
write_com(0x80+17); //将第一个字符写在向右偏移17个字符处,为后面的由右向左划入做准备。
delay(20);
for(a=0;a<13;a++)
{
write_date(table1);
delay(20);
}
write_com(0xc0+17);
delay(50);
for(a=0;a<13;a++)
{
write_date(table2);
delay(40);
}
for(a=0;a<16;a++)
{
write_com(0x18); //左移
delay1(600);
}
while(1);
}
估计就是1T与12T的问题... 正准备搞这个,先来看看 用示波器抓一下信号,信号没有给对就是这个现象 对比度引脚悬空试试,我经常悬空,就是会比较暗,但是能看到字符
页:
[1]