📄 better.c
字号:
#define uint unsigned int// // 定义新类型,方便下次使用
#define uchar unsigned char
#include"STC12C5A.h"
#include <intrins.h>
#define WaitTime 0x01
#define ENABLE_IAP 0x82
#define address 0x2800
#define CMD_IDLE 0// //定义时钟频率
#define CMD_READ 1// //读命令
#define CMD_PROGRAM 2// //写命令
#define CMD_ERASE 3// //擦除命令,一般需要几个毫秒
sbit shang=P2^0;// //行列式键盘行线的定义
sbit xia=P2^1;
sbit a =P4^6;// // 数码管段码和单片机I/O口的对应关系
sbit b =P4^5;
sbit dp =P2^4;
sbit d =P2^6;
sbit e =P2^7;
sbit g =P0^6;
sbit f =P0^7;
sbit c =P2^5;
sbit P44=P4^4;// //74hc244片选信号
sbit SMG_1=P0^1;// //数码管位选信号
sbit SMG_2=P0^2;
sbit SMG_3=P0^3;
sbit SMG_4=P0^4;
sbit SMG_5=P0^5;
sbit SMG_6=P0^0;
sbit P3_6=P3^6;// //键盘列线的定义
sbit P3_7=P3^7;
sbit P2_3=P2^3;
sbit P2_2=P2^2;
void display(uint cha);
void start();
void delay(uint time);
void disable();
void enable();
void IapIdle();
uint IapReadByte(uint addr);
void IapProgramByte(uint addr, uchar dat);
void IapEraseSector(uint addr);
void INT0_init();
void INT0time() ;
void systeminit();
static uint cha;
static long int yichu;// //时间计数,一旦达到设定值,关闭数码管
static bit state;
void main(void)
{
uchar t;
shang=0;xia=0;
systeminit();// //系统初始化函数,stc12c5a62s2单片机的I/O口工作方式的设定
start();// //系统显示校验函数,这里会从9显示到0,最后显示上一次的数码管亮的值
INT0_init();// //开启定时器0中断
while(1){ // //死循环
if(state==0 ){// //如果状态0,则执行判键及相应的显示函数
if(P3_6==0)// //键盘1和5的判键
{ delay(20);
if(P3_6==0)
{ shang=1;
if(P3_6==1)
cha=1;
else
cha=5;
shang=0;
}
}
if(P3_7==0)// //键盘2和6的判键
{ delay(20);
if(P3_7==0)
{ shang=1;
if(P3_7==1)
cha=2;
else
cha=6;
shang=0;
}
}
if(P2_3==0)// //键盘3和7的判键
{ delay(20);
if(P2_3==0)
{ shang=1;
if(P2_3==1)
cha=3;
else
cha=7;
shang=0;
}
}
if(P2_2==0) //键盘4的判键
{ delay(20);
if(P2_2==0)
cha=4; }
}
if(!(P2_2==1&&P2_3==1&&P3_6==1&&P3_7==1)) //按键按下判定语句
{ yichu=0; //如果有按键按下,重新设置溢出值,使达到关状态的时间相同
if(state==1){ //如果为关闭状态
delay(500); //延时20ms
if(!(P2_2==1&&P2_3==1&&P3_6==1&&P3_7==1)) //如果有按键按下,状态清零,开始判键程序
state=0;}
}
if(yichu>=80000) //达到数码管关闭时间
{ do{disable();}while(P2_2==1&&P2_3==1&&P3_6==1&&P3_7==1); //若无按键按下,则执行关闭语句
yichu=0; //重设溢出值
enable(); //点亮数码管
state=1; //状态设1,为关闭后点亮状态
}
if(t!=cha) //如果有不同的键按下
{ IapEraseSector(address); //eeprom擦除
IapProgramByte(address,cha); //eeprom写
t=cha; //保存目前的按键值,和下一次做比较,看是否要进行写操作
}
}
}
void systeminit()
{ P4SW=0x7F;
P0M1=0x00;
P0M0=0xff;
P2M1=0x00;
P2M0=0xff;
P3M1=0x00;
P3M0=0xff;
P4M1=0x00;
P4M0=0xff;
P44=0;
}
void display(uint cha) //显示函数,其中小数点一直关闭
{
switch(cha){
case 0: a=1;b=1;c=1;d=1;e=1;f=1;g=0;dp=0;break; //显示数值0
case 1: a=0;b=1;c=1;d=0;e=0;f=0;g=0;dp=0;break; //显示数值1
case 2: a=1;b=1;c=0;d=1;e=1;f=0;g=1;dp=0;break; //显示数值2
case 3: a=1;b=1;c=1;d=1;e=0;f=0;g=1;dp=0;break; //显示数值3
case 4: a=0;b=1;c=1;d=0;e=0;f=1;g=1;dp=0;break; //显示数值4
case 5: a=1;b=0;c=1;d=1;e=0;f=1;g=1;dp=0;break; //显示数值5
case 6: a=1;b=0;c=1;d=1;e=1;f=1;g=1;dp=0;break; //显示数值6
case 7: a=1;b=1;c=1;d=0;e=0;f=0;g=0;dp=0;break; //显示数值7
case 8: a=1;b=1;c=1;d=1;e=1;f=1;g=1;dp=0;break; //显示数值8
case 9: a=1;b=1;c=1;d=1;e=0;f=1;g=1;dp=0;break; //显示数值9
}
}
void INT0_init() //开启中断,每2000/12 us溢出一次
{ TMOD=0x18;
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
TR0=1;
ET0=1;
EA=1;
}
void start(void) //系统初始显示函数
{
uchar time=100;
char i;
shang=0;xia=0;
enable();
for(i=9;i>=0;i--) //显示数字9-0
{ display(i);
delay(3000);
}
do{display(IapReadByte(address));yichu--;}while((P3_6&&P3_7&&P2_3&&P2_2==1)); //如无按键按下,则显示上一次保存的数值
}
void delay(uint time ) //延时函数
{
unsigned long int j=time*40;
do{
; }while(j--);
}
void disable() //数码管关闭
{
SMG_1=0;
SMG_2=0;
SMG_3=0;
SMG_4=0;
SMG_5=0;
SMG_6=0;
}
void enable() //数码管开启显示
{
SMG_1=1;
SMG_2=1;
SMG_3=1;
SMG_4=1;
SMG_5=1;
SMG_6=1;
}
void INT0time() interrupt 1 //定时器中断0
{ static uchar liangdu;
TH0=(65536-2000)/256;
TL0=(65536-2000)%256;
display(cha);
liangdu++;
if(liangdu<=2*cha) //pwm控制程序,其中数字1亮度最小,占空比最小
P44=0;
else
{
P44=1;
if(liangdu==15)
liangdu=0;
}
yichu++; //每溢出一次,溢出次数加一
}
void IapIdle() //eeprom初始函数
{ IAP_CONTR = 0;
IAP_CMD = 0;
IAP_TRIG = 0;
IAP_ADDRH = 0x80;
IAP_ADDRL = 0;
}
uint IapReadByte(uint addr)
{ uint dat;
IAP_CONTR =ENABLE_IAP;
IAP_CMD = CMD_READ;
IAP_ADDRL = addr;
IAP_ADDRH = addr >> 8;
IAP_TRIG = 0x5a; //因为是IAP单片机,所以触发命令有所不同
IAP_TRIG = 0xa5;
_nop_();
dat = IAP_DATA;
IapIdle();
return dat;
}
void IapProgramByte(uint addr,uchar dat) //eeprom写函数
{IAP_CONTR = ENABLE_IAP;
IAP_CMD = CMD_PROGRAM;
IAP_ADDRL = addr;
IAP_ADDRH = addr >> 8;
IAP_DATA = dat;
IAP_TRIG = 0x5a;
IAP_TRIG = 0xa5;
_nop_();
IapIdle();
}
void IapEraseSector(uint addr) //eeprom扇区擦出函数
{IAP_CONTR = ENABLE_IAP;
IAP_CMD = CMD_ERASE;
IAP_ADDRH=addr>>8;
IAP_ADDRL=addr;
IAP_TRIG = 0x5a;
IAP_TRIG = 0xa5;
_nop_();
IapIdle();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -