十年專注單片機方案開發的方案公司英銳恩,分享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;
}
}
(文源網絡,侵刪)