以前写的那些模块的底层代码是可以正常使用的,但是当题目涉及到一些问题可能会出现乱码或者时序错误,本篇文章对部分的模块的底层代码需要更改的地方进行总结。

一、NE555+按键

  • NE555使用的时候默认使用定时器0去计数,定时器1去计时(不可颠倒),在使用的时候记得把按键的P34注释掉!!!
#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。
在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