|
這是今天花一天時(shí)間寫的,拿出來(lái)給像我一樣的菜鳥參考,希望大家一起提高.
一.原理圖

實(shí)現(xiàn)功能:四個(gè)數(shù)碼管分為兩組,四個(gè)按鍵也對(duì)應(yīng)分為兩組,每組控制對(duì)應(yīng)數(shù)碼管顯示數(shù)據(jù)的加減,數(shù)據(jù)在0--99間循環(huán)顯示,并具有掉電保護(hù)功能,通過(guò)24LC01B保存掉電前的數(shù)據(jù).程序簡(jiǎn)單易讀,是初學(xué)者的福音(因?yàn)槲乙彩遣锁B)!
二.器件介紹
1.概述 SAA1064是Philips公司生產(chǎn)的4位LED驅(qū)動(dòng)器,為雙極型電路,具有I2C接口。該電路是特別為驅(qū)動(dòng)4位帶有小數(shù)點(diǎn)的七段顯示器而設(shè)計(jì)的,通過(guò)多路開關(guān)可對(duì)兩個(gè)2位顯示器進(jìn)行切換顯示。該器件內(nèi)部帶有I2C總線從發(fā)送接收器,可以通過(guò)地址引腳ADR的輸入電平編程為4個(gè)不同的從器件地址。內(nèi)部的模式控制器可以控制LED的各個(gè)位以使其能夠工作于靜態(tài)模式、動(dòng)態(tài)模式、熄滅模式及段測(cè)試模式。 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.功能說(shuō)明 3.1 通訊規(guī)約 主器件CPU通過(guò)I2C總線對(duì)SAA1064進(jìn)行讀或?qū)?,讀/寫方式中I2C總線上的信息傳送格式如圖2所示,圖中:S為啟動(dòng)信號(hào);P為結(jié)束信號(hào);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í)分別對(duì)應(yīng)于4個(gè)不同的從地址(A1A0=00、01、10、11)。在寫方式時(shí),它們對(duì)應(yīng)的從地址字節(jié)值為70H、72H、74H、76H,而在讀方式時(shí),它們對(duì)應(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)過(guò)掉電和加電,而在讀狀態(tài)字節(jié)操作完成以后,該標(biāo)志清0。 3.4 單元地址 用位SC、SB、SA形成1個(gè)指針以確定指令字節(jié)以后的數(shù)據(jù)字節(jié)寫入哪個(gè)寄存器,而其它的數(shù)據(jù)依次寫入后繼單元中,這種特性稱為單元地址增量。單元地址指針?lè)秶鸀?~7。單元地址分配如表1所列。 3.5 控制字節(jié) 控制字節(jié)各位(C0~C6)的含義如下: C0=0 靜態(tài)顯示,數(shù)字位1和2可以連續(xù)顯示; C0=1動(dòng)態(tài)顯示,數(shù)字位1、3和2、4交替顯示; C1=0/1數(shù)字位1、3暗/亮選擇位; C2=0/1數(shù)字位2、4暗/亮選擇位; C3=1 所有段導(dǎo)通以便段測(cè)試,其電流由C4、C5、C6所決定; C4=1 段輸出電流增加3mA; C5=1 段輸出電流增加6mA; C6=1 段輸出電流增加12mA; 3.6 數(shù)據(jù)字節(jié) 數(shù)據(jù)字節(jié)中數(shù)據(jù)為1時(shí)為對(duì)應(yīng)的段導(dǎo)通(亮),數(shù)據(jù)字節(jié)D17~D10、D27~D20、D37~D30、D47~D40分別對(duì)應(yīng)于位1、2、3和4的顯示器,高位對(duì)應(yīng)于輸出端P8或P16,低位對(duì)應(yīng)于輸出端P1或P9,顯示器1~4顯示的數(shù)據(jù)對(duì)應(yīng)于單元地址1~4的內(nèi)容。 3.7 SDA、SCL SDA、SCL分別為總線的數(shù)據(jù)線和時(shí)鐘線。為防止這些引腳上出現(xiàn)過(guò)壓脈沖,應(yīng)接一個(gè)穩(wěn)壓管(5.5V)至,即正常的線電壓不應(yīng)超過(guò)5.5V。正常情況下,數(shù)據(jù)在響應(yīng)位的時(shí)鐘上跳變鎖存。 3.8 上電復(fù)位 上電復(fù)位信號(hào)是在SAA1064芯片的內(nèi)部產(chǎn)生的,該信號(hào)能使內(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在動(dòng)態(tài)顯示方式中交替導(dǎo)通,它們均由內(nèi)部時(shí)鐘的分頻信號(hào)驅(qū)動(dòng)。 在靜態(tài)方式中,MX1總是導(dǎo)通,其輸出由內(nèi)部射極跟隨器組成,可直接驅(qū)動(dòng)2位顯示器的公共極,如果超過(guò)了電路的總功耗,應(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 <pic.h>
__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ù)組存儲(chǔ)顯示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++); } //按鍵檢測(cè) 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é)議
//開始信號(hào)
void start_iic() { SDA=1; SCL=1; nop(); nop(); nop(); nop(); SDA=0; nop(); nop(); SCL=0;//it is ready to send data nop(); } //停止信號(hào) 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<<i)&0x80) { 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)吃過(guò)他的虧,而網(wǎng)上的所謂調(diào)通的程序恰恰在這些地方?jīng)]有注意,這就導(dǎo)致程序不能正常的按設(shè)想運(yùn)行.
由于我也是剛剛在學(xué)PICC,所以如有不對(duì)的地方請(qǐng)大家告之.如有更好的思路也歡迎交流.
|