51单片机---硬件学习(跑马灯、数码管、外部中断、按键、蜂鸣器)

裸机:编写的代码直接操作硬件。

一、基本概念

1、CPU,MPU,MCU,GPU,SOC的定义

1)CPU(中央处理器)

计算机的核心运算与控制单元,负责执行系统指令、处理数据,是通用计算的 "大脑"。

2)MPU(微处理器)

集成了 CPU 核心及少量外围电路的微处理器,需搭配外部存储、外设才能工作,常用于早期计算机或简单控制场景。

3)MCU(微控制器)

将 CPU 核心、存储器、I/O 接口等集成在单芯片上的 "微控制器",可独立完成控制任务,广泛用于家电、物联网等嵌入式设备。

4)GPU(图像处理器)

专门处理图形渲染和并行计算的处理器,擅长海量数据的并行运算,也用于 AI 训练、科学计算等场景。

5)SOC(高性能集成芯片)

将 CPU、GPU、存储器、外设接口及专用功能模块(如 AI 加速单元)等高度集成在单芯片上的 "系统级芯片",可实现完整电子系统功能。

2、外设寄存器

外设寄存器是嵌入在芯片外设(如GPIO、UART、定时器等)中的特殊存储单元,用于配置外设功能、读取状态或发送/接收数据。

每个寄存器对应特定功能(如配置引脚方向、设置波特率),通过读写寄存器的值可控制外设工作。

寄存器有固定的地址,CPU通过访问这些地址来操作外设(例如向GPIO的控制寄存器写入值,可设置引脚为输入/输出)。

3、LED实验中常用的寄存器(以8051或STM32为例)

LED实验的核心是控制GPIO引脚输出高低电平,常用寄存器包括:

方向寄存器(如8051的P1口寄存器、STM32的GPIOx_MODER):

配置引脚为输入或输出(例如设置为输出模式才能控制LED亮灭)。

数据寄存器(如8051的P1口数据寄存器、STM32的GPIOx_ODR):

向寄存器写入0或1,控制引脚输出低电平(LED导通)或高电平(LED截止)。

(部分芯片)上拉/下拉寄存器:若LED通过引脚高电平点亮,可能需要配置上拉电阻确保电平稳定。

4、GPIO

GPIO(General Purpose Input/Output,通用输入输出)

GPIO是芯片上的通用引脚,可通过软件配置为输入或输出,实现与外部设备的交互:

输出模式:可输出高低电平,用于控制LED、继电器、电机等。

输入模式:可读取外部信号(如按钮状态、传感器数据)。

灵活性高,是嵌入式开发中最基础、最常用的外设,几乎所有MCU/MPU都包含GPIO模块。

例如:LED实验中,GPIO被配置为输出模式,通过输出高低电平控制LED的亮灭。

5、中断与中断源

1)中断(Interrupt)

当中央处理机CPU正在处理某件事的时候外界发生了紧急事件请求,要求CPU暂停当前的工作,转而去处理这个紧急事件,处理完以后,再回到原来被中断的地方,继续原来的工作。

2)中断源(Interrupt Source)

指能主动向CPU发送"中断请求",暂停当前任务、迫使其优先处理紧急事件的硬件或软件实体。

6、中断处理流程

1)中断源发送中断请求

2)内核检查是否响应中断,以及该中断是否被屏蔽

3)内核会检查中断的中断优先级

4)保护现场

5)执行中断服务函数

6)恢复现场

7、中断嵌套

中断嵌套是高优先级中断打断低优先级中断处理过程的机制,核心是"优先处理更紧急的事件"。51单片机有2个优先级(高优先级、低优先级),可通过IP寄存器设置(如PT0=1设T0为高优先级);

低优先级中断执行时,若有高优先级中断请求,CPU会暂停低优先级中断,先处理高优先级中断;同优先级中断不会嵌套(如两个低优先级中断,先响应的先处理,后请求的需等前一个处理完);高优先级中断执行时,其他中断(无论优先级)都无法打断它。

