提交工程,小程序源码已完成,单片机待完成

This commit is contained in:
2026-02-10 20:21:41 +08:00
commit fd55a14b62
3778 changed files with 1062672 additions and 0 deletions

View File

@@ -0,0 +1,322 @@
# DX-WF-24 WiFi 模块驱动使用说明
## 目录
1. [概述](#概述)
2. [文件结构](#文件结构)
3. [API 参考](#api-参考)
4. [使用示例](#使用示例)
5. [注意事项](#注意事项)
---
## 概述
本驱动用于 STM32F103 与 DX-WF-24 WiFi 模块的串口通信,基于 HAL 库实现,支持:
- **DMA 发送** - 非阻塞式数据发送
- **DMA + 空闲中断接收** - 自动帧识别接收
- **同步应答检测** - AT 指令交互
---
## 文件结构
```
BSP_WF_24/
├── dx_wf_24.h # 头文件(配置和声明)
└── dx_wf_24.c # 实现文件
```
---
## API 参考
### 1. 初始化函数
#### `WIFI_RECV_DMA_Init()`
```c
HAL_StatusTypeDef WIFI_RECV_DMA_Init(void);
```
- **功能**:初始化 WiFi DMA 接收(空闲中断方式)
- **调用时机**main() 中,在 MX_USART1_UART_Init() 之后调用
- **返回值**HAL_OK 表示成功
---
### 2. 数据发送
#### `WIFI_SEND_DMA()`
```c
HAL_StatusTypeDef WIFI_SEND_DMA(const char *data);
```
- **功能**:通过 DMA 发送字符串(非阻塞)
- **参数**`data` - 要发送的字符串
- **返回值**
- `HAL_OK` - 发送成功启动
- `HAL_BUSY` - 上一次发送未完成
- `HAL_ERROR` - 参数错误或发送失败
---
### 3. 数据接收
#### `WIFI_Get_Received_Data()`
```c
int WIFI_Get_Received_Data(uint8_t *buffer, uint16_t len);
```
- **功能**:获取接收到的数据
- **参数**
- `buffer` - 输出缓冲区
- `len` - 缓冲区大小
- **返回值**实际复制的数据长度0 表示无数据
---
### 4. 应答检测(新增)
#### `WIFI_CheckAck()`
```c
uint8_t WIFI_CheckAck(const char *cmd, const char *expect, uint32_t timeout_ms);
```
- **功能**:发送 AT 指令并检测应答
- **参数**
- `cmd` - 要发送的 AT 指令(如 "AT\r\n"
- `expect` - 期望的应答字符串(如 "OK"
- `timeout_ms` - 超时时间(毫秒)
- **返回值**
- `1` - 收到期望应答
- `0` - 超时或收到 ERROR
### 5. MQTT连接支持认证
#### `WIFI_Connect_MQTT()`
```c
uint8_t WIFI_Connect_MQTT(const char *wifi_ssid, const char *wifi_pass,
const char *mqtt_broker, uint16_t mqtt_port,
const char *client_id, const char *mqtt_user,
const char *mqtt_pass, const char *sub_topic);
```
- **功能**完整MQTT连接流程WiFi+MQTT
- **参数**
- `wifi_ssid` - WiFi名称
- `wifi_pass` - WiFi密码
- `mqtt_broker` - MQTT服务器地址
- `mqtt_port` - MQTT端口通常为1883
- `client_id` - MQTT客户端ID需唯一
- `mqtt_user` - MQTT用户名传NULL表示无需认证
- `mqtt_pass` - MQTT密码传NULL表示无需认证
- `sub_topic` - 订阅的主题
- **返回值**
- `1` - 连接成功
- `0` - 连接失败
- **连接步骤**
1. 清理MQTT环境
2. AT指令测试
3. 设置STA模式
4. 连接WiFi带重试
5. 配置MQTT参数包括认证信息
6. 连接MQTT服务器带重试
7. 订阅主题
8. 发布上线消息
---
## 使用示例
### 示例1基础初始化
```c
#include "dx_wf_24.h"
void System_Init(void)
{
// HAL 初始化...
MX_USART1_UART_Init();
// 初始化 WiFi DMA 接收
if (WIFI_RECV_DMA_Init() != HAL_OK) {
elog_e("MAIN", "WiFi init failed!");
}
}
```
### 示例2发送数据
```c
// 发送 AT 指令测试
void WiFi_Test(void)
{
HAL_StatusTypeDef status = WIFI_SEND_DMA("AT\r\n");
if (status == HAL_OK) {
elog_i("WIFI", "Command sent");
} else if (status == HAL_BUSY) {
elog_w("WIFI", "WiFi busy, try later");
}
}
```
### 示例3检测模块就绪
```c
// 初始化时检测 WiFi 模块
uint8_t WiFi_Init_Check(void)
{
// 发送 AT期望收到 OK超时 1 秒
if (WIFI_CheckAck("AT\r\n", "OK", 1000)) {
elog_i("WIFI", "Module ready");
return 1;
} else {
elog_e("WIFI", "Module not responding");
return 0;
}
}
```
### 示例4完整的 MQTT 连接(支持认证)
```c
// 连接到 MQTT 服务器(无需认证)
void Connect_MQTT_Public(void)
{
uint8_t success = WIFI_Connect_MQTT(
"MyWiFi", // WiFi名称
"12345678", // WiFi密码
"broker.emqx.io", // MQTT服务器公共测试服务器
1883, // MQTT端口
"PetFeeder-001", // 客户端ID需唯一
NULL, // MQTT用户名NULL表示无需认证
NULL, // MQTT密码NULL表示无需认证
"pet/control" // 订阅主题
);
if (success) {
elog_i("MQTT", "Connected to public MQTT server");
} else {
elog_e("MQTT", "Connection failed");
}
}
// 连接到 MQTT 服务器(需要用户名密码认证)
void Connect_MQTT_Private(void)
{
uint8_t success = WIFI_Connect_MQTT(
"MyWiFi", // WiFi名称
"12345678", // WiFi密码
"mqtt.myserver.com", // 私有MQTT服务器
1883, // MQTT端口
"PetFeeder-001", // 客户端ID
"myusername", // MQTT用户名
"mypassword", // MQTT密码
"pet/control" // 订阅主题
);
if (success) {
elog_i("MQTT", "Connected to private MQTT server");
} else {
elog_e("MQTT", "Connection failed");
}
}
### 示例5异步接收处理
```c
// 在任务循环中处理接收数据
void WiFi_Task(void)
{
uint8_t buffer[512];
int len;
while (1) {
// 检查是否有新数据
len = WIFI_Get_Received_Data(buffer, sizeof(buffer));
if (len > 0) {
// 处理接收到的数据
elog_i("WIFI", "Received: %s", buffer);
// 根据内容做不同处理...
if (strstr((char*)buffer, "+IPD")) {
// 收到网络数据
Process_Network_Data(buffer);
}
}
osDelay(10); // 10ms 轮询
}
}
```
---
## 注意事项
### 1. 中断配置
确保 `stm32f1xx_it.c` 中已添加空闲中断处理:
```c
void USART1_IRQHandler(void)
{
// 检查空闲中断
if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)) {
WIFI_UART_IDLE_Callback(&huart1);
}
HAL_UART_IRQHandler(&huart1);
}
```
### 2. DMA 配置
`main.c``MX_USART1_UART_Init()` 中确保启用了 DMA
- USART1_TX: DMA 模式
- USART1_RX: DMA 循环模式
### 3. 缓冲区大小
默认接收缓冲区为 512 字节,可在 `dx_wf_24.h` 中修改:
```c
#define WIFI_RX_BUF_SIZE 512
```
### 4. MQTT 用户名密码认证
- 公共MQTT服务器如 broker.emqx.io通常不需要认证`NULL` 即可
- 私有MQTT服务器需要用户名和密码传入对应字符串
- 确保 MQTT 服务器已开启用户名密码认证功能
### 5. 超时处理
`WIFI_CheckAck()` 是阻塞函数,不适合在中断或高优先级任务中调用。
### 6. 多线程安全
当前实现未加互斥锁,如果在多任务环境中同时调用发送/接收,需要额外保护。
---
## 常见问题
| 问题 | 可能原因 | 解决方法 |
|------|----------|----------|
| 收不到数据 | 空闲中断未启用 | 检查 `WIFI_RECV_DMA_Init()` 返回值 |
| 数据截断 | 缓冲区太小 | 增大 `WIFI_RX_BUF_SIZE` |
| 发送失败 | DMA 忙 | 检查返回值,稍后重试 |
| 检测超时 | 波特率不匹配 | 确认模块波特率(默认 115200|
---
## 版本历史
| 版本 | 日期 | 说明 |
|------|------|------|
| 1.0 | 2026-02-09 | 初始版本,基础 DMA 收发 |
| 1.1 | 2026-02-09 | 新增 `WIFI_CheckAck()` 同步应答检测 |
| 1.2 | 2026-02-09 | 新增 `WIFI_Connect_MQTT()` 支持用户名密码认证 |
---
## 联系方式
如有问题,请参考 DX-WF-24 模块 AT 指令手册。

View File

@@ -0,0 +1,370 @@
#include "dx_wf_24.h"
#include "elog.h"
#include <string.h>
#include "cmsis_os.h"
#include "stdio.h"
/* 发送缓冲区 */
#define WIFI_TX_BUF_SIZE 512
static uint8_t wifi_tx_buffer[WIFI_TX_BUF_SIZE];
static volatile uint8_t wifi_tx_busy = 0;
/* WiFi 全局结构体 */
WIFI_HandleTypeDef wifi = {0};
/* 日志标签 */
#define TAG "WIFI"
/**
* @brief 初始化 WiFi DMA 接收(空闲中断方式)
* @retval HAL_StatusTypeDef
* @note 在 main 中调用此函数初始化
*/
HAL_StatusTypeDef WIFI_RECV_DMA_Init(void) {
/* 清空缓冲区 */
memset(&wifi, 0, sizeof(wifi));
/* 停止可能正在进行的 DMA */
HAL_UART_DMAStop(&huart1);
/* 启动 DMA 接收(环形缓冲区模式) */
HAL_StatusTypeDef status = HAL_UART_Receive_DMA(&huart1, wifi.rx_buffer, WIFI_RX_BUF_SIZE);
if (status == HAL_OK) {
/* 启用空闲中断 - 关键! */
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
elog_i(TAG, "WiFi DMA RX init OK");
} else {
elog_e(TAG, "WiFi DMA RX init failed: %d", status);
}
return status;
}
/**
* @brief 串口空闲中断回调(在 USART1_IRQHandler 中调用)
* @param huart 串口句柄
* @note 当串口空闲时触发,表示一帧数据接收完成
*/
void WIFI_UART_IDLE_Callback(UART_HandleTypeDef *huart) {
if (huart->Instance != USART1) {
return;
}
/* 清除 IDLE 标志(必须先读 SR 再读 DR */
__HAL_UART_CLEAR_IDLEFLAG(huart);
/* 停止 DMA 传输,获取已接收数据长度 */
HAL_UART_DMAStop(huart);
/* 计算本次接收的数据长度 */
uint16_t recv_len = WIFI_RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(huart->hdmarx);
if (recv_len > 0 && recv_len < WIFI_RX_BUF_SIZE) {
wifi.rx_len = recv_len;
wifi.rx_buffer[recv_len] = '\0'; // 添加字符串结束符
wifi.rx_flag = 1; // 标记接收完成
elog_d(TAG, "RX[%d]: %s", recv_len, wifi.rx_buffer);
}
/* 重新启动 DMA 接收 */
HAL_UART_Receive_DMA(&huart1, wifi.rx_buffer, WIFI_RX_BUF_SIZE);
}
/**
* @brief 获取接收到的数据
* @param buffer 输出缓冲区
* @param len 缓冲区大小
* @retval int 实际复制长度0表示无数据
*/
int WIFI_Get_Received_Data(uint8_t *buffer, uint16_t len) {
if (!wifi.rx_flag || buffer == NULL || len == 0) {
return 0;
}
uint16_t copy_len = (wifi.rx_len < len) ? wifi.rx_len : (len - 1);
memcpy(buffer, wifi.rx_buffer, copy_len);
buffer[copy_len] = '\0';
wifi.rx_flag = 0; // 清除标志
return copy_len;
}
/**
* @brief 通过 DMA 发送 WiFi 数据(非阻塞)
* @param data 要发送的字符串
* @retval HAL_StatusTypeDef 发送状态
*/
HAL_StatusTypeDef WIFI_SEND_DMA(const char *data) {
if (data == NULL) {
return HAL_ERROR;
}
size_t len = strlen(data);
if (len == 0) {
return HAL_OK;
}
if (len >= WIFI_TX_BUF_SIZE) {
elog_w(TAG, "TX data too long: %d", len);
return HAL_ERROR;
}
if (wifi_tx_busy) {
return HAL_BUSY;
}
memcpy(wifi_tx_buffer, data, len);
wifi_tx_busy = 1;
HAL_StatusTypeDef status = HAL_UART_Transmit_DMA(&huart1, wifi_tx_buffer, len);
if (status != HAL_OK) {
wifi_tx_busy = 0;
elog_e(TAG, "TX DMA failed: %d", status);
}
return status;
}
/* DMA 发送完成回调 */
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART1) {
wifi_tx_busy = 0;
elog_d(TAG, "TX complete");
}
}
/* DMA 接收完成回调(半传输/全传输) */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART1) {
/* 缓冲区满,标记接收完成 */
wifi.rx_len = WIFI_RX_BUF_SIZE;
wifi.rx_flag = 1;
elog_w(TAG, "RX buffer full!");
}
}
/**
* @brief 检测 WiFi 应答(同步阻塞式)
* @param cmd 要发送的 AT 指令
* @param expect 期望的应答字符串(如 "OK", "READY"
* @param timeout_ms 超时时间(毫秒)
* @retval 1-收到期望应答, 0-超时或失败
* @note 此函数会阻塞等待应答,建议在初始化阶段使用
* @warning 如果在 FreeRTOS 中使用,确保 configUSE_PREEMPTION 已启用
*
* @example
* // 检测模块是否就绪
* if (WIFI_CheckAck("AT\r\n", "OK", 1000)) {
* elog_i(TAG, "WiFi module ready");
* }
*/
uint8_t WIFI_CheckAck(const char *cmd, const char *expect, uint32_t timeout_ms)
{
char recv_buf[WIFI_RX_BUF_SIZE];
if (cmd == NULL || expect == NULL) {
elog_e(TAG, "Invalid parameters");
return 0;
}
// 清空之前的接收标志
wifi.rx_flag = 0;
// 发送指令
HAL_StatusTypeDef status = WIFI_SEND_DMA(cmd);
if (status != HAL_OK) {
elog_e(TAG, "Send failed: %d", status);
return 0;
}
elog_d(TAG, "Wait for: %s", expect);
// 等待应答(轮询方式)
uint32_t start_tick = HAL_GetTick();
while ((HAL_GetTick() - start_tick) < timeout_ms) {
// 检查是否接收到数据
if (wifi.rx_flag) {
// 获取数据并清零标志
int len = WIFI_Get_Received_Data((uint8_t *)recv_buf, sizeof(recv_buf));
if (len > 0) {
elog_d(TAG, "Recv: %s", recv_buf);
// 检查是否包含期望应答
if (strstr(recv_buf, expect) != NULL) {
elog_i(TAG, "Ack matched: %s", expect);
return 1;
}
// 检查是否包含错误应答
if (strstr(recv_buf, "ERROR") != NULL) {
elog_w(TAG, "Got ERROR response");
return 0;
}
}
}
// 小延时,避免忙等
HAL_Delay(1);
}
elog_w(TAG, "Ack timeout, expect: %s", expect);
return 0;
}
/**
* @brief 连接MQTT服务器完整流程支持用户名密码认证
* @param wifi_ssid WiFi名称
* @param wifi_pass WiFi密码
* @param mqtt_broker MQTT服务器地址
* @param mqtt_port MQTT端口
* @param client_id MQTT客户端ID
* @param mqtt_user MQTT用户名可为NULL表示不需要认证
* @param mqtt_pass MQTT密码可为NULL表示不需要认证
* @param sub_topic 订阅的主题
* @retval 1-连接成功, 0-失败
* @note 每一步都有重试机制,失败后不会卡死
*
* @example
* // 连接到MQTT服务器无需认证
* if (WIFI_Connect_MQTT("MyWiFi", "12345678",
* "broker.emqx.io", 1883,
* "PetFeeder-001", NULL, NULL, "pet/control")) {
* elog_i(TAG, "MQTT connected");
* }
*
* // 连接到MQTT服务器需要认证
* if (WIFI_Connect_MQTT("MyWiFi", "12345678",
* "broker.emqx.io", 1883,
* "PetFeeder-001", "user1", "pass123", "pet/control")) {
* elog_i(TAG, "MQTT connected");
* }
*/
uint8_t WIFI_Connect_MQTT(const char *wifi_ssid, const char *wifi_pass,
const char *mqtt_broker, uint16_t mqtt_port,
const char *client_id, const char *mqtt_user,
const char *mqtt_pass, const char *sub_topic)
{
char cmd_buf[128];
uint8_t retry_count = 0;
const uint8_t max_retry = 3;
elog_i(TAG, "=== Starting MQTT Connection ===");
/* 步骤1: 清理环境 */
elog_d(TAG, "Step 1: Clean MQTT environment");
if (!WIFI_CheckAck("AT+MQTTCLEAN\r\n", "OK", 2000)) {
elog_w(TAG, "MQTTCLEAN failed, continue...");
}
/* 步骤2: 恢复出厂设置(可选,根据需要启用) */
// elog_d(TAG, "Step 2: Restore factory settings");
// if (!WIFI_CheckAck("AT+RESTORE\r\n", "OK", 5000)) {
// elog_w(TAG, "RESTORE failed, continue...");
// }
// osDelay(3000); // 等待模块重启
/* 步骤3: AT测试 */
elog_d(TAG, "Step 3: AT test");
retry_count = 0;
while (retry_count < max_retry) {
if (WIFI_CheckAck("AT\r\n", "OK", 1000)) {
break;
}
retry_count++;
elog_w(TAG, "AT test retry %d/%d", retry_count, max_retry);
osDelay(500);
}
if (retry_count >= max_retry) {
elog_e(TAG, "AT test failed");
return 0;
}
/* 步骤4: 设置STA模式 */
elog_d(TAG, "Step 4: Set STA mode");
if (!WIFI_CheckAck("AT+CWMODE=1\r\n", "OK", 2000)) {
elog_e(TAG, "Set STA mode failed");
return 0;
}
/* 步骤5: 连接WiFi */
elog_d(TAG, "Step 5: Connect to WiFi: %s", wifi_ssid);
snprintf(cmd_buf, sizeof(cmd_buf), "AT+CWJAP=\"%s\",\"%s\"\r\n", wifi_ssid, wifi_pass);
retry_count = 0;
while (retry_count < max_retry) {
if (WIFI_CheckAck(cmd_buf, "WIFI GOT IP", 10000)) {
elog_i(TAG, "WiFi connected successfully");
break;
}
retry_count++;
elog_w(TAG, "WiFi connect retry %d/%d", retry_count, max_retry);
osDelay(2000);
}
if (retry_count >= max_retry) {
elog_e(TAG, "WiFi connect failed");
return 0;
}
/* 步骤6: 配置MQTT用户参数用户名和密码 */
if (mqtt_user != NULL && mqtt_pass != NULL) {
elog_d(TAG, "Step 6: Configure MQTT user authentication");
// 配置MQTT用户参数LinkID=0, scheme=1, client_id, username, password
snprintf(cmd_buf, sizeof(cmd_buf), "AT+MQTTUSERCFG=0,1,\"%s\",\"%s\",\"%s\",0,0,\"\"\r\n",
client_id, mqtt_user, mqtt_pass);
if (!WIFI_CheckAck(cmd_buf, "OK", 3000)) {
elog_e(TAG, "MQTT user configuration failed");
return 0;
}
} else {
elog_d(TAG, "Step 6: Configure MQTT without authentication");
// 无认证模式
snprintf(cmd_buf, sizeof(cmd_buf), "AT+MQTTUSERCFG=0,1,\"%s\",\"\",\"\",0,0,\"\"\r\n", client_id);
if (!WIFI_CheckAck(cmd_buf, "OK", 3000)) {
elog_e(TAG, "MQTT configuration failed");
return 0;
}
}
/* 步骤7: 连接MQTT服务器 */
elog_d(TAG, "Step 7: Connect to MQTT broker: %s:%d", mqtt_broker, mqtt_port);
snprintf(cmd_buf, sizeof(cmd_buf), "AT+MQTTCONN=0,\"%s\",%d,0\r\n", mqtt_broker, mqtt_port);
retry_count = 0;
while (retry_count < max_retry) {
if (WIFI_CheckAck(cmd_buf, "MQTTCONNECTED:", 5000)) {
elog_i(TAG, "MQTT broker connected");
break;
}
retry_count++;
elog_w(TAG, "MQTT connect retry %d/%d", retry_count, max_retry);
osDelay(1000);
}
if (retry_count >= max_retry) {
elog_e(TAG, "MQTT connect failed");
return 0;
}
/* 步骤8: 订阅主题 */
elog_d(TAG, "Step 8: Subscribe topic: %s", sub_topic);
snprintf(cmd_buf, sizeof(cmd_buf), "AT+MQTTSUB=0,\"%s\",0\r\n", sub_topic);
if (!WIFI_CheckAck(cmd_buf, "OK", 3000)) {
elog_e(TAG, "Subscribe failed");
return 0;
}
/* 步骤9: 发布上线消息 */
elog_d(TAG, "Step 9: Publish online message");
const char *online_topic = "device/online";
const char *online_msg = "{\"device\":\"PetFeeder\",\"status\":\"online\"}";
snprintf(cmd_buf, sizeof(cmd_buf), "AT+MQTTPUB=0,\"%s\",\"%s\",0,0\r\n", online_topic, online_msg);
if (!WIFI_CheckAck(cmd_buf, "OK", 2000)) {
elog_w(TAG, "Publish online message failed, continue...");
}
elog_i(TAG, "=== MQTT Connection Completed Successfully ===");
return 1;
}

View File

@@ -0,0 +1,37 @@
#ifndef __DX_WF_24_H__
#define __DX_WF_24_H__
#include "usart.h"
#include <stdint.h>
/* 默认超时时间(毫秒) */
#define WIFI_DEFAULT_TIMEOUT 1000
/* WiFi 接收缓冲区大小 */
#define WIFI_RX_BUF_SIZE 512
/* WiFi 数据结构体 */
typedef struct {
uint8_t rx_buffer[WIFI_RX_BUF_SIZE]; // 接收缓冲区
uint16_t rx_len; // 本次接收长度
uint8_t rx_flag; // 接收完成标志
} WIFI_HandleTypeDef;
extern WIFI_HandleTypeDef wifi;
/* 函数声明 */
HAL_StatusTypeDef WIFI_SEND_DMA(const char *data);
HAL_StatusTypeDef WIFI_RECV_DMA_Init(void);
void WIFI_UART_IDLE_Callback(UART_HandleTypeDef *huart);
int WIFI_Get_Received_Data(uint8_t *buffer, uint16_t len);
/* 同步应答检测函数 */
uint8_t WIFI_CheckAck(const char *cmd, const char *expect, uint32_t timeout_ms);
/* MQTT连接函数 */
uint8_t WIFI_Connect_MQTT(const char *wifi_ssid, const char *wifi_pass,
const char *mqtt_broker, uint16_t mqtt_port,
const char *client_id, const char *mqtt_user,
const char *mqtt_pass, const char *sub_topic);
#endif /* __DX_WF_24_H__ */

View File

@@ -0,0 +1,272 @@
//
// Created by wangb on 25-6-4.
//
#ifndef ELOG_H
#define ELOG_H
#include "elog_cfg.h"
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/* output log's level */
#define ELOG_LVL_ASSERT 0
#define ELOG_LVL_ERROR 1
#define ELOG_LVL_WARN 2
#define ELOG_LVL_INFO 3
#define ELOG_LVL_DEBUG 4
#define ELOG_LVL_VERBOSE 5
/* the output silent level and all level for filter setting */
#define ELOG_FILTER_LVL_SILENT ELOG_LVL_ASSERT
#define ELOG_FILTER_LVL_ALL ELOG_LVL_VERBOSE
/* output log's level total number */
#define ELOG_LVL_TOTAL_NUM 6
/* EasyLogger software version number */
#define ELOG_SW_VERSION "2.2.99"
/* EasyLogger assert for developer. */
#ifdef ELOG_ASSERT_ENABLE
#define ELOG_ASSERT(EXPR) \
if (!(EXPR)) \
{ \
if (elog_assert_hook == NULL) { \
elog_a("elog", "(%s) has assert failed at %s:%ld.", #EXPR, __FUNCTION__, __LINE__); \
while (1); \
} else { \
elog_assert_hook(#EXPR, __FUNCTION__, __LINE__); \
} \
}
#else
#define ELOG_ASSERT(EXPR) ((void)0);
#endif
#ifndef ELOG_OUTPUT_ENABLE
#define elog_raw(...)
#define elog_assert(tag, ...)
#define elog_error(tag, ...)
#define elog_warn(tag, ...)
#define elog_info(tag, ...)
#define elog_debug(tag, ...)
#define elog_verbose(tag, ...)
#else /* ELOG_OUTPUT_ENABLE */
#ifdef ELOG_FMT_USING_FUNC
#define ELOG_OUTPUT_FUNC __FUNCTION__
#else
#define ELOG_OUTPUT_FUNC NULL
#endif
#ifdef ELOG_FMT_USING_DIR
#define ELOG_OUTPUT_DIR __FILE__
#else
#define ELOG_OUTPUT_DIR NULL
#endif
#ifdef ELOG_FMT_USING_LINE
#define ELOG_OUTPUT_LINE __LINE__
#else
#define ELOG_OUTPUT_LINE 0
#endif
#define elog_raw(...) elog_raw_output(__VA_ARGS__)
#if ELOG_OUTPUT_LVL >= ELOG_LVL_ASSERT
#define elog_assert(tag, ...) \
elog_output(ELOG_LVL_ASSERT, tag, ELOG_OUTPUT_DIR, ELOG_OUTPUT_FUNC, ELOG_OUTPUT_LINE, __VA_ARGS__)
#else
#define elog_assert(tag, ...)
#endif /* ELOG_OUTPUT_LVL >= ELOG_LVL_ASSERT */
#if ELOG_OUTPUT_LVL >= ELOG_LVL_ERROR
#define elog_error(tag, ...) \
elog_output(ELOG_LVL_ERROR, tag, ELOG_OUTPUT_DIR, ELOG_OUTPUT_FUNC, ELOG_OUTPUT_LINE, __VA_ARGS__)
#else
#define elog_error(tag, ...)
#endif /* ELOG_OUTPUT_LVL >= ELOG_LVL_ERROR */
#if ELOG_OUTPUT_LVL >= ELOG_LVL_WARN
#define elog_warn(tag, ...) \
elog_output(ELOG_LVL_WARN, tag, ELOG_OUTPUT_DIR, ELOG_OUTPUT_FUNC, ELOG_OUTPUT_LINE, __VA_ARGS__)
#else
#define elog_warn(tag, ...)
#endif /* ELOG_OUTPUT_LVL >= ELOG_LVL_WARN */
#if ELOG_OUTPUT_LVL >= ELOG_LVL_INFO
#define elog_info(tag, ...) \
elog_output(ELOG_LVL_INFO, tag, ELOG_OUTPUT_DIR, ELOG_OUTPUT_FUNC, ELOG_OUTPUT_LINE, __VA_ARGS__)
#else
#define elog_info(tag, ...)
#endif /* ELOG_OUTPUT_LVL >= ELOG_LVL_INFO */
#if ELOG_OUTPUT_LVL >= ELOG_LVL_DEBUG
#define elog_debug(tag, ...) \
elog_output(ELOG_LVL_DEBUG, tag, ELOG_OUTPUT_DIR, ELOG_OUTPUT_FUNC, ELOG_OUTPUT_LINE, __VA_ARGS__)
#else
#define elog_debug(tag, ...)
#endif /* ELOG_OUTPUT_LVL >= ELOG_LVL_DEBUG */
#if ELOG_OUTPUT_LVL == ELOG_LVL_VERBOSE
#define elog_verbose(tag, ...) \
elog_output(ELOG_LVL_VERBOSE, tag, ELOG_OUTPUT_DIR, ELOG_OUTPUT_FUNC, ELOG_OUTPUT_LINE, __VA_ARGS__)
#else
#define elog_verbose(tag, ...)
#endif /* ELOG_OUTPUT_LVL == ELOG_LVL_VERBOSE */
#endif /* ELOG_OUTPUT_ENABLE */
/* all formats index */
typedef enum {
ELOG_FMT_LVL = 1 << 0, /**< level */
ELOG_FMT_TAG = 1 << 1, /**< tag */
ELOG_FMT_TIME = 1 << 2, /**< current time */
ELOG_FMT_P_INFO = 1 << 3, /**< process info */
ELOG_FMT_T_INFO = 1 << 4, /**< thread info */
ELOG_FMT_DIR = 1 << 5, /**< file directory and name */
ELOG_FMT_FUNC = 1 << 6, /**< function name */
ELOG_FMT_LINE = 1 << 7, /**< line number */
} ElogFmtIndex;
/* macro definition for all formats */
#define ELOG_FMT_ALL (ELOG_FMT_LVL|ELOG_FMT_TAG|ELOG_FMT_TIME|ELOG_FMT_P_INFO|ELOG_FMT_T_INFO| \
ELOG_FMT_DIR|ELOG_FMT_FUNC|ELOG_FMT_LINE)
/* output log's tag filter */
typedef struct {
uint8_t level;
char tag[ELOG_FILTER_TAG_MAX_LEN + 1];
bool tag_use_flag; /**< false : tag is no used true: tag is used */
} ElogTagLvlFilter, *ElogTagLvlFilter_t;
/* output log's filter */
typedef struct {
uint8_t level;
char tag[ELOG_FILTER_TAG_MAX_LEN + 1];
char keyword[ELOG_FILTER_KW_MAX_LEN + 1];
ElogTagLvlFilter tag_lvl[ELOG_FILTER_TAG_LVL_MAX_NUM];
} ElogFilter, *ElogFilter_t;
/* easy logger */
typedef struct {
ElogFilter filter;
size_t enabled_fmt_set[ELOG_LVL_TOTAL_NUM];
bool init_ok;
bool output_enabled;
bool output_lock_enabled;
bool output_is_locked_before_enable;
bool output_is_locked_before_disable;
#ifdef ELOG_COLOR_ENABLE
bool text_color_enabled;
#endif
}EasyLogger, *EasyLogger_t;
/* EasyLogger error code */
typedef enum {
ELOG_NO_ERR,
} ElogErrCode;
/* elog.c */
ElogErrCode elog_init(void);
void elog_deinit(void);
void elog_start(void);
void elog_stop(void);
void elog_set_output_enabled(bool enabled);
bool elog_get_output_enabled(void);
void elog_set_text_color_enabled(bool enabled);
bool elog_get_text_color_enabled(void);
void elog_set_fmt(uint8_t level, size_t set);
void elog_set_filter(uint8_t level, const char *tag, const char *keyword);
void elog_set_filter_lvl(uint8_t level);
void elog_set_filter_tag(const char *tag);
void elog_set_filter_kw(const char *keyword);
void elog_set_filter_tag_lvl(const char *tag, uint8_t level);
uint8_t elog_get_filter_tag_lvl(const char *tag);
void elog_raw_output(const char *format, ...);
void elog_output(uint8_t level, const char *tag, const char *file, const char *func,
const long line, const char *format, ...);
void elog_output_lock_enabled(bool enabled);
extern void (*elog_assert_hook)(const char* expr, const char* func, size_t line);
void elog_assert_set_hook(void (*hook)(const char* expr, const char* func, size_t line));
int8_t elog_find_lvl(const char *log);
const char *elog_find_tag(const char *log, uint8_t lvl, size_t *tag_len);
void elog_hexdump(const char *name, uint8_t width, const void *buf, uint16_t size);
#define elog_a(tag, ...) elog_assert(tag, __VA_ARGS__)
#define elog_e(tag, ...) elog_error(tag, __VA_ARGS__)
#define elog_w(tag, ...) elog_warn(tag, __VA_ARGS__)
#define elog_i(tag, ...) elog_info(tag, __VA_ARGS__)
#define elog_d(tag, ...) elog_debug(tag, __VA_ARGS__)
#define elog_v(tag, ...) elog_verbose(tag, __VA_ARGS__)
/**
* log API short definition
* NOTE: The `LOG_TAG` and `LOG_LVL` must defined before including the <elog.h> when you want to use log_x API.
*/
#if !defined(LOG_TAG)
#define LOG_TAG "NO_TAG"
#endif
#if !defined(LOG_LVL)
#define LOG_LVL ELOG_LVL_VERBOSE
#endif
#if LOG_LVL >= ELOG_LVL_ASSERT
#define log_a(...) elog_a(LOG_TAG, __VA_ARGS__)
#else
#define log_a(...) ((void)0);
#endif
#if LOG_LVL >= ELOG_LVL_ERROR
#define log_e(...) elog_e(LOG_TAG, __VA_ARGS__)
#else
#define log_e(...) ((void)0);
#endif
#if LOG_LVL >= ELOG_LVL_WARN
#define log_w(...) elog_w(LOG_TAG, __VA_ARGS__)
#else
#define log_w(...) ((void)0);
#endif
#if LOG_LVL >= ELOG_LVL_INFO
#define log_i(...) elog_i(LOG_TAG, __VA_ARGS__)
#else
#define log_i(...) ((void)0);
#endif
#if LOG_LVL >= ELOG_LVL_DEBUG
#define log_d(...) elog_d(LOG_TAG, __VA_ARGS__)
#else
#define log_d(...) ((void)0);
#endif
#if LOG_LVL >= ELOG_LVL_VERBOSE
#define log_v(...) elog_v(LOG_TAG, __VA_ARGS__)
#else
#define log_v(...) ((void)0);
#endif
/* assert API short definition */
#if !defined(assert)
#define assert ELOG_ASSERT
#endif
/* elog_buf.c */
void elog_buf_enabled(bool enabled);
void elog_flush(void);
/* elog_async.c */
void elog_async_enabled(bool enabled);
size_t elog_async_get_log(char *log, size_t size);
size_t elog_async_get_line_log(char *log, size_t size);
/* elog_utils.c */
size_t elog_strcpy(size_t cur_len, char *dst, const char *src);
size_t elog_cpyln(char *line, const char *log, size_t len);
void *elog_memcpy(void *dst, const void *src, size_t count);
void easylogger_init(void);
#ifdef __cplusplus
}
#endif
#endif //ELOG_H

View File

@@ -0,0 +1,59 @@
//
// Created by wangb on 25-6-4.
//
#ifndef _ELOG_CFG_H_
#define _ELOG_CFG_H_
/*---------------------------------------------------------------------------*/
/* enable log output. */
#define ELOG_OUTPUT_ENABLE
/* setting static output log level. range: from ELOG_LVL_ASSERT to ELOG_LVL_VERBOSE */
#define ELOG_OUTPUT_LVL ELOG_LVL_VERBOSE
/* enable assert check */
#define ELOG_ASSERT_ENABLE
/* buffer size for every line's log */
#define ELOG_LINE_BUF_SIZE 1024
/* output line number max length */
#define ELOG_LINE_NUM_MAX_LEN 5
/* output filter's tag max length */
#define ELOG_FILTER_TAG_MAX_LEN 30
/* output filter's keyword max length */
#define ELOG_FILTER_KW_MAX_LEN 16
/* output filter's tag level max num */
#define ELOG_FILTER_TAG_LVL_MAX_NUM 5
/* output newline sign */
#define ELOG_NEWLINE_SIGN "\r\n" //换行
/*---------------------------------------------------------------------------*/
/* enable log color */
#define ELOG_COLOR_ENABLE
/* change the some level logs to not default color if you want */
#define ELOG_COLOR_ASSERT (F_MAGENTA B_NULL S_NORMAL)
#define ELOG_COLOR_ERROR (F_RED B_NULL S_NORMAL)
#define ELOG_COLOR_WARN (F_YELLOW B_NULL S_NORMAL)
#define ELOG_COLOR_INFO (F_CYAN B_NULL S_NORMAL)
#define ELOG_COLOR_DEBUG (F_GREEN B_NULL S_NORMAL)
#define ELOG_COLOR_VERBOSE (F_BLUE B_NULL S_NORMAL)
/*---------------------------------------------------------------------------*/
/* enable log fmt */
/* comment it if you don't want to output them at all */
#define ELOG_FMT_USING_FUNC
#define ELOG_FMT_USING_DIR
#define ELOG_FMT_USING_LINE
/*---------------------------------------------------------------------------*/
/* enable asynchronous output mode */
//#define ELOG_ASYNC_OUTPUT_ENABLE
/* the highest output level for async mode, other level will sync output */
#define ELOG_ASYNC_OUTPUT_LVL ELOG_LVL_ASSERT
/* buffer size for asynchronous output mode */
#define ELOG_ASYNC_OUTPUT_BUF_SIZE (ELOG_LINE_BUF_SIZE * 10)
/* each asynchronous output's log which must end with newline sign */
#define ELOG_ASYNC_LINE_OUTPUT
/* asynchronous output mode using POSIX pthread implementation */
#define ELOG_ASYNC_OUTPUT_USING_PTHREAD
/*---------------------------------------------------------------------------*/
/* enable buffered output mode */
//#define ELOG_BUF_OUTPUT_ENABLE
/* buffer size for buffered output mode */
#define ELOG_BUF_OUTPUT_BUF_SIZE (ELOG_LINE_BUF_SIZE * 10)
#endif /* _ELOG_CFG_H_ */

View File

@@ -0,0 +1,127 @@
//
// Created by wangb on 25-6-4.
//
#include "elog.h"
#include <stdio.h>
#include "main.h"
/**
* EasyLogger port initialize
*
* @return result
*/
ElogErrCode elog_port_init(void) {
ElogErrCode result = ELOG_NO_ERR;
/* add your code here */
return result;
}
/**
* EasyLogger port deinitialize
*
*/
void elog_port_deinit(void) {
/* add your code here */
}
/**
* output log port interface
*
* @param log output of log
* @param size log size
*/
void elog_port_output(const char *log, size_t size) {
/* add your code here */
printf("%.*s", size, log); //elog 的输出
}
/**
* output lock
*/
void elog_port_output_lock(void) {
/* add your code here */
__disable_irq(); //关闭全局中断
}
/**
* output unlock
*/
void elog_port_output_unlock(void) {
/* add your code here */
__enable_irq(); //开启全局中断
}
#include <stdio.h>
/**
* get current time interface
*
* @return current time
*/
const char *elog_port_get_time(void) {
// static char rtc_time[20]; // 静态缓冲区,存 "YYYY-MM-DD HH:MM:SS"
// RTC_TimeTypeDef sTime = {0};
// RTC_DateTypeDef sDate = {0};
//
// // 1. 读取RTC时间先读时间再读日期HAL库要求
// HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN);
// HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN);
//
// // 2. 格式化时间字符串(直接拼接到静态数组)
// snprintf(rtc_time, sizeof(rtc_time), "20%02d-%02d-%02d %02d:%02d:%02d",
// sDate.Year, // 25 → 2025
// sDate.Month, // 1-12
// sDate.Date, // 1-31
// sTime.Hours, // 0-23
// sTime.Minutes, // 0-59
// sTime.Seconds); // 0-59
return "";
}
/**
* get current process name interface
*
* @return current process name
*/
const char *elog_port_get_p_info(void) {
/* add your code here */
return "";
}
/**
* get current thread name interface
*
* @return current thread name
*/
const char *elog_port_get_t_info(void) {
/* add your code here */
//获取STM32 的线程接口
return "";
}
void easylogger_init(void) {
/* init Easylogger */
elog_init();
/* set EasyLogger log format */
elog_set_fmt(ELOG_LVL_ASSERT, ELOG_FMT_ALL & ~ELOG_FMT_P_INFO);
elog_set_fmt(ELOG_LVL_ERROR, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
elog_set_fmt(ELOG_LVL_WARN, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
elog_set_fmt(ELOG_LVL_INFO, ELOG_FMT_LVL | ELOG_FMT_TAG | ELOG_FMT_TIME);
elog_set_fmt(ELOG_LVL_DEBUG, ELOG_FMT_ALL & ~(ELOG_FMT_FUNC | ELOG_FMT_P_INFO));
elog_set_fmt(ELOG_LVL_VERBOSE, ELOG_FMT_ALL & ~(ELOG_FMT_FUNC | ELOG_FMT_P_INFO));
/* start EasyLogger */
elog_start();
}

View File

@@ -0,0 +1,912 @@
//
// Created by wangb on 25-6-4.
//
#define LOG_TAG "elog"
#include "elog.h"
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#if !defined(ELOG_OUTPUT_LVL)
#error "Please configure static output log level (in elog_cfg.h)"
#endif
#if !defined(ELOG_LINE_NUM_MAX_LEN)
#error "Please configure output line number max length (in elog_cfg.h)"
#endif
#if !defined(ELOG_LINE_BUF_SIZE)
#error "Please configure buffer size for every line's log (in elog_cfg.h)"
#endif
#if !defined(ELOG_FILTER_TAG_MAX_LEN)
#error "Please configure output filter's tag max length (in elog_cfg.h)"
#endif
#if !defined(ELOG_FILTER_KW_MAX_LEN)
#error "Please configure output filter's keyword max length (in elog_cfg.h)"
#endif
#if !defined(ELOG_NEWLINE_SIGN)
#error "Please configure output newline sign (in elog_cfg.h)"
#endif
/* output filter's tag level max num */
#ifndef ELOG_FILTER_TAG_LVL_MAX_NUM
#define ELOG_FILTER_TAG_LVL_MAX_NUM 4
#endif
#ifdef ELOG_COLOR_ENABLE
/**
* CSI(Control Sequence Introducer/Initiator) sign
* more information on https://en.wikipedia.org/wiki/ANSI_escape_code
*/
#define CSI_START "\033["
#define CSI_END "\033[0m"
/* output log front color */
#define F_BLACK "30;"
#define F_RED "31;"
#define F_GREEN "32;"
#define F_YELLOW "33;"
#define F_BLUE "34;"
#define F_MAGENTA "35;"
#define F_CYAN "36;"
#define F_WHITE "37;"
/* output log background color */
#define B_NULL
#define B_BLACK "40;"
#define B_RED "41;"
#define B_GREEN "42;"
#define B_YELLOW "43;"
#define B_BLUE "44;"
#define B_MAGENTA "45;"
#define B_CYAN "46;"
#define B_WHITE "47;"
/* output log fonts style */
#define S_BOLD "1m"
#define S_UNDERLINE "4m"
#define S_BLINK "5m"
#define S_NORMAL "22m"
/* output log default color definition: [front color] + [background color] + [show style] */
#ifndef ELOG_COLOR_ASSERT
#define ELOG_COLOR_ASSERT (F_MAGENTA B_NULL S_NORMAL)
#endif
#ifndef ELOG_COLOR_ERROR
#define ELOG_COLOR_ERROR (F_RED B_NULL S_NORMAL)
#endif
#ifndef ELOG_COLOR_WARN
#define ELOG_COLOR_WARN (F_YELLOW B_NULL S_NORMAL)
#endif
#ifndef ELOG_COLOR_INFO
#define ELOG_COLOR_INFO (F_CYAN B_NULL S_NORMAL)
#endif
#ifndef ELOG_COLOR_DEBUG
#define ELOG_COLOR_DEBUG (F_GREEN B_NULL S_NORMAL)
#endif
#ifndef ELOG_COLOR_VERBOSE
#define ELOG_COLOR_VERBOSE (F_BLUE B_NULL S_NORMAL)
#endif
#endif /* ELOG_COLOR_ENABLE */
/* EasyLogger object */
static EasyLogger elog;
/* every line log's buffer */
static char log_buf[ELOG_LINE_BUF_SIZE] = { 0 };
/* level output info */
static const char *level_output_info[] = {
[ELOG_LVL_ASSERT] = "ASSERT/",
[ELOG_LVL_ERROR] = "ERROR/",
[ELOG_LVL_WARN] = "WARN/",
[ELOG_LVL_INFO] = "INFO/",
[ELOG_LVL_DEBUG] = "DEBUG/",
[ELOG_LVL_VERBOSE] = "VERBOS/",
};
#ifdef ELOG_COLOR_ENABLE
/* color output info */
static const char *color_output_info[] = {
[ELOG_LVL_ASSERT] = ELOG_COLOR_ASSERT,
[ELOG_LVL_ERROR] = ELOG_COLOR_ERROR,
[ELOG_LVL_WARN] = ELOG_COLOR_WARN,
[ELOG_LVL_INFO] = ELOG_COLOR_INFO,
[ELOG_LVL_DEBUG] = ELOG_COLOR_DEBUG,
[ELOG_LVL_VERBOSE] = ELOG_COLOR_VERBOSE,
};
#endif /* ELOG_COLOR_ENABLE */
static bool get_fmt_enabled(uint8_t level, size_t set);
static bool get_fmt_used_and_enabled_u32(uint8_t level, size_t set, uint32_t arg);
static bool get_fmt_used_and_enabled_ptr(uint8_t level, size_t set, const char* arg);
static void elog_set_filter_tag_lvl_default(void);
/* EasyLogger assert hook */
void (*elog_assert_hook)(const char* expr, const char* func, size_t line);
extern void elog_port_output(const char *log, size_t size);
extern void elog_port_output_lock(void);
extern void elog_port_output_unlock(void);
/**
* EasyLogger initialize.
*
* @return result
*/
ElogErrCode elog_init(void) {
extern ElogErrCode elog_port_init(void);
extern ElogErrCode elog_async_init(void);
ElogErrCode result = ELOG_NO_ERR;
if (elog.init_ok == true) {
return result;
}
/* port initialize */
result = elog_port_init();
if (result != ELOG_NO_ERR) {
return result;
}
#ifdef ELOG_ASYNC_OUTPUT_ENABLE
result = elog_async_init();
if (result != ELOG_NO_ERR) {
return result;
}
#endif
/* enable the output lock */
elog_output_lock_enabled(true);
/* output locked status initialize */
elog.output_is_locked_before_enable = false;
elog.output_is_locked_before_disable = false;
#ifdef ELOG_COLOR_ENABLE
/* enable text color by default */
elog_set_text_color_enabled(true);
#endif
/* set level is ELOG_LVL_VERBOSE */
elog_set_filter_lvl(ELOG_LVL_VERBOSE);
/* set tag_level to default val */
elog_set_filter_tag_lvl_default();
elog.init_ok = true;
return result;
}
/**
* EasyLogger deinitialize.
*
*/
void elog_deinit(void) {
extern ElogErrCode elog_port_deinit(void);
extern ElogErrCode elog_async_deinit(void);
if (!elog.init_ok) {
return ;
}
#ifdef ELOG_ASYNC_OUTPUT_ENABLE
elog_async_deinit();
#endif
/* port deinitialize */
elog_port_deinit();
elog.init_ok = false;
}
/**
* EasyLogger start after initialize.
*/
void elog_start(void) {
if (!elog.init_ok) {
return ;
}
/* enable output */
elog_set_output_enabled(true);
#if defined(ELOG_ASYNC_OUTPUT_ENABLE)
elog_async_enabled(true);
#elif defined(ELOG_BUF_OUTPUT_ENABLE)
elog_buf_enabled(true);
#endif
}
/**
* EasyLogger stop after initialize.
*/
void elog_stop(void) {
if (!elog.init_ok) {
return ;
}
/* disable output */
elog_set_output_enabled(false);
#if defined(ELOG_ASYNC_OUTPUT_ENABLE)
elog_async_enabled(false);
#elif defined(ELOG_BUF_OUTPUT_ENABLE)
elog_buf_enabled(false);
#endif
/* show version */
log_i("EasyLogger V%s is deinitialize success.", ELOG_SW_VERSION);
}
/**
* set output enable or disable
*
* @param enabled TRUE: enable FALSE: disable
*/
void elog_set_output_enabled(bool enabled) {
ELOG_ASSERT((enabled == false) || (enabled == true));
elog.output_enabled = enabled;
}
#ifdef ELOG_COLOR_ENABLE
/**
* set log text color enable or disable
*
* @param enabled TRUE: enable FALSE:disable
*/
void elog_set_text_color_enabled(bool enabled) {
ELOG_ASSERT((enabled == false) || (enabled == true));
elog.text_color_enabled = enabled;
}
/**
* get log text color enable status
*
* @return enable or disable
*/
bool elog_get_text_color_enabled(void) {
return elog.text_color_enabled;
}
#endif /* ELOG_COLOR_ENABLE */
/**
* get output is enable or disable
*
* @return enable or disable
*/
bool elog_get_output_enabled(void) {
return elog.output_enabled;
}
/**
* set log output format. only enable or disable
*
* @param level level
* @param set format set
*/
void elog_set_fmt(uint8_t level, size_t set) {
ELOG_ASSERT(level <= ELOG_LVL_VERBOSE);
elog.enabled_fmt_set[level] = set;
}
/**
* set log filter all parameter
*
* @param level level
* @param tag tag
* @param keyword keyword
*/
void elog_set_filter(uint8_t level, const char *tag, const char *keyword) {
ELOG_ASSERT(level <= ELOG_LVL_VERBOSE);
elog_set_filter_lvl(level);
elog_set_filter_tag(tag);
elog_set_filter_kw(keyword);
}
/**
* set log filter's level
*
* @param level level
*/
void elog_set_filter_lvl(uint8_t level) {
ELOG_ASSERT(level <= ELOG_LVL_VERBOSE);
elog.filter.level = level;
}
/**
* set log filter's tag
*
* @param tag tag
*/
void elog_set_filter_tag(const char *tag) {
strncpy(elog.filter.tag, tag, ELOG_FILTER_TAG_MAX_LEN);
}
/**
* set log filter's keyword
*
* @param keyword keyword
*/
void elog_set_filter_kw(const char *keyword) {
strncpy(elog.filter.keyword, keyword, ELOG_FILTER_KW_MAX_LEN);
}
/**
* lock output
*/
void elog_output_lock(void) {
if (elog.output_lock_enabled) {
elog_port_output_lock();
elog.output_is_locked_before_disable = true;
} else {
elog.output_is_locked_before_enable = true;
}
}
/**
* unlock output
*/
void elog_output_unlock(void) {
if (elog.output_lock_enabled) {
elog_port_output_unlock();
elog.output_is_locked_before_disable = false;
} else {
elog.output_is_locked_before_enable = false;
}
}
/**
* set log filter's tag level val to default
*/
static void elog_set_filter_tag_lvl_default(void)
{
uint8_t i = 0;
for (i =0; i< ELOG_FILTER_TAG_LVL_MAX_NUM; i++){
memset(elog.filter.tag_lvl[i].tag, '\0', ELOG_FILTER_TAG_MAX_LEN + 1);
elog.filter.tag_lvl[i].level = ELOG_FILTER_LVL_SILENT;
elog.filter.tag_lvl[i].tag_use_flag = false;
}
}
/**
* Set the filter's level by different tag.
* The log on this tag which level is less than it will stop output.
*
* example:
* // the example tag log enter silent mode
* elog_set_filter_tag_lvl("example", ELOG_FILTER_LVL_SILENT);
* // the example tag log which level is less than INFO level will stop output
* elog_set_filter_tag_lvl("example", ELOG_LVL_INFO);
* // remove example tag's level filter, all level log will resume output
* elog_set_filter_tag_lvl("example", ELOG_FILTER_LVL_ALL);
*
* @param tag log tag
* @param level The filter level. When the level is ELOG_FILTER_LVL_SILENT, the log enter silent mode.
* When the level is ELOG_FILTER_LVL_ALL, it will remove this tag's level filer.
* Then all level log will resume output.
*
*/
void elog_set_filter_tag_lvl(const char *tag, uint8_t level)
{
ELOG_ASSERT(level <= ELOG_LVL_VERBOSE);
ELOG_ASSERT(tag != ((void *)0));
uint8_t i = 0;
if (!elog.init_ok) {
return;
}
elog_output_lock();
/* find the tag in arr */
for (i =0; i< ELOG_FILTER_TAG_LVL_MAX_NUM; i++){
if (elog.filter.tag_lvl[i].tag_use_flag == true &&
!strncmp(tag, elog.filter.tag_lvl[i].tag,ELOG_FILTER_TAG_MAX_LEN)){
break;
}
}
if (i < ELOG_FILTER_TAG_LVL_MAX_NUM){
/* find OK */
if (level == ELOG_FILTER_LVL_ALL){
/* remove current tag's level filter when input level is the lowest level */
elog.filter.tag_lvl[i].tag_use_flag = false;
memset(elog.filter.tag_lvl[i].tag, '\0', ELOG_FILTER_TAG_MAX_LEN + 1);
elog.filter.tag_lvl[i].level = ELOG_FILTER_LVL_SILENT;
} else{
elog.filter.tag_lvl[i].level = level;
}
} else{
/* only add the new tag's level filer when level is not ELOG_FILTER_LVL_ALL */
if (level != ELOG_FILTER_LVL_ALL){
for (i =0; i< ELOG_FILTER_TAG_LVL_MAX_NUM; i++){
if (elog.filter.tag_lvl[i].tag_use_flag == false){
strncpy(elog.filter.tag_lvl[i].tag, tag, ELOG_FILTER_TAG_MAX_LEN);
elog.filter.tag_lvl[i].level = level;
elog.filter.tag_lvl[i].tag_use_flag = true;
break;
}
}
}
}
elog_output_unlock();
}
/**
* get the level on tag's level filer
*
* @param tag tag
*
* @return It will return the lowest level when tag was not found.
* Other level will return when tag was found.
*/
uint8_t elog_get_filter_tag_lvl(const char *tag)
{
ELOG_ASSERT(tag != ((void *)0));
uint8_t i = 0;
uint8_t level = ELOG_FILTER_LVL_ALL;
if (!elog.init_ok) {
return level;
}
elog_output_lock();
/* find the tag in arr */
for (i =0; i< ELOG_FILTER_TAG_LVL_MAX_NUM; i++){
if (elog.filter.tag_lvl[i].tag_use_flag == true &&
!strncmp(tag, elog.filter.tag_lvl[i].tag,ELOG_FILTER_TAG_MAX_LEN)){
level = elog.filter.tag_lvl[i].level;
break;
}
}
elog_output_unlock();
return level;
}
/**
* output RAW format log
*
* @param format output format
* @param ... args
*/
void elog_raw_output(const char *format, ...) {
va_list args;
size_t log_len = 0;
int fmt_result;
/* check output enabled */
if (!elog.output_enabled) {
return;
}
/* args point to the first variable parameter */
va_start(args, format);
/* lock output */
elog_output_lock();
/* package log data to buffer */
fmt_result = vsnprintf(log_buf, ELOG_LINE_BUF_SIZE, format, args);
/* output converted log */
if ((fmt_result > -1) && (fmt_result <= ELOG_LINE_BUF_SIZE)) {
log_len = fmt_result;
} else {
log_len = ELOG_LINE_BUF_SIZE;
}
/* output log */
#if defined(ELOG_ASYNC_OUTPUT_ENABLE)
extern void elog_async_output(uint8_t level, const char *log, size_t size);
/* raw log will using assert level */
elog_async_output(ELOG_LVL_ASSERT, log_buf, log_len);
#elif defined(ELOG_BUF_OUTPUT_ENABLE)
extern void elog_buf_output(const char *log, size_t size);
elog_buf_output(log_buf, log_len);
#else
elog_port_output(log_buf, log_len);
#endif
/* unlock output */
elog_output_unlock();
va_end(args);
}
/**
* output the log
*
* @param level level
* @param tag tag
* @param file file name
* @param func function name
* @param line line number
* @param format output format
* @param ... args
*
*/
void elog_output(uint8_t level, const char *tag, const char *file, const char *func,
const long line, const char *format, ...) {
extern const char *elog_port_get_time(void);
extern const char *elog_port_get_p_info(void);
extern const char *elog_port_get_t_info(void);
size_t tag_len = strlen(tag), log_len = 0, newline_len = strlen(ELOG_NEWLINE_SIGN);
char line_num[ELOG_LINE_NUM_MAX_LEN + 1] = { 0 };
char tag_sapce[ELOG_FILTER_TAG_MAX_LEN / 2 + 1] = { 0 };
va_list args;
int fmt_result;
ELOG_ASSERT(level <= ELOG_LVL_VERBOSE);
/* check output enabled */
if (!elog.output_enabled) {
return;
}
/* level filter */
if (level > elog.filter.level || level > elog_get_filter_tag_lvl(tag)) {
return;
} else if (!strstr(tag, elog.filter.tag)) { /* tag filter */
return;
}
/* args point to the first variable parameter */
va_start(args, format);
/* lock output */
elog_output_lock();
#ifdef ELOG_COLOR_ENABLE
/* add CSI start sign and color info */
if (elog.text_color_enabled) {
log_len += elog_strcpy(log_len, log_buf + log_len, CSI_START);
log_len += elog_strcpy(log_len, log_buf + log_len, color_output_info[level]);
}
#endif
/* package level info */
if (get_fmt_enabled(level, ELOG_FMT_LVL)) {
log_len += elog_strcpy(log_len, log_buf + log_len, level_output_info[level]);
}
/* package tag info */
if (get_fmt_enabled(level, ELOG_FMT_TAG)) {
log_len += elog_strcpy(log_len, log_buf + log_len, tag);
/* if the tag length is less than 50% ELOG_FILTER_TAG_MAX_LEN, then fill space */
if (tag_len <= ELOG_FILTER_TAG_MAX_LEN / 2) {
memset(tag_sapce, ' ', ELOG_FILTER_TAG_MAX_LEN / 2 - tag_len);
log_len += elog_strcpy(log_len, log_buf + log_len, tag_sapce);
}
log_len += elog_strcpy(log_len, log_buf + log_len, " ");
}
/* package time, process and thread info */
if (get_fmt_enabled(level, ELOG_FMT_TIME | ELOG_FMT_P_INFO | ELOG_FMT_T_INFO)) {
log_len += elog_strcpy(log_len, log_buf + log_len, "[");
/* package time info */
if (get_fmt_enabled(level, ELOG_FMT_TIME)) {
log_len += elog_strcpy(log_len, log_buf + log_len, elog_port_get_time());
if (get_fmt_enabled(level, ELOG_FMT_P_INFO | ELOG_FMT_T_INFO)) {
log_len += elog_strcpy(log_len, log_buf + log_len, " ");
}
}
/* package process info */
if (get_fmt_enabled(level, ELOG_FMT_P_INFO)) {
log_len += elog_strcpy(log_len, log_buf + log_len, elog_port_get_p_info());
if (get_fmt_enabled(level, ELOG_FMT_T_INFO)) {
log_len += elog_strcpy(log_len, log_buf + log_len, " ");
}
}
/* package thread info */
if (get_fmt_enabled(level, ELOG_FMT_T_INFO)) {
log_len += elog_strcpy(log_len, log_buf + log_len, elog_port_get_t_info());
}
log_len += elog_strcpy(log_len, log_buf + log_len, "] ");
}
/* package file directory and name, function name and line number info */
if (get_fmt_used_and_enabled_ptr(level, ELOG_FMT_DIR, file) ||
get_fmt_used_and_enabled_ptr(level, ELOG_FMT_FUNC, func) ||
get_fmt_used_and_enabled_u32(level, ELOG_FMT_LINE, line)) {
log_len += elog_strcpy(log_len, log_buf + log_len, "(");
/* package file info */
if (get_fmt_used_and_enabled_ptr(level, ELOG_FMT_DIR, file)) {
log_len += elog_strcpy(log_len, log_buf + log_len, file);
if (get_fmt_used_and_enabled_ptr(level, ELOG_FMT_FUNC, func)) {
log_len += elog_strcpy(log_len, log_buf + log_len, ":");
} else if (get_fmt_used_and_enabled_u32(level, ELOG_FMT_LINE, line)) {
log_len += elog_strcpy(log_len, log_buf + log_len, " ");
}
}
/* package line info */
if (get_fmt_used_and_enabled_u32(level, ELOG_FMT_LINE, line)) {
snprintf(line_num, ELOG_LINE_NUM_MAX_LEN, "%ld", line);
log_len += elog_strcpy(log_len, log_buf + log_len, line_num);
if (get_fmt_used_and_enabled_ptr(level, ELOG_FMT_FUNC, func)) {
log_len += elog_strcpy(log_len, log_buf + log_len, " ");
}
}
/* package func info */
if (get_fmt_used_and_enabled_ptr(level, ELOG_FMT_FUNC, func)) {
log_len += elog_strcpy(log_len, log_buf + log_len, func);
}
log_len += elog_strcpy(log_len, log_buf + log_len, ")");
}
/* package other log data to buffer. '\0' must be added in the end by vsnprintf. */
fmt_result = vsnprintf(log_buf + log_len, ELOG_LINE_BUF_SIZE - log_len, format, args);
va_end(args);
/* calculate log length */
if ((log_len + fmt_result <= ELOG_LINE_BUF_SIZE) && (fmt_result > -1)) {
log_len += fmt_result;
} else {
/* using max length */
log_len = ELOG_LINE_BUF_SIZE;
}
/* overflow check and reserve some space for CSI end sign and newline sign */
#ifdef ELOG_COLOR_ENABLE
if (log_len + (sizeof(CSI_END) - 1) + newline_len > ELOG_LINE_BUF_SIZE) {
/* using max length */
log_len = ELOG_LINE_BUF_SIZE;
/* reserve some space for CSI end sign */
log_len -= (sizeof(CSI_END) - 1);
#else
if (log_len + newline_len > ELOG_LINE_BUF_SIZE) {
/* using max length */
log_len = ELOG_LINE_BUF_SIZE;
#endif /* ELOG_COLOR_ENABLE */
/* reserve some space for newline sign */
log_len -= newline_len;
}
/* keyword filter */
if (elog.filter.keyword[0] != '\0') {
/* add string end sign */
log_buf[log_len] = '\0';
/* find the keyword */
if (!strstr(log_buf, elog.filter.keyword)) {
/* unlock output */
elog_output_unlock();
return;
}
}
#ifdef ELOG_COLOR_ENABLE
/* add CSI end sign */
if (elog.text_color_enabled) {
log_len += elog_strcpy(log_len, log_buf + log_len, CSI_END);
}
#endif
/* package newline sign */
log_len += elog_strcpy(log_len, log_buf + log_len, ELOG_NEWLINE_SIGN);
/* output log */
#if defined(ELOG_ASYNC_OUTPUT_ENABLE)
extern void elog_async_output(uint8_t level, const char *log, size_t size);
elog_async_output(level, log_buf, log_len);
#elif defined(ELOG_BUF_OUTPUT_ENABLE)
extern void elog_buf_output(const char *log, size_t size);
elog_buf_output(log_buf, log_len);
#else
elog_port_output(log_buf, log_len);
#endif
/* unlock output */
elog_output_unlock();
}
/**
* get format enabled
*
* @param level level
* @param set format set
*
* @return enable or disable
*/
static bool get_fmt_enabled(uint8_t level, size_t set) {
ELOG_ASSERT(level <= ELOG_LVL_VERBOSE);
if (elog.enabled_fmt_set[level] & set) {
return true;
} else {
return false;
}
}
static bool get_fmt_used_and_enabled_u32(uint8_t level, size_t set, uint32_t arg) {
return arg && get_fmt_enabled(level, set);
}
static bool get_fmt_used_and_enabled_ptr(uint8_t level, size_t set, const char* arg) {
return arg && get_fmt_enabled(level, set);
}
/**
* enable or disable logger output lock
* @note disable this lock is not recommended except you want output system exception log
*
* @param enabled true: enable false: disable
*/
void elog_output_lock_enabled(bool enabled) {
elog.output_lock_enabled = enabled;
/* it will re-lock or re-unlock before output lock enable */
if (elog.output_lock_enabled) {
if (!elog.output_is_locked_before_disable && elog.output_is_locked_before_enable) {
/* the output lock is unlocked before disable, and the lock will unlocking after enable */
elog_port_output_lock();
} else if (elog.output_is_locked_before_disable && !elog.output_is_locked_before_enable) {
/* the output lock is locked before disable, and the lock will locking after enable */
elog_port_output_unlock();
}
}
}
/**
* Set a hook function to EasyLogger assert. It will run when the expression is false.
*
* @param hook the hook function
*/
void elog_assert_set_hook(void (*hook)(const char* expr, const char* func, size_t line)) {
elog_assert_hook = hook;
}
/**
* find the log level
* @note make sure the log level is output on each format
*
* @param log log buffer
*
* @return log level, found failed will return -1
*/
int8_t elog_find_lvl(const char *log) {
ELOG_ASSERT(log);
/* make sure the log level is output on each format */
ELOG_ASSERT(elog.enabled_fmt_set[ELOG_LVL_ASSERT] & ELOG_FMT_LVL);
ELOG_ASSERT(elog.enabled_fmt_set[ELOG_LVL_ERROR] & ELOG_FMT_LVL);
ELOG_ASSERT(elog.enabled_fmt_set[ELOG_LVL_WARN] & ELOG_FMT_LVL);
ELOG_ASSERT(elog.enabled_fmt_set[ELOG_LVL_INFO] & ELOG_FMT_LVL);
ELOG_ASSERT(elog.enabled_fmt_set[ELOG_LVL_DEBUG] & ELOG_FMT_LVL);
ELOG_ASSERT(elog.enabled_fmt_set[ELOG_LVL_VERBOSE] & ELOG_FMT_LVL);
#ifdef ELOG_COLOR_ENABLE
uint8_t i;
size_t csi_start_len = strlen(CSI_START);
for(i = 0; i < ELOG_LVL_TOTAL_NUM; i ++) {
if (!strncmp(color_output_info[i], log + csi_start_len, strlen(color_output_info[i]))) {
return i;
}
}
/* found failed */
return -1;
#else
switch (log[0]) {
case 'A': return ELOG_LVL_ASSERT;
case 'E': return ELOG_LVL_ERROR;
case 'W': return ELOG_LVL_WARN;
case 'I': return ELOG_LVL_INFO;
case 'D': return ELOG_LVL_DEBUG;
case 'V': return ELOG_LVL_VERBOSE;
default: return -1;
}
#endif
}
/**
* find the log tag
* @note make sure the log tag is output on each format
* @note the tag don't have space in it
*
* @param log log buffer
* @param lvl log level, you can get it by @see elog_find_lvl
* @param tag_len found tag length
*
* @return log tag, found failed will return NULL
*/
const char *elog_find_tag(const char *log, uint8_t lvl, size_t *tag_len) {
const char *tag = NULL, *tag_end = NULL;
ELOG_ASSERT(log);
ELOG_ASSERT(tag_len);
ELOG_ASSERT(lvl < ELOG_LVL_TOTAL_NUM);
/* make sure the log tag is output on each format */
ELOG_ASSERT(elog.enabled_fmt_set[lvl] & ELOG_FMT_TAG);
#ifdef ELOG_COLOR_ENABLE
tag = log + strlen(CSI_START) + strlen(color_output_info[lvl]) + strlen(level_output_info[lvl]);
#else
tag = log + strlen(level_output_info[lvl]);
#endif
/* find the first space after tag */
if ((tag_end = memchr(tag, ' ', ELOG_FILTER_TAG_MAX_LEN)) != NULL) {
*tag_len = tag_end - tag;
} else {
tag = NULL;
}
return tag;
}
/**
* dump the hex format data to log
*
* @param name name for hex object, it will show on log header
* @param width hex number for every line, such as: 16, 32
* @param buf hex buffer
* @param size buffer size
*/
void elog_hexdump(const char *name, uint8_t width, const void *buf, uint16_t size)
{
#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ')
uint16_t i, j;
uint16_t log_len = 0;
const uint8_t *buf_p = buf;
char dump_string[8] = {0};
int fmt_result;
if (!elog.output_enabled) {
return;
}
/* level filter */
if (ELOG_LVL_DEBUG > elog.filter.level) {
return;
} else if (!strstr(name, elog.filter.tag)) { /* tag filter */
return;
}
/* lock output */
elog_output_lock();
for (i = 0; i < size; i += width) {
/* package header */
fmt_result = snprintf(log_buf, ELOG_LINE_BUF_SIZE, "D/HEX %s: %04X-%04X: ", name, i, i + width - 1);
/* calculate log length */
if ((fmt_result > -1) && (fmt_result <= ELOG_LINE_BUF_SIZE)) {
log_len = fmt_result;
} else {
log_len = ELOG_LINE_BUF_SIZE;
}
/* dump hex */
for (j = 0; j < width; j++) {
if (i + j < size) {
snprintf(dump_string, sizeof(dump_string), "%02X ", buf_p[i + j]);
} else {
strncpy(dump_string, " ", sizeof(dump_string));
}
log_len += elog_strcpy(log_len, log_buf + log_len, dump_string);
if ((j + 1) % 8 == 0) {
log_len += elog_strcpy(log_len, log_buf + log_len, " ");
}
}
log_len += elog_strcpy(log_len, log_buf + log_len, " ");
/* dump char for hex */
for (j = 0; j < width; j++) {
if (i + j < size) {
snprintf(dump_string, sizeof(dump_string), "%c", __is_print(buf_p[i + j]) ? buf_p[i + j] : '.');
log_len += elog_strcpy(log_len, log_buf + log_len, dump_string);
}
}
/* overflow check and reserve some space for newline sign */
if (log_len + strlen(ELOG_NEWLINE_SIGN) > ELOG_LINE_BUF_SIZE) {
log_len = ELOG_LINE_BUF_SIZE - strlen(ELOG_NEWLINE_SIGN);
}
/* package newline sign */
log_len += elog_strcpy(log_len, log_buf + log_len, ELOG_NEWLINE_SIGN);
/* do log output */
#if defined(ELOG_ASYNC_OUTPUT_ENABLE)
extern void elog_async_output(uint8_t level, const char *log, size_t size);
elog_async_output(ELOG_LVL_DEBUG, log_buf, log_len);
#elif defined(ELOG_BUF_OUTPUT_ENABLE)
extern void elog_buf_output(const char *log, size_t size);
elog_buf_output(log_buf, log_len);
#else
elog_port_output(log_buf, log_len);
#endif
}
/* unlock output */
elog_output_unlock();
}

View File

@@ -0,0 +1,79 @@
//
// Created by wangb on 25-6-4.
//
#include "elog.h"
#include <string.h>
/**
* another copy string function
*
* @param cur_len current copied log length, max size is ELOG_LINE_BUF_SIZE
* @param dst destination
* @param src source
*
* @return copied length
*/
size_t elog_strcpy(size_t cur_len, char *dst, const char *src) {
const char *src_old = src;
assert(dst);
assert(src);
while (*src != 0) {
/* make sure destination has enough space */
if (cur_len++ < ELOG_LINE_BUF_SIZE) {
*dst++ = *src++;
} else {
break;
}
}
return src - src_old;
}
/**
* Copy line log split by newline sign. It will copy all log when the newline sign isn't find.
*
* @param line line log buffer
* @param log origin log buffer
* @param len origin log buffer length
*
* @return copy size
*/
size_t elog_cpyln(char *line, const char *log, size_t len) {
size_t newline_len = strlen(ELOG_NEWLINE_SIGN), copy_size = 0;
assert(line);
assert(log);
while (len--) {
*line++ = *log++;
copy_size++;
if (copy_size >= newline_len && !strncmp(log - newline_len, ELOG_NEWLINE_SIGN, newline_len)) {
break;
}
}
return copy_size;
}
/**
* This function will copy memory content from source address to destination
* address.
*
* @param dst the address of destination memory
* @param src the address of source memory
* @param count the copied length
*
* @return the address of destination memory
*/
void *elog_memcpy(void *dst, const void *src, size_t count) {
char *tmp = (char *) dst, *s = (char *) src;
assert(dst);
assert(src);
while (count--)
*tmp++ = *s++;
return dst;
}

153
Core/Inc/FreeRTOSConfig.h Normal file
View File

@@ -0,0 +1,153 @@
/* USER CODE BEGIN Header */
/*
* FreeRTOS Kernel V10.0.1
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* http://www.FreeRTOS.org
* http://aws.amazon.com/freertos
*
* 1 tab == 4 spaces!
*/
/* USER CODE END Header */
#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H
/*-----------------------------------------------------------
* Application specific definitions.
*
* These definitions should be adjusted for your particular hardware and
* application requirements.
*
* These parameters and more are described within the 'configuration' section of the
* FreeRTOS API documentation available on the FreeRTOS.org web site.
*
* See http://www.freertos.org/a00110.html
*----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* Section where include file can be added */
/* USER CODE END Includes */
/* Ensure definitions are only used by the compiler, and not by the assembler. */
#if defined(__ICCARM__) || defined(__CC_ARM) || defined(__GNUC__)
#include <stdint.h>
extern uint32_t SystemCoreClock;
#endif
#ifndef CMSIS_device_header
#define CMSIS_device_header "stm32f1xx.h"
#endif /* CMSIS_device_header */
#define configUSE_PREEMPTION 1
#define configSUPPORT_STATIC_ALLOCATION 1
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configUSE_IDLE_HOOK 0
#define configUSE_TICK_HOOK 0
#define configCPU_CLOCK_HZ ( SystemCoreClock )
#define configTICK_RATE_HZ ((TickType_t)1000)
#define configMAX_PRIORITIES ( 56 )
#define configMINIMAL_STACK_SIZE ((uint16_t)128)
#define configTOTAL_HEAP_SIZE ((size_t)30000)
#define configMAX_TASK_NAME_LEN ( 16 )
#define configUSE_TRACE_FACILITY 1
#define configUSE_16_BIT_TICKS 0
#define configUSE_MUTEXES 1
#define configQUEUE_REGISTRY_SIZE 8
#define configUSE_RECURSIVE_MUTEXES 1
#define configUSE_COUNTING_SEMAPHORES 1
#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
/* Software timer definitions. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY ( 2 )
#define configTIMER_QUEUE_LENGTH 10
#define configTIMER_TASK_STACK_DEPTH 256
/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */
#define INCLUDE_vTaskPrioritySet 1
#define INCLUDE_uxTaskPriorityGet 1
#define INCLUDE_vTaskDelete 1
#define INCLUDE_vTaskCleanUpResources 0
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_vTaskDelayUntil 1
#define INCLUDE_vTaskDelay 1
#define INCLUDE_xTaskGetSchedulerState 1
#define INCLUDE_xTimerPendFunctionCall 1
#define INCLUDE_xQueueGetMutexHolder 1
#define INCLUDE_uxTaskGetStackHighWaterMark 1
#define INCLUDE_xTaskGetCurrentTaskHandle 1
#define INCLUDE_eTaskGetState 1
/*
* The CMSIS-RTOS V2 FreeRTOS wrapper is dependent on the heap implementation used
* by the application thus the correct define need to be enabled below
*/
#define USE_FreeRTOS_HEAP_4
/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4
#endif
/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15
/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* Normal assert() semantics without relying on the provision of an assert.h
header file. */
/* USER CODE BEGIN 1 */
#define configASSERT( x ) if ((x) == 0) {taskDISABLE_INTERRUPTS(); for( ;; );}
/* USER CODE END 1 */
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
/* IMPORTANT: After 10.3.1 update, Systick_Handler comes from NVIC (if SYS timebase = systick), otherwise from cmsis_os2.c */
#define USE_CUSTOM_SYSTICK_HANDLER_IMPLEMENTATION 0
/* USER CODE BEGIN Defines */
/* Section where parameter definitions can be added (for instance, to override default ones in FreeRTOS.h) */
/* USER CODE END Defines */
#endif /* FREERTOS_CONFIG_H */

52
Core/Inc/dma.h Normal file
View File

@@ -0,0 +1,52 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file dma.h
* @brief This file contains all the function prototypes for
* the dma.c file
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __DMA_H__
#define __DMA_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* DMA memory to memory transfer handles -------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_DMA_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __DMA_H__ */

49
Core/Inc/gpio.h Normal file
View File

@@ -0,0 +1,49 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file gpio.h
* @brief This file contains all the function prototypes for
* the gpio.c file
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __GPIO_H__
#define __GPIO_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_GPIO_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /*__ GPIO_H__ */

52
Core/Inc/i2c.h Normal file
View File

@@ -0,0 +1,52 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file i2c.h
* @brief This file contains all the function prototypes for
* the i2c.c file
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __I2C_H__
#define __I2C_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern I2C_HandleTypeDef hi2c1;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_I2C1_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __I2C_H__ */

99
Core/Inc/main.h Normal file
View File

@@ -0,0 +1,99 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.h
* @brief : Header for main.c file.
* This file contains the common defines of the application.
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void Error_Handler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
/* Private defines -----------------------------------------------------------*/
#define KEY1_Pin GPIO_PIN_0
#define KEY1_GPIO_Port GPIOC
#define KEY2_Pin GPIO_PIN_1
#define KEY2_GPIO_Port GPIOC
#define KEY3_Pin GPIO_PIN_2
#define KEY3_GPIO_Port GPIOC
#define KEY3C3_Pin GPIO_PIN_3
#define KEY3C3_GPIO_Port GPIOC
#define HX711_DOUT_Pin GPIO_PIN_2
#define HX711_DOUT_GPIO_Port GPIOA
#define HX711_SCK_Pin GPIO_PIN_3
#define HX711_SCK_GPIO_Port GPIOA
#define LCD_DC_Pin GPIO_PIN_4
#define LCD_DC_GPIO_Port GPIOA
#define LCD_RESET_Pin GPIO_PIN_6
#define LCD_RESET_GPIO_Port GPIOA
#define LCD_CS_Pin GPIO_PIN_4
#define LCD_CS_GPIO_Port GPIOC
#define LCD_BLK_Pin GPIO_PIN_5
#define LCD_BLK_GPIO_Port GPIOC
#define LED2_Pin GPIO_PIN_12
#define LED2_GPIO_Port GPIOB
#define LED1_Pin GPIO_PIN_13
#define LED1_GPIO_Port GPIOB
#define HC_SR505_IO_Pin GPIO_PIN_14
#define HC_SR505_IO_GPIO_Port GPIOB
#define M3_IO_Pin GPIO_PIN_15
#define M3_IO_GPIO_Port GPIOB
#define MOTOR_Pin GPIO_PIN_6
#define MOTOR_GPIO_Port GPIOC
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H */

52
Core/Inc/spi.h Normal file
View File

@@ -0,0 +1,52 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file spi.h
* @brief This file contains all the function prototypes for
* the spi.c file
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SPI_H__
#define __SPI_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern SPI_HandleTypeDef hspi1;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_SPI1_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __SPI_H__ */

View File

@@ -0,0 +1,391 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32f1xx_hal_conf.h
* @brief HAL configuration file.
******************************************************************************
* @attention
*
* Copyright (c) 2017 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F1xx_HAL_CONF_H
#define __STM32F1xx_HAL_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* ########################## Module Selection ############################## */
/**
* @brief This is the list of modules to be used in the HAL driver
*/
#define HAL_MODULE_ENABLED
/*#define HAL_ADC_MODULE_ENABLED */
/*#define HAL_CRYP_MODULE_ENABLED */
/*#define HAL_CAN_MODULE_ENABLED */
/*#define HAL_CAN_LEGACY_MODULE_ENABLED */
/*#define HAL_CEC_MODULE_ENABLED */
/*#define HAL_CORTEX_MODULE_ENABLED */
/*#define HAL_CRC_MODULE_ENABLED */
/*#define HAL_DAC_MODULE_ENABLED */
#define HAL_DMA_MODULE_ENABLED
/*#define HAL_ETH_MODULE_ENABLED */
/*#define HAL_FLASH_MODULE_ENABLED */
#define HAL_GPIO_MODULE_ENABLED
#define HAL_I2C_MODULE_ENABLED
/*#define HAL_I2S_MODULE_ENABLED */
/*#define HAL_IRDA_MODULE_ENABLED */
/*#define HAL_IWDG_MODULE_ENABLED */
/*#define HAL_NOR_MODULE_ENABLED */
/*#define HAL_NAND_MODULE_ENABLED */
/*#define HAL_PCCARD_MODULE_ENABLED */
/*#define HAL_PCD_MODULE_ENABLED */
/*#define HAL_HCD_MODULE_ENABLED */
/*#define HAL_PWR_MODULE_ENABLED */
/*#define HAL_RCC_MODULE_ENABLED */
/*#define HAL_RTC_MODULE_ENABLED */
/*#define HAL_SD_MODULE_ENABLED */
/*#define HAL_MMC_MODULE_ENABLED */
/*#define HAL_SDRAM_MODULE_ENABLED */
/*#define HAL_SMARTCARD_MODULE_ENABLED */
#define HAL_SPI_MODULE_ENABLED
/*#define HAL_SRAM_MODULE_ENABLED */
#define HAL_TIM_MODULE_ENABLED
#define HAL_UART_MODULE_ENABLED
/*#define HAL_USART_MODULE_ENABLED */
/*#define HAL_WWDG_MODULE_ENABLED */
#define HAL_CORTEX_MODULE_ENABLED
#define HAL_DMA_MODULE_ENABLED
#define HAL_FLASH_MODULE_ENABLED
#define HAL_EXTI_MODULE_ENABLED
#define HAL_GPIO_MODULE_ENABLED
#define HAL_PWR_MODULE_ENABLED
#define HAL_RCC_MODULE_ENABLED
/* ########################## Oscillator Values adaptation ####################*/
/**
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSE is used as system clock source, directly or through the PLL).
*/
#if !defined (HSE_VALUE)
#define HSE_VALUE 8000000U /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (HSE_STARTUP_TIMEOUT)
#define HSE_STARTUP_TIMEOUT 100U /*!< Time out for HSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */
/**
* @brief Internal High Speed oscillator (HSI) value.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSI is used as system clock source, directly or through the PLL).
*/
#if !defined (HSI_VALUE)
#define HSI_VALUE 8000000U /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
/**
* @brief Internal Low Speed oscillator (LSI) value.
*/
#if !defined (LSI_VALUE)
#define LSI_VALUE 40000U /*!< LSI Typical Value in Hz */
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
The real value may vary depending on the variations
in voltage and temperature. */
/**
* @brief External Low Speed oscillator (LSE) value.
* This value is used by the UART, RTC HAL module to compute the system frequency
*/
#if !defined (LSE_VALUE)
#define LSE_VALUE 32768U /*!< Value of the External oscillator in Hz*/
#endif /* LSE_VALUE */
#if !defined (LSE_STARTUP_TIMEOUT)
#define LSE_STARTUP_TIMEOUT 5000U /*!< Time out for LSE start up, in ms */
#endif /* LSE_STARTUP_TIMEOUT */
/* Tip: To avoid modifying this file each time you need to use different HSE,
=== you can define the HSE value in your toolchain compiler preprocessor. */
/* ########################### System Configuration ######################### */
/**
* @brief This is the HAL system configuration section
*/
#define VDD_VALUE 3300U /*!< Value of VDD in mv */
#define TICK_INT_PRIORITY 15U /*!< tick interrupt priority (lowest by default) */
#define USE_RTOS 0U
#define PREFETCH_ENABLE 1U
#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */
#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */
#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */
#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */
#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */
#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */
#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */
#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */
#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */
#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */
#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */
#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */
#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */
#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */
#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */
#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */
#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */
#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */
#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */
#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
/* ########################## Assert Selection ############################## */
/**
* @brief Uncomment the line below to expanse the "assert_param" macro in the
* HAL drivers code
*/
/* #define USE_FULL_ASSERT 1U */
/* ################## Ethernet peripheral configuration ##################### */
/* Section 1 : Ethernet peripheral configuration */
/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
#define MAC_ADDR0 2U
#define MAC_ADDR1 0U
#define MAC_ADDR2 0U
#define MAC_ADDR3 0U
#define MAC_ADDR4 0U
#define MAC_ADDR5 0U
/* Definition of the Ethernet driver buffers size and count */
#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
#define ETH_RXBUFNB 8U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
/* Section 2: PHY configuration section */
/* DP83848_PHY_ADDRESS Address*/
#define DP83848_PHY_ADDRESS 0x01U
/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
#define PHY_RESET_DELAY 0x000000FFU
/* PHY Configuration delay */
#define PHY_CONFIG_DELAY 0x00000FFFU
#define PHY_READ_TO 0x0000FFFFU
#define PHY_WRITE_TO 0x0000FFFFU
/* Section 3: Common PHY Registers */
#define PHY_BCR ((uint16_t)0x00) /*!< Transceiver Basic Control Register */
#define PHY_BSR ((uint16_t)0x01) /*!< Transceiver Basic Status Register */
#define PHY_RESET ((uint16_t)0x8000) /*!< PHY Reset */
#define PHY_LOOPBACK ((uint16_t)0x4000) /*!< Select loop-back mode */
#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100) /*!< Set the full-duplex mode at 100 Mb/s */
#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000) /*!< Set the half-duplex mode at 100 Mb/s */
#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100) /*!< Set the full-duplex mode at 10 Mb/s */
#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000) /*!< Set the half-duplex mode at 10 Mb/s */
#define PHY_AUTONEGOTIATION ((uint16_t)0x1000) /*!< Enable auto-negotiation function */
#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200) /*!< Restart auto-negotiation function */
#define PHY_POWERDOWN ((uint16_t)0x0800) /*!< Select the power down mode */
#define PHY_ISOLATE ((uint16_t)0x0400) /*!< Isolate PHY from MII */
#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */
#define PHY_LINKED_STATUS ((uint16_t)0x0004) /*!< Valid link established */
#define PHY_JABBER_DETECTION ((uint16_t)0x0002) /*!< Jabber condition detected */
/* Section 4: Extended PHY Registers */
#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */
#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */
#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */
/* ################## SPI peripheral configuration ########################## */
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
* Activated: CRC code is present inside driver
* Deactivated: CRC code cleaned from driver
*/
#define USE_SPI_CRC 0U
/* Includes ------------------------------------------------------------------*/
/**
* @brief Include module's header file
*/
#ifdef HAL_RCC_MODULE_ENABLED
#include "stm32f1xx_hal_rcc.h"
#endif /* HAL_RCC_MODULE_ENABLED */
#ifdef HAL_GPIO_MODULE_ENABLED
#include "stm32f1xx_hal_gpio.h"
#endif /* HAL_GPIO_MODULE_ENABLED */
#ifdef HAL_EXTI_MODULE_ENABLED
#include "stm32f1xx_hal_exti.h"
#endif /* HAL_EXTI_MODULE_ENABLED */
#ifdef HAL_DMA_MODULE_ENABLED
#include "stm32f1xx_hal_dma.h"
#endif /* HAL_DMA_MODULE_ENABLED */
#ifdef HAL_ETH_MODULE_ENABLED
#include "stm32f1xx_hal_eth.h"
#endif /* HAL_ETH_MODULE_ENABLED */
#ifdef HAL_CAN_MODULE_ENABLED
#include "stm32f1xx_hal_can.h"
#endif /* HAL_CAN_MODULE_ENABLED */
#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
#include "Legacy/stm32f1xx_hal_can_legacy.h"
#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
#ifdef HAL_CEC_MODULE_ENABLED
#include "stm32f1xx_hal_cec.h"
#endif /* HAL_CEC_MODULE_ENABLED */
#ifdef HAL_CORTEX_MODULE_ENABLED
#include "stm32f1xx_hal_cortex.h"
#endif /* HAL_CORTEX_MODULE_ENABLED */
#ifdef HAL_ADC_MODULE_ENABLED
#include "stm32f1xx_hal_adc.h"
#endif /* HAL_ADC_MODULE_ENABLED */
#ifdef HAL_CRC_MODULE_ENABLED
#include "stm32f1xx_hal_crc.h"
#endif /* HAL_CRC_MODULE_ENABLED */
#ifdef HAL_DAC_MODULE_ENABLED
#include "stm32f1xx_hal_dac.h"
#endif /* HAL_DAC_MODULE_ENABLED */
#ifdef HAL_FLASH_MODULE_ENABLED
#include "stm32f1xx_hal_flash.h"
#endif /* HAL_FLASH_MODULE_ENABLED */
#ifdef HAL_SRAM_MODULE_ENABLED
#include "stm32f1xx_hal_sram.h"
#endif /* HAL_SRAM_MODULE_ENABLED */
#ifdef HAL_NOR_MODULE_ENABLED
#include "stm32f1xx_hal_nor.h"
#endif /* HAL_NOR_MODULE_ENABLED */
#ifdef HAL_I2C_MODULE_ENABLED
#include "stm32f1xx_hal_i2c.h"
#endif /* HAL_I2C_MODULE_ENABLED */
#ifdef HAL_I2S_MODULE_ENABLED
#include "stm32f1xx_hal_i2s.h"
#endif /* HAL_I2S_MODULE_ENABLED */
#ifdef HAL_IWDG_MODULE_ENABLED
#include "stm32f1xx_hal_iwdg.h"
#endif /* HAL_IWDG_MODULE_ENABLED */
#ifdef HAL_PWR_MODULE_ENABLED
#include "stm32f1xx_hal_pwr.h"
#endif /* HAL_PWR_MODULE_ENABLED */
#ifdef HAL_RTC_MODULE_ENABLED
#include "stm32f1xx_hal_rtc.h"
#endif /* HAL_RTC_MODULE_ENABLED */
#ifdef HAL_PCCARD_MODULE_ENABLED
#include "stm32f1xx_hal_pccard.h"
#endif /* HAL_PCCARD_MODULE_ENABLED */
#ifdef HAL_SD_MODULE_ENABLED
#include "stm32f1xx_hal_sd.h"
#endif /* HAL_SD_MODULE_ENABLED */
#ifdef HAL_NAND_MODULE_ENABLED
#include "stm32f1xx_hal_nand.h"
#endif /* HAL_NAND_MODULE_ENABLED */
#ifdef HAL_SPI_MODULE_ENABLED
#include "stm32f1xx_hal_spi.h"
#endif /* HAL_SPI_MODULE_ENABLED */
#ifdef HAL_TIM_MODULE_ENABLED
#include "stm32f1xx_hal_tim.h"
#endif /* HAL_TIM_MODULE_ENABLED */
#ifdef HAL_UART_MODULE_ENABLED
#include "stm32f1xx_hal_uart.h"
#endif /* HAL_UART_MODULE_ENABLED */
#ifdef HAL_USART_MODULE_ENABLED
#include "stm32f1xx_hal_usart.h"
#endif /* HAL_USART_MODULE_ENABLED */
#ifdef HAL_IRDA_MODULE_ENABLED
#include "stm32f1xx_hal_irda.h"
#endif /* HAL_IRDA_MODULE_ENABLED */
#ifdef HAL_SMARTCARD_MODULE_ENABLED
#include "stm32f1xx_hal_smartcard.h"
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
#ifdef HAL_WWDG_MODULE_ENABLED
#include "stm32f1xx_hal_wwdg.h"
#endif /* HAL_WWDG_MODULE_ENABLED */
#ifdef HAL_PCD_MODULE_ENABLED
#include "stm32f1xx_hal_pcd.h"
#endif /* HAL_PCD_MODULE_ENABLED */
#ifdef HAL_HCD_MODULE_ENABLED
#include "stm32f1xx_hal_hcd.h"
#endif /* HAL_HCD_MODULE_ENABLED */
#ifdef HAL_MMC_MODULE_ENABLED
#include "stm32f1xx_hal_mmc.h"
#endif /* HAL_MMC_MODULE_ENABLED */
/* Exported macro ------------------------------------------------------------*/
#ifdef USE_FULL_ASSERT
/**
* @brief The assert_param macro is used for function's parameters check.
* @param expr If expr is false, it calls assert_failed function
* which reports the name of the source file and the source
* line number of the call that failed.
* If expr is true, it returns no value.
* @retval None
*/
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
#ifdef __cplusplus
}
#endif
#endif /* __STM32F1xx_HAL_CONF_H */

67
Core/Inc/stm32f1xx_it.h Normal file
View File

@@ -0,0 +1,67 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32f1xx_it.h
* @brief This file contains the headers of the interrupt handlers.
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F1xx_IT_H
#define __STM32F1xx_IT_H
#ifdef __cplusplus
extern "C" {
#endif
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void DebugMon_Handler(void);
void DMA1_Channel4_IRQHandler(void);
void DMA1_Channel5_IRQHandler(void);
void USART1_IRQHandler(void);
void TIM8_UP_IRQHandler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
#ifdef __cplusplus
}
#endif
#endif /* __STM32F1xx_IT_H */

58
Core/Inc/usart.h Normal file
View File

@@ -0,0 +1,58 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file usart.h
* @brief This file contains all the function prototypes for
* the usart.c file
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USART_H__
#define __USART_H__
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern UART_HandleTypeDef huart5;
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart3;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_UART5_Init(void);
void MX_USART1_UART_Init(void);
void MX_USART3_UART_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /* __USART_H__ */

58
Core/Src/dma.c Normal file
View File

@@ -0,0 +1,58 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file dma.c
* @brief This file provides code for the configuration
* of all the requested memory to memory DMA transfers.
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "dma.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/*----------------------------------------------------------------------------*/
/* Configure DMA */
/*----------------------------------------------------------------------------*/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/**
* Enable DMA controller clock
*/
void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Channel4_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn);
/* DMA1_Channel5_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
}
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */

206
Core/Src/freertos.c Normal file
View File

@@ -0,0 +1,206 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : freertos.c
* Description : Code for freertos applications
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "FreeRTOS.h"
#include "task.h"
#include "main.h"
#include "cmsis_os.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "dx_wf_24.h"
#include "elog.h"
#include "string.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define TAG "Main"
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN Variables */
/* USER CODE END Variables */
/* Definitions for defaultTask */
osThreadId_t defaultTaskHandle;
const osThreadAttr_t defaultTask_attributes = {
.name = "defaultTask",
.stack_size = 256 * 4,
.priority = (osPriority_t) osPriorityNormal,
};
/* Definitions for wifi_mqtt */
osThreadId_t wifi_mqttHandle;
const osThreadAttr_t wifi_mqtt_attributes = {
.name = "wifi_mqtt",
.stack_size = 1024 * 4,
.priority = (osPriority_t) osPriorityHigh,
};
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN FunctionPrototypes */
/* USER CODE END FunctionPrototypes */
void StartDefaultTask(void *argument);
void wifi_task_mqtt(void *argument);
void MX_FREERTOS_Init(void); /* (MISRA C 2004 rule 8.1) */
/**
* @brief FreeRTOS initialization
* @param None
* @retval None
*/
void MX_FREERTOS_Init(void) {
/* USER CODE BEGIN Init */
easylogger_init(); // 初始化日志系统
__enable_irq(); // 开启全局中断
/* USER CODE END Init */
/* USER CODE BEGIN RTOS_MUTEX */
/* add mutexes, ... */
/* USER CODE END RTOS_MUTEX */
/* USER CODE BEGIN RTOS_SEMAPHORES */
/* add semaphores, ... */
/* USER CODE END RTOS_SEMAPHORES */
/* USER CODE BEGIN RTOS_TIMERS */
/* start timers, add new ones, ... */
/* USER CODE END RTOS_TIMERS */
/* USER CODE BEGIN RTOS_QUEUES */
/* add queues, ... */
/* USER CODE END RTOS_QUEUES */
/* Create the thread(s) */
/* creation of defaultTask */
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
/* creation of wifi_mqtt */
wifi_mqttHandle = osThreadNew(wifi_task_mqtt, NULL, &wifi_mqtt_attributes);
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* USER CODE END RTOS_THREADS */
/* USER CODE BEGIN RTOS_EVENTS */
/* add events, ... */
/* USER CODE END RTOS_EVENTS */
}
/* USER CODE BEGIN Header_StartDefaultTask */
/**
* @brief Function implementing the defaultTask thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
/* USER CODE BEGIN StartDefaultTask */
/* Infinite loop */
for (;;) {
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);
HAL_GPIO_TogglePin(MOTOR_GPIO_Port, MOTOR_Pin);
osDelay(1000);
}
/* USER CODE END StartDefaultTask */
}
/* USER CODE BEGIN Header_wifi_task_mqtt */
/**
* @brief Function implementing the wifi_mqtt thread.
* @param argument: Not used
* @retval None
*/
/* USER CODE END Header_wifi_task_mqtt */
void wifi_task_mqtt(void *argument)
{
/* USER CODE BEGIN wifi_task_mqtt */
WIFI_RECV_DMA_Init(); // 初始化 WiFi DMA 接收
/* 等待模块启动 */
elog_i(TAG, "Waiting for WiFi module to start...");
osDelay(3000);
/* 连接MQTT服务器 */
uint8_t connect_success = WIFI_Connect_MQTT(
"ChinaNet_WBH", // WiFi名称
"88888888", // WiFi密码
"broker.emqx.io", // MQTT服务器
1883, // MQTT端口
"STM32_MQTT", // 客户端ID
NULL, // MQTT用户名NULL表示无需认证
NULL, // MQTT密码NULL表示无需认证
"pet/control" // 订阅主题
);
if (connect_success) {
elog_i(TAG, "MQTT connection successful!");
} else {
elog_e(TAG, "MQTT connection failed!");
// 可以在这里添加失败处理,如重启模块或重试
}
uint8_t rx_data[WIFI_RX_BUF_SIZE];
/* Infinite loop */
for (;;) {
/* 检查并处理接收数据 */
if (wifi.rx_flag) {
int len = WIFI_Get_Received_Data(rx_data, sizeof(rx_data));
if (len > 0) {
// 处理 WiFi 返回数据
elog_d(TAG, "WiFi response: %s", rx_data);
// 检查MQTT消息
if (strstr((char*)rx_data, "+MQTTPUBLISH")) {
elog_i(TAG, "Received MQTT message!");
// TODO: 解析并处理MQTT消息
}
}
}
osDelay(100);
}
/* USER CODE END wifi_task_mqtt */
}
/* Private application code --------------------------------------------------*/
/* USER CODE BEGIN Application */
/* USER CODE END Application */

108
Core/Src/gpio.c Normal file
View File

@@ -0,0 +1,108 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file gpio.c
* @brief This file provides code for the configuration
* of all used GPIO pins.
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "gpio.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/*----------------------------------------------------------------------------*/
/* Configure GPIO */
/*----------------------------------------------------------------------------*/
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/** Configure pins as
* Analog
* Input
* Output
* EVENT_OUT
* EXTI
*/
void MX_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, HX711_SCK_Pin|LCD_DC_Pin|LCD_RESET_Pin|GPIO_PIN_8, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOC, LCD_CS_Pin|LCD_BLK_Pin|MOTOR_Pin|GPIO_PIN_7
|GPIO_PIN_8|GPIO_PIN_9, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, LED2_Pin|LED1_Pin, GPIO_PIN_RESET);
/*Configure GPIO pins : KEY1_Pin KEY2_Pin KEY3_Pin KEY3C3_Pin */
GPIO_InitStruct.Pin = KEY1_Pin|KEY2_Pin|KEY3_Pin|KEY3C3_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pin : HX711_DOUT_Pin */
GPIO_InitStruct.Pin = HX711_DOUT_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(HX711_DOUT_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : HX711_SCK_Pin LCD_DC_Pin LCD_RESET_Pin PA8 */
GPIO_InitStruct.Pin = HX711_SCK_Pin|LCD_DC_Pin|LCD_RESET_Pin|GPIO_PIN_8;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : LCD_CS_Pin LCD_BLK_Pin MOTOR_Pin PC7
PC8 PC9 */
GPIO_InitStruct.Pin = LCD_CS_Pin|LCD_BLK_Pin|MOTOR_Pin|GPIO_PIN_7
|GPIO_PIN_8|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/*Configure GPIO pins : LED2_Pin LED1_Pin */
GPIO_InitStruct.Pin = LED2_Pin|LED1_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pins : HC_SR505_IO_Pin M3_IO_Pin */
GPIO_InitStruct.Pin = HC_SR505_IO_Pin|M3_IO_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */

114
Core/Src/i2c.c Normal file
View File

@@ -0,0 +1,114 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file i2c.c
* @brief This file provides code for the configuration
* of the I2C instances.
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "i2c.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
I2C_HandleTypeDef hi2c1;
/* I2C1 init function */
void MX_I2C1_Init(void)
{
/* USER CODE BEGIN I2C1_Init 0 */
/* USER CODE END I2C1_Init 0 */
/* USER CODE BEGIN I2C1_Init 1 */
/* USER CODE END I2C1_Init 1 */
hi2c1.Instance = I2C1;
hi2c1.Init.ClockSpeed = 100000;
hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
hi2c1.Init.OwnAddress1 = 0;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
hi2c1.Init.OwnAddress2 = 0;
hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN I2C1_Init 2 */
/* USER CODE END I2C1_Init 2 */
}
void HAL_I2C_MspInit(I2C_HandleTypeDef* i2cHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(i2cHandle->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspInit 0 */
/* USER CODE END I2C1_MspInit 0 */
__HAL_RCC_GPIOB_CLK_ENABLE();
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* I2C1 clock enable */
__HAL_RCC_I2C1_CLK_ENABLE();
/* USER CODE BEGIN I2C1_MspInit 1 */
/* USER CODE END I2C1_MspInit 1 */
}
}
void HAL_I2C_MspDeInit(I2C_HandleTypeDef* i2cHandle)
{
if(i2cHandle->Instance==I2C1)
{
/* USER CODE BEGIN I2C1_MspDeInit 0 */
/* USER CODE END I2C1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_I2C1_CLK_DISABLE();
/**I2C1 GPIO Configuration
PB6 ------> I2C1_SCL
PB7 ------> I2C1_SDA
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_7);
/* USER CODE BEGIN I2C1_MspDeInit 1 */
/* USER CODE END I2C1_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

234
Core/Src/main.c Normal file
View File

@@ -0,0 +1,234 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "cmsis_os.h"
#include "dma.h"
#include "i2c.h"
#include "spi.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void MX_FREERTOS_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE {
HAL_UART_Transmit(&huart5, (uint8_t *) &ch, 1, HAL_MAX_DELAY);
return ch;
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_I2C1_Init();
MX_SPI1_Init();
MX_UART5_Init();
MX_USART1_UART_Init();
MX_USART3_UART_Init();
/* USER CODE BEGIN 2 */
/* USER CODE END 2 */
/* Init scheduler */
osKernelInitialize();
/* Call init function for freertos objects (in cmsis_os2.c) */
MX_FREERTOS_Init();
/* Start scheduler */
osKernelStart();
/* We should never get here as control is now taken by the scheduler */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
/* USER CODE BEGIN 4 */
/* USER CODE END 4 */
/**
* @brief Period elapsed callback in non blocking mode
* @note This function is called when TIM8 interrupt took place, inside
* HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
* a global variable "uwTick" used as application time base.
* @param htim : TIM handle
* @retval None
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* USER CODE BEGIN Callback 0 */
/* USER CODE END Callback 0 */
if (htim->Instance == TIM8) {
HAL_IncTick();
}
/* USER CODE BEGIN Callback 1 */
/* USER CODE END Callback 1 */
}
/**
* @brief This function is executed in case of error occurrence.
* @retval None
*/
void Error_Handler(void)
{
/* USER CODE BEGIN Error_Handler_Debug */
/* User can add his own implementation to report the HAL error return state */
__disable_irq();
while (1)
{
}
/* USER CODE END Error_Handler_Debug */
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t *file, uint32_t line)
{
/* USER CODE BEGIN 6 */
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

115
Core/Src/spi.c Normal file
View File

@@ -0,0 +1,115 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file spi.c
* @brief This file provides code for the configuration
* of the SPI instances.
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "spi.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
SPI_HandleTypeDef hspi1;
/* SPI1 init function */
void MX_SPI1_Init(void)
{
/* USER CODE BEGIN SPI1_Init 0 */
/* USER CODE END SPI1_Init 0 */
/* USER CODE BEGIN SPI1_Init 1 */
/* USER CODE END SPI1_Init 1 */
hspi1.Instance = SPI1;
hspi1.Init.Mode = SPI_MODE_MASTER;
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi1.Init.NSS = SPI_NSS_SOFT;
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
hspi1.Init.CRCPolynomial = 10;
if (HAL_SPI_Init(&hspi1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN SPI1_Init 2 */
/* USER CODE END SPI1_Init 2 */
}
void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(spiHandle->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspInit 0 */
/* USER CODE END SPI1_MspInit 0 */
/* SPI1 clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**SPI1 GPIO Configuration
PA5 ------> SPI1_SCK
PA7 ------> SPI1_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USER CODE BEGIN SPI1_MspInit 1 */
/* USER CODE END SPI1_MspInit 1 */
}
}
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle)
{
if(spiHandle->Instance==SPI1)
{
/* USER CODE BEGIN SPI1_MspDeInit 0 */
/* USER CODE END SPI1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SPI1_CLK_DISABLE();
/**SPI1 GPIO Configuration
PA5 ------> SPI1_SCK
PA7 ------> SPI1_MOSI
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_7);
/* USER CODE BEGIN SPI1_MspDeInit 1 */
/* USER CODE END SPI1_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

View File

@@ -0,0 +1,88 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32f1xx_hal_msp.c
* @brief This file provides code for the MSP Initialization
* and de-Initialization codes.
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN Define */
/* USER CODE END Define */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN Macro */
/* USER CODE END Macro */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* External functions --------------------------------------------------------*/
/* USER CODE BEGIN ExternalFunctions */
/* USER CODE END ExternalFunctions */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* Initializes the Global MSP.
*/
void HAL_MspInit(void)
{
/* USER CODE BEGIN MspInit 0 */
/* USER CODE END MspInit 0 */
__HAL_RCC_AFIO_CLK_ENABLE();
__HAL_RCC_PWR_CLK_ENABLE();
/* System interrupt init*/
/* PendSV_IRQn interrupt configuration */
HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0);
/** NOJTAG: JTAG-DP Disabled and SW-DP Enabled
*/
__HAL_AFIO_REMAP_SWJ_NOJTAG();
/* USER CODE BEGIN MspInit 1 */
/* USER CODE END MspInit 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

View File

@@ -0,0 +1,130 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32f1xx_hal_timebase_tim.c
* @brief HAL time base based on the hardware TIM.
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "stm32f1xx_hal.h"
#include "stm32f1xx_hal_tim.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
TIM_HandleTypeDef htim8;
/* Private function prototypes -----------------------------------------------*/
void TIM8_IRQHandler(void);
/* Private functions ---------------------------------------------------------*/
/**
* @brief This function configures the TIM8 as a time base source.
* The time source is configured to have 1ms time base with a dedicated
* Tick interrupt priority.
* @note This function is called automatically at the beginning of program after
* reset by HAL_Init() or at any time when clock is configured, by HAL_RCC_ClockConfig().
* @param TickPriority: Tick interrupt priority.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
{
RCC_ClkInitTypeDef clkconfig;
uint32_t uwTimclock = 0U;
uint32_t uwPrescalerValue = 0U;
uint32_t pFLatency;
HAL_StatusTypeDef status = HAL_OK;
/* Enable TIM8 clock */
__HAL_RCC_TIM8_CLK_ENABLE();
/* Get clock configuration */
HAL_RCC_GetClockConfig(&clkconfig, &pFLatency);
/* Compute TIM8 clock */
uwTimclock = HAL_RCC_GetPCLK2Freq();
/* Compute the prescaler value to have TIM8 counter clock equal to 1MHz */
uwPrescalerValue = (uint32_t) ((uwTimclock / 1000000U) - 1U);
/* Initialize TIM8 */
htim8.Instance = TIM8;
/* Initialize TIMx peripheral as follow:
+ Period = [(TIM8CLK/1000) - 1]. to have a (1/1000) s time base.
+ Prescaler = (uwTimclock/1000000 - 1) to have a 1MHz counter clock.
+ ClockDivision = 0
+ Counter direction = Up
*/
htim8.Init.Period = (1000000U / 1000U) - 1U;
htim8.Init.Prescaler = uwPrescalerValue;
htim8.Init.ClockDivision = 0;
htim8.Init.CounterMode = TIM_COUNTERMODE_UP;
htim8.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
status = HAL_TIM_Base_Init(&htim8);
if (status == HAL_OK)
{
/* Start the TIM time Base generation in interrupt mode */
status = HAL_TIM_Base_Start_IT(&htim8);
if (status == HAL_OK)
{
/* Enable the TIM8 global Interrupt */
HAL_NVIC_EnableIRQ(TIM8_UP_IRQn);
/* Configure the SysTick IRQ priority */
if (TickPriority < (1UL << __NVIC_PRIO_BITS))
{
/* Configure the TIM IRQ priority */
HAL_NVIC_SetPriority(TIM8_UP_IRQn, TickPriority, 0U);
uwTickPrio = TickPriority;
}
else
{
status = HAL_ERROR;
}
}
}
/* Return function status */
return status;
}
/**
* @brief Suspend Tick increment.
* @note Disable the tick increment by disabling TIM8 update interrupt.
* @param None
* @retval None
*/
void HAL_SuspendTick(void)
{
/* Disable TIM8 update Interrupt */
__HAL_TIM_DISABLE_IT(&htim8, TIM_IT_UPDATE);
}
/**
* @brief Resume Tick increment.
* @note Enable the tick increment by Enabling TIM8 update interrupt.
* @param None
* @retval None
*/
void HAL_ResumeTick(void)
{
/* Enable TIM8 Update interrupt */
__HAL_TIM_ENABLE_IT(&htim8, TIM_IT_UPDATE);
}

228
Core/Src/stm32f1xx_it.c Normal file
View File

@@ -0,0 +1,228 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32f1xx_it.c
* @brief Interrupt Service Routines.
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f1xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "dx_wf_24.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
extern DMA_HandleTypeDef hdma_usart1_tx;
extern DMA_HandleTypeDef hdma_usart1_rx;
extern UART_HandleTypeDef huart1;
extern TIM_HandleTypeDef htim8;
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/******************************************************************************/
/* Cortex-M3 Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
* @brief This function handles Non maskable interrupt.
*/
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
/* USER CODE END NonMaskableInt_IRQn 0 */
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
while (1)
{
}
/* USER CODE END NonMaskableInt_IRQn 1 */
}
/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
/**
* @brief This function handles Memory management fault.
*/
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
/* USER CODE END MemoryManagement_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
/* USER CODE END W1_MemoryManagement_IRQn 0 */
}
}
/**
* @brief This function handles Prefetch fault, memory access fault.
*/
void BusFault_Handler(void)
{
/* USER CODE BEGIN BusFault_IRQn 0 */
/* USER CODE END BusFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
/* USER CODE END W1_BusFault_IRQn 0 */
}
}
/**
* @brief This function handles Undefined instruction or illegal state.
*/
void UsageFault_Handler(void)
{
/* USER CODE BEGIN UsageFault_IRQn 0 */
/* USER CODE END UsageFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
/* USER CODE END W1_UsageFault_IRQn 0 */
}
}
/**
* @brief This function handles Debug monitor.
*/
void DebugMon_Handler(void)
{
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
/* USER CODE END DebugMonitor_IRQn 0 */
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
/* USER CODE END DebugMonitor_IRQn 1 */
}
/******************************************************************************/
/* STM32F1xx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32f1xx.s). */
/******************************************************************************/
/**
* @brief This function handles DMA1 channel4 global interrupt.
*/
void DMA1_Channel4_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel4_IRQn 0 */
/* USER CODE END DMA1_Channel4_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart1_tx);
/* USER CODE BEGIN DMA1_Channel4_IRQn 1 */
/* USER CODE END DMA1_Channel4_IRQn 1 */
}
/**
* @brief This function handles DMA1 channel5 global interrupt.
*/
void DMA1_Channel5_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Channel5_IRQn 0 */
/* USER CODE END DMA1_Channel5_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart1_rx);
/* USER CODE BEGIN DMA1_Channel5_IRQn 1 */
/* USER CODE END DMA1_Channel5_IRQn 1 */
}
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* 检查空闲中断标志 */
if (__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)) {
WIFI_UART_IDLE_Callback(&huart1);
return; // 已处理,直接返回
}
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
/* USER CODE END USART1_IRQn 1 */
}
/**
* @brief This function handles TIM8 update interrupt.
*/
void TIM8_UP_IRQHandler(void)
{
/* USER CODE BEGIN TIM8_UP_IRQn 0 */
/* USER CODE END TIM8_UP_IRQn 0 */
HAL_TIM_IRQHandler(&htim8);
/* USER CODE BEGIN TIM8_UP_IRQn 1 */
/* USER CODE END TIM8_UP_IRQn 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */

244
Core/Src/syscalls.c Normal file
View File

@@ -0,0 +1,244 @@
/**
******************************************************************************
* @file syscalls.c
* @author Auto-generated by STM32CubeMX
* @brief Minimal System calls file
*
* For more information about which c-functions
* need which of these lowlevel functions
* please consult the Newlib or Picolibc libc-manual
******************************************************************************
* @attention
*
* Copyright (c) 2020-2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Includes */
#include <sys/stat.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <sys/times.h>
/* Variables */
extern int __io_putchar(int ch) __attribute__((weak));
extern int __io_getchar(void) __attribute__((weak));
char *__env[1] = { 0 };
char **environ = __env;
/* Functions */
void initialise_monitor_handles()
{
}
int _getpid(void)
{
return 1;
}
int _kill(int pid, int sig)
{
(void)pid;
(void)sig;
errno = EINVAL;
return -1;
}
void _exit (int status)
{
_kill(status, -1);
while (1) {} /* Make sure we hang here */
}
__attribute__((weak)) int _read(int file, char *ptr, int len)
{
(void)file;
int DataIdx;
for (DataIdx = 0; DataIdx < len; DataIdx++)
{
*ptr++ = __io_getchar();
}
return len;
}
__attribute__((weak)) int _write(int file, char *ptr, int len)
{
(void)file;
int DataIdx;
for (DataIdx = 0; DataIdx < len; DataIdx++)
{
__io_putchar(*ptr++);
}
return len;
}
int _close(int file)
{
(void)file;
return -1;
}
int _fstat(int file, struct stat *st)
{
(void)file;
st->st_mode = S_IFCHR;
return 0;
}
int _isatty(int file)
{
(void)file;
return 1;
}
int _lseek(int file, int ptr, int dir)
{
(void)file;
(void)ptr;
(void)dir;
return 0;
}
int _open(char *path, int flags, ...)
{
(void)path;
(void)flags;
/* Pretend like we always fail */
return -1;
}
int _wait(int *status)
{
(void)status;
errno = ECHILD;
return -1;
}
int _unlink(char *name)
{
(void)name;
errno = ENOENT;
return -1;
}
clock_t _times(struct tms *buf)
{
(void)buf;
return -1;
}
int _stat(const char *file, struct stat *st)
{
(void)file;
st->st_mode = S_IFCHR;
return 0;
}
int _link(char *old, char *new)
{
(void)old;
(void)new;
errno = EMLINK;
return -1;
}
int _fork(void)
{
errno = EAGAIN;
return -1;
}
int _execve(char *name, char **argv, char **env)
{
(void)name;
(void)argv;
(void)env;
errno = ENOMEM;
return -1;
}
// --- Picolibc Specific Section ---
#if defined(__PICOLIBC__)
/**
* @brief Picolibc helper function to output a character to a FILE stream.
* This redirects the output to the low-level __io_putchar function.
* @param c Character to write.
* @param file FILE stream pointer (ignored).
* @retval int The character written.
*/
static int starm_putc(char c, FILE *file)
{
(void) file;
__io_putchar(c);
return c;
}
/**
* @brief Picolibc helper function to input a character from a FILE stream.
* This redirects the input from the low-level __io_getchar function.
* @param file FILE stream pointer (ignored).
* @retval int The character read, cast to an unsigned char then int.
*/
static int starm_getc(FILE *file)
{
unsigned char c;
(void) file;
c = __io_getchar();
return c;
}
// Define and initialize the standard I/O streams for Picolibc.
// FDEV_SETUP_STREAM connects the starm_putc and starm_getc helper functions to a FILE structure.
// _FDEV_SETUP_RW indicates the stream is for reading and writing.
static FILE __stdio = FDEV_SETUP_STREAM(starm_putc,
starm_getc,
NULL,
_FDEV_SETUP_RW);
// Assign the standard stream pointers (stdin, stdout, stderr) to the initialized stream.
// Picolibc uses these pointers for standard I/O operations (printf, scanf, etc.).
FILE *const stdin = &__stdio;
__strong_reference(stdin, stdout);
__strong_reference(stdin, stderr);
// Create strong aliases mapping standard C library function names (without underscore)
// to the implemented system call stubs (with underscore). Picolibc uses these
// standard names internally, so this linking is required.
__strong_reference(_read, read);
__strong_reference(_write, write);
__strong_reference(_times, times);
__strong_reference(_execve, execve);
__strong_reference(_fork, fork);
__strong_reference(_link, link);
__strong_reference(_unlink, unlink);
__strong_reference(_stat, stat);
__strong_reference(_wait, wait);
__strong_reference(_open, open);
__strong_reference(_close, close);
__strong_reference(_lseek, lseek);
__strong_reference(_isatty, isatty);
__strong_reference(_fstat, fstat);
__strong_reference(_exit, exit);
__strong_reference(_kill, kill);
__strong_reference(_getpid, getpid);
#endif //__PICOLIBC__

87
Core/Src/sysmem.c Normal file
View File

@@ -0,0 +1,87 @@
/**
******************************************************************************
* @file sysmem.c
* @author Generated by STM32CubeMX
* @brief System Memory calls file
*
* For more information about which C functions
* need which of these lowlevel functions
* please consult the Newlib or Picolibc libc manual
******************************************************************************
* @attention
*
* Copyright (c) 2025 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* Includes */
#include <errno.h>
#include <stdint.h>
#include <stddef.h>
/**
* Pointer to the current high watermark of the heap usage
*/
static uint8_t *__sbrk_heap_end = NULL;
/**
* @brief _sbrk() allocates memory to the newlib heap and is used by malloc
* and others from the C library
*
* @verbatim
* ############################################################################
* # .data # .bss # newlib heap # MSP stack #
* # # # # Reserved by _Min_Stack_Size #
* ############################################################################
* ^-- RAM start ^-- _end _estack, RAM end --^
* @endverbatim
*
* This implementation starts allocating at the '_end' linker symbol
* The '_Min_Stack_Size' linker symbol reserves a memory for the MSP stack
* The implementation considers '_estack' linker symbol to be RAM end
* NOTE: If the MSP stack, at any point during execution, grows larger than the
* reserved size, please increase the '_Min_Stack_Size'.
*
* @param incr Memory size
* @return Pointer to allocated memory
*/
void *_sbrk(ptrdiff_t incr)
{
extern uint8_t _end; /* Symbol defined in the linker script */
extern uint8_t _estack; /* Symbol defined in the linker script */
extern uint32_t _Min_Stack_Size; /* Symbol defined in the linker script */
const uint32_t stack_limit = (uint32_t)&_estack - (uint32_t)&_Min_Stack_Size;
const uint8_t *max_heap = (uint8_t *)stack_limit;
uint8_t *prev_heap_end;
/* Initialize heap end at first call */
if (NULL == __sbrk_heap_end)
{
__sbrk_heap_end = &_end;
}
/* Protect heap from growing into the reserved MSP stack */
if (__sbrk_heap_end + incr > max_heap)
{
errno = ENOMEM;
return (void *)-1;
}
prev_heap_end = __sbrk_heap_end;
__sbrk_heap_end += incr;
return (void *)prev_heap_end;
}
#if defined(__PICOLIBC__)
// Picolibc expects syscalls without the leading underscore.
// This creates a strong alias so that
// calls to `sbrk()` are resolved to our `_sbrk()` implementation.
__strong_reference(_sbrk, sbrk);
#endif

406
Core/Src/system_stm32f1xx.c Normal file
View File

@@ -0,0 +1,406 @@
/**
******************************************************************************
* @file system_stm32f1xx.c
* @author MCD Application Team
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer System Source File.
*
* 1. This file provides two functions and one global variable to be called from
* user application:
* - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
* factors, AHB/APBx prescalers and Flash settings).
* This function is called at startup just after reset and
* before branch to main program. This call is made inside
* the "startup_stm32f1xx_xx.s" file.
*
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
* by the user application to setup the SysTick
* timer or configure other parameters.
*
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed
* during program execution.
*
* 2. After each device reset the HSI (8 MHz) is used as system clock source.
* Then SystemInit() function is called, in "startup_stm32f1xx_xx.s" file, to
* configure the system clock before to branch to main program.
*
* 4. The default value of HSE crystal is set to 8 MHz (or 25 MHz, depending on
* the product used), refer to "HSE_VALUE".
* When HSE is used as system clock source, directly or through PLL, and you
* are using different crystal you have to adapt the HSE value to your own
* configuration.
*
******************************************************************************
* @attention
*
* Copyright (c) 2017-2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32f1xx_system
* @{
*/
/** @addtogroup STM32F1xx_System_Private_Includes
* @{
*/
#include "stm32f1xx.h"
/**
* @}
*/
/** @addtogroup STM32F1xx_System_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F1xx_System_Private_Defines
* @{
*/
#if !defined (HSE_VALUE)
#define HSE_VALUE 8000000U /*!< Default value of the External oscillator in Hz.
This value can be provided and adapted by the user application. */
#endif /* HSE_VALUE */
#if !defined (HSI_VALUE)
#define HSI_VALUE 8000000U /*!< Default value of the Internal oscillator in Hz.
This value can be provided and adapted by the user application. */
#endif /* HSI_VALUE */
/*!< Uncomment the following line if you need to use external SRAM */
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
/* #define DATA_IN_ExtSRAM */
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
/* Note: Following vector table addresses must be defined in line with linker
configuration. */
/*!< Uncomment the following line if you need to relocate the vector table
anywhere in Flash or Sram, else the vector table is kept at the automatic
remap of boot address selected */
/* #define USER_VECT_TAB_ADDRESS */
#if defined(USER_VECT_TAB_ADDRESS)
/*!< Uncomment the following line if you need to relocate your vector Table
in Sram else user remap will be done in Flash. */
/* #define VECT_TAB_SRAM */
#if defined(VECT_TAB_SRAM)
#define VECT_TAB_BASE_ADDRESS SRAM_BASE /*!< Vector Table base address field.
This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#else
#define VECT_TAB_BASE_ADDRESS FLASH_BASE /*!< Vector Table base address field.
This value must be a multiple of 0x200. */
#define VECT_TAB_OFFSET 0x00000000U /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
#endif /* VECT_TAB_SRAM */
#endif /* USER_VECT_TAB_ADDRESS */
/******************************************************************************/
/**
* @}
*/
/** @addtogroup STM32F1xx_System_Private_Macros
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F1xx_System_Private_Variables
* @{
*/
/* This variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate()
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
Note: If you use this function to configure the system clock; then there
is no need to call the 2 first functions listed above, since SystemCoreClock
variable is updated automatically.
*/
uint32_t SystemCoreClock = 8000000;
const uint8_t AHBPrescTable[16U] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
const uint8_t APBPrescTable[8U] = {0, 0, 0, 0, 1, 2, 3, 4};
/**
* @}
*/
/** @addtogroup STM32F1xx_System_Private_FunctionPrototypes
* @{
*/
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
#ifdef DATA_IN_ExtSRAM
static void SystemInit_ExtMemCtl(void);
#endif /* DATA_IN_ExtSRAM */
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
/**
* @}
*/
/** @addtogroup STM32F1xx_System_Private_Functions
* @{
*/
/**
* @brief Setup the microcontroller system
* Initialize the Embedded Flash Interface, the PLL and update the
* SystemCoreClock variable.
* @note This function should be used only after reset.
* @param None
* @retval None
*/
void SystemInit (void)
{
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
#ifdef DATA_IN_ExtSRAM
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM */
#endif
/* Configure the Vector Table location -------------------------------------*/
#if defined(USER_VECT_TAB_ADDRESS)
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#endif /* USER_VECT_TAB_ADDRESS */
}
/**
* @brief Update SystemCoreClock variable according to Clock Register Values.
* The SystemCoreClock variable contains the core clock (HCLK), it can
* be used by the user application to setup the SysTick timer or configure
* other parameters.
*
* @note Each time the core clock (HCLK) changes, this function must be called
* to update SystemCoreClock variable value. Otherwise, any configuration
* based on this variable will be incorrect.
*
* @note - The system frequency computed by this function is not the real
* frequency in the chip. It is calculated based on the predefined
* constant and the selected clock source:
*
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
*
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
*
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
* or HSI_VALUE(*) multiplied by the PLL factors.
*
* (*) HSI_VALUE is a constant defined in stm32f1xx.h file (default value
* 8 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (**) HSE_VALUE is a constant defined in stm32f1xx.h file (default value
* 8 MHz or 25 MHz, depending on the product used), user has to ensure
* that HSE_VALUE is same as the real frequency of the crystal used.
* Otherwise, this function may have wrong result.
*
* - The result of this function could be not correct when using fractional
* value for HSE crystal.
* @param None
* @retval None
*/
void SystemCoreClockUpdate (void)
{
uint32_t tmp = 0U, pllmull = 0U, pllsource = 0U;
#if defined(STM32F105xC) || defined(STM32F107xC)
uint32_t prediv1source = 0U, prediv1factor = 0U, prediv2factor = 0U, pll2mull = 0U;
#endif /* STM32F105xC */
#if defined(STM32F100xB) || defined(STM32F100xE)
uint32_t prediv1factor = 0U;
#endif /* STM32F100xB or STM32F100xE */
/* Get SYSCLK source -------------------------------------------------------*/
tmp = RCC->CFGR & RCC_CFGR_SWS;
switch (tmp)
{
case 0x00U: /* HSI used as system clock */
SystemCoreClock = HSI_VALUE;
break;
case 0x04U: /* HSE used as system clock */
SystemCoreClock = HSE_VALUE;
break;
case 0x08U: /* PLL used as system clock */
/* Get PLL clock source and multiplication factor ----------------------*/
pllmull = RCC->CFGR & RCC_CFGR_PLLMULL;
pllsource = RCC->CFGR & RCC_CFGR_PLLSRC;
#if !defined(STM32F105xC) && !defined(STM32F107xC)
pllmull = ( pllmull >> 18U) + 2U;
if (pllsource == 0x00U)
{
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
}
else
{
#if defined(STM32F100xB) || defined(STM32F100xE)
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
/* HSE oscillator clock selected as PREDIV1 clock entry */
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
#else
/* HSE selected as PLL clock entry */
if ((RCC->CFGR & RCC_CFGR_PLLXTPRE) != (uint32_t)RESET)
{/* HSE oscillator clock divided by 2 */
SystemCoreClock = (HSE_VALUE >> 1U) * pllmull;
}
else
{
SystemCoreClock = HSE_VALUE * pllmull;
}
#endif
}
#else
pllmull = pllmull >> 18U;
if (pllmull != 0x0DU)
{
pllmull += 2U;
}
else
{ /* PLL multiplication factor = PLL input clock * 6.5 */
pllmull = 13U / 2U;
}
if (pllsource == 0x00U)
{
/* HSI oscillator clock divided by 2 selected as PLL clock entry */
SystemCoreClock = (HSI_VALUE >> 1U) * pllmull;
}
else
{/* PREDIV1 selected as PLL clock entry */
/* Get PREDIV1 clock source and division factor */
prediv1source = RCC->CFGR2 & RCC_CFGR2_PREDIV1SRC;
prediv1factor = (RCC->CFGR2 & RCC_CFGR2_PREDIV1) + 1U;
if (prediv1source == 0U)
{
/* HSE oscillator clock selected as PREDIV1 clock entry */
SystemCoreClock = (HSE_VALUE / prediv1factor) * pllmull;
}
else
{/* PLL2 clock selected as PREDIV1 clock entry */
/* Get PREDIV2 division factor and PLL2 multiplication factor */
prediv2factor = ((RCC->CFGR2 & RCC_CFGR2_PREDIV2) >> 4U) + 1U;
pll2mull = ((RCC->CFGR2 & RCC_CFGR2_PLL2MUL) >> 8U) + 2U;
SystemCoreClock = (((HSE_VALUE / prediv2factor) * pll2mull) / prediv1factor) * pllmull;
}
}
#endif /* STM32F105xC */
break;
default:
SystemCoreClock = HSI_VALUE;
break;
}
/* Compute HCLK clock frequency ----------------*/
/* Get HCLK prescaler */
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4U)];
/* HCLK clock frequency */
SystemCoreClock >>= tmp;
}
#if defined(STM32F100xE) || defined(STM32F101xE) || defined(STM32F101xG) || defined(STM32F103xE) || defined(STM32F103xG)
/**
* @brief Setup the external memory controller. Called in startup_stm32f1xx.s
* before jump to __main
* @param None
* @retval None
*/
#ifdef DATA_IN_ExtSRAM
/**
* @brief Setup the external memory controller.
* Called in startup_stm32f1xx_xx.s/.c before jump to main.
* This function configures the external SRAM mounted on STM3210E-EVAL
* board (STM32 High density devices). This SRAM will be used as program
* data memory (including heap and stack).
* @param None
* @retval None
*/
void SystemInit_ExtMemCtl(void)
{
__IO uint32_t tmpreg;
/*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is
required, then adjust the Register Addresses */
/* Enable FSMC clock */
RCC->AHBENR = 0x00000114U;
/* Delay after an RCC peripheral clock enabling */
tmpreg = READ_BIT(RCC->AHBENR, RCC_AHBENR_FSMCEN);
/* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */
RCC->APB2ENR = 0x000001E0U;
/* Delay after an RCC peripheral clock enabling */
tmpreg = READ_BIT(RCC->APB2ENR, RCC_APB2ENR_IOPDEN);
(void)(tmpreg);
/* --------------- SRAM Data lines, NOE and NWE configuration ---------------*/
/*---------------- SRAM Address lines configuration -------------------------*/
/*---------------- NOE and NWE configuration --------------------------------*/
/*---------------- NE3 configuration ----------------------------------------*/
/*---------------- NBL0, NBL1 configuration ---------------------------------*/
GPIOD->CRL = 0x44BB44BBU;
GPIOD->CRH = 0xBBBBBBBBU;
GPIOE->CRL = 0xB44444BBU;
GPIOE->CRH = 0xBBBBBBBBU;
GPIOF->CRL = 0x44BBBBBBU;
GPIOF->CRH = 0xBBBB4444U;
GPIOG->CRL = 0x44BBBBBBU;
GPIOG->CRH = 0x444B4B44U;
/*---------------- FSMC Configuration ---------------------------------------*/
/*---------------- Enable FSMC Bank1_SRAM Bank ------------------------------*/
FSMC_Bank1->BTCR[4U] = 0x00001091U;
FSMC_Bank1->BTCR[5U] = 0x00110212U;
}
#endif /* DATA_IN_ExtSRAM */
#endif /* STM32F100xE || STM32F101xE || STM32F101xG || STM32F103xE || STM32F103xG */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/

313
Core/Src/usart.c Normal file
View File

@@ -0,0 +1,313 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file usart.c
* @brief This file provides code for the configuration
* of the USART instances.
******************************************************************************
* @attention
*
* Copyright (c) 2026 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "usart.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
UART_HandleTypeDef huart5;
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart3;
DMA_HandleTypeDef hdma_usart1_tx;
DMA_HandleTypeDef hdma_usart1_rx;
/* UART5 init function */
void MX_UART5_Init(void)
{
/* USER CODE BEGIN UART5_Init 0 */
/* USER CODE END UART5_Init 0 */
/* USER CODE BEGIN UART5_Init 1 */
/* USER CODE END UART5_Init 1 */
huart5.Instance = UART5;
huart5.Init.BaudRate = 115200;
huart5.Init.WordLength = UART_WORDLENGTH_8B;
huart5.Init.StopBits = UART_STOPBITS_1;
huart5.Init.Parity = UART_PARITY_NONE;
huart5.Init.Mode = UART_MODE_TX_RX;
huart5.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart5.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart5) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN UART5_Init 2 */
/* USER CODE END UART5_Init 2 */
}
/* USART1 init function */
void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
/* USART3 init function */
void MX_USART3_UART_Init(void)
{
/* USER CODE BEGIN USART3_Init 0 */
/* USER CODE END USART3_Init 0 */
/* USER CODE BEGIN USART3_Init 1 */
/* USER CODE END USART3_Init 1 */
huart3.Instance = USART3;
huart3.Init.BaudRate = 115200;
huart3.Init.WordLength = UART_WORDLENGTH_8B;
huart3.Init.StopBits = UART_STOPBITS_1;
huart3.Init.Parity = UART_PARITY_NONE;
huart3.Init.Mode = UART_MODE_TX_RX;
huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart3.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart3) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART3_Init 2 */
/* USER CODE END USART3_Init 2 */
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==UART5)
{
/* USER CODE BEGIN UART5_MspInit 0 */
/* USER CODE END UART5_MspInit 0 */
/* UART5 clock enable */
__HAL_RCC_UART5_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/**UART5 GPIO Configuration
PC12 ------> UART5_TX
PD2 ------> UART5_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* USER CODE BEGIN UART5_MspInit 1 */
/* USER CODE END UART5_MspInit 1 */
}
else if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/* USART1 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART1 DMA Init */
/* USART1_TX Init */
hdma_usart1_tx.Instance = DMA1_Channel4;
hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_tx.Init.Mode = DMA_NORMAL;
hdma_usart1_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmatx,hdma_usart1_tx);
/* USART1_RX Init */
hdma_usart1_rx.Instance = DMA1_Channel5;
hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart1_rx.Init.Mode = DMA_CIRCULAR;
hdma_usart1_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(uartHandle,hdmarx,hdma_usart1_rx);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */
}
else if(uartHandle->Instance==USART3)
{
/* USER CODE BEGIN USART3_MspInit 0 */
/* USER CODE END USART3_MspInit 0 */
/* USART3 clock enable */
__HAL_RCC_USART3_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**USART3 GPIO Configuration
PB10 ------> USART3_TX
PB11 ------> USART3_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN USART3_MspInit 1 */
/* USER CODE END USART3_MspInit 1 */
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==UART5)
{
/* USER CODE BEGIN UART5_MspDeInit 0 */
/* USER CODE END UART5_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_UART5_CLK_DISABLE();
/**UART5 GPIO Configuration
PC12 ------> UART5_TX
PD2 ------> UART5_RX
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_12);
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_2);
/* USER CODE BEGIN UART5_MspDeInit 1 */
/* USER CODE END UART5_MspDeInit 1 */
}
else if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspDeInit 0 */
/* USER CODE END USART1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART1_CLK_DISABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_9|GPIO_PIN_10);
/* USART1 DMA DeInit */
HAL_DMA_DeInit(uartHandle->hdmatx);
HAL_DMA_DeInit(uartHandle->hdmarx);
/* USART1 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspDeInit 1 */
/* USER CODE END USART1_MspDeInit 1 */
}
else if(uartHandle->Instance==USART3)
{
/* USER CODE BEGIN USART3_MspDeInit 0 */
/* USER CODE END USART3_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART3_CLK_DISABLE();
/**USART3 GPIO Configuration
PB10 ------> USART3_TX
PB11 ------> USART3_RX
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10|GPIO_PIN_11);
/* USER CODE BEGIN USART3_MspDeInit 1 */
/* USER CODE END USART3_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */