51单片机实例 用定时器 T0 的中断控制 1 位 LED 闪烁
C51单片机实战100例要点
目录目录 1函数的使用和熟悉 6实例3:用单片机控制第一个灯亮7实例4:用单片机控制一个灯闪烁:认识单片机的工作频率7实例5:将P1口状态分别送入P0、P2、P3口:认识I/O口的引脚功能8实例6:使用P3口流水点亮8位LED 9实例7:通过对P3口地址的操作流水点亮8位LED 11实例8:用不同数据类型控制灯闪烁时间13实例9:用P0口、P1 口分别显示加法和减法运算结果 15实例10:用P0、P1口显示乘法运算结果15实例11:用P1、P0口显示除法运算结果16实例12:用自增运算控制P0口8位LED流水花样17实例13:用P0口显示逻辑"与"运算结果18实例14:用P0口显示条件运算结果18实例15:用P0口显示按位"异或"运算结果19实例16:用P0显示左移运算结果19实例17:"万能逻辑电路"实验20实例18:用右移运算流水点亮P1口8位LED 20实例19:用if语句控制P0口8位LED的流水方向22实例20:用swtich语句的控制P0口8位LED的点亮状态 23 实例21:用for语句控制蜂鸣器鸣笛次数25实例22:用while语句控制LED 27实例23:用do-while语句控制P0口8位LED流水点亮29 实例24:用字符型数组控制P0口8位LED流水点亮30实例25:用P0口显示字符串常量 32实例26:用P0 口显示指针运算结果33实例27:用指针数组控制P0口8位LED流水点亮34实例28:用数组的指针控制P0 口8 位LED流水点亮 35实例29:用P0 、P1口显示整型函数返回值37实例30:用有参函数控制P0口8位LED流水速度38实例31:用数组作函数参数控制流水花样40实例32:用指针作函数参数控制P0口8位LED流水点亮41 实例33:用函数型指针控制P1口灯花样44实例34:用指针数组作为函数的参数显示多个字符串46实例35:字符函数ctype.h应用举例48实例36:内部函数intrins.h应用举例48实例37:标准函数stdlib.h应用举例50实例38:字符串函数string.h应用举例 51实例39:宏定义应用举例2 52实例40:宏定义应用举例2 53实例41:宏定义应用举例3 53中断、定时器54实例42:用定时器T0查询方式P2口8位控制LED闪烁54 实例43:用定时器T1查询方式控制单片机发出1KHz音频 55 实例44:将计数器T0计数的结果送P1口8位LED显示56 实例45:用定时器T0的中断控制1位LED闪烁58实例46:用定时器T0的中断实现长时间定时59实例47:用定时器T1中断控制两个LED以不同周期闪烁61 实例48:用计数器T1的中断控制蜂鸣器发出1KHz音频63实例49:用定时器T0的中断实现"渴望"主题曲的播放64 实例50-1:输出50个矩形脉冲69实例50-2:计数器T0统计外部脉冲数71实例51-2:定时器T0的模式2测量正脉冲宽度71实例52:用定时器T0控制输出高低宽度不同的矩形波73 实例53:用外中断0的中断方式进行数据采集75实例54-1:输出负脉宽为200微秒的方波76实例54-2:测量负脉冲宽度77实例55:方式0控制流水灯循环点亮78实例56-1:数据发送程序81实例56-2:数据接收程序83实例57-1:数据发送程序84实例57-2:数据接收程序87实例58:单片机向PC发送数据88实例59:单片机接收PC发出的数据90数码管显示 92实例60:用LED数码显示数字5 92实例61:用LED数码显示器循环显示数字0~9 92实例62:用数码管慢速动态扫描显示数字"1234" 94实例63:用LED数码显示器伪静态显示数字1234 95实例64:用数码管显示动态检测结果96实例65:数码秒表设计100实例66:数码时钟设计103实例67:用LED数码管显示计数器T0的计数值110实例68:静态显示数字“59”112键盘控制113实例69:无软件消抖的独立式键盘输入实验113实例70:软件消抖的独立式键盘输入实验114实例71:CPU控制的独立式键盘扫描实验115实例72:定时器中断控制的独立式键盘扫描实验121实例73:独立式键盘控制的4级变速流水灯128实例74:独立式键盘的按键功能扩展:"以一当四" 132实例75:独立式键盘调时的数码时钟实验135实例76:独立式键盘控制步进电机实验143实例77:矩阵式键盘按键值的数码管显示实验148实例78:矩阵式键盘按键音154实例79:简易电子琴157实例80:矩阵式键盘实现的电子密码锁168液晶显示LCD 175实例81:用LCD显示字符'A' 175实例82:用LCD循环右移显示"Welcome to China" 181 实例83:用LCD显示适时检测结果188实例84:液晶时钟设计196一些芯片的使用*****24c02 DS18B20 X5045 ADC0832 DAC0832 DS1302 红外遥控207实例85:将数据"0x0f"写入AT24C02再读出送P1口显示207实例86:将按键次数写入AT24C02,再读出并用1602LCD显示216实例87:对I2C总线上挂接多个AT24C02的读写操作 230实例88:基于AT24C02的多机通信读取程序241实例88:基于AT24C02的多机通信写入程序249实例90:DS18B20温度检测及其液晶显示 271实例91:将数据"0xaa"写入X5045再读出送P1口显示288实例92:将流水灯控制码写入X5045并读出送P1口显示295实例93:对SPI总线上挂接多个X5045的读写操作303实例94:基于ADC0832的数字电压表 311实例95:用DAC0832产生锯齿波电压 323实例96:用P1口显示红外遥控器的按键值324实例97:用红外遥控器控制继电器 328实例98:基于DS1302的日历时钟 333实例99:单片机数据发送程序351实例100:电机转速表设计 354//模拟霍尔脉冲363函数的使用和熟悉实例3:用单片机控制第一个灯亮#include<reg51.h> //包含51单片机寄存器定义的头文件void main(void){P1=0xfe; //P1=1111 1110B,即P1.0输出低电平}实例4:用单片机控制一个灯闪烁:认识单片机的工作频率#include<reg51.h> //包含单片机寄存器的头文件/****************************************函数功能:延时一段时间*****************************************/void delay(void) //两个void意思分别为无需返回值,没有参数传递{unsigned int i; //定义无符号整数,最大取值范围65535for(i=0;i<20000;i++) //做20000次空循环; //什么也不做,等待一个机器周期}/*******************************************************函数功能:主函数(C语言规定必须有也只能有1个主函数)********************************************************/void main(void){while(1) //无限循环{P1=0xfe; //P1=1111 1110B,P1.0输出低电平delay(); //延时一段时间P1=0xff; //P1=1111 1111B,P1.0输出高电平delay(); //延时一段时间}}实例5:将P1口状态分别送入P0、P2、P3口:认识I/O口的引脚功能#include<reg51.h> //包含单片机寄存器的头文件/*******************************************************函数功能:主函数(C语言规定必须有也只能有1个主函数)********************************************************/void main(void){while(1) //无限循环{P1=0xff; // P1=1111 1111B,熄灭LEDP0=P1; // 将P1口状态送入P0口P2=P1; // 将P1口状态送入P2口P3=P1; // 将P1口状态送入P3口}}实例6:使用P3口流水点亮8位LED#include<reg51.h> //包含单片机寄存器的头文件/****************************************函数功能:延时一段时间*****************************************/void delay(void){unsigned char i,j;for(i=0;i<250;i++)for(j=0;j<250;j++);}/******************************************************* 函数功能:主函数********************************************************/ void main(void){while(1){P3=0xfe; //第一个灯亮delay(); //调用延时函数P3=0xfd; //第二个灯亮delay(); //调用延时函数P3=0xfb; //第三个灯亮delay(); //调用延时函数P3=0xf7; //第四个灯亮delay(); //调用延时函数P3=0xef; //第五个灯亮 delay(); //调用延时函数P3=0xdf; //第六个灯亮delay(); //调用延时函数P3=0xbf; //第七个灯亮 delay(); //调用延时函数P3=0x7f; //第八个灯亮 delay(); //调用延时函数}}实例7:通过对P3口地址的操作流水点亮8位LED#include<reg51.h> //包含单片机寄存器的头文件sfr x=0xb0; //P3口在存储器中的地址是b0H,通过sfr可定义8051内核单片机//的所有内部8位特殊功能寄存器,对地址x的操作也就是对P1口的操作/****************************************函数功能:延时一段时间*****************************************/void delay(void){unsigned char i,j;for(i=0;i<250;i++)for(j=0;j<250;j++); //利用循环等待若干机器周期,从而延时一段时间}/*****************************************函数功能:主函数******************************************/void main(void){while(1){x=0xfe; //第一个灯亮delay(); //调用延时函数x=0xfd; //第二个灯亮delay(); //调用延时函数x=0xfb; //第三个灯亮delay(); //调用延时函数x=0xf7; //第四个灯亮delay(); //调用延时函数x=0xef; //第五个灯亮 delay(); //调用延时函数x=0xdf; //第六个灯亮delay(); //调用延时函数x=0xbf; //第七个灯亮 delay(); //调用延时函数x=0x7f; //第八个灯亮 delay(); //调用延时函数}}实例8:用不同数据类型控制灯闪烁时间#include<reg51.h> //包含单片机寄存器的头文件/******************************************************函数功能:用整形数据延时一段时间******************************************************/void int_delay(void) //延时一段较长的时间{unsigned int m; //定义无符号整形变量,双字节数据,值域为0~65535 for(m=0;m<36000;m++); //空操作}/******************************************************函数功能:用字符型数据延时一段时间******************************************************/void char_delay(void) //延时一段较短的时间{unsigned char i,j; //定义无符号字符型变量,单字节数据,值域0~255 for(i=0;i<200;i++)for(j=0;j<180;j++); //空操作}/****************************************************** 函数功能:主函数******************************************************/ void main(void){unsigned char i;while(1){for(i=0;i<3;i++){P1=0xfe; //P1.0口的灯点亮int_delay(); //延时一段较长的时间P1=0xff; //熄灭int_delay(); //延时一段较长的时间}for(i=0;i<3;i++){P1=0xef; //P1.4口的灯点亮char_delay(); //延时一段较长的时间P1=0xff; //熄灭char_delay(); //延时一段较长的时间}}}实例9:用P0口、P1 口分别显示加法和减法运算结果#include<reg51.h>void main(void){unsigned char m,n;m=43; //即十进制数2x16+11=43n=60; //即十进制数3x16+12=60P1=m+n; //P1=103=0110 0111B,结果P1.3、P1.4、P1.7 口的灯被点亮P0=n-m; //P0=17=0001 0001B,结果P0.0、P0.4的灯被熄灭}实例10:用P0、P1口显示乘法运算结果#include<reg51.h> //包含单片机寄存器的头文件void main(void){unsigned char m,n;unsigned int s;n=71;s=m*n; //s=64*71=4544,需要16位二进制数表示,高8位送P1口,低8位送P0口//由于4544=17*256+192=H3*16*16*16+H2*16*16+H1*16+H0//两边同除以256,可得17+192/256=H3*16+H2+(H1*16+H0)/256//因此,高8位16进制数H3*16+H2必然等于17,即4544除以256的商//低8位16进制数H1*16+H0必然等于192,即4544除以256的余数P1=s/256; //高8位送P1口,P1=17=11H=0001 0001B, P1.0和P1.4口灭,其余亮P0=s%256; //低8位送P0口, P3=192=c0H=11000000B,P3.1,P3.6,P3.7口灭,其余亮}实例11:用P1、P0口显示除法运算结果#include<reg51.h> //包含单片机寄存器的头文件void main(void){P1=36/5; //求整数P0=((36%5)*10)/5; //求小数while(1); //无限循环防止程序“跑飞”}实例12:用自增运算控制P0口8位LED流水花样#include<reg51.h> //包含单片机寄存器的头文件/****************************************************** 函数功能:延时一段时间******************************************************/ void delay(void){unsigned int i;for(i=0;i<20000;i++);}/****************************************************** 函数功能******************************************************/void main(void){unsigned char i;for(i=0;i<255;i++) //注意i的值不能超过255{P0=i; //将i的值送P0口delay(); //调用延时函数}}实例13:用P0口显示逻辑"与"运算结果#include<reg51.h> //包含单片机寄存器的头文件void main(void){P0=(4>0)&&(9>0xab);//将逻辑运算结果送P0口while(1); //设置无限循环,防止程序“跑飞”}实例14:用P0口显示条件运算结果#include<reg51.h> //包含单片机寄存器的头文件void main(void){P0=(8>4)?8:4;//将条件运算结果送P0口,P0=8=0000 1000B while(1); //设置无限循环,防止程序“跑飞”}实例15:用P0口显示按位"异或"运算结果#include<reg51.h> //包含单片机寄存器的头文件void main(void){P0=0xa2^0x3c;//将条件运算结果送P0口,P0=8=0000 1000B while(1); //设置无限循环,防止程序“跑飞”}实例16:用P0显示左移运算结果#include<reg51.h> //包含单片机寄存器的头文件void main(void){P0=0x3b<<2;//将左移运算结果送P0口,P0=1110 1100B=0xec while(1); //无限循环,防止程序“跑飞”}实例17:"万能逻辑电路"实验#include<reg51.h> //包含单片机寄存器的头文件sbit F=P1^4; //将F位定义为P1.4sbit X=P1^5; //将X位定义为P1.5sbit Y=P1^6; //将Y位定义为P1.6sbit Z=P1^7; //将Z位定义为P1.7void main(void){while(1){F=((~X)&Y)|Z; //将逻辑运算结果赋给F;}}实例18:用右移运算流水点亮P1口8位LED#include<reg51.h> //包含单片机寄存器的头文件/*****************************函数功能:延时一段时间*****************************/void delay(void){unsigned int n;for(n=0;n<30000;n++);}/*****************************函数功能:主函数*****************************/void main(void){unsigned char i;while(1){P1=0xff;delay();for(i=0;i<8;i++)//设置循环次数为8{P1=P1>>1; //每次循环P1的各二进位右移1位,高位补0delay(); //调用延时函数}}}实例19:用if语句控制P0口8位LED的流水方向#include<reg51.h> //包含单片机寄存器的头文件sbit S1=P1^4; //将S1位定义为P1.4sbit S2=P1^5; //将S2位定义为P1.5/*****************************函数功能:主函数*****************************/void main(void){while(1){if(S1==0) //如果按键S1按下P0=0x0f; //P0口高四位LED点亮if(S2==0) //如果按键S2按下P0=0xf0; //P0口低四位LED点亮}}实例20:用swtich语句的控制P0口8位LED的点亮状态#include<reg51.h> //包含单片机寄存器的头文件sbit S1=P1^4; //将S1位定义为P1.4/*****************************函数功能:延时一段时间*****************************/void delay(void){unsigned int n;for(n=0;n<10000;n++);}/*****************************函数功能:主函数*****************************/void main(void){unsigned char i;i=0; //将i初始化为0while(1){if(S1==0) //如果S1键按下{delay(); //延时一段时间if(S1==0) //如果再次检测到S1键按下i++; //i自增1if(i==9) //如果i=9,重新将其置为1i=1;}switch(i) //使用多分支选择语句{case 1: P0=0xfe; //第一个LED亮break;case 2: P0=0xfd; //第二个LED亮break;case 3:P0=0xfb; //第三个LED亮break;case 4:P0=0xf7; //第四个LED亮break;case 5:P0=0xef; //第五个LED亮break;case 6:P0=0xdf; //第六个LED亮break;case 7:P0=0xbf; //第七个LED亮break;case 8:P0=0x7f; //第八个LED亮break;default: //缺省值,关闭所有LEDP0=0xff;}}}实例21:用for语句控制蜂鸣器鸣笛次数#include<reg51.h> //包含单片机寄存器的头文件sbit sound=P3^7; //将sound位定义为P3.7/****************************************函数功能:延时形成1600Hz音频****************************************/void delay1600(void){unsigned char n;for(n=0;n<100;n++);}/**************************************** 函数功能:延时形成800Hz音频****************************************/ void delay800(void){unsigned char n;for(n=0;n<200;n++);}/**************************************** 函数功能:主函数****************************************/ void main(void){unsigned int i;while(1){for(i=0;i<830;i++){sound=0; //P3.7输出低电平delay1600();sound=1; //P3.7输出高电平delay1600();}for(i=0;i<200;i++){sound=0; //P3.7输出低电平delay800();sound=1; //P3.7输出高电平delay800();}}}实例22:用while语句控制LED#include<reg51.h> //包含单片机寄存器的头文件/****************************************函数功能:延时约60ms (3*100*200=60000μs) ****************************************/void delay60ms(void){unsigned char m,n;for(m=0;m<100;m++)for(n=0;n<200;n++);}/****************************************函数功能:主函数****************************************/void main(void){unsigned char i;while(1) //无限循环{i=0; //将i初始化为0while(i<0xff) //当i小于0xff(255)时执行循环体{P0=i; //将i送P0口显示delay60ms(); //延时i++; //i自增1}}}实例23:用do-while语句控制P0口8位LED流水点亮#include<reg51.h> //包含单片机寄存器的头文件/****************************************函数功能:延时约60ms (3*100*200=60000μs)****************************************/void delay60ms(void){unsigned char m,n;for(m=0;m<100;m++)for(n=0;n<200;n++);}/****************************************函数功能:主函数****************************************/void main(void){do{P0=0xfe; //第一个LED亮delay60ms();P0=0xfd; //第二个LED亮delay60ms();P0=0xfb; //第三个LED亮delay60ms();P0=0xf7; //第四个LED亮delay60ms();P0=0xef; //第五个LED亮delay60ms();P0=0xdf; //第六个LED亮delay60ms();delay60ms();P0=0xbf; //第七个LED亮delay60ms();P0=0x7f; //第八个LED亮delay60ms();}while(1); //无限循环,使8位LED循环流水点亮}实例24:用字符型数组控制P0口8位LED流水点亮#include<reg51.h> //包含单片机寄存器的头文件/****************************************函数功能:延时约60ms (3*100*200=60000μs)****************************************/void delay60ms(void){unsigned char m,n;for(m=0;m<100;m++)for(n=0;n<200;n++);}/****************************************函数功能:主函数****************************************/void main(void){unsigned char i;unsigned char code Tab[ ]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //定义无符号字符型数组while(1){for(i=0;i<8;i++){P0=Tab[i];//依次引用数组元素,并将其送P0口显示delay60ms();//调用延时函数}}}实例25:用P0口显示字符串常量#include<reg51.h> //包含单片机寄存器的头文件/*************************************************函数功能:延时约150ms (3*200*250=150 000μs=150ms*************************************************/void delay150ms(void){unsigned char m,n;for(m=0;m<200;m++)for(n=0;n<250;n++);}/*************************************************函数功能:主函数*************************************************/void main(void){unsigned char str[]={"Now,Temperature is :"}; //将字符串赋给字符型全部元素赋值unsigned char i;while(1){i=0; //将i初始化为0,从第一个元素开始显示while(str[i]!='\0') //只要没有显示到结束标志'\0'{P0=str[i]; //将第i个字符送到P0口显示delay150ms(); //调用150ms延时函数i++; //指向下一个待显字符}}}实例26:用P0 口显示指针运算结果#include<reg51.h>void main(void){unsigned char *p1,*p2; //定义无符号字符型指针变量p1,p2 unsigned char i,j; //定义无符号字符型数据i=25; //给i赋初值25j=15;p1=&i; //使指针变量指向i ,对指针初始化p2=&j; //使指针变量指向j ,对指针初始化P0=*p1+*p2; //*p1+*p2相当于i+j,所以P0=25+15=40=0x28//则P0=0010 1000B,结果P0.3、P0.5引脚LED熄灭,其余点亮while(1); //无限循环,防止程序“跑飞”}实例27:用指针数组控制P0口8位LED流水点亮#include<reg51.h>/*************************************************函数功能:延时约150ms (3*200*250=150 000μs=150ms*************************************************/void delay150ms(void){unsigned char m,n;for(m=0;m<200;m++)for(n=0;n<250;n++);}/*************************************************函数功能:主函数void main(void){unsigned char code Tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; unsigned char *p[ ]={&Tab[0],&Tab[1],&Tab[2],&Tab[3],&Tab[4],&Tab[5],&Tab[6],&Tab[7]};unsigned char i; //定义无符号字符型数据while(1){for(i=0;i<8;i++){P0=*p[i];delay150ms();}}}实例28:用数组的指针控制P0 口8 位LED流水点亮#include<reg51.h>/*************************************************函数功能:延时约150ms (3*200*250=150 000μs=150msvoid delay150ms(void){unsigned char m,n;for(m=0;m<200;m++)for(n=0;n<250;n++);}/*************************************************函数功能:主函数*************************************************/void main(void){unsigned char i;unsigned char Tab[ ]={0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE,0xFE,0xFC,0xFB,0xF0,0xE0,0xC0,0x80,0x00,0xE7,0xDB,0xBD,0x7E,0x3C,0x18,0x00,0x81,0xC3,0xE7,0x7E,0xBD,0xDB,0xE7,0xBD,0xDB};//流水灯控制码unsigned char *p; //定义无符号字符型指针p=Tab; //将数组首地址存入指针p while(1){for(i=0;i<32;i++) //共32个流水灯控制码{P0=*(p+i); //*(p+i)的值等于a[i]delay150ms(); //调用150ms延时函数}}}实例29:用P0 、P1口显示整型函数返回值#include<reg51.h>/*************************************************函数功能:计算两个无符号整数的和*************************************************/ unsigned int sum(int a,int b){unsigned int s;s=a+b;return (s);}/*************************************************函数功能:主函数*************************************************/void main(void){unsigned z;z=sum(2008,2009);P1=z/256; //取得z的高8位P0=z%256; //取得z的低8位while(1);}实例30:用有参函数控制P0口8位LED流水速度#include<reg51.h>/*************************************************函数功能:延时一段时间*************************************************/void delay(unsigned char x){unsigned char m,n;for(m=0;m<x;m++)for(n=0;n<200;n++);}/*************************************************函数功能:主函数*************************************************/void main(void){unsigned char i;unsigned char codeTab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};//流水灯控制码while(1){//快速流水点亮LEDfor(i=0;i<8;i++) //共8个流水灯控制码{P0=Tab[i];delay(100); //延时约60ms, (3*100*200=60 000μs)}//慢速流水点亮LEDfor(i=0;i<8;i++) //共8个流水灯控制码{P0=Tab[i];delay(250); //延时约150ms, (3*250*200=150 000μs)}}}实例31:用数组作函数参数控制流水花样#include<reg51.h>/*************************************************函数功能:延时约150ms*************************************************/void delay(void){unsigned char m,n;for(m=0;m<200;m++)for(n=0;n<250;n++);}/*************************************************函数功能:流水点亮P0口8位LED*************************************************/void led_flow(unsigned char a[8]){unsigned char i;for(i=0;i<8;i++){P0=a[i];delay();}}/*************************************************函数功能:主函数*************************************************/void main(void){unsigned char codeTab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};//流水灯控制码led_flow(Tab);}实例32:用指针作函数参数控制P0口8位LED流水点亮#include<reg51.h>/*************************************************函数功能:延时约150ms*************************************************/void delay(void){unsigned char m,n;for(m=0;m<200;m++)for(n=0;n<250;n++);}/*************************************************函数功能:流水点亮P0口8位LED*************************************************/void led_flow(unsigned char *p) //形参为无符号字符型指针{unsigned char i;while(1){i=0; //将i置为0,指向数组第一个元素while(*(p+i)!='\0') //只要没有指向数组的结束标志{P0=*(p+i);// 取的指针所指变量(数组元素)的值,送P0口delay(); //调用延时函数i++; //指向下一个数组元素}}}/*************************************************函数功能:主函数*************************************************/void main(void){unsigned char codeTab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE,0xFF,0xFE,0xFC,0xFB,0xF0,0xE0,0xC0,0x80,0x00,0xE7,0xDB,0xBD,0x7E,0xFF,0xFF,0x3C,0x18,0x0,0x81,0xC3,0xE7,0xFF, 0xFF,0x7E};//流水灯控制码unsigned char *pointer;pointer=Tab;led_flow(pointer);}实例33:用函数型指针控制P1口灯花样#include<reg51.h> //包含51单片机寄存器定义的头文件unsigned char code Tab[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F}; //流水灯控制码,该数组被定义为全局变量/**************************************************************函数功能:延时约150ms**************************************************************/void delay(void){unsigned char m,n;for(m=0;m<200;m++)for(n=0;n<250;n++);}/**************************************************************函数功能:流水灯左移**************************************************************/void led_flow(void){unsigned char i;for(i=0;i<8;i++) //8位控制码{P0=Tab[i];delay();}}/**************************************************************函数功能:主函数**************************************************************/void main(void){void (*p)(void); //定义函数型指针,所指函数无参数,无返回值p=led_flow; //将函数的入口地址赋给函数型指针pwhile(1)(*p)(); //通过函数的指针p调用函数led_flow()}实例34:用指针数组作为函数的参数显示多个字符串#include<reg51.h> //包含51单片机寄存器定义的头文件unsigned char code str1[ ]="Temperature is tested by DS18B20";//C语言中,字符串是作为字符数组来处理的unsigned char code str2[ ]="Now temperature is:"; //所以,字符串的名字就是字符串的首地址unsigned char code str3[ ]="The Systerm is designed by Zhang San"; unsigned char code str4[ ]="The date is 2008-9-30";unsigned char *p[ ]={str1,str2,str3,str4}; //定义p[4]为指向4个字符串的字符型指针数组/**************************************************************函数功能:延时约150ms**************************************************************/void delay(void){unsigned char m,n;for(m=0;m<200;m++)for(n=0;n<250;n++);}/**************************************************************函数功能:流水点亮P0口8位LED**************************************************************/void led_display(unsigned char *x[ ]) //形参必须为指针数组{unsigned char i,j;for(i=0;i<4;i++) //有4个字符串要显示{j=0; //指向待显字符串的第0号元素while(*(x[i]+j)!='\0') //只要第i个字符串的第j号元素不是结束标志{P0=*(x[i]+j); //取得该元素值送到P0口显示delay(); //调用延时函数j++; //指向下一个元素}}}/**************************************************************函数功能:主函数**************************************************************/void main(void){unsigned char i;while(1){for(i=0;i<4;i++)led_display(p); //将指针数组名作实际参数传递}}实例35:字符函数ctype.h应用举例#include<reg51.h> //包含51单片机寄存器定义的头文件#include<ctype.h>void main(void){while(1){P3=isalpha('_')?0xf0:0x0f;//条件运算,若'_'是英文字母,P3=0xf0 }}实例36:内部函数intrins.h应用举例#include<reg51.h> //包含51单片机寄存器定义的头文件#include<intrins.h> //包含函数isalpha()声明的头文件/*************************************************函数功能:延时约150ms*************************************************/void delay(void){unsigned char m,n;for(m=0;m<200;m++)for(n=0;n<250;n++);}/*************************************************函数功能:主函数*************************************************/void main(void){P3=0xfe; //P3=1111 1110Bwhile(1){P3=_crol_(P3,1);// 将P3的二进制位循环左移1位后再赋给P3 delay(); //调用延时函数}}实例37:标准函数stdlib.h应用举例#include<reg51.h> //包含51单片机寄存器定义的头文件#include<stdlib.h> //包含函数isalpha()声明的头文件/*************************************************函数功能:延时约150ms*************************************************/void delay(void){unsigned char m,n;for(m=0;m<200;m++)for(n=0;n<250;n++);}/*************************************************函数功能:主函数*************************************************/void main(void){unsigned char i;。
51单片机 流水灯 中断
//51单片机控制8个LED灯,左右循环移动,当外部中断0引脚的按键,第一次按下时,停在当前位置;第二次按下时,继续向下执行//***************************************************************************** *****************************************//注释:当主函数中在执行左右流水点亮LED灯的时候,按键按下(这是第一次按下,即奇数次),CPU暂时//中断当前点亮灯的工作,转去处理中断程序(c=1),处理完后,再返回原来中断的地方继续原来的工作,//因为这时候C为1,while(c);为真,为死循环状态,即是LED亮的状态停在当前位置;当按键按下(这是第二次按下,即偶数次)//CPU中断当前状态,转去处理中断程序(c=0),处理完后,再返回原来中断的地方继续原来的工作,//这时候C为0,while(c);为假,则程序继续向下执行。
//***************************************************************************** ******************************************#include<reg51.h>#include<intrins.h>//控制左右移的头文件void delay(int);//声明延时函数unsigned char i=0,a=0,b=0,c=0;//a为判断按键按下时奇数次还是偶数次void main(){P2=0xfe;IT0=0;// 低电平有效EX0=1;//开外部中断0EA=1; //开总中断while(1){for(i=0;i<7;i++)//左循环{b=1;while(c);//C为0时,顺序向下执行,为1时停在当前状态,P2=_crol_(P2,1);delay(500);}for(i=0;i<7;i++)//右循环{b=1;while(c);//C为0时,顺序向下执行,为1时停在当前状态,P2=_cror_(P2,1);delay(500);}}while(1);//等待中断}void int0_int(void) interrupt 0 //中断服务函数{delay(40);//延时一段时间,消除抖动if(b==1){b=0;a+=1;//按键为奇数次时,停在当前的状态;偶数次时,接着原来的状态继续往下执行if(a%2)c=1;elsec=0;}}void delay(int n)//延时函数{unsigned int i,j;for(i=0;i<n;i++)for(j=0;j<50;j++);}。
C51单片机C语言程序100例
C51单片机C语言程序100例.Word文档目录目录(1)函数的使用和熟悉********************************/ (4)实例3:用单片机控制第一个灯亮(4)实例4:用单片机控制一个灯闪烁:认识单片机的工作频率(4)实例5:将P1口状态分别送入P0、P2、P3口:认识I/O口的引脚功能(5)实例6:使用P3口流水点亮8位LED (5)实例7:通过对P3口地址的操作流水点亮8位LED (6)实例8:用不同数据类型控制灯闪烁时间(7)实例9:用P0口、P1口分别显示加法和减法运算结果(8) 实例10:用P0、P1口显示乘法运算结果(9)实例11:用P1、P0口显示除法运算结果(9)实例12:用自增运算控制P0口8位LED流水花样(10)实例13:用P0口显示逻辑“与"运算结果(10)实例14:用P0口显示条件运算结果(11)实例15:用P0口显示按位"异或"运算结果(11)实例16:用P0显示左移运算结果(11)实例17:"万能逻辑电路"实验(11)实例18:用右移运算流水点亮P1口8位LED (12)实例19:用if语句控制P0口8位LED的流水方向(13)实例20:用swtich语句的控制P0口8位LED的点亮状态(13)实例21:用for语句控制蜂鸣器鸣笛次数(14)实例22:用while语句控制LED (16)实例23:用do-while语句控制P0口8位LED流水点亮(16) 实例24:用字符型数组控制P0口8位LED流水点亮(17) 实例25:用P0口显示字符串常量(18)实例26:用P0口显示指针运算结果(19)实例27:用指针数组控制P0口8位LED流水点亮(19)实例28:用数组的指针控制P0口8位LED流水点亮(20) 实例29:用P0、P1口显示整型函数返回值(21)实例30:用有参函数控制P0口8位LED流水速度(22)实例31:用数组作函数参数控制流水花样(23)实例32:用指针作函数参数控制P0口8位LED流水点亮(23)实例33:用函数型指针控制P1口灯花样(25)实例34:用指针数组作为函数的参数显示多个字符串(26)实例35:字符函数ctype.h应用举例(27)实例36:内部函数intrins.h应用举例(27)实例37:标准函数stdlib.h应用举例(28)实例38:字符串函数string.h应用举例(29)实例39:宏定义应用举例2 (29)1/192.实例40:宏定义应用举例2 (30)实例41:宏定义应用举例3 (30)中断、定时器************************************************ (31)实例42:用定时器T0查询方式P2口8位控制LED闪烁(31)实例43:用定时器T1查询方式控制单片机发出1KHz音频(31)实例44:将计数器T0计数的结果送P1口8位LED显示(32)实例45:用定时器T0的中断控制1位LED闪烁(33)实例46:用定时器T0的中断实现长时间定时(34)实例47:用定时器T1中断控制两个LED以不同周期闪烁(34)实例48:用计数器T1的中断控制蜂鸣器发出1KHz音频(36) 实例49:用定时器T0的中断实现"渴望"主题曲的播放(36) 实例50-1:输出50个矩形脉冲(39)实例50-2:计数器T0统计外部脉冲数(40)实例51-2:定时器T0的模式2测量正脉冲宽度(40)实例52:用定时器T0控制输出高低宽度不同的矩形波(41) 实例53:用外中断0的中断方式进行数据采集(42)实例54-1:输出负脉宽为200微秒的方波(43)实例54-2:测量负脉冲宽度(43)实例55:方式0控制流水灯循环点亮(44)实例56-1:数据发送程序(45)实例56-2:数据接收程序(47)实例57-1:数据发送程序(47)实例57-2:数据接收程序(49)实例58:单片机向PC发送数据(50)实例59:单片机接收PC发出的数据(51)*********************************数码管显示(52)实例60:用LED数码显示数字5 (52)实例61:用LED数码显示器循环显示数字0~9 (52)实例62:用数码管慢速动态扫描显示数字"1234" (53)实例63:用LED数码显示器伪静态显示数字1234 (54)实例64:用数码管显示动态检测结果(54)实例65:数码秒表设计(56)实例66:数码时钟设计(58)实例67:用LED数码管显示计数器T0的计数值(62)实例68:静态显示数字“59” (63)*****************************键盘控制2/192Word文档.Word 文档*****************************************************/ (63) 实例69:无软件消抖的独立式键盘输入实验(64)实例70:软件消抖的独立式键盘输入实验.............................................................64 实例71:CPU 控制的独立式键盘扫描实验. (65)实例72:定时器中断控制的独立式键盘扫描实验(68)实例73:独立式键盘控制的4 级变速流水灯(71)实例74:独立式键盘的按键功能扩展:"以一当四" (73)实例75:独立式键盘调时的数码时钟实验(75)实例76:独立式键盘控制步进电机实验(79)实例77:矩阵式键盘按键值的数码管显示实验(82)//实例78:矩阵式键盘按键音(85)实例79:简易电子琴(86)实例80:矩阵式键盘实现的电子密码锁 (92)******************************************************************* ***** **液晶显示LCD*********液晶显示LCD *****液晶显示LCD ************************************************************************/ (95)实例81:用LCD 显示字符'A' (96)实例82:用LCD 循环右移显示"Welcome to China"...............................................99 实例83:用LCD 显示适时检测结果...................................................................... 102 实例84:液晶时钟设计. (106)******************************************一些芯片的使用*****24c02 ........***** X5045 ***** ***** DS1302红外遥控**********************************************/ (112) 实例85:将数据"0x0f"写入***** 再读出送P1 口显示..................................112 实例86:将按键次数写入*****,再读出并用1602LCD 显示.......................117 实例87:对I2C 总线上挂接多个***** 的读写操作.......................................124 实例88:基于***** 的多机通信读取程序.. (129)实例88:基于***** 的多机通信写入程序....................................................133 实例90:***** 温度检测及其液晶显示...........................................................144 实例91:将数据"0xaa"写入X5045 再读出送P1 口显示.. (153)实例92:将流水灯控制码写入X5045 并读出送P1 口显示................................ 157 实例93:对SPI 总线上挂接多个X5045 的读写操作............................................161 实例94:基于***** 的数字电压表..................................................................165 实例95:用***** 产生锯齿波电压..................................................................171 实例96:用P1 口显示红外遥控器的按键值.........................................................171 实例97:用红外遥控器控制继电器.......................................................................174 实例98:基于DS1302 的日历时钟........................................................................177 实例99:单片机数据发送程序...............................................................................185 实例100:电机转速表设计.....................................................................................186 模拟霍尔脉冲(192)3 / 192.Word 文档/************************************************************ 函数的使用和熟悉***************************************************************///实例3:用单片机控制第一个灯亮#includereg51.h //包含51 单片机寄存器定义的头文件void main(void){P1=0xfe; //P1=1111 1110B ,即P1.0输出低电平}// 4//实例4:用单片机控制一个灯闪烁:认识单片机的工作频率#includereg51.h //包含单片机寄存器的头文件/****************************************函数功能:延时一段时间*****************************************/void delay(void) //两个void 意思分别为无需返回值,没有参数传递{unsigned int i; //定义无符号整数,最大取值范围*****for(i=0;i20XX年0;i++) //做20XX年0 次空循环; //什么也不做,等待一个机器周期}/*******************************************************函数功能:主函数(C 语言规定必须有也只能有1 个主函数)********************************************************/void main(void){while(1) //无限循环{P1=0xfe; //P1=***-*****B ,P1.0 输出低电平delay(); //延时一段时间P1=0xff; //P1=1111 1111B ,P1.0 输出高电平delay();//延时一段时间}}4/ 192.Word 文档// 5 P1 P0 P2 P3 I/O //实例5:将#includereg51.hP1 口状态分别送入P0、P2、P3 口:认识I/O口的引脚功能//包含单片机寄存器的头文件/******************************************************* 函数功能:主函数(C 语言规定必须有也只能有1个主函数)********************************************************/ void main(void){while(1) //无限循环{P1=0xff; // P1=1111 1111B,熄灭LEDP0=P1; // 将P1 口状态送入P0 口P2=P1; // 将P1 口状态送入P2 口P3=P1; // 将P1 口状态送入P3口}}//实例6:使用P3 口流水点亮8 位LED #includereg51.h //包含单片机寄存器的头文件/****************************************函数功能:延时一段时间*****************************************/void delay(void){unsigned char i,j;for(i=0;ii++)for(j=0;jj++);}/******************************************************* 函数功能:主函数********************************************************/ voidmain(void){.5/192Word文档.Word 文档while(1) { P3=0xfe; delay(); P3=0xfd; delay(); P3=0xfb; delay(); P3=0xf7; delay(); P3=0xef; //第一个灯亮//调用延时函数//第二个灯亮//调用延时函数//第三个灯亮//调用延时函数//第四个灯亮//调用延时函数//第五个灯亮delay(); //调用延时函数P3=0xdf; delay(); P3=0xbf; //第六个灯亮//调用延时函数//第七个灯亮delay(); //调用延时函数P3=0x7f; //第八个灯亮}}delay(); //调用延时函数//实例7:通过对P3 口地址的操作流水点亮8 位LED #includereg51.h //包含单片机寄存器的头文件sfr x=0xb0; //P3 口在存储器中的地址是b0H ,通过sfr 可定义8051 内核单片机//的所有内部8 位特殊功能寄存器,对地址x 的操作也就是对P1 口的操作/****************************************函数功能:延时一段时间*****************************************/void delay(void){unsigned chari,j;for(i=0;ii++)for(j=0;jj++); //利用循环等待若干机器周期,从而延时一段时间}/*****************************************函数功能:主函数6/ 192.******************************************/void main(void){while(1){x=0xfe;//第一个灯亮delay();//调用延时函数x=0xfd;//第二个灯亮delay();//调用延时函数x=0xfb;//第三个灯亮delay();//调用延时函数x=0xf7;//第四个灯亮delay();//调用延时函数x=0xef;//第五个灯亮delay();//调用延时函数x=0xdf;//第六个灯亮delay();//调用延时函数x=0xbf;//第七个灯亮delay();//调用延时函数x=0x7f;//第八个灯亮delay();//调用延时函数}}//实例8:用不同数据类型控制灯闪烁时间#includereg51.h//包含单片机寄存器的头文件/****************************************************** 函数功能:用整形数据延时一段时间******************************************************/ void int_delay(void)//延时一段较长的时间{unsigned int m;//定义无符号整形变量,双字节数据,值域为0~***** for(m=0;m*****;m++);//空操作}/******************************************************函数功能:用字符型数据延时一段时间******************************************************/7/192Word文档.Word 文档void char_delay(void) //延时一段较短的时间{unsigned char i,j; //定义无符号字符型变量,单字节数据,值域0~255 for(i=0;ii++)for(j=0;jj++); //空操作}/****************************************************** 函数功能:主函数******************************************************/ void main(void){unsigned char i;while(1){for(i=0;ii++){P1=0xfe; //P1.0 口的灯点亮int_delay(); //延时一段较长的时间P1=0xff; //熄灭int_delay(); //延时一段较长的时间}for(i=0;ii++){P1=0xef; //P1.4 口的灯点亮char_delay(); //延时一段较长的时间P1=0xff; //熄灭char_delay();//延时一段较长的时间} }}//实例9:用P0 口、P1 #includereg51.hvoid main(void){unsigned char m,n;口分别显示加法和减法运算结果m=43; //即十进制数2x16+11=43 8/192.Word 文档n=60; P1=m+n; //即十进制数3x16+12=60//P1=103=0110 0111B,结果P1.3、P1.4、P1.7 口的灯被点亮} P0=n-m; //P0=17=***-*****B,结果P0.0、P0.4的灯被熄灭//实例10:用P0、P1口显示乘法运算结果#includereg51.h //包含单片机寄存器的头文件void main(void){unsigned char m,n;unsigned int s;m=64;n=71;s=m*n; //s=64*71=4544,需要16 位二进制数表示,高8 位送P1 口,低8 位送P0 口//由于4544=17*256+192=H3*16*16*16+H2*16*16+H1*16+H0 //两边同除以256,可得17+192/256=H3*16+H2+ H1*16+H0)/256//因此,高8 位16 进制数H3*16+H2 必然等于17,即4544除以256 的商//低8 位16 进制数H1*16+H0 必然等于192,即4544 除以256的余数P1=s/256; //高8 位送P1 口,P1=17=11H=0001 0001B, P1.0 和P1.4 口灭,其余亮P0=s%256; //低8 位送P0 口, P3=192=c0H=1100 0000B,P3.1,P3.6,P3.7口灭,其余亮}//实例11:用P1、P0口显示除法运算结果#includereg51.h //包含单片机寄存器的头文件void main(void){P1=36/5; //求整数P0=((36%5)*10)/5;//求小数while(1) 9/ 192.; //无限循环防止程序“跑飞”}//实例12:用自增运算控制P0口8位LED流水花样#includereg51.h//包含单片机寄存器的头文件/******************************************************函数功能:延时一段时间******************************************************/void delay(void){unsigned int i;for(i=0;i20XX年0;i++);}/****************************************************** 函数功能:主函数******************************************************/ void main(void){unsigned char i;for(i=0;ii++)//注意i的值不能超过255{P0=i;//将i的值送P0口delay();//调用延时函数}}//实例13:用P0口显示逻辑"与"运算结果#includereg51.h//包含单片机寄存器的头文件void main(void){P0=(40)(90xab);//将逻辑运算结果送P0口while(1);//设置无限循环,防止程序“跑飞”}110/192Word文档.Word文档//14P0//实例14:用P0口显示条件运算结果#includereg51.h//包含单片机寄存器的头文件void main(void){P0=(84)?8:4;//将条件运算结果送P0口,P0=8=***-*****B while(1);//设置无限循环,防止程序“跑飞”}//实例15:用P0口显示按位"异或"运算结果#includereg51.h//包含单片机寄存器的头文件void main(void){P0=0xa2^0x3c;//将条件运算结果送P0口,P0=8=***-*****B while(1);//设置无限循环,防止程序“跑飞”}//16P0//实例16:用P0显示左移运算结果#includereg51.h//包含单片机寄存器的头文件void main(void){P0=0x3b2;//将左移运算结果送P0口,P0=***-*****B=0xec while(1);//无限循环,防止程序“跑飞”}#includereg51.hsbit F=P1^4; //实例17:"万能逻辑电路"实验//包含单片机寄存器的头文件//将F位定义为P1.4.Word文档1 1 1 / 1 9 2.Word 文档sbit X=P1^5; sbit Y=P1^6; sbit Z=P1^7; void main(void){while(1){//将X 位定义为//将Y 位定义为//将Z 位定义为P1.5 P1.6 P1.7 } }F=((~X)Y)|Z; //将逻辑运算结果赋给F;//实例18:用右移运算流水点亮P1 口8 位LED #includereg51.h //包含单片机寄存器的头文件/*****************************函数功能:延时一段时间*****************************/void delay(void){unsigned int n;for(n=0;n*****;n++);}/*****************************函数功能:主函数*****************************/void main(void){unsigned char i;while(1){P1=0xff;delay();for(i=0;ii++)//设置循环次数为8{P1=P11; //每次循环P1 的各二进位右移1 位,高位补0 delay(); //调用延时函数}} }112/ 192.Word 文档// 19 iff P0 8 LED //实例19:用iff 语句控制P0 口8 位LED 的流水方向#includereg51.h //包含单片机寄存器的头文件sbit S1=P1^4; //将S1 位定义为P1.4sbit S2=P1^5; //将S2 位定义为P1.5/*****************************函数功能:主函数*****************************/void main(void){while(1){if(S1==0) //如果按键S1 按下P0=0x0f; //P0 口高四位LED 点亮if(S2==0) //如果按键S2 按下P0=0xf0; //P0 口低四位LED 点亮}}//实例20:用swtich 语句的控制P0 口8 位LED 的点亮状态#includereg51.h //包含单片机寄存器的头文件sbit S1=P1^4; //将S1 位定义为P1.4/*****************************函数功能:延时一段时间*****************************/void delay(void){unsigned int n;for(n=0;n*****;n++);}/*****************************函数功能:主函数*****************************/void main(void){unsigned chari; 113/ 192.Word 文档i=0; while(1) { //将i 初始化为0 if(S1==0) { delay(); //如果S1 键按下//延时一段时间}if(S1==0) //如果再次检测到S1 键按下i++; //i 自增1if(i==9) //如果i=9,重新将其置为1 i=1; }switch(i ) }{} //使用多分支选择语句case 1: P0=0xfe; //第一个LED 亮break;case 2: P0=0xfd; //第二个LED 亮break;case 3:P0=0xfb; //第三个LED 亮break;case 4:P0=0xf7; //第四个LED 亮break;case 5:P0=0xef; //第五个LED 亮break;case 6:P0=0xdf; //第六个LED 亮break;case 7:P0=0xbf; //第七个LED 亮break;case 8:P0=0x7f; //第八个LED 亮break;default: //缺省值,关闭所有LEDP0=0xff;// 21 for//实例21:用for 语句控制蜂鸣器鸣笛次数#includereg51.h //包含单片机寄存器的头文件sbit sound=P3^7; //将sound 位定义为P3.7 /**************************************** 函数功能:延时形成1600Hz 音频114/ 192.Word 文档****************************************/ void delay1600(void){unsigned char n;for(n=0;nn++);}/**************************************** 函数功能:延时形成800Hz 音频****************************************/ void delay800(void) {unsigned charn;for(n=0;nn++);} /**************************************** 函数功能:主函数****************************************/ void main(void){unsigned int i;while(1){for(i=0;ii++){sound=0; //P3.7 输出低电平delay1600();sound=1; //P3.7 输出高电平delay1600();}for(i=0;ii++){sound=0; //P3.7 输出低电平delay800();sound=1; //P3.7输出高电平delay800();} }}115/ 192.Word文档//实例22:用whille语句控制LED #includereg51.h //包含单片机寄存器的头文件/****************************************函数功能:延时约60ms(3*100*200=*****μs) ****************************************/void delay60ms(void){unsigned char m,n;for(m=0;mm++)for(n=0;nn++);}/****************************************函数功能:主函数****************************************/void main(void){unsigned char i;while(1)//无限循环{i=0;//将i初始化为0while(i0xff)//当i小于0xff(255)时执行循环体{P0=i;//将i送P0口显示delay60ms();//延时i++;//i自增1}}}//实例23:用do-whiile语句控制P0口8位LED流水点亮#includereg51.h//包含单片机寄存器的头文件/****************************************函数功能:延时约60ms(3*100*200=*****μs)****************************************/void delay60ms(void){116/192.unsigned char m,n;for(m=0;mm++)for(n=0;nn++);}/****************************************函数功能:主函数****************************************/ void main(void){do{P0=0xfe;//第一个LED亮delay60ms();P0=0xfd;//第二个LED亮delay60ms();P0=0xfb;//第三个LED亮delay60ms();P0=0xf7;//第四个LED亮delay60ms();P0=0xef;//第五个LED亮delay60ms();P0=0xdf;//第六个LED亮delay60ms();delay60ms();P0=0xbf;//第七个LED亮delay60ms();P0=0x7f;//第八个LED亮delay60ms();}while(1);//无限循环,使8位LED循环流水点亮}//实例24:用字符型数组控制P0口8位LED流水点亮#includereg51.h//包含单片机寄存器的头文件/****************************************函数功能:延时约60ms(3*100*200=*****μs)****************************************/。
51单片机中断程序大全
//实例42:用定时器T0查询方式P2口8位控制LED闪烁#include<reg51.h> // 包含51单片机寄存器定义的头文件void main(void){// EA=1; //开总中断// ET0=1; //定时器T0中断允许TMOD=0x01; //使用定时器T0的模式1TH0=(65536-46083)/256; //定时器T0的高8位赋初值TL0=(65536-46083)%256; //定时器T0的高8位赋初值{//实例43{// EA=1;//{while(TF1==0);TF1=0;sound=~sound; //将P3.7引脚输出电平取反TH1=(65536-921)/256; //定时器T0的高8位赋初值TL1=(65536-921)%256; //定时器T0的高8位赋初值}}//实例44:将计数器T0计数的结果送P1口8位LED显示#include<reg51.h> // 包含51单片机寄存器定义的头文件sbit S=P3^4; //将S位定义为P3.4引脚void main(void){// EA=1; //开总中断// ET0=1; //定时器T0中断允许TMOD=0x02; //使用定时器T0的模式2TH0=256-156; //定时器T0的高8位赋初值TL0=256-156; //定时器T0的高8位赋初值TR0=1; //启动定时器T0while(1)//无限循环等待查询{while(TF0==0) //如果未计满就等待{if(S==0) //按键S按下接地,电平为0P1=TL0; //计数器TL0加1后送P1口显示}//实例45{EA=1;{}//实例46#include<reg51.h> // 包含51单片机寄存器定义的头文件sbit D1=P2^0; //将D1位定义为P2.0引脚unsigned char Countor; //设置全局变量,储存定时器T0中断次数void main(void){EA=1; //开总中断ET0=1; //定时器T0中断允许TMOD=0x01; //使用定时器T0的模式2TH0=(65536-46083)/256; //定时器T0的高8位赋初值TL0=(65536-46083)%256; //定时器T0的高8位赋初值TR0=1; //启动定时器T0Countor=0; //从0开始累计中断次数while(1);}/************************************************************** 函数功能:定时器T0的中断服务程序**************************************************************/ void Time0(void) interrupt 1 using 0{Countor++; //中断次数自加1if(Countor==20) //若累计满20次,即计时满1s{D1=~D1; //按位取反操作,将P2.0引脚输出电平取反Countor=0; //将Countor清0,重新从0开始计数}//实例47{EA=1;}{Countor2++; //Countor2自加1if(Countor1==2) //若累计满2次,即计时满100ms{D1=~D1; //按位取反操作,将P2.0引脚输出电平取反Countor1=0; //将Countor1清0,重新从0开始计数}if(Countor2==8) //若累计满8次,即计时满400ms{D2=~D2; //按位取反操作,将P2.1引脚输出电平取反Countor2=0; //将Countor1清0,重新从0开始计数}TH1=(65536-46083)/256; //定时器T1的高8位重新赋初值TL1=(65536-46083)%256; //定时器T1的高8位重新赋初值}//实例50-1:输出50个矩形脉冲#include<reg51.h> //包含51单片机寄存器定义的头文件sbit u=P1^4; //将u位定义为P1.4/*************************************************函数功能:延时约30ms (3*100*100=30 000μs =30m*************************************************/void delay30ms(void){ unsigned char m,n;for(m=0;m<100;m++)for(n=0;n<100;n++);}{u=1;//实例{//实例51-2#include<reg51.h> //包含51单片机寄存器定义的头文件sbit ui=P3^2; //将ui位定义为P3.0(INT0)引脚,表示输入电压void main(void){TMOD=0x0a; // TMOD=0000 1010B,使用定时器T0的模式2,GATE置1 EA=1; //开总中断ET0=0; //不使用定时器T0的中断TR0=1; //启动T0TH0=0; //计数器T0高8位赋初值TL0=0; //计数器T0低8位赋初值while(1) //无限循环,不停地将TL0计数结果送P1口{while(ui==0) : //INT0为低电平,T0不能启动TL0=0; //INT0为高电平,启动T0计时,所以将TL0清0 while(ui==1): //在INT0高电平期间,等待,计时P1=TL0; //将计时结果送P1口显示} }//实例53:用外中断0的中断方式进行数据采集#include<reg51.h> //包含51单片机寄存器定义的头文件sbit S=P3^2; //将S位定义为P3.2,void main(void){EA=1; //开放总中断EX0=1; //允许使用外中断IT0=1; //选择负跳变来触发外中断P1=0xff;{P1=~P1;//实例54-1sbit u=P1^4;{EA=1;{u=~u; //}//实例54-2sbit u=P3^2;{TMOD=0x02; //TMOD=0000 0010B,使用定时器T0的模式2EA=1; //开放总中断EX0=1; //允许使用外中断IT0=1; //选择负跳变来触发外中断ET0=1; //允许定时器T0中断TH0=0; //定时器T0赋初值0TL0=0; //定时器T0赋初值0TR0=0; //先关闭T0while(1) ; //无限循环,不停检测输入负脉冲宽度}void int0(void) interrupt 0 using 0 //外中断0的中断编号为0{ TR0=1; //外中断一到来,即启动T0计时TL0=0; //从0开始计时while(u==0) //低电平时,等待T0计时;P1=TL0; //将结果送P1口显示TR0=0; //关闭T0}//实例55:方式0控制流水灯循环点亮#include<reg51.h> //包含51单片机寄存器定义的头文件#include<intrins.h> //包含函数_nop_()定义的头文件unsigned char code Tab[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};//流水灯控制码,该数组被定义为全局变量sbit P17=P1^7;/**************************************************************{{P17=0;_nop_();_nop_();P17=1;;TI=0; //}******************************************/void main(void){unsigned char i;SCON=0x00; //SCON=0000 0000B,使串行口工作于方式0while(1){for(i=0;i<8;i++){Send(Tab[i]); //发送数据delay(); //延时}}}。
51单片机中断控制
51单片机中断控制在单片机的世界里,中断控制就像是一位高效的调度员,能够让单片机在处理各种任务时更加灵活和高效。
今天,咱们就来好好聊聊 51 单片机的中断控制。
咱们先来了解一下啥是中断。
简单说,中断就是在单片机正常执行主程序的时候,突然有个更紧急或者更重要的事情需要处理,这时候单片机就会暂停主程序,先去处理这个紧急的事情,处理完了再回来继续执行主程序。
51 单片机有 5 个中断源,分别是外部中断 0 和 1、定时器/计数器 0 和 1 的溢出中断,还有串行口中断。
每个中断源都有自己的中断标志位和中断允许位。
外部中断 0 和 1 可以通过单片机的引脚来触发。
比如说,当外部引脚检测到一个下降沿或者低电平时,就可以产生中断。
这在很多实际应用中非常有用,比如检测按键按下、外部设备的信号变化等。
定时器/计数器 0 和 1 的溢出中断则是当定时器或者计数器的值达到设定的最大值时产生中断。
这就好比一个闹钟,设定好时间,时间一到就响铃提醒单片机去做相应的处理。
串行口中断则是在串行通信过程中,当发送或者接收完一帧数据时产生中断,方便单片机及时进行数据处理。
要让中断能够正常工作,还得设置好相关的寄存器。
中断允许寄存器 IE 用来控制各个中断源是否允许中断。
比如说,如果要允许外部中断 0 中断,就需要把 IE 寄存器中的相应位设置为 1。
中断优先级寄存器 IP 则用来确定各个中断源的优先级。
当多个中断同时发生时,优先级高的中断会先得到处理。
在编写中断服务程序的时候,有几个要点需要注意。
首先,中断服务程序要有一个特定的函数格式,一般是以“void 中断服务函数名()interrupt 中断号”这样的形式来定义。
然后,在中断服务程序中,要尽量快速地完成关键处理,因为中断服务程序会打断主程序的执行,如果处理时间过长,可能会影响主程序的实时性。
比如说,在一个温度控制系统中,主程序负责采集温度数据、显示温度等常规操作。
而外部中断0 可以用来检测温度超过设定的上限值,一旦触发中断,中断服务程序就会迅速采取降温措施,比如启动风扇或者关闭加热设备,然后迅速返回主程序。
实验04:外部中断INT0、INT1控制流水灯左移、右移
实验四:外部中断系统实验一、实验目的1.结合理论教学,进一步熟悉外部中断INT0和INT1的基本概念和原理;2.理解掌握定时器控制寄存器TCON、中断允许控制寄存器IE、中断优先级别控制寄存器IP的功能和设置方法;3.了解并熟悉MCS-51单片机外部中断INT0和INT1的电路设计特点和应用特点;4.能够针对MCS-51单片机,进行外部中断INT0和INT1的初始化设置,能够完成简单中断服务程序的功能应用设计。
5.进一步熟悉、掌握MCS-51单片机指令系统和应用软件的编程方法和技巧。
二、实验设备、材料1.微型计算机(PⅣ以上);2.编程、汇编与模拟平台软件Keil uVision4;3.电子技术专业仿真软件protues运行平台;4.单片机实训开发电路板。
三、实验内容和实验步骤1.系统仿真电路参考原理图12.系统参考源程序1(用INT0控制流水灯左移1位,用INT1控制流水灯右移1位)已在实验板上演示ORG 0000HAJMP MAINORG 0003H ;INT0中断入口地址LJMP IN0ORG 0013H ;INT1中断入口地址LJMP IN1ORG 0020HMAIN:MOV TCON,#05HMOV IE,#85HMOV P2,#0FEHMOV A,#0FEHSJMP $IN0:CLR EARL A //左移MOV P2,ASETB EARETIIN1:CLR EARR A //右移MOV P2,ASETB EARETIEND3.系统参考源程序1(用8位发光二极管代表8位二进制数,用INT0控制加1递增,用INT1控制减1递减)已在实验板上演示ORG 0000HAJMP MAINORG 0003H ;INT0中断入口地址LJMP IN0ORG 0013H ;INT1中断入口地址LJMP IN1ORG 0020HMAIN:MOV TCON,#05HMOV IE,#85HMOV R0,#00HMOV A,#00HMOV P2,ASJMP $ IN0:INC R0MOV A,R0CPL AMOV P2,ARETIIN1:INC R0MOV A,R0CPL AMOV P2,ARETIEND4.系统参考源程序2(用INT0控制流水灯左移1位,用INT1控制流水灯右移1位)已在实验板上演示ORG 0000HAJMP MAINORG 0003H ;INT0中断入口地址CLR F0RETIORG 0013H ;INT1中断入口地址SETB F0RETIORG 0030HMAIN:MOV P2,#0FFHMOV TCON,#05HMOV IE,#85HMOV A,#7FHRRR:JNB F0,LLLRR A //右移MOV P2,AACALL DELAYSJMP RRRLLL:JB F0,RRRRL A //左移MOV P2,AACALL DELAYSJMP LLLDELAY:MOV R7,#8FH ;延时程序DELAY1:MOV R6,#0FFHDELAY2:MOV R5,#02HDELAY3:DJNZ R5,DELAY3DJNZ R6,DELAY2DJNZ R7,DELAY1RETEND。
51单片机的中断控制
AEH 0
ADH 0
ACH ES 0
ABH ET1
1
AAH EX1
0
A9H ET0
1
A8H EX0
0
用位操作指令
CLR ES CLR EX0 CLR EX1 SETB ET0 SETB ET1 SETB EA
; ES=0,禁止串行口中断 ; EX0=0,禁止外部中断0 ; EX1=0,禁止外部中断1 ; ET0=1,允许定时/计数中断0 ; ET1=1,允许定时/计数中断0 ; CPU开中断
TI SCON
IE EX0 EA ET0 EX1
ET1 ES
IP
PX0 1
0
PX1 1
0
PT0 1
0
PT1 1
0
PS 1
0
高
0003H 000BH 0013H 001BH 0023H
CPU
0003H 000BH 0013H 001BH 0023H
低
2. 51单片机的中断控制
中断的开放与禁止
51系列单片机的5个中断源都是可屏蔽中断,由中断系统内部的专用寄 存器IE负责控制各中断源的开放或屏蔽。
;EA位置 “1” ,CPU开中断 ;EX0位置 “1” ,允许外部中断0产生中断 ;PX1位置 “1” ,外部中断1为高级中断 ;IT1位置 “0” ,外部中断1为电平触发
3. 51单片机中断程序设计
采用中断的程序结构:
主程序起始地址0000H执行,在0000H处用无条件转移指令; 各中断入口地址,用无条件转移指令
IE A8H
7
6
EA
位地址
AF
5
4
3
2
1
0
51单片机入门零基础23定时器闪烁LED灯精品文档6页
2.3定时器应用之定时器闪烁LED灯(不含中断)2.3.1 STC15L104E定时器简介定时器具有计数功能,拿16位定时器0来举例,它产生溢出时候的位是2^16(65536),那么我们如果要定时器定时a,我们就要向定时器里存65536-a。
很多人不明白定时器到底是怎么回事,我们把定时器比喻为一个水桶,满水(65536)就溢出,我们想定时器a个数就相当于我们想向水桶里放入a水后水桶就溢出,那么水桶里原来存的水就是65536-a。
这就是定时器。
STC15L104E内部设置了两个16位定时器/计时器T0和T1,它们都有计数方式和定时方式两种工作方式。
定时还是计数由TMOD寄存器的C/T 决定,置1计数器,置0定时器。
TMOD寄存器如图 0-1所示。
定时器/计数器的核心部件是一个加法计数器,其本质是对脉冲进行计数。
脉冲来源系统时钟则采用定时方式,此时定时器每12个时钟或者1个时钟得到一个计数脉冲,计数值加1;脉冲来源单片机外部引脚(T0为P3.4,T1为P3.5)则为计数方式,每来一个脉冲加1。
定时器/计数器的工作模式由TMOD寄存器的M1、M0决定,定时器/计数器工作模式寄存器TMOD,它控制两个定时器的工作模式,高4位控制定时器1,低四位控制定时器0。
如图 0-1所示。
图 0-1 TMOD寄存器当定时器/计数器工作在定时模式时,AUXR寄存器的T0x12和T1x12分别决定系统时钟是12分频还是1分频。
AUXR寄存器如图 0-2所示。
当定时器/计数器工作在计数模式时,对外部脉冲不分频。
图 0-2 AUXR寄存器与定时器/计数器相关的寄存器还有TL0、TL1、TH0、TH1、TCON和INT_CLKO寄存器。
TL0/1、TH0/1分别为定时器0/1的低位和高位。
TCON寄存器是定时器/计数器的控制寄存器,同时也锁存T0、T1溢出中断源和外部请求中断源等,TOCN寄存器如图 0-3所示。
图 0-3 TCON寄存器图 0-4 INT_CLKO寄存器INT_CLKO寄存器的0位和1位控制定时器。
stm32单片机设计定时器中断实现1s的led灯闪烁知识应用
stm32单片机设计定时器中断实现1s的led灯闪烁知识应用要实现1s的LED灯闪烁,可以使用STM32单片机的定时器中断来控制LED的开关。
以下是实现的步骤:1. 配置定时器:选择一个定时器(如TIM2)并设置适当的预分频和计数值,以实现1s的定时周期。
2. 配置中断:使能定时器中断,并将中断优先级设置为适当的值(较高优先级)。
3. 初始化LED引脚:将LED引脚设置为输出,并初始化为高电平(LED关闭)。
4. 编写中断处理程序:在中断处理程序(如TIM2_IRQHandler)中,切换LED引脚的状态。
例如,如果LED引脚当前为高电平,则将其设置为低电平,反之亦然。
5. 启动定时器:启动定时器以开始定时。
整个步骤如下所示的代码示例:```c#include "stm32fxx.h"void TIM2_IRQHandler(void){if(TIM2->SR & TIM_SR_UIF){TIM2->SR &= ~TIM_SR_UIF; // 清除中断标志位// 切换LED引脚状态if(GPIOC->ODR & GPIO_ODR_ODR0)GPIOC->ODR &= ~GPIO_ODR_ODR0; // 关闭LEDelseGPIOC->ODR |= GPIO_ODR_ODR0; // 打开LED}}int main(){// 初始化LED引脚RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN; // 使能GPIOC时钟GPIOC->MODER |= GPIO_MODER_MODER0_0; // 将PC0设置为输出模式GPIOC->OSPEEDR |= GPIO_OSPEEDR_OSPEED0; // 设置PC0输出速度// 配置定时器RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; // 使能TIM2时钟TIM2->PSC = 8399; // 将预分频设置为8400-1,得到10kHz 的计数频率TIM2->ARR = 9999; // 将计数值设置为10000-1,得到1s的定时周期// 配置中断TIM2->DIER |= TIM_DIER_UIE; // 使能更新中断NVIC_EnableIRQ(TIM2_IRQn); // 使能TIM2中断NVIC_SetPriority(TIM2_IRQn, 0); // 设置TIM2中断优先级为最高// 启动定时器TIM2->CR1 |= TIM_CR1_CEN; // 启动TIM2定时器while(1){// 程序主循环}return 0;}```以上代码使用了TIM2定时器和PC0引脚作为LED灯的控制。
单片机实验――利用中断控制LED灯(精)
单片机实验——利用中断控制LED灯1.实验目的(1掌握单片机中断的基本原理。
(2掌握单片机中断程序的编制方法。
2.预习要点(1单片机中断基本原理(2中断程序编制方法3.实验设备计算机、单片机实验箱、信号发生器。
4.实验内容基本要求:将信号发生器输出的脉冲信号连接到CPU的INT0上,将CPU的P1.0到P1.7和八个LED连接,脉冲信号为5V、100Hz,每输入一百个脉冲LED灯亮一次,并且LED灯顺序循环移位一次,形成跑马灯。
扩展要求:提高输入脉冲频率,但跑马灯的显示频率不变。
实验4ORG 0000HAJMP MAIN;******************************************;中断子程序入口地址ORG 0003HLJMP EXINT0;******************************************;主程序ORG 0030HMAIN:MOV SP,#70HSETB IT0 ;设置为下降沿触发SETB EX0 ;开INT0的中断开关SETB EA ;开总中断开关MOV R0,#01H ;只让一盏灯亮,R0赋给P1口MOV R3,#00H ;R3用来记中断次数MOV A,R0MOV P1,AHERE:SJMP HERE ;死循环,还有另外一种形式是SJMP $ ;******************************************;外中断0服务程序EXINT0:INC R3 ;每来一次中断R3自加1CJNE R3,#100,NEXT ;当来了100次中断之后,R3清零,然后P1口的MOV R3,#00H ;数左移一位,也就是让下一个LED亮MOV A,R0RL AMOV P1,AMOV R0,A ;保存左移之后的结果NEXT:RETI;******************************************END实验4扩展ORG 0000HAJMP MAIN;******************************************;中断入口地址ORG 0003HLJMP EXINT0;******************************************;主程序ORG 0030HMAIN:MOV SP,#70H;初始化外中断0SETB IT0SETB EX0SETB EA;初始化8155MOV DPTR,#0100HMOV A,#03HMOVX @DPTR,A;显示缓存区MOV 30H,#1MOV 31H,#2MOV 32H,#3MOV 33H,#4MOV 34H,#5MOV 35H,#6MOV 36H,#7MOV 37H,#8MOV 38H,#9 ;这一句后面的CJNE会用到,用来判断1-8是否已经显示完了MOV R2,#00H ;用R2来记中断来的次数MOV 40H,#01H ;用40H存放LED的状态MOV A,40HMOV P1,AMOV R0,#30H ;显示缓存区首地址给R0MOV R4,#0FEH ;字位送R4,因为只需要亮一个数码管,所以选择静态显示,没必要用动态显示LOOP:LCALL DISPLAY ;循环调用显示程序SJMP LOOP;******************************************;中断子程序EXINT0:INC R2CJNE R2,#100,NEXT ;来100次中断之后才进行操作MOV R2,#00HMOV A,40H ;移动LEDRL AMOV P1,AMOV 40H,AINC R0 ;让显示的数+1CJNE @R0,#9,NEXT ;如果到了9就回到1,因为我们只显示1-8 MOV R0,#30HNEXT:RETI;******************************************;显示子程序DISPLAY:MOV DPTR,#0102H ;送字位MOV A,R4MOVX @DPTR,AMOV DPTR,#DTAB ;查表,送字形MOV A,@R0MOVC A,@A+DPTRMOV DPTR,#0101HMOVX @DPTR,ALCALL DELAYLD1:RET;****************************************** ;字形表DTAB:DB 3FH,06H,5BH,4FH,66HDB 6DH,7DH,07H,7FH,6FH ;0-FDB 77H,7CH,39H,5EH,79HDB 71H;****************************************** ;延时1ms子程序DELAY:MOV R7,#02HDEL1:MOV R6,#0FFHDEL2:DJNZ R6,DEL2DJNZ R7,DEL1RET;****************************************** ENDORG 0000HAJMP MAIN;中断入口地址ORG 0003HLJMP EXINT0;******************主程序ORG 0030HMAIN:MOV SP,#70H;初始化外中断0SETB IT0SETB EX0SETB EA;初始化8155MOV DPTR,#0100HMOV A,#03HMOVX @DPTR,A;显示缓存区MOV 30H,#1MOV 31H,#2MOV 32H,#3MOV 33H,#4MOV 34H,#5MOV 35H,#6MOV 36H,#7MOV 37H,#8MOV 38H,#9MOV 40H,#01H ;用40H存发光二极管的状态MOV R2,#00HMOV A,40HMOV P1,AMOV R0,#30HMOV R4,#0FEHLOOP:LCALL DISPLAY SJMP LOOP;************************* ;中断子程序EXINT0:INC R2CJNE R2,#100,NEXTMOV R2,#00HMOV A,40HRL AMOV P1,AMOV 40H,AINC R0CJNE @R0,#9,NEXT1MOV R0,#30HNEXT1:MOV A,R4RL AMOV R4,ANEXT:RETI;显示子程序DISPLAY:MOV A,R4MOV DPTR,#0102HMOVX @DPTR,AMOV DPTR,#DTABMOV A,@R0MOVC A,@A+DPTRMOV DPTR,#0101HMOVX @DPTR,ALCALL DELAY LD1:RET ;字形表 DTAB: DB3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH ;延时 1ms 子程序 DELAY: MOVR7,#02H DEL1:MOV R6,#0FFH DEL2:DJNZ R6,DEL2 DJNZ R7,DEL1 RET END ;说明: ;R4 是保存数码管字位 ;R3 ;R2 是保存中断次数满 100 清 0 ;R1 ;R0 是保存数码管的字型实验 5(1 ORG 0000H SJMPMAIN ;****************************************8*********** ;中断入口地址ORG 000BH LJMP T0INT ;************************************************ ;主程序 ORG 0030H MAIN:MOV SP,#70H MOV TMOD,#01H ;T0 选择方式 1,16 位定时器 MOV TH0,#0F6H ;#9EH ;因为用示波器观察 20HZ 的方波不易观察,频率太低了,所以我换成了 MOV TL0,#3CH ;#58H ;200HZ 的,原理都是一样的,这样只是为了让波形更容易观察,后者是 20HZ 的初值 SETB EA ;开总中断 SETB ET0 ;开定时器 0 中断 SETB TR0 ;启动定时器 0 SJMP$ ;死循环 ;********************************************************;定时器 0 中断子程序 (25ms 2.5ms 来一次中断 T0INT:MOV TH0,#0F6H ;#9EH ;重新赋初值 MOV TL0,#3CH ;#58H CPL P1.1 ;改变电平RETI ;******************************************************。
02.3.1 第二章 - 项目:单片机控制1只LED灯闪烁
现在有答案了吗?
亮和灭之间延长时间
项目说明 任务一 任务二 任务三 项目拓展
原因
单片机执行速度太快,人眼无法分辨闪烁现象
解决办法:让LED的亮和灭时间延长 —— 延时概念
延时0.1s的子程序:
干货
YANSHI:MOV R7,#250 D1:MOV R6,#200 D2:DJNZ R6,D2 DJNZ R7,D1 RET
END
开始 点亮LED
结束
教师演示
熄灭LED的程序您会写了吗?
项目说明 任务一 任务二 任务三 项目拓展
任务二
小组讨论
怎样使LED 闪烁 1次呢?
LED闪烁的状态有:点亮 和 熄灭
已知点亮LED的程序如下:
ORG 0000H MOV P2 ,#11111110B
END
LED闪烁1次程序应该怎么修改呢?
(正向导通,反向截止)
项目说明 任务一 任务二 任务三 项目拓展
项目简图
P2.0输出:“0” 亮,“1” 灭
LED亮
低电平“0”时 亮LED灭 高电平“1”时 灭
项目说明 任务一 任务二 任务三 项目展示
任务一
怎样 点亮 和 熄灭 LED呢?
分析得出P2.0输出:“0”时亮,“1”时灭
疑问 指令
演示
项目说明 任务一 任务二 任务三 项目拓展
任务三
怎样使LED一直 闪烁 呢?
程序片段:
START: MOV P2,#11111110B LCALL YANSHI MOV P2,#11111111B LCALL YANSHI
LJMP START
循环
循环概念
跳转指令 LJMP START
项目说明 任务一 任务二 LED闪烁的完整程序
单片机控制一只LED闪烁 (1)
TEXT HERETEXT HERE TEXT HERETEXT HERE TEXT HERETEXT HERE TEXT HERETEXT HERE
TEXT HERETEXT HERE TEXT HERETEXT HERE TEXT HERETEXT HERE TEXT HERETEXT HERE
ACALL D
SETB
P1.0
ACALL D
AJMP
M
D:
MOV
R1 , #250
L1:
MOV
R2 , #200
L2:
DJNZ
R2 , L2
DJNZ
R1 , L1
RET
END
7:00 8:00 9:00 10:00
7:00 8:00 9:00 10:00
单片机控制一只LED闪烁 (1).
Method 1 Method 2 Method 3 Method 4
单片机控制一只LED闪烁
连连看
CLR
程序结束
SETB
跳转到指定位置
END
点亮LED
AJMP
调用指定位置程序
ACALL
熄灭LED
如何让LED闪烁起来
点亮一只LED
ORG 0000H AJMP MAIN ORG 0100H
MAIN: CLR P1.0 ;点亮一只LED END
熄灭一只LED
如何让LED闪烁起来?
困难:在哪儿拖时间? 困难:怎么拖?
困难:在哪儿拖时间?
ORG
0000H
AJMP M
;跳到M处运行程序
ORG
0100H
M:
CLR
P1.0 ; 点亮LED
SETB
用KeilC51开发定时器计数器
用KeilC51开发定时器计数器用Keil C51开发定时器/计数器原文:基本的51单片机内部有两个16位可编程的定时器/计数器T0和T1。
它们各自具有4种工作状态,其控制字和状态均在相应的特殊功能寄存器中,可以通过软件对控制寄存器编程设置,使其工作在不同的定时状态或计数状态。
现在,许多厂家生产的8051兼容单片机上,还加入了定时器/计数器2,使单片机的应用更为灵活,适应性更强。
很多8051单片机的书籍都对定时器/计数器有详细的介绍,我们在此不再详细地讨论。
但因为编写或或阅读程序时经常要查阅定时器/计数器的设置情况,因此我们仅对一些编程时经常要用到的较重要的寄存器和设置方式进行简要简介。
1 定时器/计数器简介8051单片机的定时器/计数器基本结构如图1-1所示,定时器T0由两个8位计数器TH0和TL0构成,定时器T1也由两个8位计数器TH1和TL1构成,TMOD寄存器控制定时器的工作方式,TCON寄存器控制定时器的启动和停止以及定时器的状态。
图1-1 定时器/计数器结构在作定时器使用时,输入的时钟脉冲是由晶体振荡器的输出经12分频后得到的。
实际上,定时器就是单片机机器周期的计数器。
因为每个机器周期包含晶体振荡器的12个振荡周期,而每一个机器周期定时器加1,故其频率为晶振频率的1/12。
如果晶振频率为12MHz,则定时器每接收一个输入脉冲的时间为1?s。
选择计数器工作方式时,计数脉冲来自相应的外部输入引脚T0(P3.4)或T1(P3.5)。
在这种情况下,当检测到输入引脚上的电平由高跳变到低时,计数器就加1。
2 控制和状态寄存器(1)定时器控制寄存器(TCON)TCON为定时器/计数器的控制寄存器,同时也锁存外部中断请求标志,各位定义如下。
TF1:定时器/计数器1中断请求标志位。
当定时器计数满溢出回零时,由硬件置位,并可申请中断。
当CPU响应中断并进入中断服务程序后,TF1自动清零。
TR1:定时器/计数器1运行控制位,靠软件置位或清除。
单片机C语言编程精选例
目录实例3:用单片机控制第一个灯亮 ................................. 实例4:用单片机控制一个灯闪烁:认识单片机的工作频率........... 实例5:将 P1口状态分别送入P0、P2、P3口:认识I/O口的引脚功能.实例6:使用P3口流水点亮8位LED ............................... 实例7:通过对P3口地址的操作流水点亮8位LED ................... 实例8:用不同数据类型控制灯闪烁时间........................... 实例9:用P0口、P1 口分别显示加法和减法运算结果............... 实例10:用P0、P1口显示乘法运算结果........................... 实例11:用P1、P0口显示除法运算结果........................... 实例12:用自增运算控制P0口8位LED流水花样................... 实例13:用P0口显示逻辑"与"运算结果........................... 实例14:用P0口显示条件运算结果 ............................... 实例15:用P0口显示按位"异或"运算结果......................... 实例16:用P0显示左移运算结果 ................................. 实例17:"万能逻辑电路"实验 .................................... 实例18:用右移运算流水点亮P1口8位LED ........................ 实例19:用if语句控制P0口8位LED的流水方向.................. 实例20:用swtich语句的控制P0口8位LED的点亮状态............ 实例21:用for语句控制蜂鸣器鸣笛次数.......................... 实例22:用while语句控制LED ................................... 实例23:用do-while语句控制P0口8位LED流水点亮..............实例24:用字符型数组控制P0口8位LED流水点亮................. 实例25:用P0口显示字符串常量 ................................ 实例26:用P0 口显示指针运算结果............................... 实例27:用指针数组控制P0口8位LED流水点亮................... 实例28:用数组的指针控制P0 口8 位LED流水点亮................ 实例29:用P0 、P1口显示整型函数返回值 ........................ 实例30:用有参函数控制P0口8位LED流水速度................... 实例31:用数组作函数参数控制流水花样.......................... 实例32:用指针作函数参数控制P0口8位LED流水点亮............. 实例33:用函数型指针控制P1口灯花样........................... 实例34:用指针数组作为函数的参数显示多个字符串................ 实例35:字符函数ctype.h应用举例 .............................. 实例36:内部函数intrins.h应用举例............................ 实例37:标准函数stdlib.h应用举例............................. 实例38:字符串函数string.h应用举例........................... 实例39:宏定义应用举例2 ....................................... 实例40:宏定义应用举例2 ....................................... 实例41:宏定义应用举例3 ....................................... 实例42:用定时器T0查询方式P2口8位控制LED闪烁.............. 实例43:用定时器T1查询方式控制单片机发出1KHz音频............ 实例44:将计数器T0计数的结果送P1口8位LED显示.............. 实例45:用定时器T0的中断控制1位LED闪烁..................... 实例46:用定时器T0的中断实现长时间定时.......................实例47:用定时器T1中断控制两个LED以不同周期闪烁............. 实例48:用计数器T1的中断控制蜂鸣器发出1KHz音频.............. 实例49:用定时器T0的中断实现"渴望"主题曲的播放............... 实例50-1:输出50个矩形脉冲 ................................... 实例50-2:计数器T0统计外部脉冲数............................. 实例51-2:定时器T0的模式2测量正脉冲宽度..................... 实例52:用定时器T0控制输出高低宽度不同的矩形波............... 实例53:用外中断0的中断方式进行数据采集...................... 实例54-1:输出负脉宽为200微秒的方波.......................... 实例54-2:测量负脉冲宽度 ...................................... 实例55:方式0控制流水灯循环点亮 .............................. 实例56-1:数据发送程序 ........................................ 实例56-2:数据接收程序 ........................................ 实例57-1:数据发送程序 ........................................ 实例57-2:数据接收程序 ........................................ 实例58:单片机向PC发送数据 ................................... 实例59:单片机接收PC发出的数据............................... 实例60:用LED数码显示数字5 ................................... 实例61:用LED数码显示器循环显示数字0~9 ....................... 实例62:用数码管慢速动态扫描显示数字"1234" .................... 实例63:用LED数码显示器伪静态显示数字1234 .................... 实例64:用数码管显示动态检测结果 .............................. 实例65:数码秒表设计 ..........................................实例66:数码时钟设计 .......................................... 实例67:用LED数码管显示计数器T0的计数值..................... 实例68:静态显示数字“59” .................................... 实例69:无软件消抖的独立式键盘输入实验 ........................ 实例70:软件消抖的独立式键盘输入实验.......................... 实例71:CPU控制的独立式键盘扫描实验........................... 实例72:定时器中断控制的独立式键盘扫描实验.................... 实例73:独立式键盘控制的4级变速流水灯 ........................ 实例74:独立式键盘的按键功能扩展:"以一当四" .................. 实例75:独立式键盘调时的数码时钟实验.......................... 实例76:独立式键盘控制步进电机实验............................ 实例77:矩阵式键盘按键值的数码管显示实验...................... 实例78:矩阵式键盘按键音 ...................................... 实例79:简易电子琴 ............................................ 实例80:矩阵式键盘实现的电子密码锁............................ 实例81:用LCD显示字符'A' ..................................... 实例82:用LCD循环右移显示"Welcome to China" .................. 实例83:用LCD显示适时检测结果 ................................ 实例84:液晶时钟设计 .......................................... 实例85:将数据"0x0f"写入AT24C02再读出送P1口显示............. 实例86:将按键次数写入AT24C02,再读出并用1602LCD显示......... 实例87:对I2C总线上挂接多个AT24C02的读写操作................ 实例88:基于AT24C02的多机通信读取程序......................实例88:基于AT24C02的多机通信写入程序....................... 实例90:DS18B20温度检测及其液晶显示........................... 实例91:将数据"0xaa"写入X5045再读出送P1口显示............... 实例92:将流水灯控制码写入X5045并读出送P1口显示............. 实例93:对SPI总线上挂接多个X5045的读写操作.................. 实例94:基于ADC0832的数字电压表 .............................. 实例95:用DAC0832产生锯齿波电压 .............................. 实例96:用P1口显示红外遥控器的按键值......................... 实例97:用红外遥控器控制继电器 ................................ 实例98:基于DS1302的日历时钟 ................................. 实例99:单片机数据发送程序 .................................... 实例100:电机转速表设计 ....................................... 模拟霍尔脉冲................................................... /*函数的使用和熟悉*///实例3:用单片机控制第一个灯亮#include<reg51.h> //包含51单片机寄存器定义的头文件void main(void){while(1) //无限循环P1=0xfe; //P1=1111 1110B,即P1.0输出低电平}//实例4:用单片机控制一个灯闪烁:认识单片机的工作频率#include<reg51.h> //包含单片机寄存器的头文件/****************************************函数功能:延时一段时间*****************************************/void delay(void) //两个void意思分别为无需返回值,没有参数传递{unsigned int i; //定义无符号整数,最大取值范围65535for(i=0;i<20000;i++) //做20000次空循环; //什么也不做,等待一个机器周期}/*******************************************************函数功能:主函数(C语言规定必须有也只能有1个主函数)********************************************************/void main(void){while(1) //无限循环{P1=0xfe; //P1=1111 1110B, P1.0输出低电平delay(); //延时一段时间P1=0xff; //P1=1111 1111B, P1.0输出高电平delay(); //延时一段时间}}//实例5:将 P1口状态分别送入P0、P2、P3口:认识I/O口的引脚功能#include<reg51.h> //包含单片机寄存器的头文件/******************************************************* 函数功能:主函数(C语言规定必须有也只能有1个主函数)********************************************************/ void main(void){while(1) //无限循环{P1=0xff; // P1=1111 1111, 熄灭LEDP0=P1; // 将 P1口状态送入P0口P2=P1; // 将 P1口状态送入P2口P3=P1; // 将 P1口状态送入P3口}}//实例6:使用P3口流水点亮8位LED#include<reg51.h> //包含单片机寄存器的头文件/****************************************函数功能:延时一段时间*****************************************/void delay(void){unsigned char i,j;for(i=0;i<250;i++)for(j=0;j<250;j++);}/******************************************************* 函数功能:主函数********************************************************/ void main(void){while(1){P3=0xfe; //第一个灯亮delay(); //调用延时函数P3=0xfd; //第二个灯亮delay(); //调用延时函数P3=0xfb; //第三个灯亮delay(); //调用延时函数P3=0xf7; //第四个灯亮delay(); //调用延时函数P3=0xef; //第五个灯亮delay(); //调用延时函数P3=0xdf; //第六个灯亮delay(); //调用延时函数P3=0xbf; //第七个灯亮delay(); //调用延时函数P3=0x7f; //第八个灯亮delay(); //调用延时函数}}//实例7:通过对P3口地址的操作流水点亮8位LED#include<reg51.h> //包含单片机寄存器的头文件sfr x=0xb0; //P3口在存储器中的地址是b0H,通过sfr可定义8051内核单片机 //的所有内部8位特殊功能寄存器,对地址x的操作也就是对P1口的操作/****************************************函数功能:延时一段时间*****************************************/void delay(void){unsigned char i,j;for(i=0;i<250;i++)for(j=0;j<250;j++); //利用循环等待若干机器周期,从而延时一段时间}/*****************************************函数功能:主函数******************************************/void main(void){while(1){x=0xfe; //第一个灯亮delay(); //调用延时函数x=0xfd; //第二个灯亮delay(); //调用延时函数x=0xfb; //第三个灯亮delay(); //调用延时函数x=0xf7; //第四个灯亮delay(); //调用延时函数x=0xef; //第五个灯亮delay(); //调用延时函数x=0xdf; //第六个灯亮delay(); //调用延时函数x=0xbf; //第七个灯亮delay(); //调用延时函数x=0x7f; //第八个灯亮delay(); //调用延时函数}}//实例8:用不同数据类型控制灯闪烁时间#include<reg51.h> //包含单片机寄存器的头文件/******************************************************函数功能:用整形数据延时一段时间******************************************************/void int_delay(void) //延时一段较长的时间{unsigned int m; //定义无符号整形变量,双字节数据,值域为0~65535 for(m=0;m<36000;m++); //空操作}/******************************************************函数功能:用字符型数据延时一段时间******************************************************/void char_delay(void) //延时一段较短的时间{unsigned char i,j; //定义无符号字符型变量,单字节数据,值域0~255 for(i=0;i<200;i++)for(j=0;j<180;j++); //空操作}/******************************************************函数功能:主函数******************************************************/{unsigned char i;while(1){for(i=0;i<3;i++){P1=0xfe; //P1.0口的灯点亮int_delay(); //延时一段较长的时间P1=0xff; //熄灭int_delay(); //延时一段较长的时间}for(i=0;i<3;i++){P1=0xef; //P1.4口的灯点亮char_delay(); //延时一段较长的时间P1=0xff; //熄灭char_delay(); //延时一段较长的时间}}}//实例9:用P0口、P1口分别显示加法和减法运算结果#include<reg51.h>{unsigned char m,n;m=43; //即十进制数2x16+11=43n=60; //即十进制数3x16+12=60P1=m+n; //P1=103=0110 0111,结果P1.3、P1.4、P1.7 口的灯被点亮P0=n-m; //P0=17=0001 0001,结果P0.0、P0.4的灯被熄灭}//实例10:用P0、P1口显示乘法运算结果#include<reg51.h> //包含单片机寄存器的头文件void main(void){unsigned char m,n;unsigned int s;m=64;n=71;s=m*n; //s=64*71=4544,需要16位二进制数表示,高8位送P1口,低8位送P0口//由于4544=17*256+192=H3*16*16*16+H2*16*16+H1*16+H0 //两边同除以256,可得17+192/256=H3*16+H2+(H1*16+H0)/256//因此,高8位16进制数H3*16+H2必然等于17,即4544除以256的商//低8位16进制数H1*16+H0必然等于192,即4544除以256的余数P1=s/256; //高8位送P1口,P1=17=11H=0001 0001B, P1.0和P1.4口灭,其余亮P0=s%256; //低8位送P0口 , P3=192=c0H=1100 0000B,P3.1,P3.6,P3.7口灭,其余亮}//实例11:用P1、P0口显示除法运算结果#include<reg51.h> //包含单片机寄存器的头文件void main(void){P1=36/5; //求整数P0=((36%5)*10)/5; //求小数while(1); //无限循环防止程序“跑飞”}//实例12:用自增运算控制P0口8位LED流水花样#include<reg51.h> //包含单片机寄存器的头文件/******************************************************函数功能:延时一段时间******************************************************/void delay(void){unsigned int i;for(i=0;i<20000;i++);}/****************************************************** 函数功能:主函数******************************************************/ void main(void){unsigned char i;for(i=0;i<255;i++) //注意i的值不能超过255{P0=i; //将i的值送P0口delay(); //调用延时函数}}//实例13:用P0口显示逻辑"与"运算结果#include<reg51.h> //包含单片机寄存器的头文件void main(void){P0=(4>0)&&(9>0xab);//将逻辑运算结果送P0口while(1); //设置无限循环,防止程序“跑飞”}//实例14:用P0口显示条件运算结果#include<reg51.h> //包含单片机寄存器的头文件void main(void){P0=(8>4)?8:4;//将条件运算结果送P0口,P0=8=0000 1000B while(1); //设置无限循环,防止程序“跑飞”}//实例15:用P0口显示按位"异或"运算结果#include<reg51.h> //包含单片机寄存器的头文件void main(void){P0=0xa2^0x3c;//将条件运算结果送P0口,P0=8=0000 1000B while(1); //设置无限循环,防止程序“跑飞”}//实例16:用P0显示左移运算结果#include<reg51.h> //包含单片机寄存器的头文件void main(void){P0=0x3b<<2; //将左移运算结果送P0口,P0=1110 1100B=0xec while(1); //无限循环,防止程序“跑飞”}//实例17:"万能逻辑电路"实验#include<reg51.h> //包含单片机寄存器的头文件sbit F=P1^4; //将F位定义为 P1.4sbit X=P1^5; //将X位定义为 P1.5sbit Y=P1^6; //将Y位定义为 P1.6sbit Z=P1^7; //将Z位定义为 P1.7void main(void){while(1){F=((~X)&Y)|Z; //将逻辑运算结果赋给F ;}}//实例18:用右移运算流水点亮P1口8位LED#include<reg51.h> //包含单片机寄存器的头文件/*****************************函数功能:延时一段时间*****************************/void delay(void){unsigned int n;for(n=0;n<30000;n++);}/*****************************函数功能:主函数*****************************/void main(void){unsigned char i;while(1){P1=0xff;delay();for(i=0;i<8;i++)//设置循环次数为8{P1=P1>>1; //每次循环P1的各二进位右移1位,高位补0 delay(); //调用延时函数}}}//实例19:用if语句控制P0口8位LED的流水方向#include<reg51.h> //包含单片机寄存器的头文件sbit S1=P1^4; //将S1位定义为P1.4sbit S2=P1^5; //将S2位定义为P1.5/*****************************函数功能:主函数*****************************/void main(void){while(1){if(S1==0) //如果按键S1按下P0=0x0f; //P0口高四位LED点亮if(S2==0) //如果按键S2按下P0=0xf0; //P0口低四位LED点亮}}//实例20:用swtich语句的控制P0口8位LED的点亮状态#include<reg51.h> //包含单片机寄存器的头文件sbit S1=P1^4; //将S1位定义为P1.4/*****************************函数功能:延时一段时间*****************************/void delay(void){unsigned int n;for(n=0;n<10000;n++);}/*****************************函数功能:主函数*****************************/void main(void){unsigned char i;i=0; //将i初始化为0while(1){if(S1==0) //如果S1键按下{delay(); //延时一段时间if(S1==0) //如果再次检测到S1键按下i++; //i自增1if(i==9) //如果i=9,重新将其置为1i=1;}switch(i) //使用多分支选择语句{case 1: P0=0xfe; //第一个LED亮break;case 2: P0=0xfd; //第二个LED亮break;case 3:P0=0xfb; //第三个LED亮break;case 4:P0=0xf7; //第四个LED亮break;case 5:P0=0xef; //第五个LED亮break;case 6:P0=0xdf; //第六个LED亮break;case 7:P0=0xbf; //第七个LED亮break;case 8:P0=0x7f; //第八个LED亮break;default: //缺省值,关闭所有LEDP0=0xff;}}}//实例21:用for语句控制蜂鸣器鸣笛次数sbit sound=P3^7; //将sound位定义为P3.7 /**************************************** 函数功能:延时形成1600Hz音频****************************************/ void delay1600(void){unsigned char n;for(n=0;n<100;n++);}/**************************************** 函数功能:延时形成800Hz音频****************************************/ void delay800(void){unsigned char n;for(n=0;n<200;n++);}/**************************************** 函数功能:主函数****************************************/{unsigned int i;while(1){for(i=0;i<830;i++){sound=0; //P3.7输出低电平delay1600();sound=1; //P3.7输出高电平delay1600();}for(i=0;i<200;i++){sound=0; //P3.7输出低电平delay800();sound=1; //P3.7输出高电平delay800();}}}//实例22:用while语句控制LED#include<reg51.h> //包含单片机寄存器的头文件函数功能:延时约60ms (3*100*200=60000μs)****************************************/void delay60ms(void){unsigned char m,n;for(m=0;m<100;m++)for(n=0;n<200;n++);}/****************************************函数功能:主函数****************************************/void main(void){unsigned char i;while(1) //无限循环{i=0; //将i初始化为0while(i<0xff) //当i小于0xff(255)时执行循环体{P0=i; //将i送P0口显示delay60ms(); //延时}}}//实例23:用do-while语句控制P0口8位LED流水点亮#include<reg51.h> //包含单片机寄存器的头文件/****************************************函数功能:延时约60ms (3*100*200=60000μs)****************************************/void delay60ms(void){unsigned char m,n;for(m=0;m<100;m++)for(n=0;n<200;n++);}/****************************************函数功能:主函数****************************************/void main(void){do{P0=0xfd; //第二个LED亮delay60ms();P0=0xfb; //第三个LED亮delay60ms();P0=0xf7; //第四个LED亮delay60ms();P0=0xef; //第五个LED亮delay60ms();P0=0xdf; //第六个LED亮delay60ms();delay60ms();P0=0xbf; //第七个LED亮delay60ms();P0=0x7f; //第八个LED亮delay60ms();}while(1); //无限循环,使8位LED循环流水点亮}//实例24:用字符型数组控制P0口8位LED流水点亮#include<reg51.h> //包含单片机寄存器的头文件/****************************************函数功能:延时约60ms (3*100*200=60000μs){unsigned char m,n;for(m=0;m<100;m++)for(n=0;n<200;n++);}/****************************************函数功能:主函数****************************************/void main(void){unsigned char i;unsigned char code Tab[ ]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; //定义无符号字符型数组while(1){for(i=0;i<8;i++){P0=Tab[i];//依次引用数组元素,并将其送P0口显示delay60ms();//调用延时函数}}//实例25:用P0口显示字符串常量#include<reg51.h> //包含单片机寄存器的头文件/*************************************************函数功能:延时约150ms (3*200*250=150 000μs=150ms*************************************************/void delay150ms(void){unsigned char m,n;for(m=0;m<200;m++)for(n=0;n<250;n++);}/*************************************************函数功能:主函数*************************************************/void main(void){unsigned char str[]={"Now,Temperature is :"}; //将字符串赋给字符型全部元素赋值unsigned char i;while(1)i=0; //将i初始化为0,从第一个元素开始显示while(str[i]!='\0') //只要没有显示到结束标志'\0'{P0=str[i]; //将第i个字符送到P0口显示delay150ms(); //调用150ms延时函数i++; //指向下一个待显字符}}}//实例26:用P0 口显示指针运算结果#include<reg51.h>void main(void){unsigned char *p1,*p2; //定义无符号字符型指针变量p1,p2unsigned char i,j; //定义无符号字符型数据i=25; //给i赋初值25j=15;p1=&i; //使指针变量指向i ,对指针初始化p2=&j; //使指针变量指向j ,对指针初始化P0=*p1+*p2; //*p1+*p2相当于i+j,所以P0=25+15=40=0x28//则P0=0010 1000B,结果P0.3、P0.5引脚LED熄灭,其余点亮 while(1)}//实例27:用指针数组控制P0口8位LED流水点亮#include<reg51.h>/*************************************************函数功能:延时约150ms (3*200*250=150 000μs=150ms*************************************************/void delay150ms(void){unsigned char m,n;for(m=0;m<200;m++)for(n=0;n<250;n++);}/*************************************************函数功能:主函数*************************************************/void main(void){unsigned char code Tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; unsigned char *p[ ]={&Tab[0],&Tab[1],&Tab[2],&Tab[3],&Tab[4],&Tab[5], &Tab[6],&Tab[7]};unsigned char i; //定义无符号字符型数据{for(i=0;i<8;i++){P0=*p[i];delay150ms();}}}//实例28:用数组的指针控制P0 口8 位LED流水点亮#include<reg51.h>/************************************************* 函数功能:延时约150ms (3*200*250=150 000μs=150ms *************************************************/ void delay150ms(void){unsigned char m,n;for(m=0;m<200;m++)for(n=0;n<250;n++);}/************************************************* 函数功能:主函数void main(void){unsigned char i;unsigned char Tab[ ]={0xFF,0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE,0xFE,0xFC,0xFB,0xF0,0xE0,0xC0,0x80,0x00,0xE7,0xDB,0xBD,0x7E,0x3C,0x18,0x00,0x81,0xC3,0xE7,0x7E,0xBD,0xDB,0xE7,0xBD,0xDB};//流水灯控制码unsigned char *p; //定义无符号字符型指针p=Tab; //将数组首地址存入指针pwhile(1){for(i=0;i<32;i++) //共32个流水灯控制码{P0=*(p+i); //*(p+i)的值等于a[i]delay150ms(); //调用150ms延时函数}}}//实例29:用P0 、P1口显示整型函数返回值#include<reg51.h>函数功能:计算两个无符号整数的和*************************************************/ unsigned int sum(int a,int b){unsigned int s;s=a+b;return (s);}/************************************************* 函数功能:主函数*************************************************/ void main(void){unsigned z;z=sum(2008,2009);P1=z/256; //取得z的高8位P0=z%256; //取得z的低8位while(1);}//实例30:用有参函数控制P0口8位LED流水速度#include<reg51.h>函数功能:延时一段时间*************************************************/void delay(unsigned char x){unsigned char m,n;for(m=0;m<x;m++)for(n=0;n<200;n++);}/*************************************************函数功能:主函数*************************************************/void main(void){unsigned char i;unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};//流水灯控制码while(1){//快速流水点亮LEDfor(i=0;i<8;i++) //共8个流水灯控制码{delay(100); //延时约60ms, (3*100*200=60 000μs) }//慢速流水点亮LEDfor(i=0;i<8;i++) //共8个流水灯控制码{P0=Tab[i];delay(250); //延时约150ms, (3*250*200=150 000μs) }}}//实例31:用数组作函数参数控制流水花样#include<reg51.h>/*************************************************函数功能:延时约150ms*************************************************/void delay(void){unsigned char m,n;for(m=0;m<200;m++)for(n=0;n<250;n++);}函数功能:流水点亮P0口8位LED*************************************************/void led_flow(unsigned char a[8]){unsigned char i;for(i=0;i<8;i++){P0=a[i];delay();}}/*************************************************函数功能:主函数*************************************************/void main(void){unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};//流水灯控制码led_flow(Tab);}//实例32:用指针作函数参数控制P0口8位LED流水点亮#include<reg51.h>函数功能:延时约150ms*************************************************/void delay(void){unsigned char m,n;for(m=0;m<200;m++)for(n=0;n<250;n++);}/*************************************************函数功能:流水点亮P0口8位LED*************************************************/void led_flow(unsigned char *p) //形参为无符号字符型指针{unsigned char i;while(1){i=0; //将i置为0,指向数组第一个元素while(*(p+i)!='\0') //只要没有指向数组的结束标志{P0=*(p+i);// 取的指针所指变量(数组元素)的值,送P0口 delay(); //调用延时函数}}}/*************************************************函数功能:主函数*************************************************/void main(void){unsigned char code Tab[ ]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F, 0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0xFE,0xFF,0xFE,0xFC,0xFB,0xF0,0xE0,0xC0,0x80,0x00,0xE7,0xDB,0xBD,0x7E,0xFF,0xFF,0x3C,0x18,0x0,0x81,0xC3,0xE7,0xFF, 0xFF,0x7E};//流水灯控制码unsigned char *pointer;pointer=Tab;led_flow(pointer);}//实例33:用函数型指针控制P1口灯花样#include<reg51.h> //包含51单片机寄存器定义的头文件unsigned char code Tab[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};//流水灯控制码,该数组被定义为全局变量函数功能:延时约150ms**************************************************************/ void delay(void){unsigned char m,n;for(m=0;m<200;m++)for(n=0;n<250;n++);}/************************************************************** 函数功能:流水灯左移**************************************************************/ void led_flow(void){unsigned char i;for(i=0;i<8;i++) //8位控制码{P0=Tab[i];delay();}}/****************************************************************************************************************************/void main(void){void (*p)(void); //定义函数型指针,所指函数无参数,无返回值p=led_flow; //将函数的入口地址赋给函数型指针pwhile(1)(*p)(); //通过函数的指针p调用函数led_flow()}//实例34:用指针数组作为函数的参数显示多个字符串#include<reg51.h> //包含51单片机寄存器定义的头文件unsigned char code str1[ ]="Temperature is tested by DS18B20";//C语言中,字符串是作为字符数组来处理的unsigned char code str2[ ]="Now temperature is:"; //所以,字符串的名字就是字符串的首地址unsigned char code str3[ ]="The Systerm is designed by Zhang San"; unsigned char code str4[ ]="The date is 2008-9-30";unsigned char *p[ ]={str1,str2,str3,str4}; //定义p[4]为指向4个字符串的字符型指针数组/**************************************************************函数功能:延时约150ms**************************************************************/void delay(void)unsigned char m,n;for(m=0;m<200;m++)for(n=0;n<250;n++);}/**************************************************************函数功能:流水点亮P0口8位LED**************************************************************/void led_display(unsigned char *x[ ]) //形参必须为指针数组{unsigned char i,j;for(i=0;i<4;i++) //有4个字符串要显示{j=0; //指向待显字符串的第0号元素while(*(x[i]+j)!='\0') //只要第i个字符串的第j号元素不是结束标志 {P0=*(x[i]+j); //取得该元素值送到P0口显示delay(); //调用延时函数j++; //指向下一个元素}}}/**************************************************************函数功能:主函数**************************************************************/void main(void){unsigned char i;while(1){for(i=0;i<4;i++)led_display(p); //将指针数组名作实际参数传递}}//实例35:字符函数ctype.h应用举例#include<reg51.h> //包含51单片机寄存器定义的头文件#include<ctype.h>void main(void){while(1){P3=isalpha('_')?0xf0:0x0f;//条件运算,若'_'是英文字母,P3=0xf0 }}//实例36:内部函数intrins.h应用举例#include<reg51.h> //包含51单片机寄存器定义的头文件#include<intrins.h> //包含函数isalpha()声明的头文件/*************************************************函数功能:延时约150ms*************************************************/void delay(void){unsigned char m,n;for(m=0;m<200;m++)for(n=0;n<250;n++);}/*************************************************函数功能:主函数*************************************************/void main(void){P3=0xfe; //P3=1111 1110Bwhile(1){P3=_crol_(P3,1);// 将P3的二进制位循环左移1位后再赋给P3 delay(); //调用延时函数}}//实例37:标准函数stdlib.h应用举例#include<reg51.h> //包含51单片机寄存器定义的头文件#include<stdlib.h> //包含函数isalpha()声明的头文件/*************************************************函数功能:延时约150ms*************************************************/ void delay(void){unsigned char m,n;for(m=0;m<200;m++)for(n=0;n<250;n++);}/*************************************************函数功能:主函数*************************************************/ void main(void){unsigned char i;while(1){for(i=0;i<10;i++) //产生10个随机数{P3=rand()/160; //将产生的随机数缩小160倍后送P3显示delay();}}}//实例38:字符串函数string.h应用举例#include<reg51.h> //包含51单片机寄存器定义的头文件#include<string.h> //包含函数isalpha()声明的头文件void main(void){unsigned char str1[ ]="Now, The temperature is :";unsigned char str2[ ]="Now, The temperature is 36 Centgrade:"; unsigned char i;i=strcmp(str1,str2); //比较两个字符串,并将结果存入iif(i==0) //str1=str2P3=0x00;elseif(i<0) //str1<str2P3=0xf0;else //str1>str2P3=0x0f;while(1); //防止程序“跑飞”}//实例39:宏定义应用举例2#include<reg51.h> //包含51单片机寄存器定义的头文件# define F(a,b) (a)+(a)*(b)/256+(b) //带参数的宏定义,a和b为形参void main(void){unsigned char i,j,k;i=40;j=30;k=20;P3=F(i,j+k); //i和j+k分别为实参,宏展开时,实参将替代宏定义中的形参while(1);}//实例40:宏定义应用举例2#include<AT89X51.h>#include<ctype.h>void main(void){P3_0=0; //将P3.0引脚置低电平,LED点亮P3_1=0; //将P3.0引脚置低电平,LED点亮P3_2=0; //将P3.0引脚置低电平,LED点亮P3_3=0; //将P3.0引脚置低电平,LED点亮P3_4=1; //将P3.4引脚置高电平,LED熄灭P3_5=1; //将P3.5引脚置高电平,LED熄灭P3_6=1; //将P3.7引脚置高电平,LED熄灭P3_7=1; //将P3.7引脚置高电平,LED熄灭while(1);}//实例41:宏定义应用举例3#include<reg51.h> //包含51单片机寄存器定义的头文件#define MAX 100 //将MAX宏定义为字符串100void main(void){#if MAX>80 //如果字符串100大于80P3=0xf0; //P3口低四位LED点亮#elseP3=0x0f; //否则,P3口高四位LED点亮#endif //结束本次编译}/*中断、定时器*///实例42:用定时器T0查询方式P2口8位控制LED闪烁#include<reg51.h> // 包含51单片机寄存器定义的头文件/**************************************************************函数功能:主函数**************************************************************/ void main(void){// EA=1; //开总中断// ET0=1; //定时器T0中断允许TMOD=0x01; //使用定时器T0的模式1TH0=(65536-46083)/256; //定时器T0的高8位赋初值TL0=(65536-46083)%256; //定时器T0的高8位赋初值TR0=1; //启动定时器T0TF0=0;P2=0xff;while(1)//无限循环等待查询{while(TF0==0);TF0=0;P2=~P2;TH0=(65536-46083)/256; //定时器T0的高8位赋初值 TL0=(65536-46083)%256; //定时器T0的高8位赋初值}}//实例43:用定时器T1查询方式控制单片机发出1KHz音频#include<reg51.h> // 包含51单片机寄存器定义的头文件sbit sound=P3^7; //将sound位定义为P3.7引脚/************************************************************** 函数功能:主函数**************************************************************/ void main(void){// EA=1; //开总中断// ET0=1; //定时器T0中断允许TMOD=0x10; //使用定时器T1的模式1TH1=(65536-921)/256; //定时器T1的高8位赋初值TL1=(65536-921)%256; //定时器T1的高8位赋初值TR1=1; //启动定时器T1TF1=0;while(1)//无限循环等待查询{while(TF1==0);TF1=0;sound=~sound; //将P3.7引脚输出电平取反TH1=(65536-921)/256; //定时器T0的高8位赋初值 TL1=(65536-921)%256; //定时器T0的高8位赋初值}。
51单片机(STC89C52)的中断和定时器
51单⽚机(STC89C52)的中断和定时器STC89C51/STC89C52 Timer内部不带振荡源, 必须外接晶振采⽤11.0592MHz,或22.1184MHz,可⽅便得到串⼝通讯的标准时钟.STC89和STC90系列为12T, STC11/STC12系列为1T, 也就是⼀个指令⼀个机器周期, 这些都需要外置晶振; STC15系列有内置晶振.中断中断允许控制寄存器 IE字节地址A8H, CPU对中断系统所有中断以及某个中断源的开放和屏蔽是由中断允许寄存器IE控制的D7D6D5D4D3D2D1D0EA—ET2ES ET1EX1ET0EX0EA (IE.7): 整体中断允许位, 1:允许ET2(IE.5): T2中断允许位, 1:允许(for C52)ES (IE.4): 串⼝中断允许位, 1:允许ET1(IE.3): T1中断允许位, 1:允许EX1(IE.2): 外部中断INT1允许位, 1:允许ET0(IE.1): T0中断允许位, 1:允许EX0(IE.0): 外部中断INT0允许位, 1:允许52单⽚机⼀共有6个中断源, 它们的符号, 名称以及各产⽣的条件分别如下1. INT0 - 外部中断0, 由P3.2端⼝线引⼊, 低电平或下降沿引起2. INT1 - 外部中断1, 由P3.3端⼝线引⼊, 低电平或下降沿引起3. T0 - 定时器/计数器0中断, 由T0计数器计满回零引起4. T1 - 定时器/计数器1中断, 由T1计数器计满回零引起5. T2 - 定时器/计数器2中断, 由T2计数器计满回零引起 <--这个是52特有的6. TI/RI - 串⾏⼝中断, 串⾏端⼝完成⼀帧字符发送/接收后引起定时器中断51单⽚机内部共有两个16位可编程的定时器,即定时器T0和定时器T1, 52单⽚机内部多⼀个T2定时器. 它们既有定时功能,也有计数功能。
可通过设置与它们相关的特殊功能寄存器选择启⽤定时功能还是计数功能. 这个定时器系统是单⽚机内部⼀个独⽴的硬件部分,它与CPU和晶振通过内部某些控制线连接并相互作⽤,CPU⼀旦设置开启定时功能后,定时器便在晶振的作⽤下⾃动开始计时,但定时器的计数器计满后,会产⽣中断。
TIMER0控制单只LED闪烁
TIMER0控制单只LED闪烁
一、TIMER0控制单只LED闪烁
பைடு நூலகம்
实现原理 总体思路: 掌握89C51的I/O接口的几个PO~P3端口 的用途,用P0.0控制一个发光二极管闪烁。 在Protues仿真软件上将电路画出。 在Keil-4软件上编写程序,用硬件延迟模 式编程 实现Protues与Keil-4的链接
硬件设计
电路图仿真图: 原件:单片机89C51 晶体振荡器12MHz 普通电容30pF 电解电容10uF 电阻10千欧 电阻220欧 发光二级管
电路仿真图:
程序:
#include<reg51.h> sbit P0_0=P0^0; //定义位名称 void delay(); //延时函数声明 void main(){ while(1){ P0_0=0; //点亮信号灯 delay(); //调用延时函数 P0_0=1; //熄灭信号灯 delay(); } } void delay() { unsigned char j; //定义字符常量j TMOD=0x10; //设置定时器T1工作于方式1 for(j=0;j<0x08;j++){ //设置8次循环次数 TH1=0x3c; //设置定时器初值为0x3cb0 TL1=0xb0; TR1=1; //启动T1 while(!TF1); //查询计数是否溢出,即定时50ms时间到,TF1=1 TF1=0; //50ms定时时间到,将T1溢出位TF1清0 } }
4.5_定时器1控制LED闪烁【ZigBee基础开发】
寄存器位
寄存器名
二进制值 十六进制值
7 6 54 3 2 1 0
功能
T1CTL
保留 0 1 0 1 0101
0x05
设置定时器1/8分频、 自由运行模式
寄存器设置
IEN1:中断使能1
位 名称 复位
1
T1IE 0
定时器1中断使能
0:中断禁止
1:中断使能
描述
T1IE=1;//定时器1中断使能
寄存器设置
说明:关于时钟控制命令的相关说明请参考用户手册。
寄存器设置
T1CTL:定时器1控制寄存器
位 3:2
1:0
复位 0x00
0x00
描述
分频器划分值。活动时钟边缘更新计数器,如下: 00: 标记频率/1 01: 标记频率/8 10: 标记频率/32 11: 标记频率/128
定时器1模式选择。定时器操作模式通过下列方式选择: 00: 暂停运行。 01: 自由运行,从0x0000到0xFFFF反复计数。 10: 模,从 0x0000到T1CC0反复计数。 11: 正计数/倒计数,从 0x0000到T1CC0反复计数并且从T1CC0倒计数到0x0000。
定时器的其它功能
捕获器 比较器
通过计算捕获的差值,来测量波形的频率和宽度 模拟比较器 比较两组输入电压的大小
输出比较器 产生可调频率且占空比可调的脉冲波形
PWM 脉宽调制器,产生固定周期但占空比可调的脉冲波形
CC2530定时器/计数器工作模式
自由运行模式
模模式
正计数/倒 时数模式
寄存器设置
CLKCONCMD:时钟控制命令 将晶振频率设置为32MHz。 代码为: CLKCONCMD &=~0x7F;