實(shí)驗(yàn)4 IIC通訊與EEPROM接口
1. 用C語言編程,利用定時(shí)器產(chǎn)生一個(gè)0~99秒變化的秒表,并且顯示在數(shù)碼管上,每過一秒將這個(gè)變化寫入實(shí)驗(yàn)板上AT24C02,當(dāng)關(guān)閉實(shí)驗(yàn)板電源,并再次打開實(shí)驗(yàn)板電源時(shí),單片機(jī)從AT24C02中將原來寫入的數(shù)據(jù)讀出來,接著繼續(xù)變化在數(shù)碼管上。
#include
#define uchar unsigned char
#define uint unsigned int
//=========全局變量區(qū)============================================
bit write=0; //寫24C02的標(biāo)志;
sbit sda=P2^0;
sbit scl=P2^1;
sbit high=P2^4;
sbit mid=P2^3;
sbit low=P2^2;
uint code NumTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//數(shù)字的編碼
uchar sec,tcnt;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71
};
//=========全局變量區(qū)結(jié)束============================================
/**
步驟
接線方式:
1、P0接數(shù)碼管J12,實(shí)現(xiàn)段選
2、譯碼器和數(shù)碼管位選輸入短接,J15+J16
3、本實(shí)驗(yàn)使用的晶振是12.000
**/
//========函數(shù)區(qū)============================================
void delay()
{;;}
void delay1ms(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
/**
延時(shí)
**/
void delay_1ms(uint x){
uint i=x;
uint j;
for(;i>0;--i){
for(j=110;j>0;--j);
}
}
/**
在數(shù)碼管上顯示對應(yīng)的值
**/
void display(uchar Num)
{
P0=NumTable[Num];
delay_1ms(1);
P0=0; //送完段選信號后,進(jìn)行消影的處理
}
/**
控制數(shù)碼管顯示后3位,并分解計(jì)數(shù)值
**/
void DisplayNumByOrder(uint Value){
low=0; mid=0; high=0; display(0);
low=1; mid=0; high=0; display(0);
low=0; mid=1; high=0; display(0);
low=1; mid=1; high=0; display(0);
low=0; mid=0; high=1; display(0);
low=1; mid=0; high=1; display(Value%1000/100);
low=0; mid=1; high=1; display(Value%100/10);
low=1; mid=1; high=1; display(Value%10);
}
void start() //開始信號
{
sda=1;
delay();
scl=1;
delay();
sda=0;
delay();
}
void stop() //停止
{
sda=0;
delay();
scl=1;
delay();
sda=1;
delay();
}
void respons() //應(yīng)答
{
uchar i;
scl=1;
delay();
while((sda==1)&&(i<250))i++;
scl=0;
delay();
}
void write_byte(uchar date)
{
uchar i,temp;
temp=date;
for(i=0;i<8;i++)
{
temp=temp<<1;
scl=0;
delay();
sda=CY;
delay();
scl=1;
delay();
}
scl=0;
delay();
sda=1;
delay();
}
uchar read_byte()
{
uchar i,k;
scl=0;
delay();
sda=1;
delay();
for(i=0;i<8;i++)
{
scl=1;
delay();
k=(k<<1)|sda;
scl=0;
delay();
}
return k;
}
void write_address(uchar address,uchar date)
{
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
write_byte(date);
respons();
stop();
}
uchar read_address(uchar address)
{
uchar date;
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
start();
write_byte(0xa1);
respons();
date=read_byte();
stop();
return date;
}
void init()
{
sda=1;
delay();
scl=1;
delay();
sec=read_address(2); //讀出保存的數(shù)據(jù)賦于sec
if(sec>100) //防止首次讀取出錯誤數(shù)據(jù)
sec=0;
TMOD=0x01; //定時(shí)器工作在方式1
ET0=1;
EA=1;
TH0=(65536-50000)/256;//對TH0 TL0賦值
TL0=(65536-50000)%256;//使定時(shí)器0.05秒中斷一次
TR0=1; //開始計(jì)時(shí)
}
void main()
{
init();//初始化
while(1)
{
DisplayNumByOrder(sec);
if(write==1) //判斷計(jì)時(shí)器是否計(jì)時(shí)一秒
{
write=0; //清零
write_address(2,sec); //在24c02的地址2中寫入數(shù)據(jù)sec
}
}
}
//========函數(shù)區(qū)結(jié)束============================================
//========中斷函數(shù)區(qū)============================================
void t0() interrupt 1//定時(shí)中斷服務(wù)函數(shù)
{
TH0=(65536-50000)/256;//對TH0 TL0賦值
TL0=(65536-50000)%256;//重裝計(jì)數(shù)初值
tcnt++; //每過50ms tcnt加一
if(tcnt==20) //計(jì)滿20次(1秒)時(shí)
{
tcnt=0; //重新再計(jì)
sec++;
write=1; //1秒寫一次24C02
if(sec==100)//定時(shí)100秒,再從零開始計(jì)時(shí)
sec=0;
}
}
//========中斷函數(shù)區(qū)結(jié)束============================================