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

STC32G系列,备战2025全国大学生智能车竞赛学习贴

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2026-01-20 17:19:10
已绑定手机

3

主题

32

回帖

91

积分

注册会员

积分
91
发表于 2026-1-20 19:36:13 | 显示全部楼层

STC32G单片机外部中断笔记

第一章:中断与中断系统

一、中断的基本概念

  • 定义:当CPU正在处理某任务时,外界发生紧急事件,要求CPU暂停当前工作,转而处理该紧急事件,处理完毕后再返回原任务继续执行。
  • 类比理解:如同正在学习时,父母叫你帮忙,处理完后继续学习。

二、中断系统

  • 组成:实现中断功能的硬件和软件机制。
  • 中断源:引发中断的事件来源,单片机允许有多个中断源。
  • 中断优先级
    • 优先级高的中断可以打断正在执行的低优先级中断。
    • 优先级可通过软件设置(部分中断可设置,非全部)。

三、中断的优点

  1. 实时响应:CPU总是响应优先级最高的中断。
  2. 嵌套中断:高优先级中断可打断低优先级中断。
  3. 独立控制:每个中断源可通过软件独立开启或关闭。
  4. 优先级可配置:部分中断优先级可通过软件调整。

第二章:外部中断详解

一、什么是外部中断?

  • 触发方式:单片机引脚上的电平变化(上升沿/下降沿)。
  • 引脚限制:并非所有引脚都支持外部中断,需查看手册确认。

二、STC32G外部中断引脚

  • 外部中断0(INT0):P3.2(引脚29)
  • 外部中断1(INT1):P3.3
  • 外部中断2(INT2)INT3INT4:对应特定引脚(需查手册确认)
  • 注意:不同型号单片机的中断引脚可能不同,使用前务必核对数据手册。

三、外部中断配置寄存器

中断源 触发方式控制位 中断标志位 中断允许位 优先级控制
INT0 IT0(TCON.0) IE0(TCON.1) EX0(IE.0) PX0(IP.0)
INT1 IT1(TCON.2) IE1(TCON.3) EX1(IE.1) PX1(IP.1)
INT2~4 固定为下降沿触发 IEx(x=2~4) EXx(x=2~4) 部分可设优先级

四、触发方式

  • ITx = 0:上升沿和下降沿均可触发
  • ITx = 1:仅下降沿触发(适用于按键按下触发)

第三章:外部中断编程实践

一、编程步骤(以INT0为例)

  1. 初始化触发方式
    IT0 = 1; // 下降沿触发
    
  2. 清除中断标志位
    IE0 = 0; // 防止上电误触发
    
  3. 开启中断允许
    EX0 = 1; // 允许INT0中断
    EA = 1;  // 开启总中断
    
  4. 编写中断服务函数
    void INT0_ISR() interrupt 0 {
        // 中断处理代码,如LED取反
        LED = ~LED;
    }
    

二、完整示例:INT0控制LED

#include "exit.h"

void INT0_Init() {
    IT0 = 1;   // 下降沿触发
    IE0 = 0;   // 清除中断标志
    EX0 = 1;   // 允许INT0中断
    EA = 1;    // 开启总中断
}

void INT0_ISR() interrupt 0 {
    LED = ~LED; // 每次触发,LED状态取反
}

三、外部中断 vs 普通按键扫描

  • 普通按键:需在主循环中不断检测,响应可能延迟。
  • 外部中断:立即响应,不受主程序阻塞影响。
  • 典型应用:急停按钮、安全开关、实时事件响应。

实验对比:中断响应实时性

  • 普通按键:在 for循环延时期间按下无效,必须等循环结束才响应。
  • 外部中断:任何时刻按下都能立即响应,适合紧急场景。
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2026-01-20 17:19:10
已绑定手机

3

主题

32

回帖

91

积分

注册会员

积分
91
发表于 2026-1-20 19:40:28 | 显示全部楼层

IO中断笔记

一、IO中断的核心特点

  • 全面支持:STC32G系列所有IO口均可设置为中断引脚
  • 四种模式:支持下降沿、上升沿、低电平、高电平四种中断触发模式
  • 独立配置:每组IO都有独立的中断入口地址,每个IO口可独立设置中断模式

二、当前版本限制

  • 建议模式:当前版本建议只使用低电平中断高电平中断
  • 避免使用:暂时不要使用下降沿和上升沿中断模式

三、与外部中断的区别

  • 传统外部中断:仅特定引脚支持,触发方式有限
  • IO中断:所有IO口均可中断,功能更强大,配置更灵活
  • 创新性:IO中断是STC32G单片机的创新功能,为8051单片机首次引入

一、关键寄存器

  1. 中断模式配置寄存器

    • PnIM1PnIM0:控制IO口的中断触发模式
    • 例如:设置P3.5为低电平中断
      P3IM1 = 0x20;  // 设置P3.5为高电平使能
      P3IM0 = 0x00;  // 设置P3.5为低电平中断
      
  2. 中断使能寄存器

    • PnINTE:使能特定IO口的中断功能
    • 例如:使能P3.5中断
      P3INTE = 0x20;  // 使能P3.5中断
      
  3. 中断标志寄存器

    • PnINTF:中断标志位,需要软件清零
    • 进入中断后必须手动清除标志位

二、编程步骤(以P3.5低电平中断为例)

// 1. 配置中断模式
P3IM1 = 0x20;  // P3.5高电平使能
P3IM0 = 0x00;  // P3.5低电平中断

// 2. 使能中断
P3INTE = 0x20;  // 使能P3.5中断

// 3. 开启总中断
EA = 1;

三、中断服务函数编写

void P3_ISR() interrupt 40  // P3口中断号为40
{
    unsigned char int_flag;
  
    // 读取中断标志
    int_flag = P3INTF;
  
    // 清除中断标志(必须软件清零)
    P3INTF = 0x00;
  
    // 判断具体哪个引脚触发中断
    if(int_flag & 0x20)  // P3.5触发
    {
        // 中断处理代码
        // 注意:中断服务函数中尽量避免使用延时!
    }
}

四、中断向量号扩展

  • 问题:C251编译器默认只支持0-31号中断
  • 解决方案
    1. 安装扩展工具:从STC官网下载"标准C251中断向量扩展"工具
    2. 汇编跳转:借用13号保留中断入口进行跳转(不推荐初学者)

中断优先级设置

  • 问题现象:当多个中断同时存在时,低优先级中断可能影响高优先级任务
  • 示例:数码管刷新(定时器中断)被IO中断打断,导致显示闪烁

二、优先级配置方法

  1. 优先级寄存器

    • IP:中断优先级低字节
    • IPH:中断优先级高字节
  2. 优先级级别:0-3级(0最低,3最高)

  3. 示例:设置定时器0为最高优先级

    IP = 0x02;   // PT0=1,定时器0优先级设为1(二进制0010)
    IPH = 0x00;  // PT0H=0,与IP组合形成优先级
    // 实际优先级 = (IPH << 1) | IP = 2(十进制)
    

三、优先级规则

  1. 高优先级打断低优先级:正在执行低优先级中断时,高优先级中断可以打断它
  2. 同优先级顺序执行:相同优先级时,按中断号顺序执行
  3. 中断号小的优先:同优先级下,中断号小的先执行

四、实际应用

  • 定时器中断:通常设置为高优先级,确保实时任务不被中断
  • IO中断:根据实际需求设置优先级,紧急事件(如急停按钮)应设高优先级

实战项目 - 简易中央门禁控制系统

一、项目需求

  1. 基本功能:8个按键控制8个门锁状态(LED表示)
  2. 应急功能:按下应急按钮立即打开所有门锁
  3. 安全保护:应急状态下,普通门锁操作被禁止
  4. 恢复机制:松开应急按钮后,5秒倒计时恢复原状态

二、核心代码实现

1. 全局变量定义

unsigned char door_lock = 0xFF;  // 门锁状态,初始全部上锁
unsigned int time_countdown = 0; // 倒计时变量

2. 主循环中的处理

// 每10ms执行一次
if(time_countdown > 0)
{
    time_countdown--;  // 倒计时减1
  
    // 数码管显示倒计时(秒)
    seg0 = (time_countdown / 100) + 1;
  
    if(time_countdown == 0)
    {
        // 倒计时结束,恢复门锁状态
        // 此处可根据需要恢复之前的状态
    }
}
else
{
    // 正常状态下处理按键
    key = MatrixKey();  // 读取矩阵按键
  
    if(key != 0)
    {
        // 根据按键值切换对应门锁状态
        door_lock ^= (1 << (key - 1));
        LED = door_lock;  // 更新LED显示
    }
}

3. 应急按钮中断处理(P3.5低电平中断)

void P3_ISR() interrupt 40
{
    unsigned char int_flag = P3INTF;
    P3INTF = 0x00;  // 清除中断标志
  
    if(int_flag & 0x20)  // P3.5触发
    {
        // 应急处理:打开所有门锁
        door_lock = 0x00;
        LED = door_lock;
  
        // 启动5秒倒计时(500 * 10ms)
        time_countdown = 500;
  
        // 数码管显示"5"
        seg0 = 5;
  
        // 蜂鸣器提示
        Beep(100);
    }
}

三、项目亮点

  1. 实时响应:应急按钮使用IO中断,立即响应
  2. 状态保护:应急状态下禁止普通操作,防止误操作
  3. 安全恢复:5秒倒计时提供安全缓冲时间
  4. 可视化反馈:LED显示门锁状态,数码管显示倒计时
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2026-01-20 17:19:10
已绑定手机

3

主题

32

回帖

91

积分

注册会员

积分
91
发表于 2026-1-20 19:44:11 | 显示全部楼层

STC32G单片机ADC模数转换器课程笔记

一、ADC基础概念

1.1 什么是ADC

  • ADC = Analog-to-Digital Converter(模数转换器)
  • 功能:将连续变化的模拟信号(电压)转换为离散的数字信号(二进制数)
  • STC32G单片机内置12位高速ADC

1.2 模拟信号 vs 数字信号

  • 模拟信号:连续变化的物理量,如电压(单位:伏特V)
  • 数字信号:由0和1组成的离散二进制数
  • 单片机只能处理数字信号,ADC是连接模拟世界与数字世界的桥梁

二、ADC工作原理(逐次逼近型)

位数决定精度:12位ADC = 比较12次,精度更高(4096级)

  • 比较次数越多,结果越接近真实值
  • 逐次逼近:从最高位(最大比较值)开始,依次向下比较

三、STC32G单片机ADC特性

3.1 主要参数

  • 12位分辨率(0~4095)
  • 16个通道(通道0~14为外部引脚,通道15为内部1.19V参考源)
  • 参考电压源
    • 可使用外部VREF引脚电压
    • 或直接使用VCC电压
    • 注意:VREF引脚不能悬空,必须接参考电压或VCC

3.2 电压测量范围

  • 输入电压必须 ≤ VREF(参考电压)
  • 若VREF接2.5V基准源,则输入电压需≤2.5V
  • 若VREF接VCC(5V),则输入电压需≤5V

四、ADC相关寄存器

4.1 ADC控制寄存器(ADCCONTR)

名称 功能说明
7 ADC_POWER 1=打开ADC电源,0=关闭(睡眠时省电)
6 ADC_START 1=开始转换,转换完成后自动清零
5 ADC_FLAG 转换结束标志位(1=转换完成,需软件清零)
3-0 CHS[3:0] 通道选择(00001111对应通道015)

4.2 ADC配置寄存器(ADCCFG)

功能
7 RESFMT:结果对齐方式(0=左对齐,1=右对齐)
6-4 SPEED:ADC时钟选择(建议用慢速以增强稳定性)
3-0 保留

4.3 ADC时序控制寄存器(ADCTIM)

  • 控制通道切换时间、采样保持时间
  • 建议使用默认值(最稳定)

五、ADC编程实现

5.1 初始化步骤

  1. 配置IO口为高阻输入模式

    P1M0 = 0x01;  // P1.0高阻输入
    P1M1 = 0x01;
    
  2. 配置ADC时序(ADCTIM)

    ADCTIM = 0x3F;  // 默认最慢速度,最稳定
    
  3. 配置ADC参数(ADCCFG)

    ADCCFG = 0x02;  // 右对齐 + 最慢时钟
    
  4. 打开ADC电源

    ADCCONTR = 0x80;  // 打开电源,未启动转换
    

5.2 查询方式读取ADC

u16 ADC_Read(u8 ch)
{
    u16 adc_value;
  
    // 1. 选择通道(注意保留高4位电源控制)
    ADCCONTR = (ADCCONTR & 0xF0) | (ch & 0x0F);
  
    // 2. 启动转换
    ADCCONTR |= 0x40;  // 设置START位
  
    // 3. 等待两个时钟(空指令延时)
    _nop_();
    _nop_();
  
    // 4. 等待转换完成
    while(!(ADCCONTR & 0x20));  // 等待ADC_FLAG置1
  
    // 5. 清除标志位
    ADCCONTR &= ~0x20;
  
    // 6. 读取结果(12位右对齐)
    adc_value = (ADC_RES << 8) | ADC_RESL;
  
    return adc_value;  // 返回12位ADC值(高4位为0)
}

5.3 中断方式读取ADC

  1. 初始化时开启中断

    EADC = 1;  // 开启ADC中断
    EA = 1;    // 开启总中断
    
  2. 中断服务函数

    u16 adc_value = 0;  // 全局变量存储ADC值
    
    void ADC_ISR() interrupt 5
    {
        EADC = 0;  // 临时关闭中断
    
        // 清除标志位
        ADCCONTR &= ~0x20;
    
        // 读取ADC值
        adc_value = (ADC_RES << 8) | ADC_RESL;
    
        // 重新启动转换(如果需要连续采集)
        ADCCONTR |= 0x40;
    
        EADC = 1;  // 重新开启中断
    }
    

六、ADC数值转换为实际电压

u32 ADC_ToVoltage(u16 adc_value)
{
    u32 voltage;
    // 假设VREF = 2500mV (2.5V)
    voltage = (u32)adc_value * 2500 / 4096;
    return voltage;  // 单位: mV
}
回复

使用道具 举报 送花

  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2026-01-20 17:19:10
已绑定手机

3

主题

32

回帖

91

积分

注册会员

积分
91
发表于 2026-1-20 19:47:31 | 显示全部楼层

课程笔记:STC32G单片机ADC应用(第18集)

第一部分:ADC反推电源电压

  1. 原理

    • STC32G的ADC第15通道内部连接一个稳定的1.19V参考信号源。
    • 通过测量这个已知的内部电压,可以反推出当前为ADC提供参考电压的VREF引脚的实际电压值(通常是电源电压)。
    • 此方法在电池供电等电压不稳定的低成本应用中尤为重要,可以省去外部基准电压电路。
  2. 关键公式

    • ADC输入电压计算公式:V_in = V_REF × (ADC_Result / 4096)
    • 为了计算任意通道的输入电压(V_in),必须已知参考电压(V_REF)。反推电源电压的目的就是先精确获取V_REF的值。
  3. 实现步骤

    • 读取内部基准值:从芯片的特定寄存器(CHIPID7CHIPID8)中读取内部1.19V电压源对应的校准值,合并为一个变量(如 BGV)。
    • 初始化ADC:配置ADC,选择第15通道(内部信号源)。
    • 采样与平均:对通道15进行多次ADC采样(如8次),取平均值以提高准确性。
    • 计算V_REF:使用公式 V_REF = (4096 × BGV) / ADC_AVG 计算得到实际的参考电压值。
    • 应用:将此计算出的V_REF值代入通用公式,即可准确测量其他ADC通道的输入电压。
  4. 注意事项

    • 上电后需延时一段时间(如500ms)再进行测量,等待电源稳定。
    • 初始的几个ADC采样值应丢弃,以消除ADC模块启动时的非线性。

第二部分:ADC按键扫描

  1. 原理

    • 利用电阻分压网络,将多个按键连接到一个ADC引脚。
    • 不同的按键被按下时,会在ADC引脚上产生不同的分压值,ADC读取的数值也不同。
    • 通过判断ADC值所处的范围,即可识别出具体哪个按键被按下。
  2. 实现步骤

    • 定义键值表:根据分压电路计算或实测每个按键对应的理论ADC值(例如,256, 512, 768...)。
    • 设置容错范围:为每个键值设定一个允许的误差范围(如±64),以抵抗电阻误差和噪声干扰。
    • 按键判断:循环比较当前ADC采样值是否落在某个按键的容错区间内,并返回对应的按键编号(1-16),0表示无按键。
    • 长按与连续触发:通过记录按键状态和计时,可以实现短按、长按(如3秒)触发,以及长按后的连续快速触发(如每0.1秒一次)等功能。
  3. 优势

    • 仅需一个ADC引脚即可实现多达16个按键的检测,极大节省了单片机IO口资源,特别适合引脚数量有限的微型单片机应用。

第三部分:实战小练 - 简易时钟设置

  1. 项目功能

    • 数码管显示时间,格式为“00-00-00”(时-分-秒)。
    • 正常模式下,时钟每秒走时一次。
    • 长按按键A进入时间设置模式,此时时钟暂停,第一位(小时十位)数码管闪烁。
    • 在设置模式下,按下数字键(0-9)可输入对应数值,闪烁位会自动后移(跳过“-”显示位)。
    • 长按按键B可停止当前位的闪烁,并使秒数加一(用于微调)。
    • 按下按键D可退出设置模式,保存设定时间并恢复走时。
  2. 关键实现

    • 状态机:使用一个标志变量区分“正常走时”和“设置”两种状态。
    • 数码管闪烁:通过一个定时器控制闪烁周期,并用一个变量指定当前哪一位需要闪烁。
    • 按键驱动:调用前面实现的ADC按键扫描函数,并根据返回的键值执行不同的功能逻辑(设置数字、切换模式、调整时间等)。
    • 数据转换:将按键输入的数字分解并存储到时、分、秒的变量中,再实时更新到数码管显示缓冲区。
回复

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:61
  • 最近打卡:2026-02-07 11:52:53
已绑定手机

14

主题

125

回帖

924

积分

版主

积分
924
发表于 2026-1-21 08:38:48 | 显示全部楼层
要 做到 USB不停电下载
要 尝试 AiCube 图形化自动配置生成程序工具
推荐优先看的:  
printf_usb("Hello World !\r\n")
USB不停电下载, 演示视频链接:
https://www.stcaimcu.com/thread-19077-1-1.html

下载 最新的 AiCube-ISP-V6.96O 或以上版本软件 !

深圳国芯人工智能有限公司-工具软件

下载 最新的 USB库函数,永远用最新的 USB库函数 !
深圳国芯人工智能有限公司-库函数
下载 最新的 用户手册 !
下载 最新的 上机实践指导书 !


下载 最新的 STC32G12K128 用户手册
https://www.stcaimcu.com/data/download/Datasheet/STC32G.pdf

下载 最新的 STC32G12K128 实验指导书
AiCube 图形化自动配置生成程序工具使用说明
https://www.stcaimcu.com/data/do ... %AF%BC%E4%B9%A6.pdf



上面是 小李 演示:STC32G12K128, printf_usb("Hello World !\r\n")及usb不停电下载@AiCube之图形化程序自动生成


上面是 姚工 演示:STC32G12K128, printf_usb("Hello World !\r\n")及usb不停电下载@AiCube之图形化程序自动生成

回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2026-2-12 18:04 , Processed in 0.106961 second(s), 60 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

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