电视频道回忆功用,交通灯倒计时时刻的设定,野外 LED 广告的回忆功用,都有或许用到 EEPROM 这类存储器件。这类器材的优势是存储的数据不只能够改动,而且掉电后数据保存不丢掉,因而很多运用在各种电子产品上。
咱们这节课的例程,有点相似广告屏。上电后,1602 的榜首行显现 EEPROM 从 0x20 地址开端的 16 个字符,第二行显现 EERPOM 从 0x40 开端的 16 个字符。咱们能够经过 UART串口通讯来改动 EEPROM 内部的这个数据,而且一起也改动了 1602 显现的内容,下次上电的时分,直接会显现咱们更新过的内容。
这个程序一切的相关内容,前面都现已讲过了。可是这个程序体现在了一个归纳运用才能上。这个程序用到了 1602 液晶、UART 串口通讯、EEPROM 读写操作等多个功用的归纳运用。写个点亮小灯好简略,可是咱们想真实学好单片机,必须得学会这种归纳程序的运用,完成多个模块一起参加作业。因而同学们,要仔仔细细的把工程建立起来,一行一行的把程序编写起来,终究稳固下来。
#include
unsigned char T0RH = 0; //T0 重载值的高字节
unsigned char T0RL = 0; //T0 重载值的低字节
void InitShowStr();
void ConfigTImer0(unsigned int ms);
extern void InitLcd1602();
extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
extern void E2Read(unsigned char *buf, unsigned char addr, unsigned char len);
extern void E2Write(unsigned char *buf, unsigned char addr, unsigned char len);
extern void UartDriver();
extern void ConfigUART(unsigned int baud);
extern void UartRxMonitor(unsigned char ms);
extern void UartWrite(unsigned char *buf, unsigned char len);
void main(){
EA = 1; //开总中止
ConfigTImer0(1); //装备 T0 守时 1ms
ConfigUART(9600); //装备波特率为 9600
InitLcd1602(); //初始化液晶
InitShowStr(); //初始显现内容
while (1){
UartDriver(); //调用串口驱动
}
}
/* 处理液晶屏初始显现内容 */
void InitShowStr(){
unsigned char str[17];
str[16] = ‘’;//在终究增加字符串完毕符,保证字符串能够完毕
E2Read(str, 0x20, 16); //读取榜首行字符串,其 E2 开始地址为 0x20
LcdShowStr(0, 0, str); //显现到液晶屏
E2Read(str, 0x40, 16); //读取第二行字符串,其 E2 开始地址为 0x40
LcdShowStr(0, 1, str); //显现到液晶屏
}
/* 内存比较函数,比较两个指针所指向的内存数据是否相同,
ptr1-待比较指针 1,ptr2-待比较指针 2,len-待比较长度
回来值-两段内存数据完全相一起回来 1,不同回来 0 */
bit CmpMemory(unsigned char *ptr1, unsigned char *ptr2, unsigned char len){
while (len–){
if (*ptr1++ != *ptr2++){ //遇到不持平数据时立刻回来 0
return 0;
}
}
return 1; //比较完全部长度数据都持平则回来 1
}
/* 将一字符串收拾成 16 字节的固定长度字符串,缺乏部分补空格
out-收拾后的字符串输出指针,in-待收拾字符串指针 */
void TrimString16(unsigned char *out, unsigned char *in){
unsigned char i = 0;
while (*in != ‘’){ //复制字符串直到输入字符串完毕
*out++ = *in++;
i++;
if (i 》= 16){ //当复制长度已达到 16 字节时,强制跳出循环
break;
}
}
for ( ; i《16; i++){ //如缺乏 16 个字节则用空格补齐
*out++ = ‘ ’;
}
*out = ‘’; //终究增加完毕符
}
/* 串口动作函数,依据接纳到的指令帧履行呼应的动作
buf-接纳到的指令帧指针,len-指令帧长度 */
void UartAcTIon(unsigned char *buf, unsigned char len){
unsigned char i;
unsigned char str[17];
unsigned char code cmd0[] = “showstr1 ”; //榜首行字符显现指令
unsigned char code cmd1[] = “showstr2 ”; //第二行字符显现指令
unsigned char code cmdLen[] = { //指令长度汇总表
sizeof(cmd0)-1, sizeof(cmd1)-1,
};
unsigned char code *cmdPtr[] = { //指令指针汇总表
&cmd0[0], &cmd1[0],
};
for (i=0; i
if (len 》= cmdLen[i]){ //首要接纳到的数据长度要不小于指令长度
if (CmpMemory(buf, cmdPtr[i], cmdLen[i])){ //比较相一起退出循环
break;
}
}
}
switch (i){ //依据比较成果履行相应指令
case 0:
buf[len] = ‘’; //为接纳到的字符串增加完毕符
TrimString16(str, buf+cmdLen[0]); //收拾成 16 字节固定长度字符串
LcdShowStr(0, 0, str); //显现字符串 1
E2Write(str, 0x20, sizeof(str)); //保存字符串 1,开始地址为 0x20
break;
case 1:
buf[len] = ‘’; //为接纳到的字符串增加完毕符
TrimString16(str, buf+cmdLen[1]); //收拾成 16 字节固定长度字符串
LcdShowStr(0, 1, str); //显现字符串 1
E2Write(str, 0x40, sizeof(str)); //保存字符串 2,开始地址为 0x40
break;
default: //未找到相符指令时,给上机发送“过错指令”的提示
UartWrite(“bad command.rn”, sizeof(“bad command.rn”)-1);
return;
}
buf[len++] = ‘r’; //有用指令被履行后,在原指令帧之后增加
buf[len++] = ‘n’; //回车换行符后回来给上位机,表明已履行
UartWrite(buf, len);
}
/* 装备并发动 T0,ms-T0 守时时刻 */
void ConfigTImer0(unsigned int ms){
unsigned long tmp; //暂时变量
tmp = 11059200 / 12; //守时器计数频率
tmp = (tmp * ms) / 1000; //核算所需的计数值
tmp = 65536 – tmp; //核算守时器重载值
tmp = tmp + 33; //补偿中止呼应延时形成的差错
T0RH = (unsigned char)(tmp》》8); //守时器重载值拆分为凹凸字节
T0RL = (unsigned char)tmp;
TMOD &= 0xF0; //清零 T0 的操控位
TMOD |= 0x01; //装备 T0 为形式 1
TH0 = T0RH; //加载 T0 重载值
TL0 = T0RL;
ET0 = 1; //使能 T0 中止
TR0 = 1; //发动 T0
}
/* T0 中止服务函数,履行串口接纳监控和蜂鸣器驱动 */
void InterruptTimer0() interrupt 1{
TH0 = T0RH; //从头加载重载值
TL0 = T0RL;
UartRxMonitor(1); //串口接纳监控
}
咱们在学习 UART 通讯的时分,刚开端也是用的IO口去模仿UART通讯进程,终究完成和电脑的通讯,然后由于 STC89C52 内部具有 UART 硬件通讯模块,所以咱们直接能够经过装备寄存器就能够很轻松的完成单片机的 UART 通讯。相同的道理,这个 I2C 通讯,假如单片机内部有硬件模块的话,单片机能够直接主动完成 I2C 通讯了,就不需求咱们再进行 IO口模仿开始、模仿发送、模仿完毕,装备好寄存器,单片机就会把这些作业悉数做了。
不过咱们的STC89C52单片机内部不具有I2C的硬件模块,所以咱们运用STC89C52进行I2C通讯的话必须用IO口来模仿。运用IO口模仿I2C实际上更有利于咱们完全了解透彻I2C通讯的本质。当然了,经过学习IO口模仿通讯,往后假如遇到内部带 I2C 模块的单片机,也应该很轻松的搞定,运用内部的硬件模块,能够进步程序的履行功率。
来历;21ic