目录

1.点亮LED灯

1.1LED灯闪烁

1.2控制LED灯按时闪烁:

1.3 LED灯流水灯

1.4二进制点灯

2.独立按键控制LED灯

2.1按键控制LED亮灭

2.2.按键控制灯左右移动

3.数码管

3.1静态数码管显示

3.2.动态数码管显示

4.模块化编程

5.LCD1602调试工具

6.矩阵键盘

6.1.介绍矩阵键盘

6.2.矩阵键盘在LCD上按键显示

6.3.矩阵键盘制作密码锁

7.定时器

7.1关于定时器的基本概念

7.2.中断系统介绍

7.3.寄存器:

7.4.如何实现用定时器记1秒

7.5.模块化定时器

7.6.定时器使用的示例

1.点亮LED灯

1.1LED灯闪烁

LED点亮原理(示意图如下)

电阻:作用限流,大小为102(其中2为倍率),即1000欧姆。

由CPU通过控制配置的寄存器控制硬件电路,寄存器后面连接导线,通过一个驱动器(增大电流),连接到io口端口,使引脚输出高低电平:(TTL电平)高电平5V,低电平0V。

左端VCC接电源正极,故端口输出高电平时(表示为1),负极接正,LED不点亮;

端口输出低电平时(表示为0),负极接负,LED点亮;

注意:写代码不支持直接写二进制,二进制应该换为16进制(0x为前缀)

注意:LED灯对应的二进制数字是从右往左一一对应,如0111 1111,是第8个灯亮,不是第一个灯亮

示例1:led灯的亮灭

#include <REGX52.H>void main()
{P2=0xFE;   //亮  1111 1110P2=0xFE;   //灭 1111 1111
}

1.2控制LED灯按时闪烁:

调用stc-isp软件的软件延时计算器,调节系统频率为12.000,指令集为STC-Y1,自定义长度为800毫秒,生成C代码即可复制使用。

注意 _nop_的使用需要加头文件#include<INTRINS.H>

#include <REGX52.H>
#include<INTRINS.H>
void Delay800ms()       //@12.000MHz
{unsigned char i, j, k;_nop_();i = 7;j = 21;k = 96;do{do{while (--k);} while (--j);} while (--i);
}void main(){P2=0xFE;Delay800ms(); P2=0xFF;Delay800ms();
}

1.3 LED灯流水灯

生成1毫秒延时的函数,通过while循环实现时长的自定义调节函数。

