找回密码
 立即注册
楼主: HiMrLe

32位8051单片机原理及C语言程序设计视频教程-学习打卡

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:18
  • 最近打卡:2026-03-31 08:20:20
已绑定手机

3

主题

43

回帖

141

积分

注册会员

积分
141
发表于 2026-3-23 11:49:15 | 显示全部楼层

打卡第十集-数码管的动态显示

数码管动态刷新原理

  • 同一时刻只点亮一位数码管,其余位处于熄灭状态。
  • 依次循环点亮每一位,每位的点亮时间极短(毫秒级)。
  • 利用人眼视觉暂留效应(图像在视网膜上停留约1/16秒,即62.5ms以上),只要循环速度足够快,人眼就会感觉所有位同时稳定显示

数码管动态控制原理

image.png

在动态刷新中,每位点亮时间不宜过短,通常设为1ms左右;同时需确保一个完整的扫描周期不超过20ms,即刷新率高于50Hz,以利用人眼视觉暂留效应避免闪烁。

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:18
  • 最近打卡:2026-03-31 08:20:20
已绑定手机

3

主题

43

回帖

141

积分

注册会员

积分
141
发表于 2026-3-23 15:47:04 | 显示全部楼层

打卡第十一集-定时器的使用

一、核心作用

定时器本质上是一个自动累加的寄存器,在时钟脉冲驱动下自增。通过配置,它可以实现以下几种核心功能:

  1. 精准定时
    它可以产生精确的时间间隔。例如,设定一个1毫秒的定时,时间到后,单片机就会收到标志或触发中断。这避免了使用 delay函数时CPU“空等”造成的资源浪费。
  2. 精准计数
    它可以统计外部引脚上脉冲的个数。例如,用来统计电机编码器反馈的脉冲数,从而计算电机转速,或者统计生产线上通过的产品数量。
  3. 输入捕获
    它可以“捕获”外部信号跳变的精确时刻。例如,用来测量遥控器红外信号的脉冲宽度,或超声波传感器的回波高电平持续时间,从而计算出距离。
  4. 输出比较(生成波形)
    它可以精确地在某个时刻翻转电平,最典型的就是生成 PWM波(脉宽调制)。通过调节PWM的占空比,可以实现控制LED亮度、调节直流电机转速、控制舵机角度等功能。

二、存在的意义

为什么单片机需要配置独立的定时器硬件,而不是完全依赖软件循环?

  1. 解放CPU,提高效率
    这是最重要的意义。如果是软件延时(如 for循环),CPU在执行延时期间什么都做不了,只能空转。而使用定时器中断时,CPU可以正常处理其他任务(如扫描按键、刷新屏幕),定时器时间到后会“打断”当前任务去处理定时事件,处理完再回去继续干活。这种机制是多任务操作系统能够运行在单片机上的基础。
  2. 时间的精确性
    软件延时受编译器优化、中断干扰、流水线状态影响,误差较大。而定时器的计时来源是晶振,是确定且稳定的,能做到微秒级甚至纳秒级的精确度。这在需要严格时序的通信(如DS18B20单总线、红外解码)或电机控制中至关重要。
  3. 实时性
    对于需要严格按时处理的事件,比如电机PID控制(通常需在1ms内完成一次计算),如果依赖主循环的轮询,无法保证响应时间。定时器中断可以保证“每隔1ms,无论程序执行到哪里,都能立刻执行控制算法”,从而保证系统的实时响应
  4. 硬件PWM输出
    生成PWM波如果由软件模拟,CPU需要不停地在中断里翻转IO口,频率稍高就会导致CPU负载率100%。而使用定时器的PWM功能,一旦配置好,不需要CPU干预,硬件自己就能持续输出稳定的方波。CPU只需要在需要改变占空比时修改一下寄存器即可。

三、典型应用场景

  • LED呼吸灯/电机调速:利用定时器的PWM输出功能。
  • 电子时钟/万年历:利用定时器产生1秒的基准中断。
  • 舵机控制:利用定时器产生周期20ms,高电平0.5ms~2.5ms的精准PWM。
  • 旋转编码器读取:利用定时器的编码器模式或外部时钟计数模式。
  • 红外遥控解码:利用定时器的输入捕获功能测量高低电平的时间长度。

四、总结

如果把单片机比作一个

  • 没有定时器,就像一个人数着拍子干活(软件延时),数拍子的时候手脚不能动,效率低且不准。
  • 有了定时器,就像这个人买了一个秒表和闹钟

他可以设置闹钟(定时中断):“每过1毫秒提醒我一下,我来检查传感器”;同时让秒表在后台自动计时(输入捕获):“我看一下这个脉冲持续了多久”;甚至雇了一个助手(硬件PWM)专门在那里以固定频率推拉开关,不需要自己操心。

简而言之,定时器是单片机从“简单的顺序执行器”迈向“高效、实时、多任务嵌入式系统”的关键硬件资源。


定时器常见的工作模式有以下几种:

1. 定时模式

  • 内部时钟驱动,计数器从0累加,达到设定值后产生溢出中断或标志。
  • 用于产生精确时间间隔,如1ms系统心跳。

2. 计数模式

  • 外部引脚输入的脉冲驱动计数器累加。
  • 用于统计脉冲个数,如编码器转速测量、流水线产品计数。

3. 输入捕获模式

  • 检测外部信号(上升沿/下降沿),记录当前计数器的值。
  • 用于测量脉冲宽度、频率、占空比,如红外解码、超声波测距。

4. 输出比较模式

  • 计数器值与预设比较值相等时,自动翻转/置位/清零输出引脚,并可产生中断。
  • 用于生成精确时序信号,或触发特定时刻的动作。

5. PWM模式(脉宽调制)

  • 输出比较的特殊形式,硬件自动产生周期固定、占空比可调的方波。
  • 用于LED调光、电机调速、舵机控制,不占用CPU资源。

6. 单脉冲模式 / 一次性模式

  • 定时器只运行一个周期,产生一次中断或输出一个脉冲后自动停止。
  • 用于需要精准单次延时的场景。

7. 级联模式

  • 多个定时器串联,一个作为另一个的预分频或时钟源,实现更长计时或更复杂波形。

一句话总结:定时器通过内部时钟做定时,通过外部脉冲做计数,通过比较/捕获做测量与波形生成

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:18
  • 最近打卡:2026-03-31 08:20:20
已绑定手机

3

主题

43

回帖

141

积分

注册会员

积分
141
发表于 2026-3-23 17:32:40 | 显示全部楼层

打卡第十二集-计数器的使用

计数器的用途

计数器本质上就是统计“高低电平变化次数”的硬件。

只要外部信号能产生脉冲(上升沿或下降沿),就可以用计数器的功能来统计。常见的典型用途包括:

1. 旋转测速

电机或轮子上安装编码器霍尔传感器,每转一圈输出N个脉冲。计数器统计单位时间内的脉冲数,即可算出转速

2. 流量计量

水表、燃气表中的流量传感器,液体流过时带动叶轮旋转,输出对应频率的脉冲。计数器统计脉冲数,即可得到累计流量

3. 流水线计数

工业产线上用光电传感器检测产品经过,物品遮挡时输出一个脉冲。计数器统计脉冲数,即可完成产品计数

4. 按键/开关状态检测

机械按键按下和释放时会产生电平变化,计数器可以统计按键次数,或配合消抖电路实现可靠计数。

5. 高频脉冲测量

对于比CPU处理速度更快的脉冲信号(如几十kHz以上),用软件轮询容易丢脉冲,而硬件计数器可以直接捕获,确保不遗漏。


核心优势:计数器由硬件独立完成统计,CPU只需在需要时读取计数值,整个过程不占用CPU资源。相比用 if语句在软件里轮询电平变化,硬件计数器更精准、不丢脉冲、不拖慢程序


自动重装载模式

image.png

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:18
  • 最近打卡:2026-03-31 08:20:20
已绑定手机

3

主题

43

回帖

141

积分

注册会员

积分
141
发表于 2026-3-23 21:13:37 | 显示全部楼层

