单片机学习之项目1 流水灯2定时器
单片机学习-LESSON2流水
05 流水灯效果展示与测试
流水灯效果展示
流水灯效果
通过单片机控制LED灯的亮灭,实现LED 灯从左至右依次点亮,再从右至左依次 熄灭,循环往复,形成流水灯效果。
VS
硬件连接
将LED灯的正极连接到单片机的I/O口, 负极接地,通过单片机编程控制LED灯的 亮灭。
效果测试与评估
测试方法
通过观察LED灯的亮灭顺序和时间间 隔,判断流水灯效果是否正常。
单片机学习的展望
在未来的单片机学习中,我们将继续深入学习单片机的各种功能和控制方法,包括中断、定时器、串 口通信等。
此外,我们还将学习如何使用更高级的编程语言和开发工具进行单片机程序的编写和调试,提高我们的 编程效率和程序质量。
通过不断的学习和实践,我们将逐渐掌握单片机的各种应用,为未来的嵌入式系统开发打下坚实的基础。
单片机通常被应用于自动化控制、智能仪表、通信设备、家用电器等领域,以实 现智能化控制和信息处理。
单片机的应用领域
工业自动化控制
单片机可以用于实现各种工业 控制系统的智能化,如电机控 制、温度控制、压力控制等。
智能仪表
单片机可以用于实现各种智能 仪表的测量和控制,如智能温 度计、智能流量计等。
通信设备
汇编语言
汇编语言是一种低级语言,与硬件紧密相关,能够直接控制硬件操作。在某些 特定场合,如性能要求高或资源有限的系统中,使用汇编语言可以提高程序的 执行效率。
程序代码编写
确定流水灯的硬件连接方 式
根据单片机的引脚数量和LED灯的个数,确 定如何连接LED灯到单片机上。
编写程序代码
根据流水灯的控制需求,使用所选的编程语言编写 程序代码。
8051单片机
8051单片机是一种流行的8位单片机, 它具有简单易用、低功耗、高可靠性等 特点,被广泛应用于各种领域。
流水灯(定时器延时)
/********************** main******************************/ main() { unsigned char k,temp,temp1;//设置变量 P1= 0xff; TMOD = 0x01;//设置定时器方式为定时器方式 1 while (1) { temp = 0x01; //L1 到 L8 二极管顺序点亮 for(k=0;k<8;k++) { P1 = ~temp; delay(50); temp = temp<<1; } temp = 0x80; //L8 到 L1 二极管顺序点亮 for(k=0;k<8;k++) { P1 = ~temp; delay(50); temp = temp>>1; } temp = 0xfe;//L8L1 到 L7L2 到 L6L3 到 L5L4 顺序点亮 temp1 = 0x7f; for(k=0;k<8;k++) { P1 =(_cror_(temp,k))&(_crol_(temp1,k)); delay(50); } P1 = 0xFF; delay(200); temp = 0xFE; //L8 到 L1 二极管顺序点亮 for(k=0;k<8;k++) { P1 = temp; delay(50); temp = temp<<1; } temp = 0x7F; //L1 到 L8 二极管顺序熄灭 for(k=0;k<8;k++) { P1 = ~temp; delay(50); temp = temp>>1; } } }
/*********************************************************************************************/ /* 函 数 名: delay*****************************************************************************/ /* 功能描述: 延时*****************************************************************************/ /* 调用函数: 无 ******************************************************************************/ /* 入口参数: t*********************************************************************************/ /* 出口参数:无 ******************************************************************************/ /*********************************************************************************************/
51单片机流水灯、数码管、定时器、秒表、计算器程序
51单片机流水灯、数码管、定时器、秒表、计算器程序流水灯 #include<reg52.h>char data_group[]={0x7e,0xbd,0xdb,0xe7,0xdb,0xbd,0x7e};unsigned int a;void delay(unsigned int time) {int i,j;for(i=time;i>0;i--){for(j=100;j>0;j--);}}void move_mid_side(void) {int m;for(m=0;m<7;m++){P1=data_group[m];delay(500);}}void move_right_only(void) {int a,temp;delay(500);temp=0x80;for(a=7;a>=0;a--){temp=~temp;P1=temp;delay(500);temp=~temp;temp>>=1;}temp=0x80;delay(1000);}void move_left_only(void) { int a,temp;delay(500);temp=0x01;for(a=7;a>=0;a--){temp=~temp;P1=temp;delay(500);temp=~temp;temp<<=1;}temp=0x01;delay(1000);}void move_right_hlod(void) { int a,temp;temp=0x7f;for(a=8;a>=0;a--){P1=temp;delay(500);temp=temp>>1;}temp=~temp;delay(1000);}void move_left_hold(void) { int a,temp;temp=0xfe;for(a=8;a>=0;a--){P1=temp;delay(500);temp<<=1;}temp=~temp;delay(1000);}void main(){while(1){move_left_hold();move_mid_side();move_right_hlod();move_mid_side();move_left_only();move_right_only();}}数码管 #include <reg52.h>chardata_duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0~9 char data_wei[]={0xff,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0x00}; //0xff全关,之后为第一个数码管到第八个数码管//char data_wei_add[]={0x7f,0x3f,0x1f,0x0f,0x07,0x03,0x01,0x00};void delay(unsigned int time) {int i,j;for(i=time;i>0;i--){for(j=0;j<100;j++);}}void show_number_only(void){int i;P2=data_wei[1]; //P2为位选for(i=0;i<10;i++){P0=data_duan[i]; //P0为段选delay(500);}}/*******************数码管动态显示子程序***************/ void move_show1(void){int i;for(i=1;i<2;i++){P2=data_wei[i];P0=data_duan[i];delay(1);}}void move_show2(void){int i;for(i=1;i<3;i++){P2=data_wei[i];P0=data_duan[i];delay(1);}}void move_show3(void) {int i;for(i=1;i<4;i++){P2=data_wei[i];P0=data_duan[i]; delay(1);}}void move_show4(void) {int i;for(i=0;i<5;i++){P2=data_wei[i];P0=data_duan[i]; delay(1);}}void move_show5(void) {int i;for(i=0;i<6;i++){P2=data_wei[i];P0=data_duan[i]; delay(1);}}void move_show6(void) {int i;for(i=0;i<7;i++){P2=data_wei[i];P0=data_duan[i]; delay(1);}}void move_show7(void) {int i;for(i=0;i<8;i++){P2=data_wei[i];P0=data_duan[i]; delay(1);}}void move_show8(void) {int i;for(i=0;i<9;i++){P2=data_wei[i];P0=data_duan[i];delay(1);}}/********数码管动态显示,实现数码管由1~8在八个数码管上一次显示************/void move_show_hold(void){int temp,i;temp=1000;for(i=temp;i>0;i--)move_show1();temp=600;for(i=temp;i>0;i--)move_show2();temp=400;for(i=temp;i>0;i--)move_show3();temp=200;for(i=temp;i>0;i--)move_show4();temp=200;for(i=temp;i>0;i--)move_show5();temp=200;for(i=temp;i>0;i--)move_show6();temp=100;for(i=temp;i>0;i--)move_show7();temp=100;for(i=temp;i>0;i--)move_show8();}void show_all(void) //将所有的位选端口打开,变化段选,显示整体变化1~9{int i;P2=data_wei[9];for(i=0;i<10;i++){P0=data_duan[i];delay(500);}}int main(void) {while(1){// show_number_only();move_show8();//move_show_hold(); // show_all(); }}独立按键#include <reg52.h>sbit key1=P3^0; sbit d2=P1^0;int temp,number=0;void delay(unsigned int time) {int i,j;for(i=time;i>0;i--){for(j=100;j>0;j--) ;}}int main(void) {temp=0xfe;while(1){d2=1;key1=1;P1=temp;if(key1==0){delay(100);if(key1==0){number++;if(number<=7){temp=~temp;temp=temp<<1;temp=~temp;P1=temp;}else{temp=0xfe;number=0;}}}}}矩阵按键 #include<reg52.h>chardata_duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x80 ,0xc6,0xc0,0x86,0x8e,};//0~9 chardata_wei[]={0xff,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0x00};int number=0;void delay(unsigned int time) {int i,j;for(i=time;i>0;i--){for(j=0;j<100;j++);}}//void move_show1(void)//{// int i;// for(i=1;i<2;i++){ // P2=data_wei[i]; // P0=data_duan[i]; // delay(1);// }//}//void move_show2(void)//{// int i;// for(i=1;i<3;i++){ // P2=data_wei[i];// P0=data_duan[i]; // delay(1);// }//}void scan_key(void){int temp;P1=0xfe;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(1);temp=P1;temp=temp&0xf0;while(temp!=0xf0){switch(temp){case 0xe0:number=12;break; case 0xd0:number=13;break; case 0xb0:number=14;break; case 0x70:number=15;break; }while(temp!=0xf0){temp=P1;temp=temp&0xf0;}}}P1=0xfd;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(1);temp=P1;temp=temp&0xf0;while(temp!=0xf0){switch(temp){case 0xe0:number=8;break; case 0xd0:number=9;break; case 0xb0:number=10;break; case 0x70:number=11;break; }while(temp!=0xf0){temp=P1;temp=temp&0xf0;}}}P1=0xfb;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(1);temp=P1;temp=temp&0xf0;while(temp!=0xf0){switch(temp){case 0xe0:number=4;break; case 0xd0:number=5;break; case 0xb0:number=6;break; case 0x70:number=7;break; }while(temp!=0xf0){temp=P1;temp=temp&0xf0;}}}P1=0xf7;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(1);temp=P1;temp=temp&0xf0;while(temp!=0xf0){switch(temp){case 0xe0:number=0;break; case 0xd0:number=1;break; case 0xb0:number=2;break; case 0x70:number=3;break;}while(temp!=0xf0){temp=P1;temp=temp&0xf0;}}}// return number;}int main(void){// int num=0;while(1){// num=scan_key(num);scan_key();P2=data_wei[1];P0=data_duan[number];}}定时器中断 #include <reg52.h>chardata_duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0~9 char data_wei[]={0xff,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0x00}; //0xff全关,之后为第一个数码管到第八个数码管int number=0,time=0;int main(void){// TMOD=0x01;//设置工作方式定时器0// TH0=(65536-50000)/256; //给计数器装初值 // TL0=(65535-50000)%256;// EA=1; //开总中断 // ET0=1; //定时器T0中断允许 // TR0=1; //启动定时器0TMOD=0x10;//设置工作方式定时器1TH1=(65536-50000)/256; //给计数器装初值TL1=(65535-50000)%256;EA=1; //开总中断ET1=1; //定时器T1中断允许TR1=1; //启动定时器1while(1){if(number==20){P2=data_wei[2];P0=data_duan[4];}if(time==40){P2=data_wei[0];number=0;time=0;}}}void exter3() interrupt 3{TH1=(65536-50000)/256; //给计数器装初值TL1=(65535-50000)%256;time++;number++;}//void exter1() interrupt 1//{// TH0=(65536-50000)/256; //给计数器装初值 // TL0=(65535-50000)%256;// time++;// number++;//}时钟 #include <reg52.h>chardata_duan[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//0~9 char data_wei[]={0xff,0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe,0x00};unsigned long int second=0,minute=0,hour=0,point=0,tip=0;unsigned long int time=0,sign=0,number=0,key=0,variable=0; unsigned long int S1=0,S2=0,M1=0,M2=0,H1=0;H2=0;void delay(unsigned int time) {int i,j;for(i=time;i>0;i--){for(j=0;j<100;j++);}}void key_scan(void){int temp; //应用按键检测P1=0xf7;temp=P1;temp=temp&0xf0;while(temp!=0xf0){delay(1);temp=P1;temp=temp&0xf0;while(temp!=0xf0){switch(temp){case 0xe0:number=1;break; case 0xd0:number=2;break; case 0xb0:number=3;break; case 0x70:number=4;break; }while(temp!=0xf0){temp=P1;temp=temp&0xf0;}}}// P1=0xfb;// temp=P1;// temp=temp&0xf0; // while(temp!=0xf0){ // delay(1);// temp=P1;// temp=temp&0xf0; // while(temp!=0xf0){ // switch(temp){ // case 0xe0:number=5;break; // case 0xd0:number=6;break; // case0xb0:number=7;break; // case 0x70:number=8;break; // } // while(temp!=0xf0){ // temp=P1;// temp=temp&0xf0; // }// }////// }}void adjust_alarm(void) {if(number==1){ //控制时钟的启动与停止key=!key;if(key==1){EA=0;variable=time;}if(key==0){EA=1;}number=0;}if(number==2){ //调节时间选择标志位tip=tip+1;tip=tip%6;if(tip==0){tip=6;}number=0;}if((number==3)&&(EA==0)){if(tip==1)time=time-1;if(tip==2)time=time-10;if(tip==3)time=time-60;if(tip==4)time=time-600;if(tip==5)time=time-3600;if(tip==6)time=time-36000;number=0;}if((number==4)&(EA==0)){if(tip==1)time=time+1;if(tip==2)time=time+10;if(tip==3)time=time+60;if(tip==4)time=time+600;if(tip==5)time=time+3600;if(tip==6)time=time+36000;number=0;}// if((number==5)&&(EA==0)){ // if(tip==1) // variable=variable-1; // if(tip==2)// variable=variable-10; // if(tip==3)// variable=variable-60; // if(tip==4)// variable=variable-600; // if(tip==5)// variable=variable-3600; // if(tip==6)// variable=variable-3600; // number=0;// }// if((number==6)&(EA==0)){ // if(tip==1)// variable=variable+1; // if(tip==2)// variable=variable+10; // if(tip==3)// variable=variable+60; // if(tip==4)// variable=variable+600; // if(tip==5)// variable=variable+3600; // if(tip==6)// variable=variable+36000; // number=0;// }}void compare_time(void){if(time>variable){;}}void alarm_show_s(void){int sign2;for(sign2=1;sign2<2;sign2++){ //数码管动态显示S1=second%10;P2=data_wei[sign2];P0=data_duan[S1];delay(1);}for(sign2=2;sign2<3;sign2++){ S2=second/10;P2=data_wei[sign2];P0=data_duan[S2];delay(1);}for(sign2=3;sign2<4;sign2++){ P2=data_wei[sign2];P0=0xbf;delay(1);}for(sign2=4;sign2<5;sign2++){ M1=minute%10;P2=data_wei[sign2];P0=data_duan[M1];delay(1);}for(sign2=5;sign2<6;sign2++){ M2=minute/10;P2=data_wei[sign2];P0=data_duan[M2];delay(1);}for(sign2=6;sign2<7;sign2++){P2=data_wei[sign2];P0=0xbf;delay(1);}for(sign2=7;sign2<8;sign2++){H1=hour%10;P2=data_wei[sign2];P0=data_duan[H1];delay(1);}for(sign2=8;sign2<9;sign2++){H2=hour/10;P2=data_wei[sign2];P0=data_duan[H2];delay(1);}}void record_set_alarm(void) //设定闹钟所改变的值 { second=variable%60;minute=variable/60%60;hour=variable/3600%24;if(hour==24){variable=0;}}void record_time(void) {second=time%60;minute=time/60%60; hour=time/3600%24;if(hour==24){time=0;}}int main(void){TMOD=0x01;TH0=(65536-50000)/256; TL0=(65536-50000)%256; EA=1;ET0=1;TR0=1;while(1){record_time();// record_set_alarm(); alarm_show_s();key_scan();adjust_alarm();}}void extern1() interrupt 1 //定时器中断0 { TH0=(65536-50000)/256; //重装值TL0=(65536-50000)%256;sign++;if(sign==20){time++;sign=0;}}。
单片机的应用(1)流水灯
MOV TH1,A
TEST0: JB P32,TEST0 ;检测是否到a点 SETB TR0 ;到a点,TR0 = 1,做好取计时值准备。
T1计数 1
INT 1
解:
复习GATE的用法: GATE = 0时,TRi = 1,即可启动Ti定时 / 计数 GATE = 1时,TRi = 1,且 INTi =1,才启动定时 / 计数。
ORG 0000H
LJMP MAIN ORG 2000H
MAIN:MOV TMOD,#99H ;T0、T1均工作在定时,
ORG 0000H LJMP MAIN
ORG 000BH LJMP INSE1 ORG 1000H MAIN: MOV SP,#60H MOV TL0,#0CH MOV TH0,#0F0H MOV TMOD,#00H
SETB TR0
SETB ET0 SETB EA
SJMP $
………
INSE1: MOV TL0,#0CH MOV TH0,#0F0H CPL P10 RETI
小结:1、MCS-51单片机内有几个定时计数器?
如何计数? 2、T0、T1有几种工作方式? 3、编程应用前要事先确定的参数有几个?
定时 / 计数器的应用
复习:
TMOD TCON
GATE C/ T TF1 TR1 M1 TF0 M0 TR0 GATE C / T IE1 IT1 M1 IE0 M0 IT0
T0定时/计数,而T1停止计数,但可作波特率发生器。T0分成两独立定时/计数 器TL0和TH0。
实验三流水灯实验(io口和定时器实验)
实验三流水灯实验(I/O口和定时器实验)一、实验目的1.学会单片机I/O口的使用方法和定时器的使用方法;2.掌握延时子程序的编程方法、内部中断服务子程序的编程方法;3.学会使用I/O口控制LED灯的应用程序设计。
二、实验内容1.控制单片机P1口输出,使LED1~LED8右循环轮流点亮(即右流水),间隔时间为100毫秒。
2.控制单片机P1口输出,使LED1~LED8左循环轮流点亮(即左流水),间隔时间为100毫秒。
3.使用K1开关控制上面LED灯的两种循环状态交替进行;4. 用定时器使P1口输出周期为100ms的方波,使LED闪烁。
5.使用定时器定时,使LED灯的两种循环状态自动交替,每一种状态持续1.6秒钟(选作)。
三、实验方法和步骤1.硬件电路设计使用实验仪上的E1、E5和E7模块电路,把E1区的JP1(单片机的P1口)和E5区的8针接口L1~L8(LED的驱动芯片74HC245的输入端)连接起来,P1口就可以控制LED 灯了。
当P1口上输出低电平“0”时,LED灯亮,反之,LED灯灭。
E7区的K1开关可以接单片机P3.0口,用P3.0口读取K1开关的控制信号,根据K1开关的状态(置“1”还是置“0”),来决定LED进行左流水还是右流水。
综上,画出实验电路原理图。
2.程序设计实验1和实验2程序流程图如图3-1实验3程序流程图如图3-2所示。
图3-1 实验1,2程序流程图图3-2 实验3程序流程图实验4程序流程图如图3-3,3-4所示。
实验5程序流程图如图3-5,3-6所示。
图3-5 实验5主程序流程图图3-6 定时器中断服务子程序流程图图3-4 定时器中断服务子程序流程图图3-3 实验4主程序流程图编程要点:(1)Pl,P3口为准双向口,每一位都可独立地定义为输入或输出,在作输入线使用前,必须向锁存器相应位写入“1”,该位才能作为输入。
例如:MOV P1,A; P1口做输出MOV P1,#0FFHMOV A,P1;P1口做输入SETB P3.0MOV C,P3.1;从P3.1口读入数据(2)每个端口对应着一个寄存器,例:P1→90H(P1寄存器地址);P3→B0H(P3寄存器地址);寄存器的每一位对应着一个引脚,例:B0H.0→P3.0(3)对寄存器写入“0”、“1”,对应的外部引脚则输出“低电平”、“高电平”。
任务五 定时控制流水灯
C1
22pF
X1 R1
1k 12MHz
U1
19 XTAL1 P0.0/AD0 P0.1/AD1 P0.2/AD2 P0.3/AD3 P0.4/AD4 P0.5/AD5 P0.6/AD6 P0.7/AD7 P2.0/A8 P2.1/A9 P2.2/A10 P2.3/A11 P2.4/A12 P2.5/A13 P2.6/A14 P2.7/A15 P3.0/RXD P3.1/TXD P3.2/INT0 P3.3/INT1 P3.4/T0 P3.5/T1 P3.6/WR P3.7/RD 39 38 37 36 35 34 33 32 21 22 23 24 25 26 27 28 10 11 12 13 14 15 16 17
#include <reg51.h> Void main() { unsigned char i; TMOD=0x10; //设置Timer 1工作在方式1下定时模式 for (i=0; i<50; i++) //重复定时计数器,定时50次 { TH1=(65536-20000)/256; //往TH1中载入计数初值高8位 TL1=(65536-20000)%256; //往TL1中载入计数初值低8位定时20ms TR1=1; //启动Timer 1 while (!TF1) ; //检测Timer1溢出标志,当TF1=1,跳出 TR1=0; //关闭Timer 1 TF1=0; //将TF1清0 } }
//设置Timer 1工作在方式1下定时模式 //重复定时计数器,定时50次 //往TL1和TH1中载入计数的初始值B1E0H //定时20ms //启动Timer 1 //检测Timer1溢出标志,当TF1=1,跳出 //关闭Timer 1 //将TF1清0
C51单片机实验报告流水灯交通灯定时器双机交互时钟
C51单片机实验报告流水灯交通灯定时器双机交互时钟C51单片机实验报告流水灯交通灯定时器双机交互时钟学号:班级:自动化10 班姓名:张指导老师:胡2019.12单片机核心板实验要求一、流水灯实验、实验目的:) 简单I/O 引脚的输出2 ) 掌握软件延时编程方法3 ) 简单按键输入捕获判断 2 、完成功能要求) 开机是点亮12 发光二极管,闪烁三下2 ) 按照顺时针循环依次点亮发光二极管3 ) 通过按键将发光二极管的显示改为顺逆时针方式二、定时器或实时时钟实验、实验目的) 数码管动态显示技术2 ) 定时器的应用3 ) 按键功能定义 2 、完成功能要求) 通过按键可以设定定时时间,启动定时器,定时时间到,让12 个发光二极管闪烁,完成定时器功能。
) 实时时钟,可以设定当前时间,完成钟表功能(四位数码管分别显示分钟和秒)。
上述二个功能至少完成一种功能。
三、双机通信实验1 、实验目的UART 串行通信接口技术应用2 、完成功能要求用两片核心板之间实现串行通信,将按键信息互发到对方数码管显示。
四、交通灯实验1 、实验目的1 )按键、数码管、发光二极管综合应用编程技术2 )数据存储于EEPRO的技术(也可以不使用)3 )定时中断技术4 )按键中断技术2 、完成功能要求)对每个路口(主干道、次干道)的绿灯时间,及黄灯时间的设定。
)设定参数掉电后不丢失(如果不使用EEPRO,此功能可以不实现)。
)紧急按键功能,当按下该键时,所有路口变成红灯,相当于交警指挥特殊车辆通过。
再按该键,恢复正常显示。
实验一流水灯实验一、实验目的1 )简单I/O 引脚的输出2 )掌握软件延时编程方法 3 )简单按键输入捕获判断二、实验实现的功能 1 )开机是点亮12发光二极管,闪烁三下 2 )按照顺时针循环依次点亮发光二极管 3 )通过按键将发光二极管的显示改为顺逆时针方式三、系统硬件设计1 )如单片机核心板所示的硬件电路。
四、系统软件设计设计思路:1 )定义数组使得调用数组可以使led 灯能够顺时针和逆时针显示;2 )将按键的输入端全部置零,做单独按键使用;3 )利用“ while ”循环使得数码管可以闪烁三下;)利用“ for ”循环使得小灯能够依次点亮一个周期;5 )将以上思想汇总,编程,实现功能。
单片机控制流水灯 ppt课件
思考:前面的实验我们都是直接用一个P1 口的,那么能不能对P1口的某一个引脚来 操作呢?
任务3:
单片机应用技术
流水灯----单片机内部结构
精品资料
单片机应用技术
• 你怎么称呼老师? • 如果老师最后没有总结一节课的重点的难点,你
是否会认为老师的教学方法需要改进? • 你所经历的课堂,是讲座式还是讨论式? • 教师的教鞭 • “不怕太阳晒,也不怕那风雨狂,只怕先生骂我
单片机应用技术
这样看来程序是不是变得非常的简单了呢?但程序的可读性是不是 很差啊?能不能把P1变一下样我们来定义一个容易理解的变量呢?当然 可以了。
我们可以用C语言中define 的定义。 具体格式如下: #define 变量 预定义名 功能:用预定义名来代替前面的变量 如:#define P1 led 这样以后在程序中出现的led都代表P1口。将上面的程序修改如下: #include “reg51.h” #define P1 LED void delay() {
unsigned int i; for(i=0;i<10000;i++) ; }
void main()
{
for(;;)
{ L0 = 0;
delay(); L0 = 1; L1 = 0;
delay(); L1 = 1; L2 = 0;
delay(); L2 = 1; L3 = 0;
delay(); L3 = 1; L4 = 0;
P3.4/T0 P3.5/T1 P3.6/WR P3.7/RD
10 11 12 13 14 15 16 17
4K
1
40
2
39
3
38
单片机学习之项目1流水灯
02
硬件组成与原理
主要硬件设备介绍
LED灯
多个LED灯串联或并联在一起, 用于实现流水灯效果。
电源
为整个系统提供电能,一般采用 直流电源。
01
单片机
本项目采用常见的51单片机,负 责控制整个流水灯系统的运行。
02
03
04
电阻
用于限制电流,保护LED灯不会 因为电流过大而损坏。
电路连接及工作原理
• P0 = 0x00; // 初始状态为全灭
关键代码段解析
01
}
02
```
03
主循环代码:在循环中不断改变LED灯的亮灭状态,实现流水 灯效果
关键代码段解析
init_led(); // 初始化LED灯
void main() {
```c
01
03 02
关键代码段解析
01
while (1) { // 主循环
问题诊断及优化建议
检查单片机的程序代码,查找可 能导致问题的原因,如逻辑错误 、时序问题等。
重新进行测试验证,确保问题得 到解决,流水灯功能正常实现。
01
分析测试结果中出现的问题,如 LED灯亮灭顺序错误、时间间隔 不准确等。
02
03
根据问题原因提出相应的优化建 议,如修改程序代码、调整硬件 电路等。
关键代码段解析
01 unsigned int i, j; 02 for (i = ms; i > 0; i--) {
03
for ( j = 110; j > 0; j--); // 大约延时1ms
关键代码段解析
01
}
02
}
03
```
单片机实验报告流水灯双机通信交通灯定时时钟
实验一流水灯实验一、实验目的1)简单 I/O 引脚的输出2)掌握软件延时编程方法3)简单按键输入捕捉判断二、实验实现的功能1)开机是点亮 12 发光二极管,闪耀三下2)依据顺时针循环挨次点亮发光二极管3)经过按键将发光二极管的显示改为顺逆时针方式三、系统硬件设计流水灯原理图四、系统软件设计演示程序按键正转闪耀反转五、实验过程中碰到的问题及解决方法1) 每次循环不论正转仍是反转程序,总先是先履行P1 口的 8 位 led 灯。
原由:在利用 KEIL 自带的库函数中的 _crol_ 和_cror_ 时,在正转和反转程序中应当调动次序的,开始没注意到。
更正后显示正常。
2)在开始实验的时候推行的是向来循环的方式,利用按键嵌套。
以后发现不理想,每次按键按到三次以上后进入死循环。
解决方案:利用一个按键,显示一次。
并加入按键开释,防备误动作。
指导老师署名:日期:实验一程序 :/******************************************************************** **************工程说明:本工程主要达成了一下功能:1,复位后演示全部功能2,灯闪耀三次3,流水灯正转4,流水灯反转函数说明:yanshi() :演示程序dengss() :闪耀程序right():正转程序left():反转程序scankey() :按键扫描********************************************************************* **************/#ifndef _led_h#define _led_h#define uint unsigned int#define uchar unsigned charuchar i,j,a,b,c,d;uchar flag=0;//亮灯判断标记uchar aa,bb,cc,dd,ss;sbit H1=P3^6;sbit key1=P0^5;sbit key2=P0^6;sbit key3=P0^7;void delay(uint);//1ms 延时void yanshi(void);//演示全部亮灯方式void dengss(void);//闪耀三次void left(void); //左循环亮灯void right(void);//右循环亮灯void scankey(); //按键扫描#endif#include"stc10.h"#include<intrins.h>#include<led.h> //包含各样变量定义及函数申明main(){yanshi();delay(2000); //两秒后进入可控大循环while(1){scankey();if(flag==0)right();if(flag==1)left();if(flag==2)dengss();}}void delay(uint x){uint i,j;for(i=110;i>0;i--)for(j=x;j>0;j--);}void yanshi(){dengss();right();left();P2=0XFF;P3=0XFF;}void dengss(){for(ss=3;ss>0;ss--)P2=0;P3=0xc3;delay(1000);P2=0xff;P3=0xff;delay(1000);}flag+=3;//退出小循环,只亮一次,增大按键扫描频次}void right(){aa=0xfe;for(a=8;a>0;a--){P2=aa;aa=_crol_(aa,1);delay(500);}bb=0xfb;P2=0xff;//熄灭循环后亮着的for(b=4;b>0;b--){P3=bb;bb=_crol_(bb,1);delay(500);}//D12 保存发亮flag+=3;//退出小循环,只亮一次,增大按键扫描频次}void left(){cc=0xdf;for(c=4;c>0;c--){P3=cc;cc=_cror_(cc,1);delay(500);P3=0xff;// 熄灭 D9dd=0x7f;for(d=8;d>0;d--){P2=dd;dd=_cror_(dd,1);delay(500);}//D1 保存发亮flag+=3;//退出小循环,只亮一次,增大按键扫描频次}void scankey(){H1=0;if(key1==0){delay(10);if(key1==0){flag=0;while(!key1);//等候按键开释}}if(key2==0){delay(10);if(key2==0){flag=1;while(!key2);//等候按键开释}}if(key3==0){delay(10);if(key3==0){flag=2;while(!key3);//等候按键开释}}}实验二准时器或实不时钟实验一、实验目的1)数码管动向显示技术2)准时器的应用3)按键功能定义二、实验实现的功能1) 经过按键能够设定准不时间,启动准时器,准不时间到,让12 个发光二极管闪耀,达成准时器功能。
定时器控制流水灯
定时器控制流水灯The Standardization Office was revised on the afternoon of December 13, 2020成绩信息与通信工程学院实验报告(操作性实验)课程名称:微机原理与微控制器应用实验题目:c51单片机的定时器实验指导教师:班级: 学号:学生姓名:一、实验目的和任务1.掌握定时器中断的编程方法。
2.掌握keil C51集成开发环境在硬件仿真条件下各参数的设置。
二、实验仪器及器件硬件:电脑一台、微机原理与单片机试验箱:51开发板、开关及LED显示单元、导线若干软件:keil uVision4三、实验内容及电路图利用实验板上的八个LED灯作显示,利用定时器中断编写中断一次为50ms的定时程序,控制单片机定时器进行定时,总定时时间为。
四、流程图与程序#include ""#include<>int temp=0x01,num=0;void T0Int() interrupt 1{TH0=(65536-45872)/256;TL0=(65536-45872)%256;num++;if(num==15) {num=0;P1=_crol_(temp,1);temp=P1;}}void main(){EA=1;ET0=1;TMOD=0X01;TH0=(65536-45872)/256;TL0=(65536-45872)%256;TR0=1;while(1);}五、实验结果八个LED灯由左往右依次亮起,并且每个LED灯点亮时间大约为。
六、实验数据分析及处理从实验现象来看,LED灯从左到右依次点亮,符合实验要求,说明实验操作正确,实验结果正确。
七、实验结论与感悟(或讨论)。
单片机流水灯实训报告
一、实训目的本次实训旨在通过实践操作,让学生了解单片机的基本原理和应用,掌握单片机编程和调试方法,培养学生的动手能力和创新意识。
通过流水灯的设计与实现,让学生熟悉单片机的I/O口操作、定时器使用、按键扫描以及延时函数编写等基本技能。
二、实训内容1. 单片机硬件介绍本次实训使用的单片机为STC89C52,它是一款性能稳定、功能强大的单片机,具有32个I/O口、2个定时器、1个串行通信接口等。
STC89C52单片机的内部结构包括中央处理器(CPU)、存储器、定时器、串行通信接口等模块。
2. 流水灯设计原理流水灯是一种常见的单片机应用,通过控制LED灯的亮灭来实现动态的灯光效果。
本实训中,流水灯的设计原理如下:(1)使用单片机的I/O口控制LED灯的亮灭。
(2)利用定时器产生定时中断,实现LED灯的闪烁效果。
(3)通过按键扫描控制流水灯的流动方向。
3. 实训步骤(1)硬件连接根据电路图连接单片机、LED灯、按键等元器件。
电路图如下:```+5V ----> LED1 ----> 电阻 ----> P1.0+5V ----> LED2 ----> 电阻 ----> P1.1+5V ----> LED3 ----> 电阻 ----> P1.2+5V ----> LED4 ----> 电阻 ----> P1.3+5V ----> 按键 ----> 电阻 ----> P3.2GND ----> LED1GND ----> LED2GND ----> LED3GND ----> LED4GND ----> 按键```(2)编程使用Keil uVision5软件编写程序。
程序主要分为以下几个部分:a. 初始化函数:设置单片机的I/O口、定时器等。
b. 定时器中断服务函数:控制LED灯的闪烁。
c. 按键扫描函数:检测按键状态,控制流水灯的流动方向。
单片机实验报告流水灯
单片机实验报告流水灯单片机实验报告:流水灯引言:单片机是现代电子技术中非常重要的一部分,它广泛应用于各个领域,如家电、汽车、通信等。
单片机实验是学习单片机的基础,通过实际操作来理解单片机的原理和应用。
本报告将介绍一个常见的单片机实验项目——流水灯实验。
一、实验目的流水灯实验旨在通过控制单片机的IO口,实现多个LED灯按照顺序依次点亮和熄灭的效果。
通过这个实验,可以加深对单片机IO口的控制和编程的理解。
二、实验器材1. 单片机开发板:我们使用的是STC89C52开发板,它是一种基于8051内核的单片机开发板。
2. LED灯:我们使用了8个LED灯,分别连接到单片机开发板的8个IO口上。
3. 连接线:用于连接单片机开发板和LED灯。
三、实验原理流水灯实验的原理很简单,通过控制单片机的IO口输出高低电平来控制LED灯的亮灭。
当某个IO口输出高电平时,对应的LED灯点亮;当IO口输出低电平时,对应的LED灯熄灭。
四、实验步骤1. 连接电路:将8个LED灯分别连接到单片机开发板的8个IO口上,确保连接正确。
2. 编写程序:使用C语言编写单片机程序,控制IO口的高低电平变化。
程序的主要逻辑是通过一个循环,依次将某个IO口输出高电平,然后延时一段时间,再将该IO口输出低电平,再延时一段时间,以此循环实现流水灯的效果。
3. 烧录程序:将编写好的程序烧录到单片机开发板中,确保程序能够正确运行。
4. 调试实验:将单片机开发板连接到电源,观察LED灯是否按照预期的顺序点亮和熄灭。
如果有问题,可以通过调试程序或检查电路连接来解决。
五、实验结果经过调试和实验,我们成功地实现了流水灯的效果。
8个LED灯按照顺序依次点亮和熄灭,形成了一个流动的灯光效果。
这个实验不仅让我们学习了单片机的IO口控制,还提高了我们的动手能力和解决问题的能力。
六、实验总结通过这个实验,我们深入了解了单片机的原理和应用。
单片机作为一种微型计算机,具有体积小、功耗低、成本低等优点,广泛应用于各个领域。
单片机学习编程之流水灯篇OK
第一章单片机的基础学习第一个实验 LED发光二极管的左移右移(D1到D8依次)点亮二极管点亮的原理图如下。
实际上是接在P1口。
原理图说明:发光二极管阴极接单片机,让电流流入单片机,因为单片机输出电流小,点不亮发光二极管。
发光二极管点亮电流为5 mA至20mA。
编程说明:(1)做一个LED的左移右移,有硬件电路可知,输出“0”才能使LED亮。
开始时P1.0亮,——P1.1亮——P1.2亮….——P1.7亮——P1.0亮,重复循环点亮LED。
(2)延时时间的设计:石英晶体为12MHz,1个机器周期为1微秒,采用单片机每走一步指令需要的时间来延时。
✧延时时间子程序(10.002毫秒)Delay: MOV R4,#20 ;2个机器周期,2微秒D1: MOV R5,#248 ;2个机器周期,2微秒DJNZ R5,$ ;2个机器周期,2*248微秒DJNZ R4,D1 ;2个机器周期,2*20微秒RET这个延时子程序:20*(498+2)+2=10002个机器周期=10.002毫秒。
✧延时时间子程序(200毫秒)Delay: MOV R3,#20 ; 200微秒D1:MOV R4,#20 ;10微秒D2: MOV R5,#248DJNZ R5,$DJNZ R4,D2DJNZ R3,D1RET(3)汇编程序源代码注意:向电脑上编辑程序时注意标点符号要在英文的格式下输入。
ORG 00HMAIN: MOV A,#0FFHCLR CMOV R2,#08H;左移点亮发光二极管LOOP: RLC A ;带进位左移一位MOV P1,A;点亮LED发光二极管CALL DELAY;调用延时子程序DJNZ R2,LOOP;左移、轮流点亮发;光二极管;左移点亮发光二极管后,再右移点亮发光二极管MOV R2,#07HLOOP1: RRC A ;带进位右移一位MOV P1,A;点亮LED发光二极管CALL DELAY;调用延时子程序DJNZ R2,LOOP1JMP MAIN; 返回到初始位置;设置延时时间DELAY: MOV R3,#20D1: MOV R4,#20D2: MOV R5,#248DJNZ R5,$DJNZ R4,D2DJNZ R3,D1RETEND(4)C程序源代码#include <reg51.h>void Delay()//延时子程序{ int i,j;for(i=0;i<=255;i++)for(j=0;j<=255;j++);}void main(){unsigned int i;unsigned int temp;P1=0xff;while(1){temp=0x01;for(i=0;i<8;i++){P1=~temp;逐位取反Delay();temp=temp<<1;}}}(4)实验结果图(注意学习板上的JJ_P1连接器连上)第二个实验采用定时器来设置延时时间(方式0)说明:(1)开始时p1.0亮,延时0.2秒后左移至p1.1亮,如此左移7次后至,再延时0.2秒右移至p1.6亮,如此右移7次后至p1.0亮;(2)延时时间0.2秒,使用定时器0在方式0下工作;采用查询的方式(3)程序源代码ORG 00HMOV TMOD,#00H /***设置定时器的工作方式***/START: CLR CMOV A,#0FFHMOV R2,#08 /***设置循环次数***/LOOP: RLC A /***带进位左循环累加器,点亮发光二极管***/ MOV P1,A /***设置定时器定时时间***/MOV R3,#100CALL DELAYDJNZ R2,LOOP /***点亮了八个发光二极管吗,没有继续***/MOV R2,#07LOOP1: RRC AMOV P2,AMOV R3,#100CALL DELAYDJNZ R2,LOOP1JMP START/***通过单片机内部的定时器设置定时时间***/DELAY: SETB TR0 /***启动定时器***/AGAIN: MOV TL0,#(8192-2000) MOD 32MOV TH0,#(8192-2000) / 32LOOP2: JBC TF0,LOOP3 ;通过查询的方式来判断时间定时器的计时JMP LOOP2LOOP3: DJNZ R3,AGAINCLR TR0RET;非中断END(4)实验结果图第三个实验采用定时器来设置延时时间(方式1)(1)开始时p1.0亮,延时0.2秒后左移至p2.1亮,如此左移7次后至,再延时0.2秒右移至p1.7亮,如此右移7次后至p1.0亮;(2)延时时间0.2秒,使用定时器0在方式1下工作;采用查询的方式(3)源程序代码ORG 00HMOV TMOD,#01HSTART: CLR CMOV A,#0FFHMOV R2,#08LOOP: RLC AMOV P1,AMOV R3,#20CALL DELAYDJNZ R2,LOOPMOV R2,#07LOOP1: RRC AMOV P1,AMOV R3,#20CALL DELAYDJNZ R2,LOOP1JMP STARTDELAY: SETB TR0AGAIN: MOV TL0,#0F0HMOV TH0,#0D8HLOOP2: JBC TF0,LOOP3JMP LOOP2LOOP3: DJNZ R3,AGAINCLR TR0RETEND附录资料:红外发射器的原理图AT89S52下载器的原理图。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
可位寻址, 也可字节寻址
TF1 TR1 TF0 TR0 IE1 IP1 IE0 IP0
M1M0
00:方式0,13位计数寄存器 01:方式1 ,16位计数寄存器,用于定时 和计数 10:方式2 ,自动重装载8位计数寄存器 ,用于波特率发生器 11:方式3,2个8位计数寄存器
定时器使用步骤
1.设置TMOD,使之工作在需求状态;
时间间隔1s的双向流水灯;
方法2
50ms 初值=15536=0x3CB0 #include<reg52.h> void main() { unsigned int i,j,value; TMOD=0x01; TH0=0x3c; TL0=0xb0; TR0=1; //此位可位操作 while(1) { value=0x01; for(i=0;i<14;i++) { for(j=0;j<20;j++) { while(TF0!=1); TH0=0x3c; TL0=0xb0; TF0=0; } P1=~value; if(i<7) value=value<<1; else value=value>>1;
#include<reg52.h> void main() { unsigned int i,value,dec; TMOD=0x01; TH0=0x3c; TL0=0xb0; TR0=1; //此位可位操作 while(1) { value=254; dec=1; for(i=0;i<8;i++) { while(TF0!=1); TH0=0x3c; TL0=0xb0; P1=value; value=value-dec; dec=dec*2; } }
方法2 时间间隔50ms的流水灯; 50ms 初值=15536=0x3CB0
时间间隔1s=20*50ms的流水灯;
方法2
50ms 初值=15536=0x3CB0 #include<reg52.h> void main() { unsigned int i,j,value; TMOD=0x01; TH0=0x3c; TL0=0xb0; TR0=1; //此位可位操作 while(1) { value=0x01; for(i=0;i<8;i++) { for(j=0;j<20;j++) //20次*50ms/次 { while(TF0!=1); TH0=0x3c; TL0=0xb0; TF0=0; } P1=~value; value=value<<1; }
void main() { unsigned int i,j,value,dec; TMOD=0x01; TH0=0x3c; TL0=0xb0; TR0=1; //此位可位操作 while(1) { value=254; dec=1; for(i=0;i<8;i++) {P1=value; for(j=0;j<10;j++) //10次*50ms/次 { while(TF0!=1); TH0=0x3c; TL0=0xb0; TF0=0; } value=value-dec; dec=dec*2; } }
定时1s =50*20ms
#include<reg52.h> sbit P1_0=P1^0; void main() { unsigned int counter; TMOD=0x01; TH0=0xb1; TL0=0xe0; TR0=1; //此位可位操作 while(1) { if(1==TF0) {TH0=0xb1; TL0=0xe0; counter++;} if(50==counter) {counter=0; P1_0=~P1_0; } } }
20ms 初值=45536=0xB1E0
TF0=0;
复习
定时器定时功能的使用
• TMOD:选择T0还是T1 • TCON:选择方式1 • 设置初值放置于TH0,TL0或TH1,TL1中
方式1: 定时时间=(65536-初值)*机器周期 初值=65536-定时时间/机器周期
时间间隔0.5s=10*50ms的流水灯; 书上程序 50ms 初值=15536=0x3CB0 #include<reg52.h>
LOGO
C / T :功能选择位。当=0时选择定时功能,计数脉冲由
内部提供,计数周期等于机器周期。当=1时选择为计数 功能,计数脉冲为外部引脚T0、T1引入的外部脉冲信号。
LOGO
M1和M0:T0和T1工作方式控制位。定时/计数器的工作方 式有M1M0两位状态决定,这两位有四种编码方式,对应 于四种工作方式。四种方式定义如表所示:
书上方法
TF0=0;
时间间隔1s=20*50ms的流水灯; 书上方法 50ms 初值=15536=0x3CB0 #include<reg52.h>
void main() { unsigned int i,j,value,dec; TMOD=0x01; TH0=0x3c; TL0=(1) { value=254; dec=1; for(i=0;i<8;i++) { for(j=0;j<20;j++) //20次*50ms/次 { while(TF0!=1); TH0=0x3c; TL0=0xb0; TF0=0; } P1=value; value=value-dec; dec=dec*2; } }
LOGO
单片机定时器/计数器结构图
LOGO
定时器的工作原理: 定时器/计数器是一个加“1”计数器,来一个脉冲即 进行加1计数,直至计数器的各位全为“1”,再来一个脉 冲,计数器回0(即溢出),且使TF0(定时器0)或TF1 (定时器1)置1,表示时间到,计数值乘以脉冲周期就 是定时时间。 输入的脉冲来源有2个:一个是单片机晶体振荡器经 12分频;另一个是T0/T1端的外部输入脉冲。作定时器用 时,应采用晶体振荡器经12分频的脉冲。
LOGO
定时器功能
两个寄存器:TMOD和TCON 4个计数寄存器:TH0,TL0;TH1,TL1 方式1: 定时时间=(65536-初值)*12/振荡频率 初值=65536-定时时间*振荡频率/12
例如定时1ms:
初值=65536-1s*12*103Hz/12 =65536-1000 =64536 =0xFC18
计数器:在机器周期内采样T0(或T1)
脉冲的下降沿,来一个下降沿计数器的 值加1。当计数器值溢出(全1)时回0,中 断标志TF置1.
1。定时器知识 (1)定时器/计数器的内部结构及工作原理 单片机内部设有2个16位的可编程的定时器/计数器。 简称为定时器0(T0)、定时器1(T1)。可编程是指其 功能(如工作模式、定时时间等)均可通过指令来确定 或改变。
任务三 利用硬件 定时实现流水灯
LOGO
常用延时方法
非精确延时 • For(i=0;i<100;i++); • i=0;while(i--);
精确延时
• 利用库函数_nop_ ( ) ; //延时一个机器周期 (需要include<intrins.h>) • 利用定时器进行定时
定时时间=(65536-初值)*12/振荡频率≤65536μs
#include<reg52.h> sbit P1_0=P1^0; void main() { TMOD=0x01; TH0=0; TL0=0; TR0=1; //此位可位操作 while(1) { if(1==TF0) { //TH0=0; TL0=0; TF0=0; //此位可位操作 P1_0=~P1_0; //此位可位操作 } } }
操作练习1
请用定时器0实现:
• 时间间隔50ms的流水灯; • 时间间隔1s的流水灯;
操作练习2
请用硬件定时器实现:
任选三个LED灯,分别作为红、黄、绿交
通灯,实现绿灯亮1s,然后黄灯快闪3次,再 红灯亮2s,黄灯快闪3次,绿灯亮1s,……
时间间隔50ms的流水灯; 50ms 初值=15536=0x3CB0
M1M0 00 01 10 方式 方式0 方式1 方式2 说明 TL的低5位和TH的8位构成13位计数器 TL的8位和TH的8位构成16位的计数器 具有自动重装功能的8位计数器 T0分成两个独立的计数器,T1可工作 在方式0~方式2
11
方式3
LOGO
TCON
if(1==TF0) {TH0=0xff; TL0=0x00; TF0=0; P1_0=~P1_0; } 或if(1==TF1) {TH1=0xfc; TL1=0x18; TF1=0; P1_0=~P1_0; }
定时1ms 初值=65536-1000=0xFC18
#include<reg52.h> sbit P1_0=P1^0; void main() { TMOD=0x01; TH0=0xfc; TL0=0x18; TR0=1; //此位可位操作 while(1) { if(1==TF0) {TH0=0xfc; TL0=0x18; TF0=0; //此位可位操作 P1_0=~P1_0; //此位可位操作 } } }
#include<reg52.h> void main() { unsigned int i,value; TMOD=0x01; TH0=0x3c; TL0=0xb0; TR0=1; //此位可位操作 while(1) { value=0x01; for(i=0;i<8;i++) { while(TF0!=1); TH0=0x3c; TL0=0xb0; TF0=0; P1=~value; value=value<<1; } } }