51单片机学习

Last updated on October 6, 2024 am

51单片机学习

教程来自B站:江协科技 , 非常好的UP主!江协科技的主页:关于我们 (jiangxiekeji.com)

一、准备材料

51单片机开发板

软件:keil5(编写程序), STC-ISP(程序烧录到单片机)

开发板驱动安装,驱动程序安装在C盘下;设备管理器下,端口显示CH340

二、点亮LED

2-1 点亮一个LED

μVision新建工程

选择单片机芯片公司Atmel; AT89C52

新建project后,左侧可以看到工程文件夹,Source Group存放代码,新建C语言文件

添加主函数 void main()

{}两个花括号之间缩进一个tab

开发板LED模块

VCC:电源正极

从VCC,经过电阻

开发板上电阻写了102,理解为10的后面补2个零,1000=1K,最后一位数字代表倍率

左侧红色的P2数字指连接的单片机引脚,由于二极管特性,当P20输出高电平(5V),LED不会亮;输出低电平(0V),电流由正到负,灯亮。电流方向从右到左

那么,单片机是如何控制输出的电流大小呢

如上,单片机(MCU)内CPU向寄存器内写入1,通过驱动器放大,通过IO口输出5V高电平;写0则低电平

代码

记得添加头文件,里面包含了寄存器地址

1
2
3
4
5
6
7
8
9
10
#include <REGX52.H>

void main()
{
P2=0xFE;//1111 1110
while(1) //while(1),True,porgram run
{

}
}

0x 指用的是十六进制

P2寄存器(8位)写入,控制电流;1111 1110,但机器不识别这样写,用十六进制

Create HEX File; Build编译

程序写入单片机

STC-ISP 软件,找到对应的单片机(STC89C52RC)及串口型号CH340; 购买的板子和B站江协老师的有点不同

芯片型号必须正确,不然STC-ISP会一直显示”正在检测目标单片机“

打开.hex文件,并选择”下载/编程”

注意开发板冷启动,开关一下

1
2
3
4
5
6
7
8
9
10
#include <REGX52.H>

void main()
{
P2=0x55;//0101 0101
while(1)
{

}
}

2-2 LED闪烁

LED在亮灭之间需要延时才能由肉眼看见闪烁,可使用STC-ISP 软件的延时计算器,添加延时函数,系统频率要选择单片机旁边的晶振频率,8051指令集选STC-Y1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <REGX52.H>
#include <INTRINS.H>

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

_nop_(); //void,nothing but waste time
i = 4;
j = 129;
k = 119;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}


void main()
{

while(1)
{
P2=0xFE; //light one led
Delay500ms();
P2=0xFF; //not light
Delay500ms();
}
}

右键打开<INTRINS.H> ,它定义了_nop_

注:
#include <INTRINS.H> 是一个C语言头文件,它提供了一些内嵌汇编函数,可以在C语言程序中直接使用汇编指令。 这些函数可以用于访问特殊的CPU指令集,如MMX、SSE、AVX等指令集,以及一些特殊的寄存器和操作。

2-3 LED流水灯

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <REGX52.H>
#include <INTRINS.H>

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

_nop_();
i = 4;
j = 205;
k = 187;
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();
}
}

改造代码:调节流水灯的延时速度

思路是先生成一个1ms的延时函数,此时Delay1ms()没有参数;写入参数xms, Delay1ms(xms), 但是C语言中需要指定变量的类型。(注:在Python中,通常情况下不需要显式指定变量的数据类型,因为Python是一种动态类型语言,它会自动根据变量的值来确定其数据类型。R 也是)

1
2
3
4
5
6
7
8
9
10
11
12
13
void Delay1ms()		//@11.0592MHz
{
unsigned char i, j;

_nop_();
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}

单片机中 int 是16位的,而家用计算机是32位;只写int ,默认为(signed) int

float: 浮点型; double :双精度浮点型 ;用科学计数法表示小数

所以指定变量类型:

1
void Delay1ms(unsigned int xms)

在后面调用Delay1ms()这个函数时;Delay1ms(500),将500这个形参赋给unsigned int xms ;就可以调速

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <REGX52.H>

void Delay1ms(unsigned int xms) //@11.0592MHz
{
unsigned char i, j;
while(xms)
{
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
xms = xms-1; //or can write xms--;
}
}

void main()
{
while(1)
{
P2=0xFE;//1111 1110
Delay1ms(500);
P2=0xFD;//1111 1101
Delay1ms(500);
P2=0xFB;//1111 1011
Delay1ms(500);
P2=0xF7;//1111 0111
Delay1ms(500);
P2=0xEF;//1110 1111
Delay1ms(500);
P2=0xDF;//1101 1111
Delay1ms(500);
P2=0xBF;//1011 1111
Delay1ms(500);
P2=0x7F;//0111 1111
Delay1ms(500);
}
}

三、独立按键

普中51开发板上独立按键模块和单片机IO连接口

寄存器会检测IO口的电平然后再写

P2_0是P2口其中一个LED灯;对应参见头文件<REGX52.H>

P3_1是开发板原理图的K1按键对应的端口号

代码:按下点亮,松手熄灭

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <REGX52.H>

void main()
{
while(1)
{
if(P3_1==0)
{
P2_0=0;//lightingLED
}
else
{
P2_0=1;
}
}
}

C51数据运算

注:赋值写成 c+1=3不可以;右边算出来给左边,不能写成解方程

位运算
1
2
3
4
5
6
7
8
9
0011 1100<<1 //按位左移1位
0111 1000 //移出1位后,高位补零
0011 1100>>2
0000 1111

0001 1000 & 0010 1010 //按位与 -> 0000 1000 //只有全真,即2个1才是1
0001 1000 | 0010 1010 //按位或 -> 1011 1010
0001 1000 ^ 0010 1010 //按位异或 -> 0011 0010 //一样为0,不一样为1
~ 0001 1000 //按位取反 -> 1110 0111

C51基本语句