打卡第十三集-简易多任务处理

extern 是 C 语言中用于声明外部变量或函数的关键字,告诉编译器:“这个变量/函数在其他文件中定义,请链接时去找。”


主要用途

1. 跨文件共享全局变量

假设有两个文件:main.ccounter.c,想在 main.c 中使用 counter.c 中定义的全局变量 count

  • counter.c 中定义:
    c

    int count = 0;   // 全局变量定义(分配内存)
    
  • main.c 中声明:
    c

    extern int count;   // 声明,不是定义,不分配内存
    

这样 main.c 就可以访问 count 了。

2. 在头文件中声明全局变量

通常做法:在头文件 .h 中用 extern 声明变量,在某个 .c 文件中实际定义。

  • counter.h
    c

    extern int count;   // 声明
    void increment(void);
    
  • counter.c
    c

    int count = 0;      // 定义
    void increment(void) {
        count++;
    }
    
  • main.c 包含头文件即可:
    c

    #include "counter.h"
    count = 10;   // 可以直接访问
    

3. 函数声明

函数默认是 extern 的,即可以跨文件调用。显式写 extern 不是必须的,但可增强可读性。

c

// 这两种写法等价
void func(void);
extern void func(void);

重要原则

  • 声明 vs 定义extern 只做声明,不分配内存;定义才分配内存。一个变量只能定义一次,但可以声明多次。
  • 作用域extern 声明的变量具有文件作用域,从声明处开始到文件末尾有效。
  • static 对立static 修饰的全局变量只能在本文件内使用,extern 用于跨文件访问。

常见误区

  • 在头文件中直接定义变量(不加 extern)会导致多个源文件包含该头文件时出现重复定义错误。
  • extern 不能用于局部变量(函数内部),只能用于全局变量和函数。

一句话总结extern 是 C 语言中实现跨文件共享全局变量的关键手段,遵循“头文件声明,源文件定义”的原则。



static 在 C 语言中根据修饰对象不同,有三种作用


1. 修饰局部变量(静态局部变量)

  • 生命周期:从程序启动到结束,不随函数调用结束而销毁。
  • 作用域:仍局限在函数内部,外部无法访问。
  • 初始化:只执行一次,默认初始化为 0。

c

void func() {
    static int count = 0;  // 只初始化一次
    count++;
    printf("%d", count);   // 每次调用递增
}

2. 修饰全局变量(静态全局变量)

  • 作用域:限制在当前文件内,其他文件无法通过 extern 访问。
  • 用于实现文件内部私有变量,防止命名冲突。

c

// file1.c
static int secret = 100;   // 仅 file1.c 可见

3. 修饰函数(静态函数)

  • 作用域:限制在当前文件内,其他文件无法调用。
  • 用于实现文件内部私有函数,仅被本文件的其他函数使用。

c

// file1.c
static void helper() {     // 仅 file1.c 可调用
    // ...
}

模块化编程就是将程序拆分成独立、可复用、职责清晰的模块,每个模块负责一个特定的功能。


一、模块化的核心思想

  • 接口与实现分离:头文件(.h)公开接口(函数声明、宏、类型),源文件(.c)隐藏实现细节(函数定义、私有变量)。
  • 信息隐藏:模块内部的变量和辅助函数对外不可见,通过 static 实现。
  • 依赖清晰:模块之间通过头文件建立依赖,避免全局变量直接共享。

二、典型模块结构

timer 模块为例:

timer.h(对外接口)

c

#ifndef TIMER_H
#define TIMER_H

// 公共函数声明
void timer_init(void);
void timer_start(void);
unsigned int timer_get_ms(void);

#endif

timer.c(内部实现)

c

#include "timer.h"

// 静态全局变量(仅本文件可见)
static unsigned int ms_counter = 0;
static void (*callback)(void) = NULL;  // 私有数据

// 静态函数(内部辅助)
static void timer_isr(void) {
    ms_counter++;
    if (callback) callback();
}

// 公共函数定义
void timer_init(void) {
    // 配置硬件定时器
    // 注册中断,调用 timer_isr
}

