十年专注单片机方案开发的方案公司英锐恩,分享F72+24C01+LED+按键。英锐恩现提供服务产品涉及主控芯片:8位单片机、16位单片机、32位单片机及各类运算放大器等。
#include
#include
#define uchar unsigned char
#define uint unsigned int
#define bitset(var,bitno)((var)|=1<<(bitno))
#define bitclr(var,bitno)((var)&=~(1<<(bitno)))
static volatile unsigned char acc @ 0x20;
static volatile bit acc0 @ (unsigned)&acc*8+0;
static volatile bit acc7 @ (unsigned)&acc*8+7;
static volatile unsigned char err @ 0x21;
static volatile bit err0 @ (unsigned)&err*8+0;
static volatile bit err3 @ (unsigned)&err*8+3;
static volatile bit err6 @ (unsigned)&err*8+6;
static volatile bit err7 @ (unsigned)&err*8+7;
#define SCL RA1 //1 ;24C01-6
#define SDA RA2 //2 ;24C01-5
#define SCLIO TRISA1 //1
#define SDAIO TRISA2 //2
#define SLAW 0x0A0//寻址字节写
#define SLAR 0x0A1//寻址字节读
#define KS1 RA3
#define KS2 RA4
#define KS3 RA5
#define Ksec RC0
#define Kmin RC1
const unsigned char table[11]={ 0x0C0, 0x0F9, 0x0A4,0x0B0, 0x99, 0x92,0x82, 0x0F8,0x80,0x90,0x0ff};
unsigned char y,Tsmh, sec, min,hour ;
uchar BCD[4];//数据送LED的数据 暂存区
uchar Reeprom[5];
/////中断//////////////////
void interrupt adint( )
{ uchar x,y,z;
TMR0=39;
OPTION =0x87;// B'10000111' //取消B口上拉电阻 1:256 预分频器分配给定时器0,分频比1:64
//ADIF=0;//清/AD中断标志位
T0IF=0;// ;清定时器0溢出中断标志位
x++;// 记 数器
if(x==18)
{
x=0;
sec--; //秒-1
y++; //秒 记 数器
if(y==60)
{
y=0;
min--;//分-1
z++; // 记 数器
if(z==60)
{
z=0;
hour--; //时-1
}
}
}
}
//延时子程序
void delay()
{
unsigned int i=300;
while(i--); //for(i=300;0<i;>}
//十六进制转十进制程序
void H_BCD (uchar x,uchar i)
{
BCD [1]=x%10;
BCD [0]=x/10;
BCD [3]=i%10;
BCD [2]=i/10; // BCD [0]=x/100;
}
void display()//显示程序
{
unsigned char b,c;
b=0x10;
for(c=0;c<4;c++)
{
PORTB=table[BCD[c]] ;
PORTC=(PORTC&8)|b;
CLRWDT();
delay();
b=b<<1;
} PORTB=err;
PORTC=(PORTC&8)|4;
CLRWDT();
delay();
PORTC=PORTC&8;
}
//系统 各I/O初始化子程序
void initial ()
{ TRISB=0;
TRISC=3;
ADCON1=7;;//设置RA为IO口
TRISA=0x0ff;
OPTION=135;//取消B口上拉电阻 B'10000111'; 1:256 B'10000101'1:64
// 预分频器分配给定时器0,
T0IF= 0; // 清溢出中断标志位
T0IE=1; //定时器0溢出中断允许
// GIE=1; //总中断允许
TMR0=39;
}
//////////////24C01/////////////////
//--------应答位检查---------
void Cack()
{ SCL=1;
SDAIO=1;//输入1
SCLIO=0;
err7=SDA;//c=1错误ERR
SCL=0;
}
///--------发送非应答位----------
void Mnack()
{
SDA=1;
SCLIO=0;
SDAIO=0;//输出
SCL=1;
NOP();
NOP();
SCL=0;
SDA=0;
}
//-------发送应答位---------------
void Mack()
{
SDA=0;
SCLIO=0;
SDAIO=0;//输出
SCL=1;
NOP();
NOP();
SCL=0;
SDA=1;
}
//--------停止IC总线---------------
void Stop()
{
SDA=0;
SCLIO=0;
SDAIO=0;//输出
SCL=1;
NOP();
NOP();
SDA=1;
NOP();
NOP();
}
//--------;启动IC总线-------------
void Sta()
{
SDAIO=0;//输出
SCLIO=0;
SDA=1;
SCL=1;
NOP();
NOP();
SDA=0;
NOP();
NOP();
SCL=0;
}
//--------写一字节------------------------
void Wrbyt(uchar x)
{
uchar i;
acc=x;
SCLIO=0;
SDAIO=0;
for(i=8;i>0;i--)
{
SDA=acc7;
SCL=1;
NOP();
NOP();
SCL=0;
SDA=0;
acc=acc<<1;
}
}
//---------读一字节-----------------
uchar Rdbyt( )
{
uchar i;
SCLIO=0;
SDAIO=1;//;输入
for(i=8;i>0;i--)
{
acc=acc<<1;//接收数据左移寄存器
SCL=1;
acc0=SDA;
SCL=0;
NOP();
}
return(acc);
}
////---------读n个数据----------------
void Rdnbyt (uchar SLARtemp ,uchar Repromn,uchar temp2) //Repromn传送数据个数
{
uchar i;
i= temp2;
do{
Sta(); //启动IC总线-//
Wrbyt(SLARtemp); //写一字节
Cack(); //应答位检查-
} while(err7==1);
while(Repromn--)
{
Reeprom[i]=Rdbyt(); //读一字节
i++;
Mack(); //发送应答位
}
Mnack(); // 发送非应答位
Stop(); //停止IC总线
}
//---------写n个数据---------------
void Wrnbyt(uchar SLAwtemp , uchar Wepromn,uchar temp1)
{ uchar i;
i= temp1;
err7=1;
while(Wepromn--)
{
if(err7==1) //c=1E0,ERR
{ i=temp1;
Sta(); //启动IC总线
Wrbyt(SLAwtemp); //写一字节
Cack(); //应答位检查-
}
Wrbyt( Reeprom[i]);// Reeprom[t]);//写一字节
i++;
Cack();//应答位检查
}
Stop(); //停止IC总线
}
//////////按键扫描/////////////////////////////////////////////////
void Key()
{
uchar a,b,i,c,d;
if( KS3==0)
{ a=20;
while(a--) display();
if(56!=(PORTA&56))
{
while( KS3==0) display(); di();
if (Ksec ){b=1;i=3;c=1;}//是秒???
else {b=3;i=5;c=3;}//
d=0;
while (b<i&&d<20)> {
uchar z,x;
for(z=50;z>0&&b<i;z--)> { z--;
H_BCD (Reeprom[c],Reeprom[c+1] ); //十六进制转十进制程序
display();
a=PORTA&56 ;
switch(a)
{
case 48 : if(Reeprom[b]!=99) //110 ks1=0
Reeprom[b]++;
for(x=10;x>0&&56!=(PORTA&56);x--)
display();d=0; break;
case 40 : if(Reeprom[b]!=0) //101 ks2=0
Reeprom[b]--;
for(x=10;x>0&&56!=(PORTA&56);x--)
display(); d=0; break;
case 24 : b++; while( KS3==0) display();d=0; break; //011 ks3=0
}
}
if (b<i)
{
for(z=50; z>0&&56==(PORTA&56);z--)//被调整数闪烁程序
{
if (b==1||b==3) { BCD[0]=10; BCD[1]=10;}
else { BCD[2]=10; BCD[3]=10;}
display( );
//z--;
} d++;
}
}
while( KS3==0)display( );
Wrnbyt( SLAW ,5,0); //写2个数据
Tsmh=0;
err3=1; //开机结束
}
}
}
void main()
{
initial (); //系统 各I/O初始化子程序
Wrnbyt ( SLAW ,1,0); //写1个数据=0
Rdnbyt ( SLAR ,4,1); //寻址字节读#0A1
sec= Reeprom[1];
min= Reeprom[3];
err3=0;
bitclr( err,0);
Tsmh=1;
while(1)
{
while (Tsmh)
{ ei();
if(err3==0){ if (Ksec ){H_BCD (sec,Reeprom[2]);Tsmh=sec;}//秒
else {H_BCD (min,Reeprom[4]);Tsmh=min;}//分
RC3=0; bitclr( err,1); bitset( err,2);
} //关机
else { if (Ksec ){H_BCD (Reeprom[1],sec);Tsmh=sec;}//秒
else {H_BCD (Reeprom[3],min);Tsmh=min;}//分
RC3=1; bitset( err,1); bitclr( err,2);
} //开机
display(); //显示程序
Key(); //按键扫描
if(err6!=Ksec){Tsmh=0;err6=Ksec; err3=1;} //判断是否转换//开机结束
}
if(err3==0) {err3=1;sec=Reeprom[2];min=Reeprom[4];} //送开机 数据
else {err3=0;sec=Reeprom[1];min=Reeprom[3];} //送关机 数据
if (Ksec ) Tsmh=sec;
else Tsmh=min;
}
}
(文源网络,侵删)