本帖最后由 tom_xu 于 2010-3-18 15:11 编辑
1602控制器采用ST7066,4位总线,
有个比较奇怪的地方是,这块板子的
DB7------------------P0_1
DB6------------------P0_2
DB5------------------P0_3
DB4------------------P0_4
E------------------ P1_0
RW------------------P1_1
RS------------------P1_2
我烧录了下面的程序进入芯片,现象是1602先显示第一行16块液晶,然后就消失。
没有显示“4”,不知道怎么回事?用万用表测量1602上DB7~DB4, E/RW/RS数据是正确的。
#define LCD_DB7_DATA p0_1
#define LCD_DB6_DATA p0_2
#define LCD_DB5_DATA p0_3
#define LCD_DB4_DATA p0_4
#define LCD_EN_DATA p1_0
#define LCD_RW_DATA p1_1
#define LCD_RS_DATA p1_2
void delay(unsigned int d)
{
while(--d);
}
void init(void)
{
//**************************************
// Port0 Setting
//**************************************
pd0=0x9F; //Port P0 direction register,0b10011111
//P0_1 is output
//P0_2 is output
//P0_3 is output
//P0_4 is output
//**************************************
// Port1 Setting
//**************************************
pd1=0x07; //Port P1 direction register,0b00000111
//P1_0 is output
//P1_1 is output
//P1_2 is output
}
void wrcmd(char cmd)
{
LCD_RS_DATA=0; //SEND COMMAND
LCD_RW_DATA=0; //WRITE
if((cmd&0x80)==0x80) //需要读数据
{
LCD_DB7_DATA=1;
}
else
{
LCD_DB7_DATA=0;
}
if((cmd&0x40)==0x40)
{
LCD_DB6_DATA=1;
}
else
{
LCD_DB6_DATA=0;
}
if((cmd&0x20)==0x20)
{
LCD_DB5_DATA=1;
}
else
{
LCD_DB5_DATA=0;
}
if((cmd&0x10)==0x10)
{
LCD_DB4_DATA=1;
}
else
{
LCD_DB4_DATA=0;
}
delay(200);
LCD_EN_DATA=1;
delay(20);
LCD_EN_DATA=0;
delay(1200);
LCD_RS_DATA=0;
LCD_RW_DATA=0;
if((cmd&0x08)==0x08)
{
LCD_DB7_DATA=1;
}
else
{
LCD_DB7_DATA=0;
}
if((cmd&0x04)==0x04)
{
LCD_DB6_DATA=1;
}
else
{
LCD_DB6_DATA=0;
}
if((cmd&0x02)==0x02)
{
LCD_DB5_DATA=1;
}
else
{
LCD_DB5_DATA=0;
}
if((cmd&0x01)==0x01)
{
LCD_DB4_DATA=1;
}
else
{
LCD_DB4_DATA=0;
}
delay(200);
LCD_EN_DATA=1;
delay(20);
LCD_EN_DATA=0;
delay(1200);
}
void wrdata(char data)
{
LCD_RS_DATA=1; //SEND DATA
LCD_RW_DATA=0; //WRITE
if((data&0x80)==0x80)
{
LCD_DB7_DATA=1;
}
else
{
LCD_DB7_DATA=0;
}
if((data&0x40)==0x40)
{
LCD_DB6_DATA=1;
}
else
{
LCD_DB6_DATA=0;
}
if((data&0x20)==0x20)
{
LCD_DB5_DATA=1;
}
else
{
LCD_DB5_DATA=0;
}
if((data&0x10)==0x10)
{
LCD_DB4_DATA=1;
}
else
{
LCD_DB4_DATA=0;
}
delay(200);
LCD_EN_DATA=1;
delay(20);
LCD_EN_DATA=0;
delay(1200);
LCD_RS_DATA=1; //SEND DATA
LCD_RW_DATA=0; //WRITE
if((data&0x08)==0x08)
{
LCD_DB7_DATA=1;
}
else
{
LCD_DB7_DATA=0;
}
if((data&0x04)==0x04)
{
LCD_DB6_DATA=1;
}
else
{
LCD_DB6_DATA=0;
}
if((data&0x02)==0x02)
{
LCD_DB5_DATA=1;
}
else
{
LCD_DB5_DATA=0;
}
if((data&0x01)==0x01)
{
LCD_DB4_DATA=1;
}
else
{
LCD_DB4_DATA=0;
}
delay(200);
LCD_EN_DATA=1;
delay(20);
LCD_EN_DATA=0;
// lcd_wait();
delay(1200); //wait for 60 us
}
void lcd_init()
{
delay(20000); //wait 50ms
LCD_RS_DATA=0; //SEND COMMAND
LCD_RW_DATA=0; //WRITE
LCD_DB7_DATA=0;
LCD_DB6_DATA=0;
LCD_DB5_DATA=1; //DB5=1, function set
LCD_DB4_DATA=1; //DB4=1, 8bit mode
delay(200);
LCD_EN_DATA=1;
delay(20);
LCD_EN_DATA=0; //according ST7066 4bit spec, should send
//0x38 first.只要发送高半个字节。
delay(50); //wait 60 us*/
delay(50);
wrcmd(0x28); //0x00101000, function set, 4bit mode, 2line display
delay(1350);
wrcmd(0x28); //0x00101000, function set, 4bit mode, 2line display
delay(1350); //wait for 60 us
wrcmd(0x0F); //0x00001111, display on /off, enter display is on, cursor
delay(1350); //wait for 60 us
wrcmd(0x01); //clear display
delay(8500); //wait for 2.4 ms
wrcmd(0x06); //0x00000110, entry mode set, cursor/blink moves to
//shift of entire display is not moved.
delay(1350); //wait for 60 us
}
void main(void)
{
lcd_init();
wrcmd(0x80); //set CGRAM address
wrdata('4');
for(;;) //Main processing
{
;
}
} |