void timer_start(void) {
    // 启动定时器
}

unsigned int timer_get_ms(void) {
    return ms_counter;
}

main.c(使用模块)

c

#include "timer.h"

int main(void) {
    timer_init();
    timer_start();
    while(1) {
        unsigned int t = timer_get_ms();
        // ...
    }
}

三、模块化中的关键修饰符

修饰符 在模块化中的作用
static 修饰全局变量或函数,将其作用域限制在本文件,实现私有成员。
extern 在头文件中声明变量/函数,供其他模块使用。通常与 #include 配合,无需显式写 extern

四、模块化的好处

  1. 可维护性:修改一个模块不影响其他模块。
  2. 可复用性:模块可以在不同项目中直接复用。
  3. 可测试性:可以单独编译和测试每个模块。
  4. 协作开发:不同开发者负责不同模块,通过接口约定协作。

在模块化编程中,为重要函数添加清晰的说明注释,是保证代码可读性、可维护性的关键。通常采用 Doxygen 风格的注释,放在函数声明(头文件)或定义(源文件)之前。


标准函数说明应包含的内容

  • 功能简述:函数是做什么的
  • 参数:每个参数的含义、取值范围、输入/输出方向
  • 返回值:返回值的含义
  • 注意事项:调用前提、副作用、线程/中断安全等

示例(头文件中)

c

/**
 * @brief   初始化定时器模块
 * @param   freq    定时器工作频率,单位 Hz,范围 1000~100000
 * @param   mode    工作模式:0=单次模式,1=循环模式
 * @return  0: 成功, -1: 参数错误, -2: 硬件初始化失败
 * @note    必须在调用 timer_start() 之前调用本函数
 * @warning 若 freq 超出范围,函数会返回 -1 并保持原有配置不变
 */
int timer_init(unsigned int freq, int mode);

常用标签

标签 用途
@brief 简要描述
@param 参数说明(可标注 [in]/[out])
@return@retval 返回值说明
@note 补充说明
@warning 警告信息
@see 关联其他函数

为什么要加这些说明?

  • 方便他人理解:不需要阅读函数实现就知道怎么用
  • 自动生成文档:配合 Doxygen 等工具可直接生成 API 文档
  • 减少使用错误:明确参数范围、注意事项,降低误用风险
  • 方便代码审查:注释清晰,审查者能快速判断接口设计是否合理
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:18
  • 最近打卡:2026-03-31 08:20:20
已绑定手机

3

主题

43

回帖

141

积分

注册会员

积分
141
发表于 2026-3-23 22:16:13 | 显示全部楼层

打卡第十四集-矩阵按键

一、什么是矩阵按键?

当单片机需要连接很多按键时,如果每个按键都独立占用一个I/O口,会非常浪费资源。
矩阵按键采用 行线列线 交叉的方式,将按键排列成矩阵。

  • 如果有 m 行 × n 列,就可以实现 m × n 个按键。
  • 占用的I/O口数量仅为 m + n,而不是 m×n。

例如:4×4 矩阵键盘,占用 8 个 I/O 口,却能实现 16 个按键,大大节省了引脚资源。


二、矩阵按键的结构与原理

1. 硬件连接

  • 行线:通常连接到单片机的输出引脚(或输入引脚,带内部上拉)。
  • 列线:通常连接到单片机的输入引脚(带内部上拉)。
  • 每个按键位于某一行和某一列的交叉点,按下时将该行和该列连通。

2. 工作原理(扫描法)

行扫描法 为例,步骤如下:

  1. 初始化:所有行线输出低电平,所有列线设置为输入且上拉有效。
  2. 检测是否有按键按下:读取所有列线,如果某列变为低电平,说明该列有按键按下。
  3. 逐行扫描确定具体按键
    • 依次将每一行输出低电平,其他行输出高电平(或高阻态)。
    • 读取所有列线状态。
    • 如果某列读回低电平,则说明当前扫描的行与该列交叉处的按键被按下。
  4. 消除抖动:通常加入延时(如10-20ms)后再次确认状态,避免误判。

