新闻中心

单片机·LCD1602

作者: 时间:2016-11-24 来源:网络 收藏
实验2:读取eeprom存储数据,再通过uart通信发送,+1后再存储回eeprom
程序:
main.h
# ifndef _MAIN_H_
# define _MAIN_H_
# include
# include
typedef unsigned char uint8 ;
typedef unsigned int uint16 ;
typedef unsigned long uint32 ;
sbit SCL = P3^7 ;
sbit SDA = P3^6 ;
sbit RS = P1^0 ;
sbit RW = P1^1 ;
sbit EN = P1^5 ;
sbit BUSY = P0^7 ;
# endif
main.c
# include "main.h"
void delay(void)
{
_nop_() ;
_nop_() ;
_nop_() ;
_nop_() ;
}
void I2C_init(void)
{
SDA = 1 ;
SCL = 1 ;
}
void I2C_start(void)
{
SDA = 1 ;
delay() ;
SCL = 1 ;
delay() ;
SDA = 0 ;
delay() ;
SCL = 0 ;
delay() ;
}
void I2C_stop(void)
{
SCL = 0 ;
delay() ;
SDA = 0 ;
delay() ;
SCL = 1 ;
delay() ;
SDA = 1 ;
delay() ;
}
void I2C_send(uint8 byte)
{
uint8 i ;
for (i=0; i<8; i++)
{
SCL = 0 ;
delay() ;
SDA = byte&0x80 ;
byte<<= 1 ;
delay() ;
SCL = 1 ;
delay() ;
}
SCL = 0 ;
SDA = 1 ;
delay() ;
SCL = 1 ;
delay() ;
SCL = 0 ; //为下一次输入数据做准备
delay() ;
}
uint8 I2C_read (void)
{
uint8 i, byte = 0 ;
for(i=0; i<8; i++)
{
SCL = 0;
SDA = 1 ; //读数据必须要保证SDA = 1 ;且 SCL = 1 ,不写入
delay() ;
SCL = 1 ;
delay() ;
byte<<=1 ;
if(SDA == 1)
byte |= 0x01 ;
delay();
}
SCL = 0 ;
SDA = 1 ;
delay() ;
SCL = 1 ;
delay() ;
SCL = 0 ;
delay() ;
return byte ;
}
void write_eeprom(uint8 addr ,uint8 databyte)
{
I2C_start() ;
I2C_send(0xa0) ;
I2C_send(addr) ;
I2C_send(databyte) ;
I2C_stop() ;
}
uint8 read_eeprom(uint8 addr)
{
uint8 byte ;
I2C_start() ;
I2C_send(0xa0) ;
I2C_send(addr) ;
I2C_start() ;
I2C_send(0xa1) ;
byte = I2C_read() ;
I2C_stop() ;
return byte ;
}
void UART_init(void)
{
SCON = 0x50 ;
TMOD = 0x20 ;
TH1 = 0xFD ;
TL1 = 0xFD ;
TR1 = 1 ;
}
void UART_send_byte(uint8 byte)
{
SBUF = byte ;
while(!TI) ;
TI = 0 ;
}
void wait(void)
{
P0 = 0xFF ;
while(BUSY)
{
RS = 0 ;
RW = 1 ;
EN = 0 ;
EN = 1 ;
}
EN = 0 ;
}
void w_cmd(uint8 byte)
{
wait() ;
EN = 0 ;
P0 = byte ;
RS = 0 ;
RW = 0 ;
EN = 1 ;
EN = 0 ;
}
void w_dat(uint8 byte)
{
wait() ;
EN = 0 ;
P0 = byte ;
RS = 1 ;
RW = 0 ;
EN = 1 ;
EN = 0 ;
}
void LCD_init()
{
w_cmd(0x38) ;
w_cmd(0x0c) ;
w_cmd(0x06) ;
w_cmd(0x01) ;
}
void w_hexnum(uint8 dat)
{
uint8 a, b ;
a = dat/16 ;
if(a>9) {w_dat(a+7);}
else {w_dat(a+0);}
b = dat ;
if(b>9) {w_dat(b+7);}
else {w_dat(b+0);}
}
void LCD_show(uint8 dat) //需要考虑
{
static uint16 i=0 ;
LCD_init() ;
i++ ;
if(i<=16) {w_cmd(0x80 + i) ;}
if(i>16 ) {w_cmd(0xc0 + i-16) ;}
if(i==32) {i=0;}
w_hexnum(dat) ;
}
void main(void) //对于同一个器件的操作,必须给读取和存储留有时间
{
uint8 addr = 0x00, databyte = 0x00 ;
uint8 dat = 0;
uint16 i ;
UART_init() ;
I2C_init() ;
while(1)
{
write_eeprom(addr, databyte) ;
for (i=0; i<10000; i++) //延时4ms,让数据写入
{
delay() ;
}
dat = read_eeprom(addr) ;
LCD_show(dat) ;
UART_send_byte(dat) ;
addr++ ;
databyte++ ;
if(addr==0xff) {addr=0;}
if(databyte==0xff){databyte=0;}
for (i=0; i<10000; i++) // 延时4ms,让数据读出
{
delay() ;
}
}
}
这个LCD1602还有一点缺陷,没有能显示上一次输入的数据,仅变成一次显示一个数据,主要是在主函数中eeprom的延时太久了,但这似乎不能避免,想不到更好的方法。
上一页 1 2 下一页

关键词:单片机LCD160

评论


技术专区