前言:历经一个月的空白期,特此写一道省赛题恢复感觉
题目
题目解析与感觉
这个题目涉及到的模块很少,还是设计各个模块之间的统合。
我的编程思路是先做显示模块,将显示模块调试好后就调按键。
涉及到输入数字的按键会发现有很多重复的地方,我就把输入数字给独立出来,这样就可以很大程度简化代码,增加代码的可读性。
void shuru_an(unsigned char number){
unsigned char i;
if(weishu < 5){
for(i = 0;i < 4;i++){
shuru[4-i] = shuru[3-i];
}
shuru[0] = number;
weishu++;
}
if(weishu >= 5){
weishu = 5;
}
}
修改也是一样,然后根据模式来进行输入。
对于输入数字,每次输入都需要把位数+1,输入位数到了就要进行判断(我觉得应该搞个确认按键)
清除要把所有清除,包括位数(我一开始没看清要求,做了个退位,还调试了一段时间:(。但我感觉这还蛮具有代表性的,如果考到可以比较快速做出来)
密码有5位数,尚且可以用long ,但我觉得更好的对比方法还是用数组比对。
密码和修改不是马上生效,而是要经过S12进行确认,因而修改和密码要分开两个数组。
底层驱动代码
本题只涉及IIC通讯
void eepromwirte(unsigned char addr,unsigned char dat){
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(0x00 + addr);
I2CWaitAck();
I2CSendByte(dat);
I2CWaitAck();
I2CStop();
}
unsigned char eepromread(unsigned char addr){
unsigned char ret;
I2CStart();
I2CSendByte(0xa0);
I2CWaitAck();
I2CSendByte(0x00+addr);
I2CWaitAck();
I2CStart();
I2CSendByte(0xa1);
I2CWaitAck();
ret = I2CReceiveByte();
I2CSendAck(1);
I2CStop();
return ret;
}
延时代码以及锁存器的驱动代码
#include <STC15F2K60S2.H>
#include "delay.h"
void inithc138(unsigned char channel){
switch(channel){
case 0:P2 = (P2 & 0x1f) | 0x00;break;
case 4:P2 = (P2 & 0x1f) | 0x80;break;
case 5:P2 = (P2 & 0x1f) | 0xa0;break;
case 6:P2 = (P2 & 0x1f) | 0xc0;break;
case 7:P2 = (P2 & 0x1f) | 0xe0;break;
}
}
void outputp0(unsigned char channel,unsigned char dat){
inithc138(0);
P0 = dat;
inithc138(channel);
inithc138(0);
}
void showsmg(unsigned char pos,unsigned char dat){
outputp0(7,0xff);
outputp0(6,0x01 << (pos - 1));
outputp0(7,dat);
Delay(1);
}
void initsys(){
outputp0(4,0xff);
outputp0(5,0x00);
outputp0(6,0xff);
outputp0(7,0xff);
}
void Delay(unsigned int xms) //@12.000MHz
{
while(xms--){
unsigned char data i, j;
i = 12;
j = 169;
do
{
while (--j);
} while (--i);
}
}
主程序
#include <STC15F2K60S2.H>
#include "delay.h"
#include "inithc138.h"
#include "iic.h"
#define de 5
#define ep 5
code unsigned char Seg_Table[17] =
{
0xc0, //0
0xf9, //1
0xa4, //2