#include <REGX52.H>
#include <INTRINS.H>
void Delay1ms(unsigned int xms)     //@12.000MHz
{unsigned char i, j;while(xms){i = 2;j = 239;do{while (--j);} while (--i);xms--;}
}void main(){while(1){P2=0xFE;   //1111 1110Delay1ms(800);P2=0xFD;    //1111 1101Delay1ms(700);P2=0xFB;   //1111 1011Delay1ms(600);P2=0xF7;   //1111 0111Delay1ms(500);P2=0xEF;   //1110 1111Delay1ms(400);P2=0xDF;   //1101 1111Delay1ms(300);P2=0xBF;  //1011 1111Delay1ms(200);P2=0x7F;   //0111 1111Delay1ms(100);}
}

1.4二进制点灯

#include <REGX52.H>
#include <INTRINS.H>
void Delay(unsigned int xms)        //@12.000MHz
{unsigned char i, j;while(xms){i = 2;j = 239;do{while (--j);} while (--i);xms--;}
}void main(){    unsigned char LEDnum=0;         //引入变量while(1){if(P3_1==0){Delay(20);          //通过delay去抖while(P3_1==0);     //while作用://按键启动if循环,松手走出while循环,运行下一步代码Delay(20);LEDnum++;      //16进制0,1,2,3,4P2=~LEDnum;    //取反}}

2.独立按键控制LED灯

2.1按键控制LED亮灭

1.按键抖动:对于机械开关,当机械触点断开、闭合时,由于机械触点的弹性作用,一个开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开,所以在开关闭合及断开的瞬间会伴随一连串的抖动

2.认识独立按键:一端共同接正极,当另一端(P3)连接低电平时,即表示按键接通

注意K1,K2,K3,K4分别对应代码的P3_1 P3_0 P3_2 P3_3

#include <REGX52.H>
#include <INTRINS.H>
void Delayms(unsigned int xms)      //@12.000MHz
{unsigned char i, j;while(xms){i = 2;j = 239;do{while (--j);} while (--i);xms--;}
}void main(){if(P3_1==0){   //按键执行Delayms(20);   //除去抖动while(P3_1==0);   //按键,进入空白循环,不执行下面Delayms(20);    P2_1=~P2_1;    //松键状态改变}
}

2.2.按键控制灯左右移动

相关运算符

按位左移:0011 1100<<1    即0111 1000

按位右移:0011 1100>>2    即0000 1111

按位与:0001 1000& 0010 1010 每一位单独操作   结果0000 1000 即0&一切 为0  1&X为X本身

按位或:0001 1000 | 0010 1010    结果0011 1010   1|一切为1 0|X为X本身

按位异或:0001 1000^0010 1010  结果0011 0010   即一样为0,不一样为1

取反:~00001111     11110000

#include <REGX52.H>
#include <INTRINS.H>
void Delay(unsigned int xms)        //@12.000MHz
{unsigned char i, j;while(xms){i = 2;j = 239;do{while (--j);} while (--i);xms--;}
}void main(){unsigned char LEDnum=0;while(1){if(P3_1==0){Delay(20);while(P3_1==0);   Delay(20);if(LEDnum>=8){    LEDnum=0;}//LEDnum=1   0000 0001---0000 0010  取反1111 1101 P2=~(0x01<<LEDnum);LEDnum++;}if(P3_3==0){Delay(20);while(P3_3==0);   Delay(20);if(LEDnum==0){    LEDnum=7;}else{LEDnum--;}P2=~(0x01<<LEDnum);}}
}

3.数码管

3.1静态数码管显示

3.1.1.一位数码管

示意图如下:

共阴极连接(右上图):8个LED的阴极都连接到一个端口上

共阳极连接(右下图):8个LED的阳极都连接到一个端口上

51单片机的开发板为共阴极连接,即公共端阴极接低电平,未选端给相应数据,输入1即为亮;反之,共阳极连接则将公共端接正极电源,未选端输入0为亮

3.1.2.多位数码管

示意图如下:

即多分出几个小单元,公共端独立,未选端连在一起,作用是节省了io口,但同一个时刻下只能显示同样的数字,若要显示不同数字可通过动态数码管显示(利用人眼视觉暂留和数码管显示余晖的原理)

3.1.3. 138译码器

作用:和数码管相连接,8个io口简化为3个,其示意图如下:

使用原理:

左边P2端123依次输入二进制数字,右边对应的十进制接口显示0,其他均为1

示例:输入二进制(101),对应十进制(5),即Y5口为0,对应LED口数据为1111 1011,(0即为接通,即第6个数码管显示,其他数码管不显示)(注意Y是从0开始计,Y5为0即LED6为0)

3.1.4.  74HC245 

(示意图如上)

作用:单片机高电平驱动能力有限,输出的最大电流不能太大,低电平驱动能力强一些。加入缓冲器74HC245,提高驱动能力,吸收P0端口的微弱信号,再从VCC电源汲取能量,驱动数码管灯光更亮

3.1.5 操作示例一:使第三个数码管显示6

P2口控制数码管显示的位置,0为接通,P0口控制数码管显示的数字,1为接通;

其中:由计算可得

0对应0x3F、1对应0x06、2对应0x5B、3对应0x4F、4对应0x66、

5对应0x6D、6对应0x7D、7对应0x07、8对应0x7F、9对应0x6F

A对应0x77、B对应0x7C、C对应0x39、D对应0x5E、

E对应0x79、F对应0x71、空对应0x00,

#include <REGX52.H>
void main(){P2_4=1;      //ABC ——234——011 —— 3 —— Y2 —— 第二个数码管P2_3=1;P2_2=0;   while(1){ P0=0x7D;   //注意从下往上读数0111 1101 —— 显示6}
}

 操作示例二:写一个函数,方便改变数码管显示位置和数字

#include <REGX52.H>
unsigned char NUM[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void Nixie(unsigned char location,number){switch(location){case 1:     P2_4=1;P2_3=1;P2_2=1;     break;case 2:   P2_4=1;P2_3=1;P2_2=0;break;case 3: P2_4=1;P2_3=0;P2_2=1;break;case 4:  P2_4=1;P2_3=0;P2_2=0;       break;case 5:     P2_4=0;P2_3=1;P2_2=1;break;case 6:     P2_4=0;P2_3=1;P2_2=0;break;case 7:     P2_4=0;P2_3=0;P2_2=1;break;case 8:     P2_4=0;P2_3=0;P2_2=0;break;}P0=NUM[number];
}void main(){Nixie(1,1); while(1){};   //不可省去
}

3.2.动态数码管显示

#include <REGX52.H>
void Delayms(unsigned int xms)      //@12.000MHz
{unsigned char i, j;while(xms){i = 2;j = 239;do{while (--j);} while (--i);xms--;}
}
unsigned char NUM[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void Nixie(unsigned char location,unsigned char number){switch(location){case 1:     P2_4=1;P2_3=1;P2_2=1;       break;case 2:   P2_4=1;P2_3=1;P2_2=0;break;case 3: P2_4=1;P2_3=0;P2_2=1;break;case 4:  P2_4=1;P2_3=0;P2_2=0;       break;case 5:     P2_4=0;P2_3=1;P2_2=1;break;case 6:     P2_4=0;P2_3=1;P2_2=0;break;case 7:     P2_4=0;P2_3=0;P2_2=1;break;case 8:     P2_4=0;P2_3=0;P2_2=0;break;}P0=NUM[number];Delayms(2);P0=0x00;   //把前一个数据清零,防止对下一个显示有影响
}void main(){ while(1){Nixie(1,1);Nixie(2,3);Nixie(3,1);Nixie(4,4);     };
}

4.模块化编程

1.基本概念

传统方式编程:所有的函数均放在main.c里,若使用的模块比较多,则一个文件内会有很多的代码,不利于代码的组织和管理,而且很影响编程者的思路

模块化编程:把各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数的声明,其它.c文件想使用其中的代码时,只需要#include "XXX.h"文件即可。使用模块化编程可极大的提高代码的可阅读性、可维护性、可移植性等

.c文件:函数、变量的定义

.h文件:可被外部调用的函数、变量的声明

注意:任何自定义的变量、函数在调用前必须有定义或声明(同一个.c) 使用到的自定义函数的.c文件必须添加到工程参与编译 使用到的.h文件必须要放在编译器可寻找到的地方(工程文件夹根目录、安装目录、自定义)

C语言的预编译:以#开头,作用是在真正的编译开始之前,对代码做一些处理(预编译)

示例:

1.文件必须添加到目录列表中

2.Delay.h   函数声明

#ifndef _DELAY_H_
#define _DELAY_H_void Delay(unsigned int xms);#endif

3.Delay.c   函数定义

#include <REGX52.H>
#include <INTRINS.H>
void Delay(unsigned int xms)        //@12.000MHz
{unsigned char i, j;while(xms){i = 2;j = 239;do{while (--j);} while (--i);xms--;}
}

4.Nixie.h 函数声明

#ifndef _Nixie_H_
#define _Nixie_H_void Nixie(unsigned char location,unsigned char number);#endif

5.Nixie.c 函数定义

#include <REGX52.H>
#include "Delay.h"
unsigned char NUM[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
void Nixie(unsigned char location,unsigned char number){switch(location){case 1:     P2_4=1;P2_3=1;P2_2=1;       break;case 2:   P2_4=1;P2_3=1;P2_2=0;break;case 3: P2_4=1;P2_3=0;P2_2=1;break;case 4:  P2_4=1;P2_3=0;P2_2=0;       break;case 5:     P2_4=0;P2_3=1;P2_2=1;break;case 6:     P2_4=0;P2_3=1;P2_2=0;break;case 7:     P2_4=0;P2_3=0;P2_2=1;break;case 8:     P2_4=0;P2_3=0;P2_2=0;break;}P0=NUM[number];Delay(2);P0=0x00;
}

6.main.c  主函数

#include <REGX52.H>  是在安装目录寻找文件
#include "Delay.h"   是在程序目录寻找文件

#include <REGX52.H>
#include "Delay.h"
#include "Nixie.h"
void main(){while(1){Nixie(1,1);Nixie(2,3);Nixie(3,1);Nixie(4,4);           }
}

5.LCD1602调试工具

1.基本概念:使用LCD1602液晶屏作为调试窗口,提供类似printf函数的功能,可实时观察单片机内部数据的变换情况,便于调试和演示。 LCD1602代码属于模块化的代码,即只需要知道所提供函数的作用和使用方法就可以使用LCD1602,不用自己编码程序。

模块化代码如下:

2.注意:由于外设互相干扰,使用LCD1602后,数码管显示乱码

原理(示意图如下):LCD1602连接P0口(数码管接口)和P2口(3个LED接口),引脚冲突,故使用LCD1602时无法正常使用数码管和LED灯

3.使用注意:模块函数LCD1602.c和LCD1602.h应该和project放在同一个文件里

4.示例1:使用LCD1602输出

注意:主函数使用LCD前要初始化,加入LCD_Init();

#include <REGX52.H>
#include "LCD1602.h"
void main(){LCD_Init();while(1){LCD_ShowChar(1,1,'A');LCD_ShowString(1,3,"hello world");LCD_ShowNum(2,1,18,4);  //无符号数字,长度4位,多余补0,显示0018LCD_ShowSignedNum(2,6,-65,3);  //有符号数字LCD_ShowHexNum(2,10,0xFF,2);   //输出FFLCD_ShowBinNum(2,13,0xF,4);   //二进制数在keil里用16进制表示,输出1111}}

示例2:使用LCD显示递增数字,主函数如下

#include <REGX52.H>
#include "LCD1602.h"
#include "Delay.h"unsigned int number=0;
void main(){LCD_Init(); while(1){Delay(300);LCD_ShowNum(1,1,number,4);number++;}
}

6.矩阵键盘

6.1.介绍矩阵键盘

1.概念:在键盘中按键数量较多时,为了减少IO口的占用,通常将按键排列成矩阵形式 采用逐行或逐列的“扫描”,就可以读出任何位置按键的状态,其特点是:两端都接io口,可以按行扫描或按列扫描。

2.扫描

数码管扫描(输出扫描)原理:显示第1位→显示第2位→显示第3位→……,然后快速循环这个过程,最终实现所有数码管同时显示的效果

矩阵键盘扫描(输入扫描)原理:读取第1行(列)→读取第2行(列) →读取第3行(列) → ……,然后快速循环这个过程,最终实现所有按键同时检测的效果

以上两种扫描方式的共性:节省I/O口

3.注意事项:为了避免外设互相干扰,矩阵键盘使用按列扫描

矩阵键盘的P10~13口和五线四相步进电机相连,进而与蜂鸣器的BZ口相连,驱使蜂鸣器一直响。采用逐列扫描,即给P10~13口赋值,读取P14~17。

示例:P13~10从左到右依次赋值0111 即第一列接通,1011即第二列接通……逐列依次读取P14~17的数据。

6.2.矩阵键盘在LCD上按键显示

按下矩阵键盘Sn:LCD1602屏幕显示相应数字n;

思路如下:

(1)定义MatrixKey()函数:按键后给变量keynum赋相应的值并作为返回值输出;

(2)主函数调用LCD1602()函数中的LCD_ShowNum()函数,输出MatrixKey()函数的返回值;

定义函数MatrixKey.c如下:

#include <REGX52.H>
#include  "Delay.h"
unsigned int Keynumber=0;
unsigned int MatrixKey(){Keynumber=0;P1=0xFF;       P1_3 = 0;   //第一列 if(P1_7==0)        //S1
{Delay (20);while(P1_7==0);Delay(20);Keynumber=1;}if(P1_6==0)        //S5
{Delay(20);while(P1_6==0);Delay(20);Keynumber=5;}if(P1_5==0)        //S9
{Delay(20);while(P1_5==0);Delay(20);Keynumber=9;}if(P1_4==0)        //S13
{Delay(20);while(P1_4==0);Delay(20);Keynumber=13;}P1=0xFF;P1_2=0;    //第二列
if(P1_7==0)        //S2
{Delay(20);while(P1_7==0);Delay(20);Keynumber=2;}if(P1_6==0)        //S6
{Delay(20);while(P1_6==0);Delay(20);Keynumber=6;}if(P1_5==0)        //S10
{Delay(20);while(P1_5==0);Delay(20);Keynumber=10;}if(P1_4==0)        //S14
{Delay(20);while(P1_4==0);Delay(20);Keynumber=14;}P1=0xFF;P1_1=0;    //第三列
if(P1_7==0)        //S3
{Delay(20);while(P1_7==0);Delay(20);Keynumber=3;}if(P1_6==0)        //S7
{Delay(20);while(P1_6==0);Delay(20);Keynumber=7;}if(P1_5==0)        //S11
{Delay(20);while(P1_5==0);Delay(20);Keynumber=11;}if(P1_4==0)        //S15
{Delay(20);while(P1_4==0);Delay(20);Keynumber=15;}P1=0xFF;P1_0=0;    //第四列
if(P1_7==0)        //S4
{Delay(20);while(P1_7==0);Delay(20);Keynumber=4;}if(P1_6==0)        //S8
{Delay(20);while(P1_6==0);Delay(20);Keynumber=8;}if(P1_5==0)        //S12
{Delay(20);while(P1_5==0);Delay(20);Keynumber=12;}if(P1_4==0)        //S16
{Delay(20);while(P1_4==0);Delay(20);Keynumber=16;}return Keynumber;
}

依次加入定义和声明后主函数main.c如下:

#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "MatrixKey.h"
unsigned char keynum;
void main(){LCD_Init();LCD_ShowString(1,1,"hello world");while(1){keynum=MatrixKey();if(keynum){LCD_ShowNum(2,1,keynum,2);}}
}

6.3.矩阵键盘制作密码锁

主函数如下:

注意每一次按键赋值之后,keynum要重新赋值为0;

#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "MatrixKey.h"unsigned int keynum=0;
unsigned int Password=0;
unsigned int count=0;
void main(){LCD_Init();LCD_ShowString(1,1,"hello:");while(1){keynum = MatrixKey();if(keynum){if(keynum<=10){if(count<4){Password=Password*10;Password+=keynum;keynum=0;count++;LCD_ShowNum(2,1,Password,4);}    }}if(keynum==11){if(Password==2431){LCD_ShowString(2,7,"OK");Password=0;count=0;}else{LCD_ShowString(2,7,"ERR");Password=0;count=0;}            }}
}

7.定时器

7.1关于定时器的基本概念

1.定时器介绍

51单片机的定时器属于单片机的内部资源,其电路的连接和运转均在单片机内部完

2.定时器作用

(1)用于计时系统,可实现软件计时,或者使程序每隔一固定时间完成一项操作

(2)使用Delay期间,单片机不工作,定时器可以替代长时间的Delay,提高CPU的运行效率和处理速度

3.STC89C52定时器资源

定时器个数:3个(T0、T1、T2)

T0和T1与传统的51单片机兼容,T2是此型号单片机增加的资源 注意:定时器的资源和单片机的型号是关联在一起的,不同的型号可能会有不同的定时器个数和操作方式,但一般来说,T0和T1的操作方式是所有51单片机所共有的。

4.定时器框图

定时器在单片机内部就像一个小闹钟一样,根据时钟的输出信号,每隔“一秒”,计数单元的数值就增加一,当计数单元数值增加到“设定的闹钟提醒时间”时,计数单元就会向中断系统发出中断申请,产生“响铃提醒”,使程序跳转到中断服务函数中执行

 5.STC89C52的T0和T1均有四种工作模式

模式0:13位定时器/计数器

模式1:16位定时器/计数器(常用)   

模式2:8位自动重装模式

模式3:两个8位计数器

工作模式1框图:

SYSclk:系统时钟,即晶振周期,本开发板上的晶振为12MHz,若选择连接12T mode,连C/T=0,分频12MHz分为1M,每隔1微秒记一次时。

计数器:分为2个字节:TL0(低字节) TH0(高字节) 总共存储65535,即最大容量为65535。左边计数系统每提供一个脉冲,右边计数器加1,加到最大值(65535)时,在下一个脉冲时产生溢出,向中断系统申请中断,计数器数值归0。

控制位:TR0控制定时器启动或暂停

7.2.中断系统介绍

 工作示意图:

作用:可以同时完成两个任务,可以提高效率。

中断源个数:8个(外部中断0、定时器0中断、外部中断1、定时器1中断、串口中断、定时器2中断、外部中断2、外部中断3)

中断号如下:

注意:中断的资源和单片机的型号是关联在一起的,不同的型号可能会有不同的中断资源,例如中断源个数不同、中断优先级个数不同等等

中断系统内部连接示意图:(TF0接ET0接EA接PT0)

7.3.寄存器

单片机通过配置寄存器控制内部线路的连接。寄存器是连接软硬件的媒介,在单片机中寄存器就是一段特殊的RAM存储器,一方面,寄存器可以存储和读取数据,另一方面,每一个寄存器背后都连接了一根导线,控制着电路的连接方式,寄存器相当于一个复杂机器的“操作按钮”

示例:配置工作模式寄存器TMOD(不可位寻址:必须整体赋值):赋值0000 0001 即选择定时器0的M0模式(示意图如下)

示例:配置控制寄存器TCON(如下图)(可位寻址:可以单独赋值也可以整体赋值,类似LED灯的P2寄存器)如TF0=0;TR0=1;

 中断系统寄存器:

理解:定时器的工作不需要单片机的执行,是独立的一部分,依靠外部晶振产生的脉冲自动计数,单片机只是控制开始和初始值,定时器就可以自动累加,这过程中程序可以继续运行,当定时器自动累加到溢出时,就会产生中断信号,使程序跳转到interrupt 1中执行中断程序。溢出后定时器从0开始累加,所以在中断后需要重新给计数器赋初值,定时器相当于在一直累加,和主程序同时运行。

7.4.如何用定时器计时

原理:计时器容量为65535,每隔1us加1,从0开始增加到65535时就执行中断系统,故总共定时时间为65535微秒。当人为赋初值为64535,则1000微秒(1毫秒)后就执行中断,1000次中断即为1秒。

计时器赋初始值:高字节TH0=64535/256

低字节TL0=64535%256(16进制数字取位操作)

【类比10进制取位:百位234/100;后2位234%100】

示例:定时器T0工作在方式一,晶振频率为11.0592MHZ,需要定时时间0.5s

方法一:计算思路:

  • 5ms的定时时间先换算成us单位就是5000us
  • 代入公式:(65536-X)× 12 ÷ 11.0592=5000(us)得 X=60928
  • 把十进制60928转换为16进制=0xee00,分配高8位TH=0xee,低8位TL=0x00,初始值这样就算好了。

方法二:在烧录软件找到定时计算器,选好定时器、工作方式、时钟以及定时长度(初始值),就能自动得到初始值了

代码示意:实现LED闪烁,间隔1秒

先初始化定时器系统,主函数先运行,到达定时器限定时间后中断主函数,跳转执行void Timer0_Routine() interrupt 1之后再返回主函数。

#include <REGX52.H>void Timer0Init(void)   //外设配置
{TMOD=0x01;  //0000 0001TF0=0;TR0=1;TH0=65435/256;TL0=65435%256;ET0=1;EA=1;PT0=0;
}void main(){Timer0Init();  //先初始化while(1){}
}
unsigned int T0Count=0;
void Timer0_Routine() interrupt 1
{TH0=65435/256;TL0=65435%256;  T0Count++;if(T0Count>=1000){    //间隔1秒P2_0=~P2_0;T0Count=0;}
}

代码缺陷:TMOD赋值0000 0001,若同时使用定时器1和定时器0则受影响

改进如下:

TMOD =TMOD & 0xF0;  低四位清零,高四位保持不变

如1010 0011 & 1111 0000——1010 0000

TMOD =TMOD & 0xF1;  低四位赋值1,高四位保持不变

如1010 0000 | 1111 0001——1010 0001

7.5.模块化定时器

方便随时使用

定义Timer0.c

#include <REGX52.H>
void Timer0Init(void)       //1微秒@12.000MHz
{//AUXR &= 0x7F;       //定时器时钟12T模式TMOD &= 0xF0;      //设置定时器模式TMOD |= 0x01;TL0 = 0x18;     //设置定时初值TH0 = 0xFC;        //设置定时初值TF0 = 0;       //清除TF0标志TR0 = 1;      //定时器0开始计时ET0 =1;EA=1;PT0=0;
}

声明Timer0.h

#ifndef _TIMER0_H_
#define _TIMER0_H_void Timer0_Routine();#endif

7.6.定时器使用的示例

示例1:按键控制流水灯左右扭转

主函数如下:LED每个一秒移位,按下S1改变移动位方向;其中调用了_crol_函数要加头文件#include <INTRINS.H>

#include <REGX52.H>
#include "Delay.h"
#include "MatrixKey.h"
#include <INTRINS.H>
unsigned int keynum=0;
unsigned int T0Count=0;
unsigned int LCDMode=0;
void main()
{P2=0xFE; Timer0Init();while(1){keynum=MatrixKey();if(keynum){if(keynum==1){LCDMode++;keynum==0;if(LCDMode>=2){LCDMode=0;keynum==0;}}}}
}
void Timer0_Routine() interrupt 1
{TL0 = 0x18;       //设置定时初值TH0 = 0xFC;    T0Count++;if(T0Count>=1000){T0Count=0;if(LCDMode==0){P2=_crol_(P2,1);}if(LCDMode==1){P2=_cror_(P2,1);}}
}

示例2:制作简单时钟,主函数代码如下

#include <REGX52.H>
#include "Timer0.h"
#include "Delay.h"
#include "LCD1602.h"
unsigned int hour=23;
unsigned int min=59;
unsigned int s=50;
void main(){LCD_Init();Timer0Init();while(1){LCD_ShowString(1,1,"time:");LCD_ShowNum(2,1,hour,2);LCD_ShowString(2,3,":");LCD_ShowNum(2,4,min,2);LCD_ShowString(2,6,":");LCD_ShowNum(2,7,s,2);}
}void Timer0_Routine() interrupt 1
{static unsigned int T0Count=0;TL0 = 0x18;        //ÉèÖö¨Ê±³õÖµTH0 = 0xFC;  T0Count++;if(T0Count>=1000){s++;T0Count=0;}if(s>=60){min++;s=0;}if(min>=60){hour++;min=0;}if(hour>=24){hour=0;}
}

AutoLeader控制组——51单片机学习笔记(一)相关推荐

  1. AutoLeaders控制组—51单片机学习笔记

    文章目录 AutoLeaders控制组-51单片机学习笔记 1.1单片机及开发板介绍 单片机介绍 单片机应用领域 STC89C52单片机 内部结构 开发板介绍 2.1点亮一个Led 新建工程 编程 认 ...

  2. Autoleaders控制组——51单片机学习笔记

    前要:本笔记为初学者上b站江科大自化协的51单片机入门教程P1-P12所得笔记,包含单片机简介和LED.独立按键.数码管相关内容. 目录 1.1.什么是单片机以及为什么要学单片机?51是什么? 2-1 ...

  3. AutoLeaders控制组——51单片机学习笔记(AD/DA、红外遥控)

    本篇内容是观看B站江科大自化协UP主的教学视频所做的笔记,对其中内容有所引用,并结合自己的单片机板块进行了更改调整. 以下笔记内容以一个视频为一个片段(内容较多,可能不适合速食,望见谅) 一些内容涉及 ...

  4. AutoLeaders控制组—51单片机学习笔记(LED控制、独立按键、数码管)

    本篇内容是观看B站江科大自化协UP主的教学视频所做的笔记,对其中内容有所引用,并结合自己的单片机板块进行了更改调整. 以下笔记内容以一个视频为一个片段(内容较多,可能不适合速食,望见谅) 根据测试,目 ...

  5. AutoLeaders控制组——51单片机学习笔记(定时器、串口通信)

    本篇内容是观看B站江科大自化协UP主的教学视频所做的笔记,对其中内容有所引用,并结合自己的单片机板块进行了更改调整. 以下笔记内容以一个视频为一个片段(内容较多,可能不适合速食,望见谅) 一些内容涉及 ...

  6. AutoLeaders控制组——51单片机学习笔记(蜂鸣器、AT24C02芯片)

    本篇内容是观看B站江科大自化协UP主的教学视频所做的笔记,对其中内容有所引用,并结合自己的单片机板块进行了更改调整. 以下笔记内容以一个视频为一个片段(内容较多,可能不适合速食,望见谅) 一些内容涉及 ...

  7. AutoLeaders控制组——51单片机学习笔记(模块化编程、LCD_1602、矩阵键盘)

    本篇内容是观看B站江科大自化协UP主的教学视频所做的笔记,对其中内容有所引用,并结合自己的单片机板块进行了更改调整. 以下笔记内容以一个视频为一个片段(内容较多,可能不适合速食,望见谅) 一些内容涉及 ...

  8. AutoLeaders控制组——51单片机学习笔记(DS18B20温度传感器、LCD1602、直流电机+PWM)

    本篇内容是观看B站江科大自化协UP主的教学视频所做的笔记,对其中内容有所引用,并结合自己的单片机板块进行了更改调整. 以下笔记内容以一个视频为一个片段(内容较多,可能不适合速食,望见谅) 一些内容涉及 ...

  9. 51单片机学习笔记-1简介及点灯

    51单片机学习笔记 文章目录 51单片机学习笔记 1. 51单片机简介 1.1 安装软件 1.2 单片机简介 2. LED灯 2.1点亮一个LED 2.1.1原理分析 2.1.2 创建工程 2.2LE ...

最新文章

  1. matplotlib.pyplot绘制函数图像希腊字母latex效果设置
  2. 【问链-Eos公开课】第三课 EOS 的新共识机制 BFT-DPoS
  3. 虚拟服务器放2个网站,如何一个虚拟主机空间放两个网站的基本原理
  4. getcwd函数_PHP getcwd()函数与示例
  5. Seata 单机环境搭建_01
  6. linux本地时间与utc不一致_Linux下CST和UTC时间的区别以及不一致的解决方法
  7. linux 文件格式压缩
  8. Python框架篇之Django(ORM对象关系映射)
  9. pip安装包时报错:The repository located at pypi.doubanio.com is not a trusted or secure host
  10. RNN Attention
  11. JAVA开发一个合并单元格报表,纵向同值单元格的合并
  12. 前端常用插件、工具类库汇总,不要重复造轮子啦!!!
  13. IPFS是创建DWeb应用程序中基础技术的领先者
  14. cacti 文件服务器,免费的服务器和网络监控工具-CactiEZ
  15. 推荐6个实用的Vue模板
  16. MySQL 字符集和校对集
  17. PCB原理图绘制(种草立创eda)
  18. A4纸是多少像素大小?
  19. 人工智能从概念到实战
  20. 培训学校管理系统之家校管理

热门文章

  1. python 正整数因数分解_python将一个正整数分解质因数.
  2. greenDao框架浅入深出
  3. android游戏开发系列(2)——背景音乐播放技术
  4. ListView缓存机制小结
  5. BPM那些事儿——开源BPM引擎
  6. 基于SPO语义三元组的疾病知识发现
  7. 蓝桥杯 ALGO-1005 数字游戏
  8. 天池大赛 - 特征提取 总结
  9. VUE+WebPack游戏设计:欲望都市,构建类RPG游戏的开发
  10. 女朋友想要听歌,我反手用Flutter做了2个音乐播放器,给她拿捏了