单片机(89C51)---基础知识

发布于:2025-09-04 ⋅ 阅读:(30) ⋅ 点赞:(0)

一、核心基础概念

裸机

        裸机开发指代码直接与硬件交互,不依赖操作系统(OS),通过直接操作寄存器或硬件接口实现功能,是嵌入式入门(如LED、按键控制)的常用开发模式。

Soc(系统级芯片)

        未明确展开,通常指集成多个功能模块的芯片,可包含CPU/MCU核心、内存、外设(如GPIO、UART)等,是复杂嵌入式设备(如手机、物联网网关)的核心。

核心计算/控制芯片(CPU、MPU、MCU、GPU)

四者均为芯片级核心,核心区别在于功能定位与集成度,覆盖从通用计算到专用控制的不同场景:

  • CPU(中央处理器):通用计算核心,负责执行计算机指令运算,是PC、服务器等设备的“大脑”,不直接集成专用外设
  • MPU(微处理器):可理解为“无集成外设的CPU”,需外接内存、存储和外设才能工作,常见于高端嵌入式设备(如手机SoC中的应用处理器)。
  • MCU(微控制器):“微型计算机”,高度集成(含CPU核心、RAM/ROM内存、GPIO/UART等外设),体积小、成本低,是LED控制、传感器采集等简单场景的核心,典型例子为C8051单片机、STM32
  • GPU(图形处理器):专用图形计算核心,擅长并行运算,负责图像渲染、视频处理,也可用于AI算力加速(如显卡中的GPU)。
二、外设寄存器
定义

        外设寄存器是硬件外设(如GPIO、UART、TIMER)与软件的交互接口,本质是一块具有固定地址的高速存储单元,用于存储“控制指令”或“硬件状态数据”,相当于硬件的“控制开关面板”。

        寄存器(外设):是指能够操作硬件的,具有固定地址的内存空间

作用逻辑

软件通过“读写寄存器”实现对硬件的控制:

  • 写寄存器:配置外设工作模式(如设置GPIO为输出模式、控制LED电平);
  • 读寄存器:获取外设实时状态(如读取按键是否按下、TIMER计数是否完成)。
适用架构

在x86、ARM、MIPS、8051等主流嵌入式/计算机架构中均存在,是跨平台硬件控制的核心机制。

三、GPIO(通用输入输出端口)
定义

        GPIO是单片机/MCU上的通用引脚接口,可通过软件灵活配置工作模式,是嵌入式开发中最基础、最常用的外设接口。

工作模式与应用
  • 输出模式:控制外部设备,如驱动LED亮灭、继电器吸合;
  • 输入模式:读取外部信号,如检测按键是否按下、传感器输出的电平信号。
典型应用场景

LED实验、按键检测实验、传感器数据采集(如温湿度传感器)等,均依赖GPIO实现硬件交互。

四、LED实验(基于C8051单片机)
实验关键信息
  • 硬件逻辑:LED采用“高电平灭、低电平亮”(文档1明确提及);
  • 控制端口:使用C8051的P2端口(代码中通过操作P2寄存器实现LED控制);
  • 核心功能:实现LED全亮、全灭及“跑马灯”效果(从0~7引脚循环点亮,再从6~0引脚循环点亮)。
用到的寄存器

LED实验的核心是通过GPIO端口寄存器控制电平,不同平台寄存器存在差异:

平台 核心寄存器 作用
C8051单片机 P2端口寄存器 直接控制P2引脚电平,如P2=0(全亮)、P2=0xff(全灭)
STM32 GPIO模式寄存器(MODER) 设置GPIO引脚为“输出模式”,确保可控制LED电平
STM32 GPIO输出数据寄存器(ODR) 直接控制引脚输出高/低电平,是LED状态控制的关键
STM32 GPIO上拉/下拉寄存器(PUPDR) 可选配置,防止引脚电平浮动,避免LED误亮
完整实验代码
主函数代码(main.c)
#include <reg52.h>
#include "led.h" // 引入LED控制函数头文件



int main(void)
{
    int i;
    led_all_off(); // 初始化:LED全灭(P2=0xff)

    while(1) // 死循环,持续执行跑马灯逻辑
    {
        // 跑马灯:从引脚0~7依次点亮
        for(i = 0; i < 8; ++i)
        {
            led_on(~(1 << i)); // 控制单个LED点亮(~(1<<i)确保对应引脚为低电平)
            delay(30000);     // 延时,保持LED点亮状态
        }

        // 跑马灯:从引脚6~0依次点亮(跳过引脚7)
        for(i = 6; i > 0; --i)
        {
            led_on(~(1 << i));
            delay(30000);
        }
    }
}

LED控制函数实现(led.c)
#include "led.h"
#include <reg52.h> // C8051寄存器定义头文件

// LED全亮:P2端口置0(所有引脚低电平)
void led_all_on(void)
{
    P2 = 0;
}

// LED全灭:P2端口置0xff(所有引脚高电平)
void led_all_off(void)
{
    P2 = 0xff;
}

// 单个LED点亮:n为P2端口的控制值(低电平对应LED亮)
void led_on (unsigned int n)
{
    P2 = n;
}
LED控制函数声明(led.h)
#ifndef __LED_H_
#define __LED_H_

// 函数声明:供外部文件调用
extern void led_all_on(void);   // LED全亮
extern void led_all_off(void);  // LED全灭
extern void led_on (unsigned int n); // 单个LED点亮

#endif

#include <reg52.h>
#include "digiter.h"
#include "delay.h"

void bit_select(int n)
{
	P1 &= ~(0x0f << 0);				 
	P1 |= (1 << n);
	
}

void segmment_select(int n)	 // 0 ~ 9
{
	unsigned char t[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
	P0 = t[n];
	delay(300);	  // 保证二极管导通
	P0 = 0;
	delay(300);	  // 消影	
}

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

延迟函数实现

// 延时函数:通过循环实现简单延时
void delay(unsigned int n)
{
    while (n--);
}
五、数码管相关
数码管段码表(0~9)

用于控制数码管显示数字,段码为十六进制值,对应数码管的“段点亮逻辑”:

// 数组t[0]~t[9]分别对应显示数字0~9
unsigned char t[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
数码管显示代码片段

数码管控制函数声明(led.c)(需注意不能加delay,避免影响显示刷新):

#include <reg52.h>
#include "digiter.h"
#include "delay.h"

void bit_select(int n)
{
	P1 &= ~(0x0f << 0);				 
	P1 |= (1 << n);
	
}

void segmment_select(int n)	 // 0 ~ 9
{
	unsigned char t[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
	P0 = t[n];
	delay(300);	  // 保证二极管导通
	P0 = 0;
	delay(300);	  // 消影	
}

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


网站公告

今日签到

点亮在社区的每一天
去签到