用户国营 发表于 2024-7-16 21:33:45

单片机学习笔记——入门51单片机

一、单片机基础先容

1.何为单片机

单片机,英文Micro Controller Unit,简称MCU 。内部集成了中央处理器CPU、随机存储器ROM、只读存储器RAM、定时器/盘算器、中断系统和IO口等一系列电脑的常用硬件功能 单片机的使命是信息采集(依靠传感器)、处理(依靠CPU)和硬件设备(比方电机,LED等)的控制 。单片机跟盘算机相比,单片机算是一个袖珍版盘算机,一个芯片就能构成完整的盘算机系统。但在性能上,与盘算机相差甚远,但单片机资本低、体积小、布局简单,在生存和工业控制领域大有所用。 同时,学习利用单片机是了解盘算机原理与布局的最佳选择。
单片机工作的基本时序
我们都知道在学校是通过铃声来控制所有班级的上下课时间,我们都知道单片机实验指令的过程就是从ROM取出一条指令实验来完成它在各个地方的作用,那它什么时间取指令这个是次序呢?这里引入一个时序的周期,每访问一次ROM的时间,就是一个机器周期的时间。
1个机器周期 = 6个状态周期 = 12个时钟(振荡)周期  
时钟周期:即单片机的基本时间单位,若晶体的频率=12MHZ,那时钟周期 = 1/12MHZ,一个时钟周期 = 1/12MHZ = 1/12000 000每秒
机器周期:即12x1/12 000 000 =0.000001s = 1us,访问一次ROM取指令的时间就是1us
2.单片机命名规则

https://img-blog.csdnimg.cn/direct/5ac6bcc7ab8f461ab7c67836e33983b7.png
3.单片机内部布局

https://img-blog.csdnimg.cn/direct/e1e5ea57457c4aa69bae882d2cb661ef.png
重点需记:单片机管脚
1.电源:Vcc:正极     Gnd:负极             2.XTAL:单片机时钟引脚,外接晶振
3.RST:复位
https://img-blog.csdnimg.cn/direct/6a882b7458014728b6ad6577a04defdd.png
https://img-blog.csdnimg.cn/direct/816d54bc368c4399837811cd6bb7d022.png
4.开发板先容

https://img-blog.csdnimg.cn/direct/78bbb039fbb34cb799a9f13a2e10a11f.png
开发板原理图

https://img-blog.csdnimg.cn/direct/88befe97d9594631b6b226405b48b20e.png
二、单片机的一些基础项目

2-1、点亮一个led灯

#include <REGX52.H>
void main()
{
        P2=0x7f;//1111 1110d1   16 15
                //0111 1111d8    7 16
                //1011 1111d7   11 16
       
       
} 通过高低电平控制led亮否
2-2、led闪灼

#include <REGX52.H>
#include <INTRINS.H>

//延时函数
void Delay500ms()                //@11.0592MHz
{
        unsigned char i, j, k;

        _nop_();
        i = 4;
        j = 129;
        k = 119;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}

void main()
{
        while(1){
        P2=0xfe;//亮
Delay500ms();//延时500ms
        P2=0xff;//灭
Delay500ms();//延时500ms
        }
} 通过延时函数使led闪灼
2-3、流水灯

#include <REGX52.H>
#include <INTRINS.H>

void Delay500ms()                //@11.0592MHz
{
        unsigned char i, j, k;

        _nop_();
        i = 4;
        j = 129;
        k = 119;
        do
        {
                do
                {
                        while (--k);
                } while (--j);
        } while (--i);
}

void main()
{
        while(1){
        P2=0xfe;//1111 1110
Delay500ms();
        P2=0xfd;//1111 1101
Delay500ms();
                P2=0xfb;//1111 1011
Delay500ms();
                P2=0xf7;//1111 0111
Delay500ms();
                P2=0xef;//1110 1111
Delay500ms();
                P2=0xdf;//1101 1111
Delay500ms();
                P2=0xbf;//1011 1111
Delay500ms();
                P2=0x7f;//0111 1111
Delay500ms();
        }
} 位运算做法:
2-4、流水灯plus

#include <REGX52.H>
#include <INTRINS.H>

//任意延时函数——1ms的延时函数执行x次循环
void Delay1ms(unsigned int xms)                //@11.0592MHz
{
        unsigned char i, j;
while(xms)
        {
        _nop_();
        i = 2;
        j = 199;
        do
        {
                while (--j);
        } while (--i);

        xms--;}
}

void main()
{
        while(1){
        P2=0xfe;//1111 1110
Delay1ms(100);
        P2=0xfd;//1111 1101
Delay1ms(100);
                P2=0xfb;//1111 1011
Delay1ms(100);
                P2=0xf7;//1111 0111
Delay1ms(100);
                P2=0xef;//1110 1111
Delay1ms(100);
                P2=0xdf;//1101 1111
Delay1ms(100);
                P2=0xbf;//1011 1111
Delay1ms(100);
                P2=0x7f;//0111 1111
Delay1ms(100);
        }
} 通过任意延时函数去简化步骤
3-1、通过独立按键控制led闪灼

#include <REGX52.H>

void main()
{
        while(1)
        {
                if(P3_1==0)//低电平 按下按键接地为0
                {
                        P2_0=0;//d1亮
                }
                else {
                        P2_0=1;
                }
        }
} 3-2、通过独立按键控制led状态

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

void main()
{
        while(1)
        {
                if(P3_1==0)
                {
               Delay(20);//取消前摇
                        while(P3_1==0);//判断何时松手
                        Delay(20);//取消后摇
                       
                        P2_0=~P2_0;//按位取反
        }
}
} 取消按键时的抖动,使单片机稳定判定状态。按一次亮,按一次灭。
3-3、通过独立按键控制led完成二进制

#include <REGX52.H>
#include <INTRINS.H>

void Delay(unsigned int xms)                //@11.0592MHz
{
        unsigned char i, j;
while(xms){
        _nop_();
        i = 2;
        j = 199;
        do
        {
                while (--j);
        } while (--i);
        xms--;
}
}

void main()
{
        unsigned int lednum=0;
        while(1)
        {
                if(P3_1==0)
                {
                        Delay(20);
                        while(P3_1==0);
                        Delay(20);
                       
                        lednum++;
                        P2=~lednum;
        }
}
} 也可以直接用P2--;取代末了两句,完成二进制运算。
3-4、用独立按键控制led灯移位

#include <REGX52.H>
#include <INTRINS.H>

void Delay(unsigned int xms)                //@11.0592MHz
{
        unsigned char i, j;
while(xms){
        _nop_();
        i = 2;
        j = 199;
        do
        {
                while (--j);
        } while (--i);
        xms--;
}
}

void main()
{
        unsigned int lednum=0;
        P2=~0x01;
        while(1)
        {
                if(P3_1==0)//k1
                {
                        Delay(20);
                        while(P3_1==0);
                        Delay(20);
                       
                        lednum++;
                        if(lednum>=8)
                                lednum=0;
                        P2=~(0x01<<lednum);
        }
                if(P3_0==0)//k2
                {
                        Delay(20);
                        while(P3_0==0);
                        Delay(20);
                       
                       
                        if(lednum==0)
                                lednum=7;
                        else lednum--;
                        P2=~(0x01<<lednum);
}
}
        } 4-1 静态数码管

1.常见数码管

https://img-blog.csdnimg.cn/direct/3d559e1f091048489ef11d00da3cb4d1.png
2.控制数码管表现的原理图

https://img-blog.csdnimg.cn/direct/f10cd182c5114c3abc417aaca22cf630.pnghttps://img-blog.csdnimg.cn/direct/93495269c8c9402c914691d5bea70013.png
3.管脚界说(对应字母控制对应位置亮):上面的为共阴极、下面的为共阳极(可以明白为3,8管脚处为供电,三角形尖尖有一横的是负极,所有共阴极),两个图中的数字为引脚:

https://img-blog.csdnimg.cn/direct/9b7c916a4d9e48e2b4681dbae7d620ed.png

4.下面为多个数码管,PCB板的4个为一体,同样上面为共阴极、下面为共阳极的原理图:

https://img-blog.csdnimg.cn/direct/c4861b3d4d764bce8b8b19fa046291fb.png
5.STC89C52实现数字表现

①原理图是共阴极(上面给0、下给1亮)

https://img-blog.csdnimg.cn/direct/07314885cf0a41c196f20e4ec77be5e4.png
②138译码器:输入3(ABC,读的时间是从下读 C B A )个口,控制输出8个口,输出口连接共阴极的,是0还是1,在这里控制:使能端连接(按下图给1和0就可以用了)

https://img-blog.csdnimg.cn/img_convert/dc380746d24c62f2501a193af0d0ee6d.webp?x-oss-process=image/format,png
通过CBA给数字0和1二进制转换10进制(得到数字几)就控制Y几,Y0头上“—”是表示低电平有效(即给0):
https://img-blog.csdnimg.cn/img_convert/875ed8239634df976a50208b5fcc5130.webp?x-oss-process=image/format,png
③双向缓冲,高电平往低电平送数据


https://img-blog.csdnimg.cn/img_convert/98648c19255eb170f84742d6c8c635ff.webp?x-oss-process=image/format,png
CC2电容作用:滤波电容,稳定电源,确定电路稳定性,提高电路工作性能可靠运行;
RP4:排阻,限流,防止电流过大

④这里的P01......P07,就是用P0口,后面代码就是通过P0口控制灯的


https://img-blog.csdnimg.cn/img_convert/bfec2204c4dad1048b01dca19df1bdd5.webp?x-oss-process=image/format,png

只有Y5为0,其他Y0...Y7都为1;

https://img-blog.csdnimg.cn/img_convert/92cfce37a99270cd688ed6cd2f226cb1.webp?x-oss-process=image/format,png


读取次序都是从下到上

https://img-blog.csdnimg.cn/img_convert/a28e4318e9aabfb18e73a23206909cb2.webp?x-oss-process=image/format,png
⑤代码控制公共端,从下往上写:


https://img-blog.csdnimg.cn/img_convert/f24c48d2679924c83357bbbfb468446d.webp?x-oss-process=image/format,png
二进制101转换为1十进制为5,控制Y5,即公共端的LED6;

https://img-blog.csdnimg.cn/img_convert/33d44f36c7588ad439a823421f1ccc08.webp?x-oss-process=image/format,png
要表现下图的数字6

https://img-blog.csdnimg.cn/img_convert/e32217f6ec2b57f3631df26092621185.webp?x-oss-process=image/format,png
代码实现如下(P2控制共阴极,P0控制表现数字)及结果;

https://img-blog.csdnimg.cn/img_convert/13150612cf890f7872feaa3ad47d09b4.webp?x-oss-process=image/format,png

https://img-blog.csdnimg.cn/img_convert/90846c55d9db84c00242bb9339175011.webp?x-oss-process=image/format,png
 ⑥优化操作代码:通过数组,子函数来优化代码

#include <REGX52.H>
#include <INTRINS.H>

unsigned char NixieTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};

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=NixieTable;
}

void main()
{
        Nixie(7,10);
        while(1);
        } 要表现的数字对应的值

https://img-blog.csdnimg.cn/img_convert/7e39c7b9d5e7e61da7f34bf13d24dcd3.webp?x-oss-process=image/format,png
4-2、动态数码管 

#include <REGX52.H>
#include <INTRINS.H>

unsigned char NixieTable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00};

void Delay (unsigned int xms)                //@11.0592MHz
{
        unsigned char i, j;
while(xms--){
        _nop_();
        i = 2;
        j = 199;
        do
        {
                while (--j);
        } while (--i);
}
}

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=NixieTable;
        Delay(1);//保证亮度
P0=0x00;//清零
}

void main()
{
        while(1){
        Nixie(2,1);
// Delay(20);
        Nixie(3,2);
// Delay(20);
        Nixie(4,3);
//        Delay(20);
        }
} https://img-blog.csdnimg.cn/direct/16453bddae454ad78ce93072da28f302.png
注释掉上面的延时调用,旁边的管会有些影响,需要消影,段选、位选影响造成串位,如下代码消除;

https://img-blog.csdnimg.cn/img_convert/7d0699d3aa2ace7744e0d3d6f5b3aa57.webp?x-oss-process=image/format,png
了解

https://img-blog.csdnimg.cn/img_convert/da6c1d2bac550aca603801005df7d66f.webp?x-oss-process=image/format,png

5-1、模块化编程 

https://img-blog.csdnimg.cn/direct/0609cc6df63041f0bac677f02f2df77e.png
1)驱动,先会用,后续有详细内容:


https://img-blog.csdnimg.cn/img_convert/cf8722f7a5de1575e81de9eedc9796c4.webp?x-oss-process=image/format,png
2)模块化,功能函数用点C文件写,点H文件声明函数,在main函数文件引入头文件直接调用:


https://img-blog.csdnimg.cn/img_convert/b2c4aae5865f757366280bdc94184ac3.webp?x-oss-process=image/format,png
3)注意事项


https://img-blog.csdnimg.cn/img_convert/12029d5a32949471c15f8f2d1d3ecb8b.webp?x-oss-process=image/format,png
4)预编译


https://img-blog.csdnimg.cn/img_convert/8d61318fcd8f022e5917e9793a3d63fe.webp?x-oss-process=image/format,png
5)延时函数文件


https://img-blog.csdnimg.cn/img_convert/d588a8c4d8fdac9ce1c545c3213a265f.webp?x-oss-process=image/format,png
6)头文件延迟


https://img-blog.csdnimg.cn/img_convert/77df40ae79b357e2d25dc9ae73b32345.webp?x-oss-process=image/format,png
7)主函数文件步伐入口:


https://img-blog.csdnimg.cn/img_convert/b56ae47a5dd6e7ee7b08309a86e85d45.webp?x-oss-process=image/format,png
8)数码管模块,用到的头文件要引用:


https://img-blog.csdnimg.cn/img_convert/89b050a2df55ce69ea757f035eb813f5.webp?x-oss-process=image/format,png
9)数码管模块头文件


https://img-blog.csdnimg.cn/img_convert/268971f0a8cc2130b309f1652db1001c.webp?x-oss-process=image/format,png
10)函数调用


https://img-blog.csdnimg.cn/img_convert/b40bed47c4e70cdfe9468bb74ac4665f.webp?x-oss-process=image/format,png
11)表现


https://img-blog.csdnimg.cn/img_convert/a367df43ee81a28d6c2f2f608503ca93.webp?x-oss-process=image/format,png

5-2 、LCD1602调试工具-------


https://img-blog.csdnimg.cn/img_convert/e089cd299717c44791d474ce4c8e26bf.webp?x-oss-process=image/format,png
1)调试工具原理图


https://img-blog.csdnimg.cn/img_convert/85219d67b9adee00a210cb28392895cb.webp?x-oss-process=image/format,png
2)模块化代码,下完放到自己工程目录下:

https://img-blog.csdnimg.cn/direct/be2416284e7e4575bdede8b51a3184eb.png


3)将下好的两个文件添加到工程:


https://img-blog.csdnimg.cn/img_convert/93991b4ca3756ca66c8cc5f3f0aee264.webp?x-oss-process=image/format,png


4)文件重要内容如下:


https://img-blog.csdnimg.cn/img_convert/b6150d67a9f0e50a3301f12b824b79b0.webp?x-oss-process=image/format,png
5)main函数调用:


https://img-blog.csdnimg.cn/img_convert/71e53004b0b0d0fa052d075a00a28dd6.webp?x-oss-process=image/format,png
6)表现其他管脚辩论,所有会一起表现:


https://img-blog.csdnimg.cn/img_convert/4dc68799bd4311dd0c36d983da1a90bf.webp?x-oss-process=image/format,png
7)其他函数的调用及功能,可以设置表现位置和范围:


https://img-blog.csdnimg.cn/img_convert/b47acaa6c0f0976ece839d73e115cd52.webp?x-oss-process=image/format,png
8)需要用到延迟函数:可以直接将前面模块化文件复制到工程目录下,添加进来引用即可;

9)娱乐:小计时器

#include <REGX52.H>
#include "LCD1602.h"
#include "Delay.h"

int Result=0;

void main()
{
        LCD_Init();//初始化
       
        while(1)
                {
                Result++;
                        Delay(1000);
                        LCD_ShowNum(1,1,Result,3);
                }//计时器

6-1.矩阵键盘

1)基础先容:

https://img-blog.csdnimg.cn/65e74d0a697c4a4f81526cbb4413abc3.png
https://img-blog.csdnimg.cn/322d07eb3e5a4c9980aee7d975901716.png
P14-P17给0就代表扫描,其他给1(没选中),一次只能扫描一行;P10-P13给0表示按下,给1表示没按下;(逐列扫描)

https://img-blog.csdnimg.cn/img_convert/1e68ec6901bd6e7ced528e601f15f418.webp?x-oss-process=image/format,png
2.代码实现:

①:创建工程并把“Delay”与“LCD1602”的模块参加此工程中。

②:编写MatrixKey(矩阵)代码

#include <REGX52.H>
#include "Delay.h"

unsigned char MatrixKey()
{
        unsigned char KeyNumber=0;
       
        P1=0xff;      //按列扫描
        P1_3=0;       //控制扫描的列
        if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=1;}    //while判断何时松手
        if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=5;}
        if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=9;}
        if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=13;}
       
        P1=0xff;
        P1_2=0;
        if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=2;}
        if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=6;}
        if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=10;}
        if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=14;}
       
        P1=0xff;
        P1_1=0;
        if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=3;}
        if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=7;}
        if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=11;}
        if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=15;}
       
        P1=0xff;
        P1_0=0;
        if(P1_7==0){Delay(20);while(P1_7==0);Delay(20);KeyNumber=4;}
        if(P1_6==0){Delay(20);while(P1_6==0);Delay(20);KeyNumber=8;}
        if(P1_5==0){Delay(20);while(P1_5==0);Delay(20);KeyNumber=12;}
        if(P1_4==0){Delay(20);while(P1_4==0);Delay(20);KeyNumber=16;}
       
       
        return KeyNumber;
}
        ③.编写主函数

#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "matrixKey.h"

unsigned char KeyNum;

void main()
{
        LCD_Init();   //LCD上电初始化
        LCD_ShowString(1,1,"Helloworld");
        while(1)
        {
                KeyNum=MatrixKey();
                if(KeyNum){
                        LCD_ShowNum(2,1,KeyNum,2);
        }
}
        } ④.软件利用小本领

快速天生常用格式代码:

https://img-blog.csdnimg.cn/img_convert/5378d53276fbfb7c98a91cbfb2788198.webp?x-oss-process=image/format,png
设置,完成后双击就可以天生了:

https://img-blog.csdnimg.cn/img_convert/18f96aa04b9dfd060b21899b9d0274ac.webp?x-oss-process=image/format,png

6-2.矩阵键盘暗码锁

1):把6-1文件全部cv到6-2工程文件中

2):代码实现

#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "matrixKey.h"

unsigned char KeyNum;
unsigned int Password,count;


void main()
{
        LCD_Init();
        LCD_ShowString(1,1,"Helloworld");
        while(1)
        {
                KeyNum=MatrixKey();
                if(KeyNum){
                        if(KeyNum<=10){                                //s1~s10按下密码
                                if(count<4){
                                Password*=10;
                                Password+=KeyNum%10;       //这两句是用来实现四位密码的显示
                                count++;                 //计数防止按下的密码数超过四位       
                                }
                                LCD_ShowNum(2,1,Password,4);//更新显示
                        }
                       
                        if(KeyNum==11){    //s11设置为确认键
                                if(Password==2345){
                                        LCD_ShowString(1,14,"OK ");
                                        Password=0;//密码清零
                                        count=0;      //计数清零
                                        LCD_ShowNum(2,1,Password,4);//更新显示
                        }
                                else {LCD_ShowString(1,14,"ERR");
                                        Password=0;//密码清零
                                        count=0;      //计数清零
                                        LCD_ShowNum(2,1,Password,4);//更新显示
                                }
        }
                       
           if(KeyNum==12){//定义S12为取消键
                       Password=0;
                       count=0;
                       LCD_ShowNum(2,1,Password,4);
               }
}
        }
}
7.定时器先容

1)先容,Delay前面CPU是一直在等的,用定时器在Delay时可以去检测按键,提高CPU利用率:


https://img-blog.csdnimg.cn/img_convert/1f4f6b88ebb046f9b0ad9f21f0df0554.webp?x-oss-process=image/format,png

https://img-blog.csdnimg.cn/img_convert/3034c6a70791fe11aee4714788cc7d3a.webp?x-oss-process=image/format,png

https://img-blog.csdnimg.cn/img_convert/b9e29b524d0d0326d6970e397cd419ee.webp?x-oss-process=image/format,png

https://img-blog.csdnimg.cn/img_convert/6c4b3a40560946117d80a6ba462d4f1f.webp?x-oss-process=image/format,png

https://img-blog.csdnimg.cn/img_convert/a9c5a6864f12ab8e00d5e32110ef5fd8.webp?x-oss-process=image/format,png

https://img-blog.csdnimg.cn/img_convert/51a9ce26fc892962d7ed47706352528e.webp?x-oss-process=image/format,png

https://img-blog.csdnimg.cn/img_convert/be98e3612ec539a2b4cf68289c4a5361.webp?x-oss-process=image/format,png
2)模式1最常用:


https://img-blog.csdnimg.cn/img_convert/117074363801599a296843e9c9b50c14.webp?x-oss-process=image/format,png
3)模式:时钟--计数最大65535(计数系统TL0\TH0:每来一个脉冲+1方法计数)-TF0(标记位,到最大了回到0)-中断:


https://img-blog.csdnimg.cn/img_convert/914788018d4aee79c9dbee6977360f9d.webp?x-oss-process=image/format,png
4)非门与门图形为控制部分(TR0是否启动暂定)

5)定时器部分:


https://img-blog.csdnimg.cn/img_convert/6674e83e819c1ba8287049764ddad2ae.webp?x-oss-process=image/format,png
6)时钟可以由系统提供(上图,晶振),也可以由外部T0P提供(如下图引脚)


https://img-blog.csdnimg.cn/img_convert/20561c3577aa2f29f9aeb0392e58e84b.webp?x-oss-process=image/format,png
7)C/T,给1连上面为控制器,给0连接下面为定时器(如下图):


