PIC單片機(jī)實(shí)例二:基于I2C的SAA1064數(shù)碼管顯示
掃描二維碼
隨時(shí)隨地手機(jī)看文章
一.原理圖
實(shí)現(xiàn)功能:四個(gè)數(shù)碼管分為兩組,四個(gè)按鍵也對應(yīng)分為兩組,每組控制對應(yīng)數(shù)碼管顯示數(shù)據(jù)的加減,數(shù)據(jù)在0--99間循環(huán)顯示,并具有掉電保護(hù)功能,通過24LC01B保存掉電前的數(shù)據(jù).程序簡單易讀,是初學(xué)者的福音(因?yàn)槲乙彩遣锁B)!
二.器件介紹
1.概述
SAA1064是Philips公司生產(chǎn)的4位LED驅(qū)動器,為雙極型電路,具有I2C接口。該電路是特別為驅(qū)動4位帶有小數(shù)點(diǎn)的七段顯示器而設(shè)計(jì)的,通過多路開關(guān)可對兩個(gè)2位顯示器進(jìn)行切換顯示。該器件內(nèi)部帶有I2C總線從發(fā)送接收器,可以通過地址引腳ADR的輸入電平編程為4個(gè)不同的從器件地址。內(nèi)部的模式控制器可以控制LED的各個(gè)位以使其能夠工作于靜態(tài)模式、動態(tài)模式、熄滅模式及段測試模式。
2.引腳功能及封裝形式
SAA1064采用24腳DIP和SOT兩種封裝形式,圖1所示為24腳DIP封裝的引腳排列。各主要引腳的功能如下:
ADR(1):地址輸入線;
CEXT(2):內(nèi)部振蕩器電容輸入端,典型值為2.7nF;
P8~P1(3~10):段數(shù)據(jù)輸出口1;
P9~P16(15~22):段數(shù)據(jù)輸出口2;
MX1(11):多路選擇開關(guān)輸出1;
MX2(14):多路選擇開關(guān)輸出2:
VEE(12):地;
VCC(13):電源;
SDA(23):I2C總線串行數(shù)據(jù)線;
SCL(24):I2C總線串行時(shí)鐘線;
3.功能說明
3.1 通訊規(guī)約
主器件CPU通過I2C總線對SAA1064進(jìn)行讀或?qū)?,讀/寫方式中I2C總線上的信息傳送格式如圖2所示,圖中:S為啟動信號;P為結(jié)束信號;A為響應(yīng)位;X為任意值;A1A0由ADR輸入電位確定2位地址位;SC SB SA為單元地址位;C6~C0為控制位;PR為上電復(fù)位標(biāo)志。
3.2 SAA1064的從地址
SAA1064的從地址是由引腳ADR上的輸入電平?jīng)Q定的。ADR引腳在接VEE、3/8VCC、5/8VCC和VCC時(shí)分別對應(yīng)于4個(gè)不同的從地址(A1A0=00、01、10、11)。在寫方式時(shí),它們對應(yīng)的從地址字節(jié)值為70H、72H、74H、76H,而在讀方式時(shí),它們對應(yīng)的從地址字節(jié)值為71H、73H、75H、77H。其他的地址不為該器件所響應(yīng)。
3.3 狀態(tài)字節(jié)
SAA1064的狀態(tài)字節(jié)中只用1位:即上電復(fù)位標(biāo)志位PR,它為邏輯“1”時(shí),表示從上次讀狀態(tài)以后出現(xiàn)過掉電和加電,而在讀狀態(tài)字節(jié)操作完成以后,該標(biāo)志清0。
3.4 單元地址
用位SC、SB、SA形成1個(gè)指針以確定指令字節(jié)以后的數(shù)據(jù)字節(jié)寫入哪個(gè)寄存器,而其它的數(shù)據(jù)依次寫入后繼單元中,這種特性稱為單元地址增量。單元地址指針范圍為0~7。單元地址分配如表1所列。
3.5 控制字節(jié)
控制字節(jié)各位(C0~C6)的含義如下:
C0=0 靜態(tài)顯示,數(shù)字位1和2可以連續(xù)顯示;
C0=1動態(tài)顯示,數(shù)字位1、3和2、4交替顯示;
C1=0/1數(shù)字位1、3暗/亮選擇位;
C2=0/1數(shù)字位2、4暗/亮選擇位;
C3=1 所有段導(dǎo)通以便段測試,其電流由C4、C5、C6所決定;
C4=1 段輸出電流增加3mA;
C5=1 段輸出電流增加6mA;
C6=1 段輸出電流增加12mA;
3.6 數(shù)據(jù)字節(jié)
數(shù)據(jù)字節(jié)中數(shù)據(jù)為1時(shí)為對應(yīng)的段導(dǎo)通(亮),數(shù)據(jù)字節(jié)D17~D10、D27~D20、D37~D30、D47~D40分別對應(yīng)于位1、2、3和4的顯示器,高位對應(yīng)于輸出端P8或P16,低位對應(yīng)于輸出端P1或P9,顯示器1~4顯示的數(shù)據(jù)對應(yīng)于單元地址1~4的內(nèi)容。
3.7 SDA、SCL
SDA、SCL分別為總線的數(shù)據(jù)線和時(shí)鐘線。為防止這些引腳上出現(xiàn)過壓脈沖,應(yīng)接一個(gè)穩(wěn)壓管(5.5V)至,即正常的線電壓不應(yīng)超過5.5V。正常情況下,數(shù)據(jù)在響應(yīng)位的時(shí)鐘上跳變鎖存。
3.8 上電復(fù)位
上電復(fù)位信號是在SAA1064芯片的內(nèi)部產(chǎn)生的,該信號能使內(nèi)部各位清0而顯示全暗,此時(shí)只有掉電標(biāo)志置位。
3.9 外部定時(shí)控制電容
在SAA1064的引腳(2腳)上接一個(gè)定時(shí)電容到地可使內(nèi)部多路轉(zhuǎn)換的振蕩器工作。在靜態(tài)工作方式中,因?yàn)椴恍枰袷幤鞴ぷ?,因此,該引腳可接或浮空。
3.10 段數(shù)據(jù)輸出端
P1~P16是吸收電流可控的段數(shù)據(jù)輸出端,可用相應(yīng)的數(shù)字位控制其導(dǎo)通,并由C4、C5、C6控制位控制其電流的大小。
3.11 多路輸出端
SAA1064的多路輸出端MX1和MX2在動態(tài)顯示方式中交替導(dǎo)通,它們均由內(nèi)部時(shí)鐘的分頻信號驅(qū)動。
在靜態(tài)方式中,MX1總是導(dǎo)通,其輸出由內(nèi)部射極跟隨器組成,可直接驅(qū)動2位顯示器的公共極,如果超過了電路的總功耗,應(yīng)當(dāng)用晶體管把11腳和14腳相連在一起。
三,程序(PICC調(diào)通)
//Use for DN-100 Cotroller
//Date:from 2007.12.7 to
//Author:wujie
//Company:Wuxi Zhouxiang complete set of welding equipment CO.LTD
//Introduce:
//MCU:p16f73
//display IC:SAA1064 addr:0x70
//START
#include
__CONFIG(XT&WDTDIS&BORDIS);
//程序聲明
void initial(void);
void display(char cur_hex,char time_hex);
void button_test(void);
void start_iic();
void stop_iic(void);
void ack_iic();
void nack_iic();
void send_iic(char c);
char receive_iic(void);
//預(yù)定義
#define nop() asm("nop")
#define SDA RC4
#define SCL RC3
unsigned int i,rxbuf;
char cur,time;
//初始化
void initial(void)
{
TRISA=0X3F; //ALL PORTS ARE INPUT
PORTA=0X00;
TRISB=0X03; //RB0,RB1 ARE INPUTS
PORTB=0X00;
TRISC=0XE7; // RC3,RC4, ARE outPUTS
PORTC=0X18; //RC3,RC4 ARE IN HIGH
cur=0;
time=0;
}
//顯示子程序
void display(char cur_hex,char time_hex)
{
char d1buf,d2buf,d3buf,d4buf;
//數(shù)組存儲顯示7段碼
char bit_dis[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0xee,0x3e,0x9c,0x7a,0x9e,0x8e,0x00};
d2buf=bit_dis[cur_hex%10];//CUR的個(gè)位
d1buf=bit_dis[cur_hex%100/10];//CUR的十位
d4buf=bit_dis[time_hex%10];//TIME的個(gè)位
d3buf=bit_dis[time_hex%100/10];//TIME的十位
nop();
start_iic();
nop();
send_iic(0x70);//SAA1064的地址
send_iic(0x00);
send_iic(0x37);//查上面資料
send_iic(d1buf);
send_iic(d2buf);
send_iic(d3buf);
send_iic(d4buf);
nop();
stop_iic();
}
//write 24cl01b subroutine
void w_24cl01b(unsigned char cur_tmp,unsigned char time_tmp)
{
start_iic();
send_iic(0xa0);
send_iic(0x10);
send_iic(cur_tmp);
send_iic(time_tmp);
stop_iic();
for(i=0;i<500;i++);
}
//read 24cl01b subroutine
char r_24cl01b()
{
start_iic();
send_iic(0xa0);
send_iic(0x10);
start_iic();
send_iic(0xa1);
cur=receive_iic();
ack_iic();
time=receive_iic();
nack_iic();
stop_iic();
display(cur,time);
for(i=0;i<10000;i++);
}
//按鍵檢測
void button_test(void)
{
if(RC1==1)
{
for(i=0;i<=2000;i++);//延時(shí) 20mS
if(RC1==1)
{
cur++;
cur=cur%100;//讓CUR<100,因?yàn)橹荒茱@示2位
w_24cl01b(cur,time);
}
}
if(RC2==1)
{
for(i=0;i<=2000;i++);
if(RC2==1)
{
cur--;
if(cur<=0)
w_24cl01b(cur,time);//寫入24LC01B保存
{
cur=cur+100;//讓CUR>0,因?yàn)橹荒茱@示2位
}
}
}
if(RC5==1)
{
for(i=0;i<=2000;i++);
if(RC5==1)
{
time++;
time=time%100;//讓TIME<100,因?yàn)橹荒茱@示2位
w_24cl01b(cur,time);
}
}
if(RC6==1)
{
for(i=0;i<=2000;i++);
if(RC6==1)
{
time--;
if(time<=0)
{
time=time+100;//讓TIME>0,因?yàn)橹荒茱@示2位
}
w_24cl01b(cur,time);
}
}
display(cur,time);
for(i=0;i<10000;i++);
}
//I2C協(xié)議
//開始信號
void start_iic()
{
SDA=1;
SCL=1;
nop();
nop();
nop();
nop();
SDA=0;
nop();
nop();
SCL=0;//it is ready to send data
nop();
}
//停止信號
void stop_iic(void)
{
SDA=0;
SCL=1;
nop();
nop();
nop();
nop();
SDA=1;
nop();
}
//發(fā)送應(yīng)答
void ack_iic()
{
SDA=0;
nop();
nop();
SCL=1;
nop();
nop();
nop();
nop();
SCL=0;
nop();
nop();
}
//發(fā)送一個(gè)字節(jié)
void send_iic(char c)
{
for(i=0;i<8;i++)
{
SCL=0;
if((c<{
SDA=1;
}
else
{
SDA=0;
}
SCL=1;
nop();
nop();
nop();
nop();
SCL=0;
nop();
}
SDA=1;
TRISC4=1;//置輸入狀態(tài),等待應(yīng)答
SCL=1;//認(rèn)為應(yīng)答一直有
nop();
nop();
nop();
nop();
SCL=0;
nop();
TRISC4=0;//恢復(fù)為輸出
}
//接受一個(gè)字節(jié)
char receive_iic(void)
{
SDA=1;
rxbuf=0;
TRISC4=1;//注意:一定要置輸入
for(i=0;i<8;i++)
{
SCL=0;
nop();
nop();
nop();
nop();
SCL=1;
nop();
rxbuf=rxbuf<<1;
if(SDA==1)
{
rxbuf=rxbuf+1;
}
}
nop();
nop();
SCL=0;
nop();
TRISC4=0;//恢復(fù)為輸出
return (rxbuf);
}
//主程序
void main(void)
{
initial();
r_24cl01b();//讀出掉電前保存在24LC01B內(nèi)的數(shù)據(jù)
while(1)
{
button_test();
}
}
四.總結(jié)
上面程序中紫色標(biāo)注的地方一定要注意,我曾經(jīng)吃過他的虧,而網(wǎng)上的所謂調(diào)通的程序恰恰在這些地方?jīng)]有注意,這就導(dǎo)致程序不能正常的按設(shè)想運(yùn)行.