51单片机交通灯这个实例主要用到的知识点有:
>如何点亮LED
>38译码器位选与段选
>定时器控制
>中断控制
#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(); } } }