汽车单片机原理程序复习.doc
【精品文档】如有侵权,请联系网站删除,仅供学习与交流汽车单片机原理程序复习.精品文档.第 01 篇 基础程序设计01闪烁的LED/* 名称:闪烁的LED说明:LED按设定的时间间隔闪烁#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit LED=P10;/延时void DelayMS(uint x)uchar i;while(x-)for(i=0;i<120;i+);/主程序void main()while(1)LED=LED;DelayMS(150);02 从左到右的流水灯/* 名称:从左到右的流水灯说明:接在P0口的8个LED从左到右循环依次点亮,产生走马灯效果#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int/延时void DelayMS(uint x)uchar i;while(x-)for(i=0;i<120;i+);/主程序void main()P0=0xfe;while(1)P0=_crol_(P0,1); /P0的值向左循环移动DelayMS(150);03 8只LED左右来回点亮/* 名称:8只LED左右来回点亮说明:程序利用循环移位函数_crol_和_cror_形成来回滚动的效果#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned int/延时void DelayMS(uint x)uchar i;while(x-)for(i=0;i<120;i+);/主程序void main()uchar i;P2=0x01;while(1)for(i=0;i<7;i+)P2=_crol_(P2,1); /P2的值向左循环移动DelayMS(150);for(i=0;i<7;i+)P2=_cror_(P2,1); /P2的值向右循环移动DelayMS(150);04 单只数码管循环显示09/*名称:单只数码管循环显示09说明:主程序中的循环语句反复将09的段码送至P0口,使数字09循环显示#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar code DSY_CODE=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff;/延时void DelayMS(uint x)uchar t;while(x-) for(t=0;t<120;t+);/主程序void main()uchar i=0;P0=0x00;while(1) /* for(;i<11;i+) P0=DSY_CODEi; DelayMS(300); /注:另一方案 */P0=DSY_CODEi;i=(i+1)%10;DelayMS(300);05 8只数码管滚动显示单个数字/*名称:8只数码管滚动显示单个数字说明:数码管从左到右依次滚动显示07,程序通过每次仅循环选通一只数码管#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar code DSY_CODE=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90;/延时void DelayMS(uint x)uchar t;while(x-) for(t=0;t<120;t+);/主程序void main()uchar i,wei=0x80;while(1)for(i=0;i<8;i+)P2=0xff; /关闭显示wei=_crol_(wei,1);P0=DSY_CODEi; /发送数字段码P2=wei; /发送位码DelayMS(300);06 8只数码管动态显示多个不同字符电路如上图/*名称:8只数码管动态显示多个不同字符说明:数码管动态扫描显示07。#include<reg51.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intuchar code DSY_CODE=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90;/延时void DelayMS(uint x)uchar t;while(x-) for(t=0;t<120;t+);/主程序void main()uchar i,wei=0x80;while(1)for(i=0;i<8;i+)P2=0xff;P0=DSY_CODEi; /发送段码wei=_crol_(wei,1);P2=wei; /发送位码DelayMS(2);7 K1-K4 按键状态显示/*名称:K1-K4 按键状态显示说明:K1、K2按下时LED点亮,松开时熄灭, K3、K4按下并释放时LED点亮,再次按下并释放时熄灭;#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit LED1=P00;sbit LED2=P01;sbit LED3=P02;sbit LED4=P03;sbit K1=P10;sbit K2=P11;sbit K3=P12;sbit K4=P13;/延时void DelayMS(uint x)uchar i;while(x-) for(i=0;i<120;i+);/主程序void main()P0=0xff;P1=0xff;while(1)LED1=K1;LED2=K2;if(K3=0)while(K3=0);LED3=LED3;if(K4=0)while(K4=0);LED4=LED4;DelayMS(10);8 开关控制LED/*名称:开关控制LED说明:开关S1和S2分别控制LED1和LED2。#include<reg51.h>sbit S1=P10;sbit S2=P11;sbit LED1=P00;sbit LED2=P01;/主程序void main()while(1)LED1=S1;LED2=S2;9 按键发音/*名称:按键发音说明:按下不同的按键会是SOUNDER发出不同频率的声音。本例使用延时函数实现不同频率的声音输出,以后也可使用定时器#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit BEEP=P37;sbit K1=P14;sbit K2=P15;sbit K3=P16;sbit K4=P17;/延时void DelayMS(uint x)uchar t;while(x-) for(t=0;t<120;t+);/按周期t发音void Play(uchar t)uchar i;for(i=0;i<100;i+)BEEP=BEEP;DelayMS(t);BEEP=0;void main()P1=0xff;BEEP=0;while(1)if(K1=0)Play(1);if(K2=0)Play(2);if(K3=0)Play(3);if(K4=0)Play(4);10 INT0中断计数/*名称:INT0中断计数说明:每次按下计数键时触发INT0中断,中断程序累加计数, 计数值显示在3只数码管上,按下清零键时数码管清零#include<reg51.h>#define uchar unsigned char#define uint unsigned int/09的段码uchar code DSY_CODE=0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00;/计数值分解后各个待显示的数位uchar DSY_Buffer=0,0,0;uchar Count=0;sbit Clear_Key=P36;/数码管上显示计数值void Show_Count_ON_DSY()DSY_Buffer2=Count/100;/获取3个数DSY_Buffer1=Count%100/10;DSY_Buffer0=Count%10;if(DSY_Buffer2=0) /高位为0时不显示DSY_Buffer2=0x0a;if(DSY_Buffer1=0) /高位为0,若第二位为0同样不显示DSY_Buffer1=0x0a;P0=DSY_CODEDSY_Buffer0;P1=DSY_CODEDSY_Buffer1;P2=DSY_CODEDSY_Buffer2;/主程序void main()P0=0x00;P1=0x00;P2=0x00;IE=0x81;/允许INT0中断IT0=1;/下降沿触发while(1)if(Clear_Key=0) Count=0;/清0Show_Count_ON_DSY();/INT0中断函数void EX_INT0() interrupt 0Count+; /计数值递增11 外部INT0中断控制LED/*名称:外部INT0中断控制LED说明:每次按键都会触发INT0中断,中断发生时将LED状态取反,产生LED状态由按键控制的效果#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit LED=P00;/主程序void main()LED=1;EA=1;EX0=1;IT0=1;while(1);/INT0中断函数void EX_INT0() interrupt 0LED=LED; /控制LED亮灭12 定时器控制单只LED/*名称:定时器控制单只LED说明:LED在定时器的中断例程控制下不断闪烁。#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit LED=P00;uchar T_Count=0;/主程序void main()TMOD=0x00; /定时器0工作方式0TH0=(8192-5000)/32;/5ms定时TL0=(8192-5000)%32;IE=0x82;/允许T0中断TR0=1;while(1);/T0中断函数void LED_Flash() interrupt 1TH0=(8192-5000)/32;/恢复初值TL0=(8192-5000)%32;if(+T_Count=100)/0.5s开关一次LEDLED=LED;T_Count=0; 13 定时器控制4个LED滚动闪烁/*名称:定时器控制4个LED滚动闪烁说明:4只LED在定时器控制下滚动闪烁。#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit B1=P00;sbit G1=P01;sbit R1=P02;sbit Y1=P03;uint i,j,k;/主程序void main()i=j=k=0;P0=0xff;TMOD=0x02; /定时器0工作方式2TH0=256-200;/200us定时TL0=256-200;IE=0x82;TR0=1;/启动定时器while(1);/T0中断函数void LED_Flash_and_Scroll() interrupt 1if(+k<35)return; /定时中断若干次后执行闪烁k=0;switch(i)case 0:B1=B1;break;case 1:G1=G1;break;case 2:R1=R1;break;case 3:Y1=Y1;break;default:i=0;if(+j<300) return; /每次闪烁持续一段时间j=0;P0=0xff; /关闭显示i+; /切换到下一个LED14 10s的秒表/*名称:10s的秒表说明:首次按键计时开始,再次按键暂停,第三次按键清零。#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit K1=P37;uchar i,Second_Counts,Key_Flag_Idx;bit Key_State;uchar DSY_CODE=0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f;/延时void DelayMS(uint ms)uchar t;while(ms-) for(t=0;t<120;t+);/处理按键事件void Key_Event_Handle()if(Key_State=0)Key_Flag_Idx=(Key_Flag_Idx+1)%3;switch(Key_Flag_Idx)case 1:EA=1;ET0=1;TR0=1;break;case 2:EA=0;ET0=0;TR0=0;break;case 0:P0=0x3f;P2=0x3f;i=0;Second_Counts=0;/主程序void main()P0=0x3f; /显示00P2=0x3f;i=0;Second_Counts=0; Key_Flag_Idx=0; /按键次数(取值0,1,2,3)Key_State=1; /按键状态TMOD=0x01;/定时器0方式1TH0=(65536-50000)/256;/定时器0:15msTL0=(65536-50000)%256;while(1)if(Key_State!=K1)DelayMS(10);Key_State=K1;Key_Event_Handle();/T0中断函数void DSY_Refresh() interrupt 1TH0=(65536-50000)/256;/恢复定时器0初值TL0=(65536-50000)%256;if(+i=2)/50ms*2=0.1s转换状态i=0;Second_Counts+;P0=DSY_CODESecond_Counts/10;P2=DSY_CODESecond_Counts%10;if(Second_Counts=100) Second_Counts=0;/满100(10s)后显示0015 用计数器中断实现100以内的按键计数/*名称:用计数器中断实现100以内的按键计数说明:本例用T0计数器中断实现按键技术,由于计数寄存器初值为1,因此 P3.4引脚的每次负跳变都会触发T0中断,实现计数值累加。 计数器的清零用外部中断0控制。#include<reg51.h>#define uchar unsigned char#define uint unsigned int/段码uchar code DSY_CODE=0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00;uchar Count=0;/主程序void main()P0=0x00; P2=0x00;TMOD=0x06;/计数器T0方式2TH0=TL0=256-1;/计数值为1ET0=1;/允许T0中断EX0=1;/允许INT0中断EA=1;/允许CPU中断IP=0x02;/设置优先级,T0高于INT0IT0=1;/INT0中断触发方式为下降沿触发TR0=1;/启动T0while(1)P0=DSY_CODECount/10;P2=DSY_CODECount%10;/T0计数器中断函数void Key_Counter() interrupt 1Count=(Count+1)%100;/因为只有两位数码管,计数控制在100以内(0099)/INT0中断函数void Clear_Counter() interrupt 0Count=0;16 定时器控制交通指示灯/*名称:定时器控制交通指示灯说明:东西向绿灯亮5s后,黄灯闪烁,闪烁5次亮红灯, 红灯亮后,南北向由红灯变成绿灯,5s后南北向黄灯闪烁, 闪烁5次后亮红灯,东西向绿灯亮,如此往复。#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit RED_A=P00; /东西向指示灯sbit YELLOW_A=P01;sbit GREEN_A=P02;sbit RED_B=P03; /南北向指示灯sbit YELLOW_B=P04;sbit GREEN_B=P05;/延时倍数,闪烁次数,操作类型变量uchar Time_Count=0,Flash_Count=0,Operation_Type=1;/定时器0中断函数void T0_INT() interrupt 1TL0=-50000/256;TH0=-50000%256;switch(Operation_Type)case 1:/东西向绿灯与南北向红灯亮5sRED_A=0;YELLOW_A=0;GREEN_A=1;RED_B=1;YELLOW_B=0;GREEN_B=0;if(+Time_Count!=100) return; /5s(100*50ms)切换Time_Count=0;Operation_Type=2;break;case 2:/东西向黄灯开始闪烁,绿灯关闭if(+Time_Count!=8) return;Time_Count=0;YELLOW_A=YELLOW_A;GREEN_A=0;if(+Flash_Count!=10) return;/闪烁Flash_Count=0;Operation_Type=3;break; case 3:/东西向红灯与南北向绿灯亮5sRED_A=1;YELLOW_A=0;GREEN_A=0;RED_B=0;YELLOW_B=0;GREEN_B=1;if(+Time_Count!=100) return; /5s(100*50ms)切换Time_Count=0;Operation_Type=4;break;case 4:/南北向黄灯开始闪烁,绿灯关闭if(+Time_Count!=8) return;Time_Count=0;YELLOW_B=YELLOW_B;GREEN_A=0;if(+Flash_Count!=10) return;/闪烁Flash_Count=0;Operation_Type=1;break;/主程序void main()TMOD=0x01;/T0方式1IE=0x82;TR0=1;while(1);17 单片机之间双向通信/*名称:甲机串口程序说明:甲机向乙机发送控制命令字符,甲机同时接收乙机发送的数字,并显示在数码管上。#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit LED1=P10;sbit LED2=P13;sbit K1=P17;uchar Operation_No=0;/操作代码/数码管代码uchar code DSY_CODE=0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f;/延时void DelayMS(uint ms)uchar i;while(ms-) for(i=0;i<120;i+);/向串口发送字符void Putc_to_SerialPort(uchar c)SBUF=c;while(TI=0);TI=0;/主程序void main()LED1=LED2=1;P0=0x00;SCON=0x50;/串口模式1,允许接收TMOD=0x20;/T1工作模式2PCON=0x00;/波特率不倍增TH1=0xfd;TL1=0xfd;TI=RI=0;TR1=1;IE=0x90;/允许串口中断while(1)DelayMS(100);if(K1=0)/按下K1时选择操作代码0,1,2,3while(K1=0);Operation_No=(Operation_No+1)%4;switch(Operation_No)/根据操作代码发送A/B/C或停止发送case 0:Putc_to_SerialPort('X');LED1=LED2=1;break;case 1:Putc_to_SerialPort('A');LED1=LED1;LED2=1;break;case 2:Putc_to_SerialPort('B');LED2=LED2;LED1=1;break;case 3:Putc_to_SerialPort('C');LED1=LED1;LED2=LED1;break;/甲机串口接收中断函数void Serial_INT() interrupt4if(RI)RI=0;if(SBUF>=0&&SBUF<=9) P0=DSY_CODESBUF;else P0=0x00;/*名称:乙机程序接收甲机发送字符并完成相应动作说明:乙机接收到甲机发送的信号后,根据相应信号控制LED完成不同闪烁动作。#include<reg51.h>#define uchar unsigned char#define uint unsigned intsbit LED1=P10;sbit LED2=P13;sbit K2=P17;uchar NumX=-1;/延时void DelayMS(uint ms)uchar i;while(ms-) for(i=0;i<120;i+);/主程序void main()LED1=LED2=1;SCON=0x50;/串口模式1,允许接收TMOD=0x20;/T1工作模式2TH1=0xfd;/波特率9600TL1=0xfd;PCON=0x00;/波特率不倍增RI=TI=0;TR1=1;IE=0x90;while(1)DelayMS(100);if(K2=0)while(K2=0);NumX=+NumX%11;/产生010范围内的数字,其中10表示关闭SBUF=NumX;while(TI=0);TI=0;void Serial_INT() interrupt 4if(RI)/如收到则LED则动作RI=0;switch(SBUF)/根据所收到的不同命令字符完成不同动作case 'X':LED1=LED2=1;break;/全灭case 'A':LED1=0;LED2=1;break;/LED1亮case 'B':LED2=0;LED1=1;break;/LED2亮case 'C':LED1=LED2=0;/全亮第02篇 硬件应用01 24C04与数码管/*名称:24C04与数码管说明:每次运行时,程序将24C04芯片内的计数字节值 递增并显示在数码管上,反复运行,实现计数。#include<reg51.h>#include<intrins.h> #define uchar unsigned char#define uint unsigned int#define Delay4us() _nop_();_nop_();_nop_();_nop_();sbit SCL=P10;sbit SDA=P11;/数码管段码uchar code DSY_CODE=0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff;/三位数显示缓冲uchar DISP_Buffer=0,0,0;uchar Count=0;/延时void DelayMS(uint ms)uchar i;while(ms-) for(i=0;i<120;i+);/IIC启动void Start()SDA=1;SCL=1;Delay4us();SDA=0;Delay4us();SCL=0;/IIC停止void Stop()SDA=0;SCL=0;Delay4us();SCL=1;Delay4us();SDA=1;/读取应答void RACK()SDA=1;Delay4us();SCL=1;Delay4us();SCL=0;/发送非应答信号void NO_ACK()SDA=1;SCL=1;Delay4us();SCL=0;SDA=0;/向24C04中写一个字节数据void Write_A_Byte(uchar byte)uchar i;for(i=0;i<8;i+)byte<<=1;SDA=CY;_nop_();SCL=1;Delay4us();SCL=0;RACK();/向指定地址写数据void Write_Random_Adress_Byte(uchar addr,uchar dat)Start();Write_A_Byte(0xa0);Write_A_Byte(addr);Write_A_Byte(dat);Stop();DelayMS(10);/从24C04中读一个字节数据uchar Read_A_Byte()uchar i,b;for(i=0;i<8;i+) SCL=1;b<<=1;b|=SDA;SCL=0;return b;/从当前地址读取数据uchar Read_Current_Address_Data()uchar dat;Start();Write_A_Byte(0xa1);dat=Read_A_Byte();NO_ACK();Stop();return dat;/从任意地址读取数据uchar Random_Read(uchar addr)Start();Write_A_Byte(0xa0);Write_A_Byte(addr);Stop();return Read_Current_Address_Data();/数据转换与显示void Convert_And_Display() DISP_Buffer2=Count/100;DISP_Buffer1=Count%100/10;DISP_Buffer0=Count%100%10;if(DISP_Buffer2=0) /高位为0不显示DISP_Buffer2=10;if(DISP_Buffer1=0)/高位为0,次高位为0也不显示DISP_Buffer1=10;P0=0xff;P2=0x80;/个位P0=DSY_CODEDISP_Buffer0;DelayMS(2);P0=0xff;P2=0x40;/十位P0=DSY_CODEDISP_Buffer1;DelayMS(2);P0=0xff;P2=0x20;/百位P0=DSY_CODEDISP_Buffer2;DelayMS(2);/主程序void main()Count=Random_Read(0x00)+1;/从24C04的0x00地址读取数据并递增Write_Random_Adress_Byte(0x00,Count);/将递增后的计数值写入24C04while(1) Convert_And_Display();/转换并持续刷新数码管显示02 1602液晶显示时钟#include<reg52.h>#include<intrins.h>#define uchar unsigned char#define uint unsigned intsbit rs=P20; sbit rw=P21;sbit e=P22;sbit k1=P10;sbit k2=P11;sbit k3=P12;sbit beep=P37;uchar miao,fen,shi;uchar count=0,num;uchar code table=" Current Time "/此处改为你的学号/延时函数void delay(uint x)uint i;while(x-) for(i=0;i<120;i+);/发送命令子程序void com(uchar com)/com(0x0f)rs=0;e=0;P0=com;e=1;delay(5);e=0;/发送数据子程序void date(uchar date)/date(0x3f)rs=1;e=0;P0=date;e=1;delay(5);e=0;/写子程序void write_sfm(uchar add,uchar num)uchar shi,ge;shi=num/10;ge=num%10;com(0x80+0x40+add);date(0x30+shi);date(0x30+ge);/喇叭发生子程序void di()uint i;for(i=50;i>0;i-)beep=0;delay(3);beep=1;/初始化子程序void init()uchar i;rw=0;e=0;fen=0;shi=0;miao=0;count=0;num=0;com(0x38);com(0x0c);com(0x06);com(0x01);com(0x80);for(i=0;i<15;i+)date(tablei);delay(5);com(0x80+0x40+6);date(':');com(0x80+0x40+9);date('