📄 temp.c
字号:
#include "reg51.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
sbit SDA=P3^0;
sbit SCL=P3^1;
sbit Ok_Key=P0^7;
sbit Up_Key=P2^7;
sbit Down_Key=P1^7;
bit Key;
bit Flash;
bit Write;
uchar b;
uchar s;
uchar g;
uint Tcount;
uint TimeCount;
uint TimeSet;
uchar KeyCount;
//unsigned code tab[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
//上面注释的是标准的数码管字形码,由于P0.0、P1.0和P2.0是键盘端口
//所以,就将这些字形码的最高位置1,这样不会对键盘扫描产生负面影响
unsigned code tab[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};
//函数列表
void delay(void);
void Delay(int time);
void delay1(void);
void write_8bit(unsigned char ch);
void ACK(void);
uchar ReadIIC_24C01(unsigned char address);
void WriteIIC_24C01(unsigned char address,unsigned char ddata);
void init(void);
void DataDivision(uint Ddata);
void LedFlash(uchar No);
void KBScan(void);
void Display(void);
void delays(void);
//键盘中断服务程序
//首先INT0触发,进入中断服务程序。然后检测是哪个键按下
//如果是Ok_Key按下,检测它处于哪个状态(分为四个状态:修改百位、十位、个位和确认),然后显示对应的要修改信息
//如果下一个外部中断触发,同样确认是哪个键,再根据Ok_Key键所处的状态,对的位进行增加、减少修改,同时也可以进行
//进行数据确认并写入EEPROM,这样,时间设定就完成了,接下来单片机进行倒计时
void intersvr0(void) interrupt 0 using 1
{
ET0=0;
TR0=0;
if(!Ok_Key) //中断触发后,确认是哪一个键按下
{
if(KeyCount==0)//第一次按Ok_Key键,进入第一个状态,修改百位
{
KeyCount++;
P1=0x80;
P2=0x80;
P0=tab[b];
}
else if(KeyCount==1)//第二次按Ok_Key键,进入第二个状态,修改十位
{
KeyCount++;
P0=tab[b];
P2=tab[s];
P1=0x80;
}
else if(KeyCount==2)//第三次按Ok_Key键,进入第三个状态,修改个位
{
KeyCount++;
P0=tab[b];
P2=tab[s];
P1=tab[g];
}
else //确认,并把数据写入EEPROM
{
KeyCount=0;
Write=1;
}
}
else if(!Up_Key) //中断触发后,确认是哪一个键按下
{
if(KeyCount==1) //Ok_Key键位于第一个状态,对百位数据进行调整
{
if(b==9)
b=0;
else
b=b+1;
P1=0x80;
P2=0x80;
P0=tab[b];
}
else if(KeyCount==2) //Ok_Key键位于第二个状态,对百位数据进行调整
{
if(s==9)
s=0;
else
s=s+1;
P1=0x80;
P2=tab[s];
P0=tab[b];
}
else if(KeyCount==3) //Ok_Key键位于第三个状态,对百位数据进行调整
{
if(g==9)
g=0;
else
g=g+1;
P1=tab[g];
P2=tab[s];
P0=tab[b];
}
else
return;
}
else if(!Down_Key) //中断触发后,确认是哪一个键按下
{
if(KeyCount==1) //Ok_Key键位于第一个状态,对百位数据进行调整
{
if(b==0)
b=9;
else
b=b-1;
P1=0x80;
P2=0x80;
P0=tab[b];
}
else if(KeyCount==2) //Ok_Key键位于第二个状态,对百位数据进行调整
{
if(s==0)
s=9;
else
s=s-1;
P1=0x80;
P2=tab[s];
P0=tab[b];
}
else if(KeyCount==3)//Ok_Key键位于第三个状态,对百位数据进行调整
{
if(g==0)
g=9;
else
g=g-1;
P1=tab[g];
P2=tab[s];
P0=tab[b];
}
else
return;
}
}
/////////////////
//12M晶振最大延时为65.536ms,这里延时为50ms
void time0(void) interrupt 1 using 1
{
TH0=(65536-50000)/256; //设置定时器高8位初值
TL0=(65536-50000)%256; //设置定时器低8位初值
if(Tcount==20) //通过调整数字可以确定计数的最小单位
{ //例如,如果为20,表示每1s数码管数据改变一次,如果为1200,则是1m改变一次
Tcount=0;
TimeCount=TimeCount-1; //用来长时间定时
}
b=TimeCount/100; //将当前数据的百、十、个位分离
s=(TimeCount/10)%10;
g=TimeCount%10;
P0=tab[b]; //分离后的数据显示到数码管
P2=tab[s];
P1=tab[g];
Tcount=Tcount+1;
}
//短延时函数
void delay(void)
{
unsigned int i=1200;
while(i--);
}
//这里,延时30可以使数码管闪烁
void Delay(int time)
{
while(time--)
delay();
}
/*----------------------------------------------------------------------------
调用方式:write_8bit(unsigned char ch) ﹫2001/03/23
函数说明:内函数,私有,用户不直接调用。
-------------------------------------------------------------------------------
*/
void write_8bit(unsigned char ch)
{
unsigned char i=8;
SCL=0;
_nop_();_nop_();_nop_();_nop_();_nop_();
while (i--)
{
SDA=(bit)(ch&0x80);
_nop_();_nop_();_nop_();_nop_();_nop_();
ch<<=1;
SCL=1;
_nop_();_nop_();_nop_();_nop_();_nop_();
SCL=0;
_nop_();_nop_();_nop_();_nop_();_nop_();
}
_nop_();_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();_nop_();_nop_();_nop_();
}
/*------------------------------------------------------------------------------
调用方式:void ACK(void) ﹫2001/03/23
函数说明:内函数,私有,用户不直接调用。
-------------------------------------------------------------------------------
*/
void ACK(void)
{
unsigned char time_1;
SDA=1;
SCL=0;
_nop_();_nop_();_nop_();_nop_();_nop_();
SCL=1;
time_1=5;
while(SDA) {if (!time_1) break;} //ACK
SCL=0;
_nop_();_nop_();_nop_();_nop_();_nop_();
}
unsigned char ReadIIC_24C01(unsigned char address)
{
unsigned char ddata=0;
unsigned char i=8;
SCL=1;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); //Tsu:STA
SDA=0;
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Thd:STA
SCL=0; //START
write_8bit( (address<<1) | 0x01); //写页地址和操作方式
ACK();
while (i--)
{
SDA=1;
ddata<<=1;
SCL=0;_nop_();_nop_();_nop_();_nop_();_nop_();SCL=1;
if (SDA) ddata|=0x01;
}
SCL=0;_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
SDA=0;_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
SDA=1; //STOP
delay();
return ddata;
}
void WriteIIC_24C01(unsigned char address,unsigned char ddata)
{
SCL=1;
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); //Tsu:STA
SDA=0;
_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); //Thd:STA
SCL=0; //START
write_8bit( (address<<1) & 0xfe); //写页地址和操作方式,对于24C32-24C256,page不起作用
ACK();
write_8bit(ddata); //发送数据
ACK();
SDA=0;
_nop_();SCL=1;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
SDA=1; //STOP
delay();
}
//芯片初始化
void init(void)
{
uchar i=10;
Tcount=0; //用来产生长延时的标志
KeyCount=0; //Ok_Key键所处状态标志
Write=0; //修改后的数据是否写入EEPROM标志
b=ReadIIC_24C01(0x00); //从EEPROM里读取百位数据
s=ReadIIC_24C01(0x01); //从EEPROM里读取十位数据
g=ReadIIC_24C01(0x02); //从EEPROM里读取个位数据
TimeSet=b*100+s*10+g; //根据从EEPROM里读取的数据,计算出预设的时间初值
TimeCount=TimeSet; //所要定时的标志
while(i--) //开机后,将原来所存初始值取出,闪烁10次
{
P0=tab[b];
P2=tab[s];
P1=tab[g];
Delay(50);
P0=0x80;
P2=0x80;
P1=0x80;
Delay(50);
}
EA=1; //开全局中断
ET0=1;//开定时器中断
TR0=1;//开定时器0中断
EX0=1;//开外部中断
IT0=1;//开INTO中断
TH0=(65536-50000)/256; //设置定时器高8位初值
TL0=(65536-50000)%256; //设置定时器低8位初值
}
main()
{
init();
while(1)
{
if(Write) //如果向EEPROM写标志使能,将调整后的数据写入EEPROM内
{
WriteIIC_24C01(0x00,b);
WriteIIC_24C01(0x01,s);
WriteIIC_24C01(0x02,g);
TimeSet=b*100+s*10+g; //根据设定值来计算出设定值
TimeCount=TimeSet; //将设定值赋给定时标志
ET0=1; //定时器中断使能
TR0=1;
TH0=(65536-50000)/256; //设置定时器高8位初值
TL0=(65536-50000)%256; //设置定时器低8位初值*/
Write=!Write;
}
if(TimeCount==0)
{
TimeCount=TimeSet; //如果定时完成,重新开始
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -