当前位置: 首页 > news >正文

STM32串口双机模拟汽车电量里程项目:Protues仿真与源码解析

STM32单片机开发的串口双机模拟汽车电量里程项目,两个STM32单片机进行数据交互,模拟主控与驱动传感器发送数据,可以手动调节数据,并显示屏显示出来。 包括程序源码和protues仿真8.12版本。 程序源码注释详细。 非常适合开发人员,需要可以看下。

最近做了个超有趣的项目——基于STM32单片机开发的串口双机模拟汽车电量里程项目。在这个项目里,两个STM32单片机之间会进行数据交互,模拟主控与驱动传感器发送数据,而且还能手动调节数据,并通过显示屏显示出来。下面就跟大家详细唠唠。

一、项目原理

我们的项目核心在于两个STM32单片机的串口通信。其中一个单片机模拟主控,负责收集数据并发送给另一个模拟驱动传感器的单片机。同时,我们可以通过按键等方式手动调节电量和里程数据,再通过显示屏直观地呈现出来。

二、Protues仿真(8.12版本)

  1. 搭建电路
    - 首先在Protues中放置两个STM32F103C8T6单片机,这是我们常用的型号,资源丰富且容易上手。
    - 连接串口通信电路,将一个单片机的TX引脚连接到另一个单片机的RX引脚,反之亦然,这样就搭建好了串口通信的物理链路。
    - 添加按键用于手动调节数据,这里我们可以使用普通的轻触按键,一端接地,另一端连接到单片机的GPIO口。
    - 显示屏选择LCD1602,它能很好地满足我们显示简单数据的需求。按照引脚定义连接到单片机的GPIO口,注意电源和对比度调节引脚的连接。
  2. 仿真设置

在完成电路搭建后,我们需要对单片机进行设置,加载编译好的hex文件,就能开始仿真啦,观察各个数据的变化和显示情况。

三、程序源码及分析

主控单片机代码

#include "stm32f10x.h" // 定义按键和LCD相关GPIO口 #define KEY_GPIO_PORT GPIOC #define KEY_GPIO_CLK RCC_APB2Periph_GPIOC #define KEY1_PIN GPIO_Pin_0 // LCD相关定义省略 void USART_Config(void) { USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; // 使能串口和GPIO时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); // 配置PA9(TX)为复用推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置PA10(RX)为浮空输入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); // 串口基本配置 USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); // 使能串口 USART_Cmd(USART1, ENABLE); } void KEY_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; // 使能按键GPIO时钟 RCC_APB2PeriphClockCmd(KEY_GPIO_CLK, ENABLE); // 配置按键引脚为浮空输入 GPIO_InitStructure.GPIO_Pin = KEY1_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(KEY_GPIO_PORT, &GPIO_InitStructure); } int main(void) { uint16_t mileage = 0; uint8_t power = 100; USART_Config(); KEY_Config(); // LCD初始化省略 while (1) { if (GPIO_ReadInputDataBit(KEY_GPIO_PORT, KEY1_PIN) == 0) { // 按键按下,调节里程 mileage += 10; while (GPIO_ReadInputDataBit(KEY_GPIO_PORT, KEY1_PIN) == 0); } // 手动调节电量代码省略 // 将数据发送给从机 char data[10]; sprintf(data, "%d,%d", mileage, power); for (int i = 0; i < strlen(data); i++) { while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET); USART_SendData(USART1, data[i]); } // LCD显示数据省略 } }

在这段代码里,USARTConfig函数负责串口的初始化设置,包括波特率、数据位、停止位等关键参数。KEYConfig函数配置按键引脚。在main函数中,我们初始化了串口和按键,通过按键调节里程数据,再将里程和电量数据打包成字符串通过串口发送出去。

从机单片机代码