8、中断向量表

中断向量表是存储"中断源"与"对应中断服务程序入口地址"的表格,本质是CPU的"中断导航图"------当某个中断源触发时,CPU通过查表就能快速找到该中断该去哪里执行处理逻辑。

9、51单片机的定时器工作原理

可编程的 16 位加 1 计数器,先通过程序向定时器寄存器(THx 高 8 位、TLx 低 8 位)写入初始计数值,随后定时器在系统时钟(经 12 分频后)或外部引脚输入脉冲的驱动下开始累加计数,当计数值累加到最大值(如 16 位时为 0xFFFF)并产生溢出时,会自动触发定时器中断请求(若中断使能),同时可选择自动重装初始值(仅模式 2)或需程序重新赋值,以此实现定时(基于内部时钟)或计数(基于外部脉冲)功能。

10、PWM及其重要参数

1)PWM(脉冲宽度调制,Pulse Width Modulation)

是一种利用数字信号(高低低电平脉冲)模拟模拟信号的技术,核心原理是通过周期性地输出高低电平脉冲,通过改变高(或低电平)在一个周期内的占比。

2)PWM的核心参数

占空比、周期与频率、分辨率、幅值。

二、功能实现(应用示例)

1、LED灯:全亮(led_all_on)、全灭(led_all_off)、指定灯亮(led_on)

cs 复制代码
#include "led.h"
#include <reg52.h>

void led_all_on(void)
{
	P2 = 0;
}

void led_all_off(void)
{
	P2 = 0xFF;
}

void led_on(unsigned char n)
{
	P2 = n;
}

2、数码管显示屏:位选(bit_select)、0~9显示(segment------select)、9999以内数字显示(show_number)

cs 复制代码
#include "delay.h"
#include "digiter.h"
#include <reg52.h>

//位选
void  bit_select(int n)
{
	P1 &= ~(0x0F << 0); 
	P1 |= (1 << n); 
}

