PIC單片機(jī)C語言程序設(shè)計(15)
b. 主函數(shù)main( ) 調(diào)用delay(M) 時, 其M 值分別是45000(1 秒)、95000(2 秒) 和145000(3 秒)。
c. LED 燈點(diǎn)亮?xí)r的無限循環(huán),由while 語句完成。
d. 上述程序都以LED 的各功能函數(shù)lightl();light2( );light3( ) 完成。程序運(yùn)行時,由主函數(shù)main( ) 調(diào)用各LED 的功能函數(shù)和延時函數(shù),此方法是編輯復(fù)雜C 程序所必備的。
3. PIC 單片機(jī)端口的位定義
PIC 單片機(jī)是一種系列產(chǎn)品, 其端口數(shù)和端口的位與具體型號有關(guān)。如PIC16F877 的端口有PORTA ~ PORTE, 端口的位不都是8位, 其PORTA 口只有6 位(RAO ~ RA5),PORTAB、BORTC 和PORTD 是8 位, 分別為RB0 ~ RB7、RC0 ~ RC7、RD0 ~ RD7。在編輯C 程序時,要訪問上述端口的某個位,必須先把這一位的地址確定下來, 這可通過@add(address) 結(jié)構(gòu)和bit 關(guān)鍵字來實現(xiàn),其中@是地址標(biāo)識符、add(address) 是絕對地址。利用上述地址符,可對PIC 單片機(jī)端口的位進(jìn)行定義,爾后便可隨意對端口的位進(jìn)行訪問。下面是對PIC16F84A 的PORTB 口進(jìn)行位定義的語句:
# dafine PORTBIT ( add , bit ) ( ( unsigned )
?。╝dd)*8+(bit))
Satic bit PORTB_0@PORTBIT(PORTB,0);//定義PORTB 的0 位
Satic bit PORTB_1@PORTBIT(PORTB,1)//定義PORTB 的1 位
……
Static bit PORTB_7@PORTBIT(PORTB,7);//定義PORTB 的7 位
其中“”和”*”符號,在C 語言中是作為按位運(yùn)算符用的,而8 是指8 位。在編輯PIC 單片機(jī)C 程序時,一旦某個端口,如PORTB,定義后, 其對應(yīng)位(bit) 還可寫成RBO、RB1、RB2、RB3…RB7, 以使程序代碼簡化。
有關(guān)端口位定義后的應(yīng)用,還可參看《單片機(jī)C 語言程序設(shè)計(6)》一文中的程序pic06.c。
4. LED 數(shù)碼顯示函數(shù)的應(yīng)用
下面以倒計數(shù)、倒計時C 程序?qū)嵗?說明LED 數(shù)碼顯示函數(shù)display(x) 的應(yīng)用。
?。?)硬件電路利用PIC16F84A 的4 位LED 數(shù)碼顯示電路( 參見《單片機(jī)C 語言程序設(shè)計(4)》一文中的圖3、圖4) 制作2 位數(shù)碼管(另兩位不用)的99 ~ 0 倒計數(shù)、倒計時顯示。倒計數(shù)以秒為單位,倒計時以分為單位,只要有顯示函數(shù)display(),其計數(shù)、計時程序的格式相同。
?。?) 99 ~ 0(以分鐘計)的C 源程序清單如下,程序名為pic13.c。
#includepic.h> // 頭文件
# define PORTAIT ( add , bit ) ( ( unsigned )
?。╝dd)*8+(bit))
static bit PORT _ 2@ PORTAIT ( PORTA , 2 ) ;
//PORTA 口位定義
static bit PORT_3 @PORTAIT(PORTA,3);
static bit PORT_4 @PORTAIT(PORTA,4);
unsigned int x=0; // 無符號的整形變量
void delay(unsigned long int k )
// 延時函數(shù)開始
{
unsigned long int i; // 說明語句
for(i=0;i=k;i++) //for 執(zhí)行語句
continue; // 繼續(xù)循環(huán)
}
void display(unsigned int x)
// 數(shù)碼管LED 顯示函數(shù)
{
unsigned int d=5700,unit_bit,ten_bit;
// 無符號整型變量D,個位、十位
unsigned char SEG7[10]={0xc0,0xf9,0xa4,
//0 ~ 9 的7 段碼數(shù)組
0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unit_bit=x%10; //picc 可識別個位數(shù)
ten_bit=x/10%10; //picc 可識別十位數(shù)
while(d>0) //while 語句開始
{
PORTA=0x1F;
//PORTA 口的低位輸出高電平
PORTB=SEG7[unit_bit];
// 個位字段碼數(shù)組送B 口
RA3=0; //RA3 賦值0,LED 個位顯示
delay(200); // 延時以便觀察
RA3=1; //RA3 賦值1,LED 個位數(shù)滅
delay(2); // 短延時
PORTB=SEG7[ten_bit];
// 十位字段碼數(shù)組送B 口
RA2=0; //RA2 賦值0,LED 十位數(shù)顯示
delay(200); // 延時以使觀察
RA2=1; //RA2 賦值1,LED 十位數(shù)滅
delay(2); // 短延時
d--; //d 自減量
}
}
void main( ) // 主函數(shù)開始
{
TRISB=0x00; //B 口全為輸出
TRISA=0x10; //A 口低4 位為輸出
PORTB=0x40; // 給B 口低位輸出0
INTCON=0x00; // 關(guān)閉所有中斷
PORTA=0x10; //A 口低位輸出0
x=99; // 給整形變量x 賦值99
while(RA4) // 顯示起動信號
{; //RA4 為0,計時開始
}
while(1) // while 循環(huán)語句開始
{
display(x); // 調(diào)用顯示函數(shù)
x--; //x 自減
if(x==-1) // 若x 自減到-1
x=99; // 給x 賦值99
}
}
說明:a. 對上述的C 源程序,只需將顯示函數(shù)display(x) 中的無符號整型變量d(unsignedint d) 從5700 改為95,即可變成以秒為單位的99 ~ 0 倒計數(shù)程序,因為d 值決定了數(shù)碼管顯示的個位時間 ( 具有唯一性)。
b. 若要使用上述程序, 且對計時( 分或秒)的精度有嚴(yán)格要求時,可對整型變量d 值(57000)以標(biāo)準(zhǔn)時鐘為準(zhǔn)進(jìn)行微調(diào),以實現(xiàn)高精度的分或秒定時。
c. 上述所有PIC 單片機(jī)的C 源程序,都是可執(zhí)行的, 初學(xué)者可放心使用。
5. 關(guān)于PIC 單片機(jī)c 語言程序SIM 軟件仿真的問題
在《單片機(jī)C 語言程序設(shè)計(11)》、《單片機(jī)C 語言程序設(shè)計(12)》中,詳細(xì)介紹了C 程序的SIM 軟件仿真過程。軟件仿真對初學(xué)者編輯PIC 單片機(jī)C 語言程序十分有用, 利用它不僅可以觀察到程序運(yùn)行過程,而且可以發(fā)現(xiàn)程序中的問題,即使是已掌握了PIC 編程技術(shù)的專業(yè)人員,也常通過SIM 軟件仿真來找出程序中的問題。
結(jié)束語
上面介紹的延時函數(shù)的三種表達(dá)式、電路功能相同形式不同的四種C 程序、端口的位定義、LED 數(shù)碼顯示函數(shù)和C 語言程序SIM 軟件仿真問題等內(nèi)容,均是初學(xué)PIC 單片機(jī)用C 語言編輯源程序的基本知識,大家要理解其內(nèi)容,最好能熟記和背誦。在此基礎(chǔ)上,還要自己獨(dú)立想一些簡單電路功能,用PIC 單片機(jī)C 語言完成(一定是編譯成功可執(zhí)行的程序)。之后,即可進(jìn)一步學(xué)習(xí)C 語言中的運(yùn)算符、結(jié)構(gòu)、聯(lián)合、A/D 轉(zhuǎn)換、串行通信等內(nèi)容。學(xué)習(xí)時,仍應(yīng)以編輯可執(zhí)行的實用程序為目標(biāo)。
評論