嵌入式开发之51单片机入门(一)与LED灯的故事

得而不惜就该死。

--小泽

继续傻冒开始,这次的傻冒之旅是关于嵌入式的51单片机开发,这个系列只讲程序开发逻辑,如需初始环境安装配置,建议移步B站江协科技大佬,本系列也是对大佬所讲内容的复刻,同时添加一些自己的学习感受,权当自己的复习笔记了。废话不多,开始干!

一、点亮第一个LED

1、创建工程

1.1 Project->New

1.2 创建51Project文件夹,用于存放之后的项目文件

(此操作便于日后项目管理)

1.3 选择单片机型号:AT89C52

1.4 创建第一个C语言项目文件

简单初始程序

cpp 复制代码
#include <REGX52.H>

void main(){
	
	return;
}

快捷插入头文件

1.5 点亮第一个LED灯

那么我们该如何进行点亮,这里面的底层逻辑涉及到什么呢?首先看一看开发板的原理图。

这张图涉及到很多口,我们此时只关注右下角的21-28(p20-p27),这是用于连接LED的接口

在来看看LED灯的接口,LED的左侧接口与上述MCU的右下角一一对应,但是发现LED的右侧统一接上VCC电源正极,并且我们知道对于任何灯来说,需要在灯的两端接上正负,才能使其点亮。由于右侧恒为正,所以我们只需要控制p20-p27的正负就能控制这八个灯的点亮状态,而p20到p27的正负可以使用代码控制,0为负,1为正。

由于我们的目标是点亮一个LED灯,所以只需要将p20-p27任意一个设置为0即可,我们选择点亮p20处LED

修改后的代码

cpp 复制代码
#include <REGX52.H>

void main(){
	P2 = 0xFE; //1111 1110 
				//使用十六进制 标识:0x
	return;
}

1.6 运行生成

对keil5的一些简单配置

1.6.1 此设置能在build编译后生成HEX文件,用于后续板子测试

1.6.2 此设置编码格式,UTF-8能够兼容中文字体

1.6.2 控制设置代码字体大小

开始编译build

2、操作

2.1 选择板子类型和串口

对于串口,插上板子后会自动检测

2.2 打开程序文件,选中刚刚生成的HEX文件

2.3 下载源程序,查看结果

二、LED闪烁

1、创建工程

步骤和一同理,不再赘述,说一个区别,在51Project文件夹中创建2-2 LED闪烁,保存即可,其余操作均一致。

选择单片机型号:AT89C52

1.1 初始工程模样

1.2 编程

根据我们实验一的描述, LED为正负则亮,0 1分别表示正负,所以控制LED闪烁则需要控制0 1交替变换,代码如下

cpp 复制代码
#include <REGX52.H>

void main(){
	while(1){
		P2 = 0xFE;//p20Ϊ0ʱ ÁÁ
		
		P2 = 0xFF;//p20Ϊ1ʱ °µ
	}
	return;
}

但是按照此逻辑去下载程序,我们观察到单片机板子的p20恒亮,这是因为单片机切换速度太块,导致肉眼就看不出变化所以我们借助stc-isp.exe去生成停顿函数,控制切换速度。

设置如下

系统频率:12MHz

定时长度:500毫秒

8051指令集:STC-Y1

1.3 编译代码

修改后代码:

cpp 复制代码
#include <REGX52.H>
#include <INTRINS.H>

void Delay500ms()		//@12.000MHz
{
	unsigned char i, j, k;
    //_nop_()函数在INTRINS.H头文件中
	_nop_();
	i = 4;
	j = 205;
	k = 187;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void main(){
	while(1){
		
		P2 = 0xFE;//p20Ϊ0ʱ ÁÁ
		Delay500ms();
		P2 = 0xFF;//p20Ϊ1ʱ °µ
		Delay500ms();
	}
	return;
}

在编译前我们设置输出文件HEX

开始编译

2、操作

2.1单片机类型: STC89C52RC/LE52RC

2.2串口号:插入板子后自动识别

2.3打开源文件程序

2.4下载/编程

2.5查看结果

三、LED流水线

1、创建工程

创建工程同上,不在赘述。

选择单片机型号:AT89C52。

1.1 工程结构

1.2 代码如下:

cpp 复制代码
#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();
	}
	return;
}

1.3勾选output HEX输出

1.4编译

2、操作

同一和二中的操作。

2.1单片机类型: STC89C52RC/LE52RC

2.2串口号:插入板子后自动识别

2.3打开源文件程序

2.4下载/编程

3、进阶

修改Delay500ms()函数,变成传参函数,传入参数标识停顿的毫秒数。

修改的方向:由于我们的单片机为12MHz,12.000MHz 的时钟频率下,一个机器周期是 1 微秒(因为 1 / 12MHz * 12 = 1μs),又因为500毫秒为500,000微秒,所以我们让循环接近500,000即可。

3.1函数解释

(1)函数定义:void DelayMs(unsigned int ms) 定义了一个名为 DelayMs 的函数,它接收一个无符号整型参数 ms,代表要延时的毫秒数,函数无返回值。

(2)外层循环:for (i = 0; i < ms; i++) 这个循环会执行 ms 次,每次循环会产生大约 1 毫秒的延时。

(3)内层嵌套循环:

for (j = 0; j < 123; j++):外层循环,循环 123 次。

for (k = 0; k < 4; k++);:内层循环,循环 4 次。

这两层嵌套循环的组合能让 CPU 执行一定数量的空操作,从而实现大约 1 毫秒的延时。

(4)空操作指令:_nop_(); 执行一个空操作,占用一个机器周期,在这可能用于微调延时时间。

cpp 复制代码
#include <intrins.h>

// 定义一个函数用于实现毫秒级延时
void DelayMs(unsigned int ms) {
    unsigned int i;
    unsigned char j, k;
    // 外层循环,循环次数为传入的毫秒数
    for (i = 0; i < ms; i++) {
        // 空操作,可能用于微调延时
        _nop_();
        // 以下循环用于实现约 1 毫秒的延时
        for (j = 0; j < 123; j++) {
            for (k = 0; k < 4; k++);
        }
    }
}
    

至此,初步结束

相关推荐
zd8451015007 分钟前
STM32 HAL DHT11驱动程序
stm32·单片机·嵌入式硬件
lzb75921 分钟前
蓝桥杯单片机刷题——ADC测量电位器的电压
单片机·蓝桥杯
_She00123 分钟前
硬件知识积累 单片机+ 光耦 + 继电器需要注意的地方
单片机·嵌入式硬件
南梦也要学习3 小时前
STM32江科大-----SPI
stm32·单片机·嵌入式硬件
willhu20083 小时前
Keil调试STM32:未定义OS_EVENT以及停在“BEAB BKPT 0xAB”处等问题
stm32·单片机·嵌入式硬件
卡尔曼的BD SLAMer3 小时前
问题 | 对于初学者来说,esp32和stm32哪个比较适合?
stm32·单片机·嵌入式硬件
不脱发的程序猿3 小时前
ESP32与STM32哪种更适合初学者?
arm开发·stm32·嵌入式硬件
lzb7595 小时前
蓝桥杯单片机刷题——通过按键触发串口传输电压值
单片机·蓝桥杯
Ronin-Lotus8 小时前
嵌入式硬件篇---加法&减法&积分&微分器
嵌入式硬件·模拟电子技术·加法器·减法器·积分器·微分器
田甲9 小时前
【STM32】ST7789屏幕驱动
stm32·单片机·嵌入式硬件