除了行扫描法,还有 反转法(先输出行扫描码,再交换方向读取列值)等,原理类似。


三、矩阵按键的优缺点

优点 缺点
节省I/O口资源,适合按键数量多的场景 不能直接检测多个按键同时按下(存在组合键识别问题,但可通过软件优化部分支持)
电路结构简单,成本低 扫描过程需要软件配合,占用一定的CPU时间
易于扩展,可以轻松组成4×4、8×8等 布线稍复杂,尤其是在PCB设计时

四、实际应用中的注意事项

  1. 按键消抖
    机械按键在按下和释放瞬间会产生抖动,软件中一般通过延时(10~20ms)或定时器采样去抖。
  2. 组合键与多键冲突
    在矩阵电路中,如果同时按下多个按键,可能会出现“鬼键”现象(检测到实际未按下的键)。
    解决方法:增加二极管(每个按键串联一个二极管)隔离,或通过软件逻辑识别无效组合。
  3. 行列复用
    在一些低引脚数的单片机上,行线和列线可以复用其他功能,只要在按键扫描时切换引脚方向即可。

五、与独立按键的对比

  • 独立按键:每个按键占用一个I/O口,程序简单,适合按键数量少(≤4个)的场景。
  • 矩阵按键:程序相对复杂,但能在有限引脚下支持更多按键,是嵌入式设备、键盘、控制面板等常用方案。

总结

矩阵按键是一种通过行列交叉结构,用较少的I/O口实现多个按键的硬件设计方法。其核心在于利用单片机的引脚方向控制和扫描算法来识别具体按键。你理解的“减少I/O口占用”正是它的主要优势,在实际开发中,掌握矩阵按键的扫描原理是嵌入式入门的重要一环。


矩阵按键的控制原理

image.png

按键识别原理:端口默认为高电平,当检测到引脚为低电平时,表示按键按下。

具体识别步骤如下:

  1. 列检测:将 P0.0–P0.3 设为低电平,P0.6–P0.7 设为高电平。若有按键按下,对应列的 I/O 引脚会被拉低,从而确定按下按键所在的列。
  2. 行检测:将 P0.0–P0.3 设为高电平,P0.6–P0.7 设为低电平。若有按键按下,对应行的 I/O 引脚会被拉低,从而确定按下按键所在的行。
  3. 按键定位:结合行与列的信息,即可唯一确定被按下的按键。
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:18
  • 最近打卡:2026-03-31 08:20:20
已绑定手机

3

主题

43

回帖

141

积分

注册会员

积分
141
发表于 2026-3-23 22:56:26 | 显示全部楼层

打卡第十五集-外部中断

中断和中断系统

一、什么是中断?

中断 是指CPU在正常运行程序时,由于内部或外部事件的触发,暂时停止当前程序的执行,转而去执行一个专门处理该事件的程序(称为中断服务程序),处理完毕后再返回原程序继续执行的过程。

形象比喻
你正在看书(主程序),突然电话响了(中断请求),你放下书去接电话(中断响应),接完电话后回到刚才的地方继续看书(中断返回)。


二、为什么需要中断?

如果没有中断,CPU只能通过轮询(不断查询)的方式检测外部事件,这会占用大量CPU时间,尤其在事件发生频率不高时效率极低。

中断的优势:

  • 实时性:事件发生时能立即得到响应。
  • 高效性:CPU平时可以专注于主任务,只在必要时处理突发事件。
  • 低功耗:空闲时CPU可以进入休眠模式,通过中断唤醒。

三、中断系统的组成

一个完整的中断系统通常包含以下几个部分:

1. 中断源

能产生中断请求的来源。常见的中断源:

  • 外部中断:由外部引脚电平变化触发(如按键、传感器)。
  • 定时器中断:由内部定时器溢出或匹配触发。
  • 通信中断:如串口接收/发送完成、I²C、SPI等。
  • ADC转换完成中断等。

2. 中断控制器

负责管理多个中断请求,包括:

  • 使能控制:允许或禁止某个中断。
  • 优先级管理:多个中断同时发生时,决定先响应哪一个。
  • 中断标志:记录哪个中断发生了。

在简单的单片机(如8051、AVR、STM32)中,中断控制器的功能集成在CPU内部或外设中。

3. 中断向量表

每个中断源对应一个固定的中断向量地址。当中断发生时,CPU会自动跳转到该地址执行对应的中断服务程序。

4. 中断服务程序(ISR)

是专门处理中断事件的函数。需要满足:

  • 尽量短小精悍,避免执行耗时操作。
  • 保护现场(保存被中断程序的寄存器状态)。
  • 清除中断标志,防止重复进入。

四、中断处理流程

  1. 中断请求:中断源产生有效中断信号。
  2. 中断判优:若多个中断同时请求,中断控制器根据优先级选择最高优先级的中断。
  3. 中断响应:CPU执行完当前指令后,保护断点(下一条指令的地址)和现场(关键寄存器),然后跳转到对应的中断服务程序。
  4. 中断处理:执行ISR中的代码。
  5. 中断返回:恢复现场和断点,继续执行原程序。

五、中断优先级与嵌套

  • 优先级:每个中断源可以设定一个优先级。高优先级的中断可以打断低优先级的中断,形成中断嵌套
  • 在单片机中,通常支持多个优先级级别,例如STM32的NVIC支持4~16级可编程优先级。
  • 优先级相同的多个中断,若同时发生,会按照硬件指定的“自然优先级”顺序响应。

六、中断与矩阵按键的结合

在矩阵按键检测中,如果采用轮询扫描,CPU需要不断地去读取行、列状态,即便没有按键按下也会空耗资源。

使用中断可以优化:

  • 将矩阵按键的某一行或某一列连接到一个外部中断引脚(比如所有列线通过“与”逻辑接到一个外部中断引脚)。
  • 当有按键按下时,该引脚电平变化触发中断,在中断服务程序中再去执行矩阵扫描(此时只进行一次完整的行列扫描),从而确定具体哪个按键被按下。
  • 这样CPU平时可以处理其他任务,只在有按键时才介入,既节省了资源,又保证了按键响应的实时性。

七、单片机中的典型中断应用

中断类型 典型用途
外部中断 按键、传感器信号、紧急停机信号
定时器中断 产生精确的时间基准、PWM、周期性任务调度
串口中断 接收/发送数据,实现异步通信
ADC中断 完成一次模拟信号采集后及时读取结果
DMA中断 数据传输完成通知

八、中断使用注意事项

  • 临界区保护:在中断中修改的全局变量,在主循环中访问时可能需要关闭中断或使用原子操作,防止数据不一致。
  • 中断服务程序不能阻塞:不要在ISR中使用 delay或等待标志等耗时操作。
  • 中断优先级设置要合理:高优先级中断不宜过多,否则可能导致低优先级中断长时间得不到响应。
  • 清除中断标志:大多数中断需要软件清除标志位,否则会重复进入。

什么是外部中断

外部中断就是在单片机的一个引脚上,由于外部因素导致了一个电平的变化(比如由高变低),而通过捕获这个变化,单片机内部自主运行的程序就会被暂时打断,转而去执行相应的中断处理程序,执行完后又回到原来中断的地方继续执行原来的程序。


回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:18
  • 最近打卡:2026-03-31 08:20:20
已绑定手机

3

主题

43

回帖

141

积分

注册会员

积分
141
发表于 昨天 17:07 | 显示全部楼层

打卡第十六集-IO中断

基本概念

单片机的IO引脚除了作为普通的输入输出外,往往可以复用为中断输入引脚。当该引脚上出现预设的电平变化(如上升沿、下降沿或低电平)时,单片机硬件会自动暂停当前正在执行的主程序,保存现场,并跳转到对应的中断服务程序执行。处理完中断后,再返回到主程序继续执行。


触发方式

单片机IO中断通常支持多种触发方式,可根据需要选择:

  • 边沿触发

    • 上升沿触发:引脚电平从低到高变化时产生中断。
    • 下降沿触发:引脚电平从高到低变化时产生中断。
    • 双边沿触发:上升沿和下降沿均产生中断(部分单片机支持)。
  • 电平触发

    • 低电平触发:引脚为低电平时持续产生中断(需注意中断服务程序需清除中断标志或改变电平,否则可能反复进入中断)。
    • 高电平触发:引脚为高电平时产生中断(较少见)。

image.png

image.png

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:18
  • 最近打卡:2026-03-31 08:20:20
已绑定手机

3

主题

43

回帖

141

积分

注册会员

积分
141
发表于 昨天 18:10 | 显示全部楼层

打卡第十七集-模数转换器ADC

模数转换器即A/D转换器,或简称ADC(Analog-to-digital converter),通常是指一个将模拟信号转变为数字信号的电子元件。

模拟信号 -> 电压

数字信号 -> 0和1组成的二进制数


模数转换的核心过程

ADC将连续的模拟电压转换为离散的数字量,一般经过三个步骤:

1. 采样与保持

  • 采样:以固定的时间间隔对模拟信号进行“快照”,获取瞬间的电压值。
  • 保持:由于转换需要一定时间,采样后的电压必须稳定不变,直到转换完成。采样保持电路会“冻结”该电压。

2. 量化

将采样后的电压与参考电压进行比较,将其归入有限个离散的电压等级。比如,一个8位ADC会将输入电压分为256个等级(2⁸)。

3. 编码

将量化后的等级用二进制数字表示。例如,0V对应0x00,参考电压对应0xFF。


image.png

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:18
  • 最近打卡:2026-03-31 08:20:20
已绑定手机

3

主题

43

回帖

141

积分

注册会员

积分
141
发表于 昨天 19:51 | 显示全部楼层

打卡第二十集-串口通信

通信指设备之间通过一定的协议进行的信息交换。

串口通信核心概念

  • 串行 vs 并行
    串行通信逐位传输,节省引脚、适合长距离;并行通信多位同时传输,速度快但线缆多、抗干扰差。
  • 异步 vs 同步
    串口通信多为异步,无独立时钟线,依赖双方约定的波特率;同步通信需时钟线,如I²C、SPI。
  • 全双工/半双工/单工
    • 全双工:可同时收发(如RS-232)。
    • 半双工:可分时收发(如RS-485)。
    • 单工:单向传输。

二、物理层:电气标准与连接

1. 常见电气接口

标准 逻辑电平 特点 典型应用
TTL 0V=0,3.3V/5V=1 短距离,单片机直接使用 开发板、传感器
RS-232 -3~-15V=1,+3~+15V=0 点对点,15米内 老式PC、工业设备
RS-485 差分电压差(A-B)决定逻辑 多点通信,1200米以上,抗干扰 工业总线、智能仪表

2. 最小连接(三线制)

  • TXD → 对方 RXD
  • RXD → 对方 TXD
  • GND → 对方 GND

*注:TTL与RS-232互连需电平转换芯片(如MAX3232)。*


三、协议层:通信参数

通信双方必须完全一致以下参数:

参数 说明 常用值
波特率 每秒传输的符号数(bps),决定位宽时间。 9600, 115200, 460800
数据位 实际数据的位数。 8(常用),7,5
停止位 标志帧结束的位数。 1(常用),2
校验位 奇/偶/无校验,用于简单检错。 None, Even, Odd

数据帧结构
起始位(1位低电平) + 数据位(LSB在前) + 校验位(可选) + 停止位(高电平)

image.png

image.png

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看I
  • 打卡总天数:18
  • 最近打卡:2026-03-31 08:20:20
已绑定手机

3

主题

43

回帖

141

积分

注册会员

积分
141
发表于 昨天 22:33 | 显示全部楼层

打卡第二十一集-串口应用

image.png

TXD几和RXD几表示这是第几组串口

TXD_几和RXD_几表示这是该组串口的第几个通道

芯片与芯片之间的通讯:如果通信协议和电平都一样,直接TX和RX链接就可以通信。


驱动(Device Driver) 是操作系统与硬件设备之间的“翻译官”和“管理者”。它是一个软件程序,让操作系统(如Windows、Linux)能够识别硬件并与之通信,而无需上层应用程序关心硬件的具体电路细节。


一、驱动的本质:软硬件的桥梁

硬件设备(如USB转串口模块、显卡、网卡)由电子电路构成,只能识别高低电平、执行指令;而操作系统和应用程序运行在抽象的软件层面。驱动的作用就是将操作系统通用的“打开、读写、关闭”等抽象操作,转换为硬件能够理解的寄存器配置、时序信号和数据传输

没有驱动,操作系统只能识别设备的存在(如“未知设备”),但不知道如何控制它。


二、驱动的主要作用

1. 设备识别与初始化

  • 向操作系统报告设备的基本信息(厂商ID、设备ID、功能)。
  • 对硬件进行上电、复位、初始状态配置,使其进入可用状态。

2. 提供统一的访问接口

  • 为上层应用提供标准化的API(如Windows下的 CreateFileReadFileWriteFile;Linux下的文件操作 openreadwrite)。
  • 应用程序可以像操作普通文件一样操作硬件,无需了解底层时序。

3. 数据转换与传输

  • 将系统内存中的数据转换为硬件能识别的格式(如串口驱动将字节转换为带有起始位、停止位的串行比特流)。
  • 管理数据的缓冲、流控、超时重试等机制。

4. 资源管理与冲突解决

  • 管理硬件占用的中断号(IRQ)、I/O地址、DMA通道等稀缺资源。
  • 协调多个程序同时访问同一设备(如通过互斥锁、队列)。

5. 错误处理与电源管理

  • 检测硬件异常(如断开连接、通信超时),向上层报告错误码。
  • 在系统休眠/唤醒时对硬件进行相应的电源状态切换。

三、串口通信中的驱动实例

以你之前关注的USB转TTL串口模块(如CH340、CP2102)为例,驱动的作用非常典型:

  1. 无驱动时:插入模块,系统弹出“无法识别的USB设备”,设备管理器中出现黄色感叹号。操作系统只知道有一个USB设备插入了,但不知道它是串口,也不知道如何与之通信。
  2. 安装驱动后
    • 驱动告知操作系统:这是一个“串行通信设备”。
    • 操作系统为其创建一个虚拟COM口(如Windows下的COM3,Linux下的 /dev/ttyUSB0)。
    • 驱动将上层应用程序对COM口的读写操作,转化为USB总线上的批量传输,进而由模块硬件转换为TTL串口电平。

结果:你的串口调试助手可以通过 COM3 打开设备,像操作传统物理串口一样进行收发数据,而实际上底层是通过USB传输的——这一切转换都由驱动完成。


四、驱动的分类

类型 特点 示例
内核驱动 运行在内核态,直接与硬件交互 显卡驱动、网卡驱动、USB主控驱动
用户态驱动 运行在用户态,通常通过内核驱动间接访问硬件 某些打印机驱动、虚拟串口驱动
通用驱动 操作系统自带,支持标准设备 CDC类驱动(用于简易USB串口)、HID驱动
私有驱动 硬件厂商提供,实现特定功能 CH340驱动、FTDI驱动、CP2102驱动

五、常见场景中的驱动

  • 单片机开发:使用USB转TTL模块时,需要安装对应芯片(CH340/CP2102/FT232)的驱动,否则电脑无法识别出COM口。
  • 显卡:没有显卡驱动,屏幕只能显示基本画面(VGA兼容模式),无法实现高分辨率、3D加速、多显示器。
  • 打印机:安装驱动后,操作系统才能知道打印机的具体指令集(如PCL、PostScript),将文档转换为打印机识别的数据。
  • 网卡:驱动负责将网络协议栈的IP包转换为网卡能够发送的物理层信号。

六、总结

驱动是硬件在操作系统中的“代言人”。它屏蔽了硬件的物理细节,让应用程序可以用统一的方式操作不同设备。对于串口通信而言,驱动就是让电脑能够通过USB口“模拟”出一个传统串口的软件层,从而让你能够用调试助手、Python脚本与单片机进行通信。

回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-3-31 18:30 , Processed in 0.123643 second(s), 86 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表