题目如下
通过串口助手控制 LCD 显示屏,通过 LCD1602 显示并保存在 EEPROM 中,实现 数据的掉电保存(例 如:串口向单片机发送一串英文字符,该字符在 LCD 上显示出 来,若按下 k1 则实现数据的保存,按下 k2 实 现读取上次保存的数据,显示在 1602 上)
效果如下
#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器
#include "i2c.h"
#include typedef unsigned int u16; //对数据类型进行声明定义 typedef unsigned char u8; sbit LSA=P2^2; sbit LSB=P2^3; sbit LSC=P2^4; sbit k1=P3^1; sbit k2=P3^0; sbit k3=P3^2; //定义按键端口 sbit LCD1602_RS=P2^6; sbit LCD1602_RW=P2^5; sbit LCD1602_E=P2^7; u8 num=0;u8 i,flag; u8 table[16]="I received is: "; u8 table1[16]="My memory is: "; u8 table2[16]; u8 table3[16]; u8 count,rec; u8 dat,flag1,j; /******************************************************************************* * 函 数 名 : delay * 函数功能 : 延时函数,i=1时,大约延时10us *******************************************************************************/ void delay(u16 i) { while(i--); } void Lcd1602_Delay1ms(u16 c) //误差 0us { u8 a,b; for (; c>0; c--) { for (b=199;b>0;b--) { for(a=1;a>0;a--); } } } void write_com(u8 com) { LCD1602_E = 0; //使能 LCD1602_RS = 0; //选择发送命令 LCD1602_RW = 0; //选择写入 P0= com; //放入命令 Lcd1602_Delay1ms(1); //等待数据稳定 LCD1602_E = 1; //写入时序 Lcd1602_Delay1ms(5); //保持时间 LCD1602_E = 0; } void write_data(u16 dat) { LCD1602_E = 1; //使能 LCD1602_RS = 1; //选择发送命令 LCD1602_RW = 0; //选择写入 P0=dat; //放入命令 Lcd1602_Delay1ms(1); //等待数据稳定 LCD1602_E = 1; //写入时序 Lcd1602_Delay1ms(5); //保持时间 LCD1602_E = 0; } void Init() { write_com(0x38); write_com(0x0f); write_com(0x06); write_com(0x01); //清屏 write_com(0x80); //设置数据指针起点 } /******************************************************************************* * 函数名 :Keypros() * 函数功能 :按键处理函数 * 输入 : 无 * 输出 : 无 *******************************************************************************/ void Keypros() { if(k1==0) { delay(1000); //消抖处理 if(k1==0) { count=strlen(table2); //计算要记忆的字符串的长度 for(i=0;i At24c02Write(5*i+2,table2[i]); //在对应的地址中放入对应的字符 delay(1000); } } while(!k1); } if(k2==0) { delay(1000); //消抖处理 if(k2==0) { flag=0; write_com(0x01); for(i=0;i<16;i++) { write_data(table1[i]); //显示my memory is: } write_com(0x80+0x40); //换行 for(i=0;i<16;i++) { table3[i]= At24c02Read(5*i+2); write_data(table3[i]); delay(1000); } } while(!k2); } if(k3==0) { delay(1000); //消抖处理 if(k3==0) { write_com(0x01); } while(!k3); } } void UsartInit() { SCON = 0x50; TMOD |= 0x20; PCON = 0x80; TH1 = 0xFD; TL1 = 0xFD; EA = 1; ES = 1; TR1 = 1; } void lcdDisplay() { write_com(0x01); for(i=0;i<16;i++) { write_data(table[i]); } write_com(0x80+0x40); for(i=0;i write_data(table2[i]); } num=0; flag=0; } /******************************************************************************* * 函 数 名 : main * 函数功能 : 主函数 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ void main() { Init(); UsartInit(); while(1) { if(flag==1) { lcdDisplay(); } Keypros(); } } void Usart() interrupt 4 { if(RI) { table2[num]=SBUF; RI = 0; //Usartdelay5ms(); SBUF = table2[num]; while(!TI); TI = 0; //Usartdelay5ms(); num++; flag = 1; } } #include"i2c.h" /******************************************************************************* * 函数名 : Delay10us() * 函数功能 : 延时10us * 输入 : 无 * 输出 : 无 *******************************************************************************/ void Delay10us() { unsigned char a,b; for(b=1;b>0;b--) for(a=2;a>0;a--); } /******************************************************************************* * 函数名 : I2cStart() * 函数功能 : 起始信号:在SCL时钟信号在高电平期间SDA信号产生一个下降沿 * 输入 : 无 * 输出 : 无 * 备注 : 起始之后SDA和SCL都为0 *******************************************************************************/ void I2cStart() { SDA=1; Delay10us(); SCL=1; Delay10us();//建立时间是SDA保持时间>4.7us SDA=0; Delay10us();//保持时间是>4us SCL=0; Delay10us(); } /******************************************************************************* * 函数名 : I2cStop() * 函数功能 : 终止信号:在SCL时钟信号高电平期间SDA信号产生一个上升沿 * 输入 : 无 * 输出 : 无 * 备注 : 结束之后保持SDA和SCL都为1;表示总线空闲 *******************************************************************************/ void I2cStop() { SDA=0; Delay10us(); SCL=1; Delay10us();//建立时间大于4.7us SDA=1; Delay10us(); } /******************************************************************************* * 函数名 : I2cSendByte(unsigned char dat) * 函数功能 : 通过I2C发送一个字节。在SCL时钟信号高电平期间,保持发送信号SDA保持稳定 * 输入 : num * 输出 : 0或1。发送成功返回1,发送失败返回0 * 备注 : 发送完一个字节SCL=0,SDA=1 *******************************************************************************/ unsigned char I2cSendByte(unsigned char dat) { unsigned char a=0,b=0;//最大255,一个机器周期为1us,最大延时255us。 for(a=0;a<8;a++)//要发送8位,从最高位开始 { SDA=dat>>7; //起始信号之后SCL=0,所以可以直接改变SDA信号 dat=dat<<1; Delay10us(); SCL=1; Delay10us();//建立时间>4.7us SCL=0; Delay10us();//时间大于4us } SDA=1; Delay10us(); SCL=1; while(SDA)//等待应答,也就是等待从设备把SDA拉低 { b++; if(b>200) //如果超过2000us没有应答发送失败,或者为非应答,表示接收结束 { SCL=0; Delay10us(); return 0; } } SCL=0; Delay10us(); return 1; } /******************************************************************************* * 函数名 : I2cReadByte() * 函数功能 : 使用I2c读取一个字节 * 输入 : 无 * 输出 : dat * 备注 : 接收完一个字节SCL=0,SDA=1. *******************************************************************************/ unsigned char I2cReadByte() { unsigned char a=0,dat=0; SDA=1; //起始和发送一个字节之后SCL都是0 Delay10us(); for(a=0;a<8;a++)//接收8个字节 { SCL=1; Delay10us(); dat<<=1; dat|=SDA; Delay10us(); SCL=0; Delay10us(); } return dat; } /******************************************************************************* * 函数名 : void At24c02Write(unsigned char addr,unsigned char dat) * 函数功能 : 往24c02的一个地址写入一个数据 * 输入 : 无 * 输出 : 无 *******************************************************************************/ void At24c02Write(unsigned char addr,unsigned char dat) { I2cStart(); I2cSendByte(0xa0);//发送写器件地址 I2cSendByte(addr);//发送要写入内存地址 I2cSendByte(dat); //发送数据 I2cStop(); } /******************************************************************************* * 函数名 : unsigned char At24c02Read(unsigned char addr) * 函数功能 : 读取24c02的一个地址的一个数据 * 输入 : 无 * 输出 : 无 *******************************************************************************/ unsigned char At24c02Read(unsigned char addr) { unsigned char num; I2cStart(); I2cSendByte(0xa0); //发送写器件地址 I2cSendByte(addr); //发送要读取的地址 I2cStart(); I2cSendByte(0xa1); //发送读器件地址 num=I2cReadByte(); //读取数据 I2cStop(); return num; }
上一篇:stc51单片机串口通信程序
下一篇:51 单片机 EEPROM小结(FLASH)
推荐阅读最新更新时间:2024-10-30 10:15
设计资源 培训 开发板 精华推荐
- LT1055 的典型应用 - 精密、高速、JFET 输入运算放大器
- CH9340K USB转TTL模块
- Esp-12F烧录板
- S12XD,16 位汽车微控制器评估板
- AT32F403AVGT7最小系统板
- 当 LTC2379CDE-18 中启用数字增益压缩时,使用 LT6350 的典型应用被配置为接受 ±10V 输入信号,同时运行一个 5.5V 单电源
- 驭风ESP_Mini遥控器
- 使用 LT3045EDD 并联多个线性稳压器以提供 2A 输出电流的典型应用
- STDES-IDS003V1和STDES-IDS002V1的无线接收器板套件
- 采用 EZ-PD™ PAG1 和 CoolGaN™ 的 45W USB-PD/PPS 电源适配器解决方案