https://img-blog.csdnimg.cn/img_convert/a17e7fac8052e0ef10667c00e6274275.webp?x-oss-process=image/format,png
8)中断系统:


https://img-blog.csdnimg.cn/img_convert/73b21c06e09e89ba427a29f458f603fe.webp?x-oss-process=image/format,png
9)中断资源


https://img-blog.csdnimg.cn/img_convert/8fc63250af41149b153b62c9f205826c.webp?x-oss-process=image/format,png
10)定时器和中断系统


https://img-blog.csdnimg.cn/img_convert/adf8af416195507a7084ef5551dba2a6.webp?x-oss-process=image/format,png
11)定时器相关寄存器


https://img-blog.csdnimg.cn/img_convert/6806693448bc1611ffd2dff995d00f7c.webp?x-oss-process=image/format,png


7-1.独立按键控制流水灯的模式

1.TMOD寄存器工作模式,定时器0配置利用(不可位寻址,只能整体赋值)


https://img-blog.csdnimg.cn/img_convert/27008afe8a3a1100330b525e61292aaf.webp?x-oss-process=image/format,png
2.定时器模式1:门控端给0,就是tr0单独控制:C/T,T这里有一横表示低电平有效,就给0是用T(定时器模式),给1用C(控制器模式),M1,M0工作模式选择


https://img-blog.csdnimg.cn/img_convert/278a34d36d150184d3c9e225f935ef14.webp?x-oss-process=image/format,png
3.TCON控制寄存器(可位寻址,可以单独每一位赋值)


https://img-blog.csdnimg.cn/img_convert/17bc1ad84a485b8484e850f344c9685c.webp?x-oss-process=image/format,png
中断溢出标记位:
TF=0(等于1产生中断);
TR0=1(定时器是否开启,给1开始,电机开始工作);
IE0、IT0:控制外部中断引脚,可以不配置

4.定时器配置  TH0\TL0


https://img-blog.csdnimg.cn/img_convert/c7e3c16c0ea58cbdfcb64e74d6de7fb7.webp?x-oss-process=image/format,png

TH0\TL0 分开储存

https://img-blog.csdnimg.cn/img_convert/9e69a689c9c3e18820067dfd7dc07e77.webp?x-oss-process=image/format,png
代码优化,TMOD题目(不可位寻址)配置两个的时间,后面的会把前面的覆盖;
因此,可采用“与或”法设定TMOD


https://img-blog.csdnimg.cn/img_convert/02516c6c0a142d8620865b2bba493c68.webp?x-oss-process=image/format,png
 https://img-blog.csdnimg.cn/direct/f3d3fca3431848a6982751dc017efe07.png

5.中断配置T0-->ET0=1--EA=1,PT0=0


https://img-blog.csdnimg.cn/img_convert/93b51c4a80caf19a37d92f5f9f327438.webp?x-oss-process=image/format,png

6.定时器配置完成,模块化编程

#include <REGX52.H>

void Timer0_Init(void)                //1ms@11.0592MHz
{
        TMOD &= 0xF0;                //设置定时器模式
        TMOD |= 0x01;                //设置定时器模式
        TL0 = 0x66;                //设置定时器初值
        TH0 = 0xFC;                //设置定时器初值
        TF0 = 0;                //清除TF0标志
        TR0 = 1;                //定时器0开始计时
        ET0=1;    //下面三行为中断的配置
        EA=1;
        PT0=0;
}



 7.定时器中断函数模板


void Timer0_Routine() interrupt 1//中断函数
{
        static unsigned int T0Count;
        TL0 = 0x66;                //设置定时器初值
        TH0 = 0xFC;                //设置定时器初值
        T0Count++;
        if(T0Count>=1000)   //每隔1s
        {               
         T0Count=0;

        }
} 8.独立按键模块

#include <REGX52.H>
#include "Delay.h"



unsigned char Key()
{
       
        unsigned char KeyNumber=0;
       
        if(P3_1==0){Delay(20);while(P3_1==0);Delay(20);KeyNumber=1;}
        if(P3_0==0){Delay(20);while(P3_0==0);Delay(20);KeyNumber=2;}
        if(P3_2==0){Delay(20);while(P3_2==0);Delay(20);KeyNumber=3;}
        if(P3_3==0){Delay(20);while(P3_3==0);Delay(20);KeyNumber=4;}
       
        return KeyNumber;
} 9.主函数

#include <REGX52.H>
#include "Timer0.h"
#include "key.h"
#include <INTRINS.H>

