51單片機交通燈這個實例主要用到的知識點有:git
>如何點亮LEDspa
>38譯碼器位選與段選code
>定時器控制blog
>中斷控制it
#include <reg52.h> /************ 交通燈 ***********/ #define GPIO_DIG P0 //數碼管顯示交通燈等待的時間 #define GPIO_TRAFFIC P1 //定義交通燈 sbit RED10 = P1^0; //上面的人行道紅燈 sbit GREEN10 = P1^1; //上面的人行道綠燈 sbit RED11 = P1^2; //上面的機動車通行紅燈 sbit YELLOW11 = P1^3; //上面的機動車通行黃燈 sbit GREEN11 = P1^4; //上面的機動車通行綠燈 sbit RED00 = P3^0; //右邊的人行道紅燈 sbit GREEN00 = P3^1; //右邊的人行道綠燈 sbit RED01 = P1^5; //右邊的機動車通行紅燈 sbit YELLOW01 = P1^6; //右邊的機動車通行黃燈 sbit GREEN01 = P1^7; //右邊的機動車通行綠燈 //38譯碼器的位選輸入端 sbit A1 = P2^2; sbit B1 = P2^3; sbit C1 = P2^4; typedef unsigned int u16; typedef unsigned char u8; u16 second = 1; void timer_init(){ TMOD |= 0x01; //定時器工做方式1,啓用T0定時器, GATE位爲0,用TCON的TR0控制T0定時器的啓動 //設置定時器的初始計數值 //計算方法 //假設定時器爲1ms,一個機器週期爲 1/單片機的晶振頻率 即: 1/12M = 1us //而1個機器週期 = 12個時鐘週期 因此: n x 機器週期 = 1ms ===> n x 1us = 1ms //因此n = 1000,也就是通過1000個機器週期,定時器要溢出(從0開始計數) //因此定時器的初始值爲65535 - 1000 + 1 = 64536 ===> 0xFC18 TH0 = 0xFC; //計時器初始值的高8位 TL0 = 0x18; //計時器初始值的低8位 EA = 1; //總中斷開關 ET0 = 1; //T0中斷 TR0 = 1;//啓動T0定時器 } void delay( u16 i ) { while( i-- ); } void trigger_timer() interrupt 1{ static u16 i = 0; TH0 = 0xFC; TL0 = 0x18; i++; if( i == 1000 ) { //1秒 i = 0; second++; } } u8 digital[16] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71 }; u8 DisplayData[8]; void showDigital(){ int i = 0; for ( i = 0; i < 8; i++ ) { switch( i ) { case 0: //位選第一個數碼管 A1 = 0x0; B1 = 0x0; C1 = 0x0; break; case 1: A1 = 0x1; B1 = 0x0; C1 = 0x0; break; case 2: A1 = 0x0; B1 = 0x1; C1 = 0x0; break; case 3: A1 = 0x1; B1 = 0x1; C1 = 0x0; break; case 4: A1 = 0x0; B1 = 0x0; C1 = 0x1; break; case 5: A1 = 0x1; B1 = 0x0; C1 = 0x1; break; case 6: A1 = 0x0; B1 = 0x1; C1 = 0x1; break; case 7: A1 = 0x1; B1 = 0x1; C1 = 0x1; break; } GPIO_DIG = DisplayData[ i ]; delay( 100 ); GPIO_DIG = 0x00; //消隱 } } void main(){ u8 shiwei = 0, gewei = 0; timer_init(); while( 1 ){ if( second == 70 ) { //紅綠燈總共70秒 而後輪迴 second = 1; } if( second < 31 ) { DisplayData[0] = 0x00; //數碼管1顯示的數字 DisplayData[1] = 0x00; //數碼管2顯示的數字 shiwei = ( 30 - second ) % 100 / 10; gewei = ( 30 - second ) % 10; DisplayData[2] = digital[ shiwei ]; DisplayData[3] = digital[ gewei ]; DisplayData[4] = 0x00; //數碼管5顯示的數字 DisplayData[5] = 0x00; //數碼管6顯示的數字 DisplayData[6] = DisplayData[2]; DisplayData[7] = DisplayData[3]; //寶田路通行 GPIO_TRAFFIC = 0xFF; //熄滅全部的燈 RED00 = 1; GREEN00 = 1; GREEN11 = 0; //寶田路綠燈亮 RED10 = 0; //寶田路人行道 紅燈亮 GREEN00 = 0; //前進路人行道綠燈亮 RED01 = 0; //前進路紅燈亮 showDigital(); } else if ( second < 36 ){ //黃燈切換 DisplayData[0] = 0x00; //數碼管1顯示的數字 DisplayData[1] = 0x00; //數碼管2顯示的數字 shiwei = ( 35 - second ) % 100 / 10; gewei = ( 35 - second ) % 10; DisplayData[2] = digital[ shiwei ]; DisplayData[3] = digital[ gewei ]; DisplayData[4] = 0x00; //數碼管5顯示的數字 DisplayData[5] = 0x00; //數碼管6顯示的數字 DisplayData[6] = DisplayData[2]; DisplayData[7] = DisplayData[3]; //寶田路黃燈切換 GPIO_TRAFFIC = 0xFF; //熄滅全部的燈 RED00 = 1; GREEN00 = 1; YELLOW11 = 0; //寶田路黃燈亮 RED10 = 0; //寶田路人行道 紅燈亮 GREEN00 = 0; //前進路人行道綠燈亮 RED01 = 0; //前進路紅燈亮 showDigital(); } else if ( second < 66 ){ //前進路通行 DisplayData[0] = 0x00; //數碼管1顯示的數字 DisplayData[1] = 0x00; //數碼管2顯示的數字 shiwei = ( 65 - second ) % 100 / 10; gewei = ( 65 - second ) % 10; DisplayData[2] = digital[ shiwei ]; DisplayData[3] = digital[ gewei ]; DisplayData[4] = 0x00; //數碼管5顯示的數字 DisplayData[5] = 0x00; //數碼管6顯示的數字 DisplayData[6] = DisplayData[2]; DisplayData[7] = DisplayData[3]; //前進路通行 GPIO_TRAFFIC = 0xFF; //熄滅全部的燈 RED00 = 1; GREEN00 = 1; GREEN01 = 0; //前進路綠燈亮 RED00 = 0; //前進路人行道 紅燈亮 GREEN10 = 0; //寶田路人行道綠燈亮 RED11 = 0; //寶田路紅燈亮 showDigital(); } else { //黃燈切換 DisplayData[0] = 0x00; //數碼管1顯示的數字 DisplayData[1] = 0x00; //數碼管2顯示的數字 shiwei = ( 70 - second ) % 100 / 10; gewei = ( 70 - second ) % 10; DisplayData[2] = digital[ shiwei ]; DisplayData[3] = digital[ gewei ]; DisplayData[4] = 0x00; //數碼管5顯示的數字 DisplayData[5] = 0x00; //數碼管6顯示的數字 DisplayData[6] = DisplayData[2]; DisplayData[7] = DisplayData[3]; //前進路通行 GPIO_TRAFFIC = 0xFF; //熄滅全部的燈 RED00 = 1; GREEN00 = 1; YELLOW01 = 0; //前進路黃燈亮 RED00 = 0; //前進路人行道 紅燈亮 GREEN10 = 0; //寶田路人行道綠燈亮 RED11 = 0; //寶田路紅燈亮 showDigital(); } } }