void segment_select(int n) //0~9
{	  
	unsigned char t[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
	P0 = t[n];
	delay(400);//保证二极管导通
	P0 = 0;//消去残影
	delay(100);
}

void show_number(int n)
{
	int t = 0;
	if(t > 9999)
	{
		return ;
	}
	else if(n == 0)
	{
		bit_select(0);
		segment_select(0);
	}
	while(n)
	{
		bit_select(t++);
		segment_select(n % 10);
		n /= 10;
	}
}

3、延迟函数:delay

cs 复制代码
#include "delay.h"
#include <reg52.h>

void delay(unsigned int n) //0~65535
{
	while(n--);
}

4、来回显示跑马灯

cs 复制代码
#include <reg52.h>
#include "led.h"
#include "delay.h"

int main(void)
{
	//跑马灯
	led_all_off();
	P2 = 0xFF;
	while(1)
	{
	 	int i = 0;
		for(i = 0; i < 8; i++)
		{
			led_on(1 << i);
			delay(9000);
		}
		for(i = 6; i >= 0; --i)
		{
			led_on(1 << i);
			delay(9000);
		}
	}
}

5、数码管显示:重复显示0~9

cs 复制代码
#include <reg52.h>
#include "led.h"
#include "digiter.h"
#include "delay.h"

int main(void)
{
	 int i = 0;
	 bit_select(2);
	 while(1)
	 {		
	 	segment_select(i++);
		if(i > 9)
		{
			i = 0;
		}
		delay(20000);	
	 }
}

6、按键:初始化按键(init_key)、按键选择(key_pressed)

cs 复制代码
#include <reg52.h>
#include "digiter.h"
#include "key.h"
#include "delay.h"

void init_key(void)
{
	P1 |= (0x0F << 4);//0000 1111 
	P3 |= (0x0F << 4);
}

int key_pressed(void)
{
	int ret = 0;
	if((P1 & (1 << 4)) == 0)
	{
		ret = 1;
	}
	else if((P1 & (1 << 5)) == 0)
	{
		ret = 2;
	}
	else if((P1 & (1 << 6)) == 0)
	{
		ret = 3;
	}
	else if((P1 & (1 << 7)) == 0)
	{
		ret = 4;
	}
	else if((P3 & (1 << 5)) == 0)
	{
		ret = 5;
	}
	return ret;
}

int main(void)
{
	init_key();
	P2 = 0xFF;
	while(1)
	{
		
		int key;
		key = key_pressed();
		if(key != 0)
		{
			P2 = 0;//亮灯
		}
		delay(0x9000);
	}
	return 0;
}

7、外部中断:外部中断0---加、外部中断0---减

cs 复制代码
#include <reg52.h>
#include "delay.h"
#include "digiter.h"

void init_eint0(void)
{
	IE |= (1 << 7) | (1 << 0) | (1 << 2);
	TCON |= (1 << 2);
	TCON &= ~(1 << 0);//enit0 low
	P3 |= (1 << 2) | (1 << 3);
}

int num = 0;

void enit0_handle(void) interrupt 0
{
	++num;
	if(num > 9999)
	{
		num = 0;
	}
}

void enit1_handle(void) interrupt 2
{
	--num;
	if(num < 0)
	{
		num = 9999;
	}
}

int main(void)
{
	init_eint0();
	P2 = 0xFF;
	while(1)
	{
		show_number(num);
	}
}

8、定时器:实现类似电子琴的效果

cs 复制代码
#include <reg52.h>
#include "key.h"

#define Hz200 63035
#define Hz400 64285
#define Hz600 64702
#define Hz800 64910
#define Hz1000 65035

unsigned short n = Hz200;

void init_timer0(void)
{
	TMOD &= ~(3 << 2);
	TMOD &= ~(3 << 0);
	TMOD |= (1 << 0);
	TH0 = n >> 8;
	TL0 = n;
	
	IE |= (1 << 7) | (1 << 1); 
}

void timer0_handler(void) interrupt 1
{
	P2 ^= (1 << 1);
	TH0 = n >> 8;
	TL0 = n;
}

int main(void)
{
	init_timer0();
	init_key();
	while(1)
	{
		int key;
		key = key_pressed();
		if(key == 1)
		{
			n = Hz200;
			TCON |= (1 << 4);
		}
		else if(key == 2)
		{
			n = Hz400;
			TCON |= (1 << 4);
		}
		else if(key == 3)
		{
			n = Hz600;
			TCON |= (1 << 4);
		}
		else if(key == 4)
		{
			n = Hz800;
			TCON |= (1 << 4);
		}
		else if(key == 5)
		{
			n = Hz1000;
			TCON |= (1 << 4);
		}
		else if(key == 0)
		{
			TCON &= ~(1 << 4);
		}
	}
	return 0;
}

【END】

相关推荐
充哥单片机设计1 小时前
【STM32项目开源】基于STM32的智能语音分类垃圾桶
stm32·单片机·嵌入式硬件
张人玉2 小时前
C# UDP 服务端与客户端2.0
单片机·udp·c#
小林up3 小时前
《Unity Shader入门精要》学习1:Phong 模型中法向量归一化的正确位置
学习·unity·游戏引擎
Lojarro3 小时前
GO学习2:基本数据类型 与 转换
后端·学习·golang
come112343 小时前
冀教版三年级上册英语-学习思路和引导方法
学习
派森先生3 小时前
sk07.【scikit-learn基础】--『监督学习』之支持向量机
学习·支持向量机·scikit-learn
wdfk_prog4 小时前
`git rm --cached`:如何让文件“脱离”版本控制
大数据·linux·c语言·笔记·git·学习·elasticsearch
lingliang4 小时前
机器学习之三大学习范式:监督学习、无监督学习、强化学习
人工智能·学习·机器学习
派森先生5 小时前
sk06.【scikit-learn基础】--『监督学习』之决策树
学习·决策树·scikit-learn
stolentime5 小时前
二维凸包——Andrew 算法学习笔记
c++·笔记·学习·算法·计算几何·凸包