unsigned char KeyNumber,LEDmode;
void main()
{
        P2=0xfe;//与INTRINS.H中的循环左右移函数共同实现流水灯
        Timer0_Init(); //上电初始化
        while(1)
        {
                KeyNumber=Key();
                if(KeyNumber)
                {
                        if(KeyNumber==1)
                        {
                                LEDmode++;
                                if(LEDmode>=2) LEDmode=0;
                        }
                       
                }
               
        }
}



void Timer0_Routine() interrupt 1//中断函数
{
        static unsigned int T0Count;
        TH0=64535/256;
        TL0=64535%256;        
        T0Count++;
        if(T0Count>=1000)   //每隔1s
        {
                T0Count=0;
       if(LEDmode==0) P2=_crol_(P2,1);
       if(LEDmode==1) P2=_cror_(P2,1);
        }
}

https://img-blog.csdnimg.cn/img_convert/ebde2534598e4e3d06b280b8812330b3.webp?x-oss-process=image/format,png

7-2.时钟 

1.把LCD1602液晶表现、延迟、定时器、的代码复制到工程目录下,导入;

2.主函数包含其他模块头文件并初始化;


https://img-blog.csdnimg.cn/img_convert/147d8b967576d5b95914d968edbf558d.webp?x-oss-process=image/format,png
3.复制定时器中断函数到main函数下:


https://img-blog.csdnimg.cn/img_convert/8ff4c27cac5d1625508c922824a54233.webp?x-oss-process=image/format,png

https://img-blog.csdnimg.cn/img_convert/8eb5c9f2945ed812fc5ddd2b2900bc7b.webp?x-oss-process=image/format,png
4.界说变量,秒计数、分、小时并表现:


https://img-blog.csdnimg.cn/img_convert/b5263d885d51fe322137503afd89c479.webp?x-oss-process=image/format,png
5.代码综合

#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "Timer0.h"

unsigned char Sec,Min,Hour;
void main()
{
        LCD_Init();//³õʼ»¯
        Timer0_Init();
        LCD_ShowString(1,1,"CLOCK:");
        LCD_ShowString(2,1,"::");
        while(1)
        {
        LCD_ShowNum(2,1,Hour,2);
        LCD_ShowNum(2,4,Min,2);
        LCD_ShowNum(2,7,Sec,2);
        }
}

void Timer0_Routine() interrupt 1
{
        static unsigned int T0Count;
        TL0 = 0x66;               
        TH0 = 0xFC;               
        T0Count++;
        if(T0Count>=1000)   
        {
                T0Count=0;
    Sec++;
                if(Sec>=60)
                {
                        Sec=0;
                        Min++;
                        if(Min>=60)
                        {
                                Min=0;
                                Hour++;
                                if(Hour>=24)
                                {
                                        Hour=0;}
                                }
                        }
                }
               
        }

8-1串口先容

1)先容


https://img-blog.csdnimg.cn/img_convert/38b6545d25317c267e04903ebce5a7f7.webp?x-oss-process=image/format,png
2)向单片机发送数据(下面框),返回(上框)


https://img-blog.csdnimg.cn/img_convert/76776192bc0e376b12bbe8a174e73a70.webp?x-oss-process=image/format,png
3)DB9串口传输数据(注意利用的电压是否同等)利用RS232或RS485电平


https://img-blog.csdnimg.cn/img_convert/16172b8fe3bc22b842bb1a8023027a4a.webp?x-oss-process=image/format,png
4)知识点

①硬件电路


https://img-blog.csdnimg.cn/img_convert/b121a9ce0c14e337b358c7658a2dc766.webp?x-oss-process=image/format,png
注:最少需要三根线实现双向通信:TXD,RXD,GND。VCC不一定需要,可独立供电。
②电平尺度 

 https://i-blog.csdnimg.cn/direct/3ce1701f029f43acac237f7e2e7b25f2.png
 差分信号优点:传送距离远(1km+)   TTL与RS232(10m)

③常见通信接口比较

https://i-blog.csdnimg.cn/direct/26cf5b05f21447459b7ae134eb55106f.png
 CAN总线:常用于汽车领域,由于利用的是差分信号传输,传输距离远、稳定。
通信方式的相关术语:
https://i-blog.csdnimg.cn/direct/605e6bb1900443ce9e82a93475315ff8.png
 
④51单片机里的UART串口 

https://i-blog.csdnimg.cn/direct/ed499d5d0ee4430a8e22491d1d0e1f68.png
 https://i-blog.csdnimg.cn/direct/478619484a114070beee7ecaab724cb0.png
 
 https://i-blog.csdnimg.cn/direct/c74a20b0c3b24ec2802e6b1a8088eb1c.png
 
   中心部分用来控制波特率,依靠定时器来约定速率,T1的溢出率通过分频后来控制收发器的采样时间。
  SBUF:收发数据后,会产生相应的TI(发送中断)/RI(接收中断),继而进入中断函数,进行相应的中断函数内部的操作。

https://i-blog.csdnimg.cn/direct/4f4dffe90f1c4ad6a60b618c053bff28.png 
 配置ES、EA,PS此时不需要配置,由于只有一个中断,不需要进行优先级判定。

https://i-blog.csdnimg.cn/direct/4dbf2aa283b146e093088d61dc3d497e.png 
 配置好SCON和PCON,读SBUF,配置定时器T1,打开EA和ES,即串口可以开始工作。

8-2.实际配置串口 

1)将延迟函数复制过来并导入工程里面;

2)配置串口控制寄存器,配置模式1最常用,REN允许接收给1,不允许接收给0(也可以给1表面不给发就行);


https://img-blog.csdnimg.cn/img_convert/5bf443e17008dd0c139ece82339e5ee3.webp?x-oss-process=image/format,png

https://img-blog.csdnimg.cn/img_convert/48a67ec583df8b31ed247d8d24f5cc58.webp?x-oss-process=image/format,png

https://img-blog.csdnimg.cn/img_convert/193b908bf7e263ffc101b415a55a3f16.webp?x-oss-process=image/format,png
3)TI、RI发送完置1(硬件只负责),但必须软件复位置0;


https://img-blog.csdnimg.cn/img_convert/4ad08d6624ade8c82226df70dcfc6499.webp?x-oss-process=image/format,png

https://img-blog.csdnimg.cn/img_convert/8f26e57787ed3ff60105ff656e0b7d41.webp?x-oss-process=image/format,png
 故SCON=0x40
PCON
4)配置定时器


https://img-blog.csdnimg.cn/img_convert/92c10f1e3b8152976dc785a3df2ff1c7.webp?x-oss-process=image/format,png
这里定时器1,没有定时器0,所有要把高位修改(不影响高低位配置用“”& |“”这两个方式)

https://img-blog.csdnimg.cn/img_convert/2abab286a628c2268d5bbefe88591b53.webp?x-oss-process=image/format,png
选择8位自动重载模式

https://img-blog.csdnimg.cn/img_convert/2b9af2593c5ef0ee4e8fd2dc9fe49a88.webp?x-oss-process=image/format,png

5)可以直接用STC-isp来配置串口 

https://i-blog.csdnimg.cn/direct/6007c5d771b144228ec804bc58f20742.png
系统频率根据板子选择,波特率4800,波特率发生器选择8位自动重载,时钟12T
https://i-blog.csdnimg.cn/direct/426853c5c73248d7a20c47ac892ada09.png
6)发送数据的函数

https://i-blog.csdnimg.cn/direct/01c49aee83284ae8af555b1a39df53f2.png
7)发送单项数据

https://i-blog.csdnimg.cn/direct/ef381375c5504b3fb7f8b2f8a83984bc.png
https://i-blog.csdnimg.cn/direct/d81986345ceb4049b414470f3a0ed40a.jpeg

8)模块化

https://i-blog.csdnimg.cn/direct/901d3123f5fa417db1d5768b0d074890.png
https://i-blog.csdnimg.cn/direct/123532b5a06c4b099d9039cebb629eb1.png
9)数据表现模式 

https://i-blog.csdnimg.cn/direct/35c4bf0371b141b1997e39a5d13a4549.png
https://i-blog.csdnimg.cn/direct/6bda55bf28534ab4b83a148e5c2e32cf.png


8-3.串口实例实现 

1)每一秒发送一个递增的数字

https://i-blog.csdnimg.cn/direct/46a2596e493f477e823153614023a485.png
 
 2)电脑通过串口控制LED灯,并且返回电脑读入的数据

1.需要打开串口的中断功能

https://i-blog.csdnimg.cn/direct/f5167195cd524770a0d0560fccf8c7da.png
SCON = 0x50;  EA=1;ES=1; 
注:要分清这里是禁止了定时器1的中断功能,只是让它的溢出率去开启串口收发的功能,中断的产生是由于串口收发数据产生的中断。
2.编写串口中断函数

https://i-blog.csdnimg.cn/direct/cb2570bc4c61418f8fcf0972b924a7cd.png
串口中断函数模板:
void UART_Routine() interrupt 4
{
       if(RI==1)
       {
               
               RI=0;   //复位清0
       }
}  
3.整体代码

https://i-blog.csdnimg.cn/direct/582013c696454e5db84bdb58cfc8be38.png 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 单片机学习笔记——入门51单片机