#include "stm32f10x.h" // LCD相关定义省略 void USART_Config(void) { USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; // 使能串口和GPIO时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE); // 配置PA9(TX)为复用推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置PA10(RX)为浮空输入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); // 串口基本配置 USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART1, &USART_InitStructure); // 使能串口 USART_Cmd(USART1, ENABLE); } int main(void) { uint16_t mileage = 0; uint8_t power = 0; char data[10]; uint8_t index = 0; USART_Config(); // LCD初始化省略 while (1) { if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE)!= RESET) { char temp = USART_ReceiveData(USART1); if (temp!= '\0') { data[index++] = temp; } if (temp == '\n') { data[index] = '\0'; sscanf(data, "%d,%d", &mileage, &power); index = 0; } } // LCD显示接收到的数据省略 } }

从机代码的USART_Config函数和主机类似,负责串口初始化。在main函数中,不断检测串口接收中断,一旦接收到数据,就将数据存储起来,当接收到换行符时,解析出里程和电量数据,并在LCD上显示。

STM32单片机开发的串口双机模拟汽车电量里程项目,两个STM32单片机进行数据交互,模拟主控与驱动传感器发送数据,可以手动调节数据,并显示屏显示出来。 包括程序源码和protues仿真8.12版本。 程序源码注释详细。 非常适合开发人员,需要可以看下。

这个项目对于开发人员来说,无论是在串口通信,还是GPIO控制以及数据处理方面,都能积累不少经验,感兴趣的小伙伴不妨动手试试。

http://www.jsqmd.com/news/473708/

相关文章:

  • 无人零售/五金厂必看!边缘设备Java+YOLOv11推理稳定性全攻略:崩溃率从15%降到0.1%,断点续检1秒恢复
  • ThinkPHP反序列化漏洞深度解析:CacheStore组件为何成为攻击入口?
  • 探索Matlab在两相流动相场法与自适应网格中的应用
  • MATLAB代码:基于多能互补的热电联供型微网优化运行 关键词:多能互补 综合需求响应 热电联...
  • 微电网二次控制:下垂控制与基于数据采样二次控制的奇妙融合
  • 运用stata对CFPS数据库进行打开清洗和处理,以政府转移支付为例
  • 基于PDR算法的室内定位应用:运用行人轨迹推算算法实现连续定位,并优化轨迹采用卡尔曼滤波及无痕...
  • Screeps Arena 实战编程:从零构建你的RTS对战AI
  • 油藏数值模拟中的两相流动 IMPES 方法及 Matlab 实现
  • VSCODE离线环境也能玩转AI编程?手把手教你用CodeGPT插件本地跑大模型
  • 从实验室到开源社区:Scloud+后量子密码算法如何借力openHiTLS加速产业化
  • 提示词工程:这样跟AI说话,它才听你的!
  • 大模型(2):大模型推理文本分类
  • Passmark计算机系统测试工具全解析:从压力测试到性能评分
  • OAuth2.0中state参数的深度应用:业务数据的安全传输与防CSRF实践
  • 新年限定零食礼包推荐:生肖款与新品礼盒,哪一种更能代表节庆氛围? - Top品牌推荐官
  • 优化电动汽车充放电策略实现削峰填谷:一种面向多目标的Matlab调度算法
  • 如果 Canal 跑得比 MySQL 主从同步还快,脏数据怎么防?
  • CentOS7下DuckDB JDBC驱动兼容性构建实战:绕过GLIBC版本限制的三种方案
  • JavaDay07包机制及JavaDoc生成文档
  • Android 休眠机制详解 ——WakeLock、Doze 模式与待机功耗优化实战
  • 5种一维数据转图像的黑科技:GAFS/MTF/递归图实战对比(附Python代码)
  • uni-id-pages配置email
  • Mesa图形栈实战:从GLSL到NIR的完整编译链接流程解析
  • 【java】Queue(队列)接口详解
  • HTML5游戏革命:Facebook Instant Game如何重塑社交娱乐体验
  • 内存马二:Filter
  • ESP32-C3驱动4*4矩阵键盘与OLED显示屏的交互实现
  • Stable Diffusion Anything V5保姆级教程:从部署到生成第一张二次元图
  • 从生肖款918g大礼袋到新品礼盒装,新年限定零食礼包推荐怎么选更稳 - Top品牌推荐官