解:用P1端口的6個引腳控制交通燈,高電平燈亮,低電平燈滅。
代碼
#include <at89x52.h>
//sbit用來定義壹個符號位地址,方便編程,提高可讀性,和可移植性
sbit SNRed =P1^0; //南北方向紅燈
sbit SNYellow =P1^1; //南北方向黃燈
sbit SNGreen =P1^2; //南北方向綠燈
sbit EWRed =P1^3; //東西方向紅燈
sbit EWYellow =P1^4; //東西方向黃燈
sbit EWGreen =P1^5; //東西方向綠燈
/* 用軟件產生延時壹個單位時間 */
void Delay1Unit( void )
{
unsigned int i, j;
for( i=0; i<1000; i++ )
for( j<0; j<1000; j++ ); //通過實測,調整j循環次數,產生1ms延時
//還可以通過生成匯編程序來計算指令周期數,結合晶體頻率來調整j循環次數,接近1ms
}
/* 延時n個單位時間 */
void Delay( unsigned int n ){ for( ; n!=0; n-- ) Delay1Unit(); }
void main( void )
{
while( 1 )
{
SNRed=0; SNYellow=0; SNGreen=1; EWRed=1; EWYellow=0; EWGreen=0; Delay( 60 );
SNRed=0; SNYellow=1; SNGreen=0; EWRed=1; EWYellow=0; EWGreen=0; Delay( 10 );
SNRed=1; SNYellow=0; SNGreen=0; EWRed=0; EWYellow=0; EWGreen=1; Delay( 60 );
SNRed=1; SNYellow=0; SNGreen=0; EWRed=0; EWYellow=1; EWGreen=0; Delay( 10 );
}
}
第四節:數碼管驅動
顯示“12345678”
P1端口接8聯***陰數碼管SLED8的段極:P1.7接段h,…,P1.0接段a
P2端口接8聯***陰數碼管SLED8的段極:P2.7接左邊的***陰極,…,P2.0接右邊的***陰極
方案說明:晶振頻率fosc=12MHz,數碼管采用動態刷新方式顯示,在1ms定時斷服務程序中實現
代碼
#include <at89x92.h>
unsigned char DisBuf[8]; //全局顯示緩沖區,DisBuf[0]對應右SLED,DisBuf[7]對應左SLED,
void DisplayBrush( void )
{ code unsigned char cathode[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //陰極控制碼
Code unsigned char Seg7Code[16]= //用十六進數作為數組下標,可直接取得對應的七段編碼字節
{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
static unsigned char i=0; // (0≤i≤7) 循環刷新顯示,由於是靜態變量,此賦值只做壹次。
P2 = 0xff; //顯示消隱,以免下壹段碼值顯示在前壹支SLED
P1 = Seg7Code[ DisBuf[i] ]; //從顯示緩沖區取出原始數據,查表變為七段碼後送出顯示
P2 = cathode[ i ]; //將對應陰極置低,顯示
if( ++i >= 8 ) i=0; //指向下壹個數碼管和相應數據
}
void Timer0IntRoute( void ) interrupt 1
{
TL0 = -1000; //由於TL0只有8bits,所以將(-1000)低8位賦給TL0
TH0 = (-1000)>>8; //取(-1000)的高8位賦給TH0,重新定時1ms
DisplayBrush();
}
void Timer0Init( void )
{ TMOD=(TMOD & 0xf0) | 0x01; //初始化,定時器T0,工作方式1
TL0 = -1000; //定時1ms
TH0 = (-1000)>>8;
TR0 = 1; //允許T0開始計數
ET0 = 1; //允許T0計數溢出時產生中斷請求
}
void Display( unsigned char index, unsigned char dataValue ){ DisBuf[ index ] = dataValue; }
void main( void )
{
unsigned char i;
for( i=0; i<8; i++ ){ Display(i, 8-i); } //DisBuf[0]為右,DisBuf[7]為左
Timer0Init();
EA = 1; //允許CPU響應中斷請求
While(1);
}