快捷搜索:

STC89C52单片机和EEPROM存储器的编程设计

电视频道影象功能,交通灯倒计时光阴的设定,户外 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

您可能还会对下面的文章感兴趣: