资讯动态

stm32概述

发布时间:2026/8/19 8:44:56 来源:尧图企业网站定制
1.stm32常用外设first :GPIO 控制高低电平 读取引脚的电平/电压secend : 通信接口2.volatile动用外部神秘力量没关系我用更简单的方式来解释什么是 volatile想象你有一个**记事本**上面记着家里灯的开关状态0表示关1表示开。### 没有volatile的情况被优化了int light_on 0; // 灯关着// 你写了个程序检查灯是否开了while (light_on 0) {// 等待开灯...}**问题**- 编译器看到 light_on 在循环里没被修改过觉得你太傻了- 自作聪明地把代码改成了if (light_on 0) {while (1) { } //永远循环再也不检查了}- 结果你去开灯程序却永远不知道灯已经开了### 有volatile的情况告诉编译器别自作聪明cvolatile int light_on 0; // 告诉编译器这变量随时可能变化while (light_on 0) {// 每次循环都重新检查light_on的值}## 生活中的比喻### 场景等快递**没有volatile**- 你问老婆快递到了吗- 老婆看了一眼说没到- 然后你就坐在那里再也没问过以为不会变化- 结果快递到了你也不知道**有volatile**- 你不停地问到了吗到了吗- 每次都会重新去看快递状态## 三个最常用的场景### 1. 硬件按钮检测volatile int button_pressed 0;// 当按钮被按下中断里执行void on_button_press() {button_pressed 1; // 标记按钮被按了}int main() {while (1) {if (button_pressed) {printf(按钮被按下了\n);button_pressed 0;}}}### 2. 传感器数据读取c// 温度传感器硬件自动更新数据volatile int temperature 25;void check_temperature() {// 每次都去读真实温度不用缓存的值if (temperature 30) {printf(太热了\n);}}### 3. 多任务共享数据cvolatile int message_received 0;// 任务1发送消息void task1() {send_message();message_received 1; // 标记消息已发送}// 任务2检查消息void task2() {if (message_received) {process_message();message_received 0;}}## 简单记法**用volatile就告诉编译器**- 这个变量可能会被外部改变- 不要自作主张帮我优化- 每次都去内存里读真实的值**不用纠结太多**记住- 如果变量会被**中断**修改 → 加volatile- 如果变量对应**硬件寄存器** → 加volatile- 如果变量被**多个任务**共享 → 可能需要volatile简单理解就是**当变量的值可能在意想不到的时候被改变就用volatile**应用常见的延时函数错误写法void delay(int count) { while (count--) { // 空循环 } } // 调用 delay(1000000); // 想延时一会儿目录1.stm32常用外设first :GPIO 控制高低电平 读取引脚的电平/电压secend : 通信接口2.volatile应用常见的延时函数问题编译器看到count--啥也没干可能直接把这个循环优化没了我看了一下 关键在于 while(count--){这里面是空的}建议使用3.寄存器什么是寄存器寄存器设置以LED灯为例实现SOS闪烁1.delay函数不是毫秒单位我的SOS代码#include stdint.h// ¼Ä´æÆ÷¶¨Òå#define RCC_APB2ENR (*(volatile uint32_t *)0x40021018)#define GPIOE_CRL (*(volatile uint32_t *)0x40011800)#define GPIOE_BSRR (*(volatile uint32_t *)0x40011810)#define LED1_PIN 4#define LED2_PIN 3#define DELAY_SHORT 1000000 // ????#define DELAY_LONG 3000000 // ????#define DELAY_GAP 500000 // ???#define DELAY_LETTER 1500000 // ????#define DELAY_CYCLE 3000000 // ????void delay(volatile uint32_t n) {while(n--);}// delay functionvoid LED_Init(void) {RCC_APB2ENR | (1 6);// RCC timerGPIOE_CRL ~(0xFF 12);GPIOE_CRL | (0x33 12);}void LED1_On(void) { GPIOE_BSRR (1 (LED1_PIN 16)); }void LED1_Off(void) { GPIOE_BSRR (1 LED1_PIN); }void LED2_On(void) { GPIOE_BSRR (1 (LED2_PIN 16)); }void LED2_Off(void) { GPIOE_BSRR (1 LED2_PIN); }void letter_s(void) {for(int i 0; i 3; i) {LED1_On();LED2_On();delay(DELAY_SHORT);LED1_Off();LED2_Off();delay(DELAY_GAP);}}void letter_l(void) {for(int i 0; i 3; i) {LED1_On();LED2_On();delay(DELAY_LONG);LED1_Off();LED2_Off();delay(DELAY_GAP);}}int main(void) {// SystemInit()ÒѾ­ÔÚÆô¶¯ÎļþÖе÷ÓùýÁËLED_Init();while(1) {letter_s();letter_l();letter_s();delay(6000000 );//间隔咱也不知道是几秒反正挺长的}}void SystemInit(void){}一.引言上一节中我说到了SOS函数 但是是使用寄存器操作 这样有一个致命缺点于是我使用库函数此为打开时钟二.需要准备的东西————————————————版权声明本文为CSDN博主「2402_86559504」的原创文章遵循CC 4.0 BY-SA版权协议转载请附上原文出处链接及本声明。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价