蓝桥杯单片机模块代码完善:NE555、EEPROM与DS1302模块深度解析
以前写的那些模块的底层代码是可以正常使用的,但是当题目涉及到一些问题可能会出现乱码或者时序错误,本篇文章对部分的模块的底层代码需要更改的地方进行总结。
一、NE555+按键
#include <key.h>
unsigned char KeyDisp()
{
unsigned char temp = 0;//一定要赋值!
P44 = 0;
P42 = 1;
P35 = 1;
//P34 = 1;
if(P33 == 0) temp = 4;
if(P32 == 0) temp = 5;
P44 = 1;
P42 = 0;
P35 = 1;
//P34 = 1;
if(P33 == 0) temp = 8;
if(P32 == 0) temp = 9;
return temp;
}
void Timer0_Init(void) //100微秒@12.000MHz
{
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x05;
TL0 = 0; //设置定时初始值
TH0 = 0; //设置定时初始值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
void Timer1_Init(void) //1毫秒@12.000MHz
{
AUXR &= 0xBF; //定时器时钟12T模式
TMOD &= 0x0F; //设置定时器模式
TL1 = 0x18; //设置定时初始值
TH1 = 0xFC; //设置定时初始值
TF1 = 0; //清除TF1标志
TR1 = 1; //定时器1开始计时
ET1 = 1; //使能定时器1中断
EA = 1;
}
void Timer1_Isr(void) interrupt 3
{
/*NE555*/
if(++Time_1s == 1000)
{
Time_1s = 0;
Freq = (TH0 << 8) | TL0;
TH0 = TL0 = 0;
}
}
void main()
{
Timer0_Init();
Timer1_Init();
while(1)
{
//...
}
}
Freq
和时间Time_1s
一定要定义成unsigned int
类型!二、EEPROM上锁问题
1.什么时候要上锁?
如果题目明确指定将数据存放到EEPROM的某个位置,这个时候是不用做其他操作的,正常读写EEPROM即可,例如:
当题目没有明确存放的地方时,恭喜你,触发了隐藏副本,需要在读写数据前增加上锁工作,例如:
2.怎么上锁?
假如题目要在按键S4按下时将数据Date
写入EEPROM,并且在上电时从EEPROM读出。
正常写法:
idata unsigned char Date = 1;
void KeyProc()
{
if(KeyDown == 4)
EepromWrite(&Date,0,1);
}
void main()
{
EepromRead(&Date,0,1);
while(1);
}
上锁写法:
idata unsigned char Date = 1;
idata unsigned char Lock = 5;//锁
void KeyProc()
{
if(KeyDown == 4)
{
EepromWrite(&Date,0,1);
//将锁存放在EEPROM的下一页
EepromWrite(&Lock,8,1);
}
}
void main()
{
unsigned char read;
//上电时先定义一个中间变量读取EEPROM的位置8的值
//将读取的值与锁进行比较
//如果读取的是锁值,则Date正常读取位置0的数据
//如果不是,则丢弃
EepromRead(&read,8,1);
if(read == Lock)
EepromRead(&Date,0,1);
while(1);
}
三、DS1302底层改为十进制
除了将DS1302底层代码改为十进制,还增加读取时间时通过关开定时器中断防止时序对DS1302的影响。
code unsigned char Ds1302_Arr[4] = {0x84,0x82,0x80,0x8E};
void SetRtc(unsigned char *Rtc)
{
unsigned char i;
Write_Ds1302_Byte(Ds1302_Arr[3],0x00);//关闭写保护
for(i = 0; i < 3; i++)
Write_Ds1302_Byte(Ds1302_Arr[i],(Rtc[i] / 10 << 4) | Rtc[i] % 10);
//打开写保护
Write_Ds1302_Byte(Ds1302_Arr[3],0x80);
}
void GetRtc(unsigned char *Rtc)
{
unsigned char i, temp;
EA = 0;//关闭中断
for(i = 0; i < 3; i++)
{
temp = Read_Ds1302_Byte(Ds1302_Arr[i]+1);
Rtc[i] = temp / 16 * 10 + temp % 16;
}
EA = 1;//打开中断
}
四、IIC底层代码
如果数码管显示的AD值会闪烁,其他时序都没问题,不妨试试以下改法:将DELAY_TIME
的10改成5。
作者:星光始终闪耀