关键芯片都驱动,且测试成功

This commit is contained in:
2026-07-18 16:09:06 +08:00
parent 3466c4c062
commit fe107ea9af
42 changed files with 16193 additions and 501 deletions

View File

@@ -18,6 +18,8 @@
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "dma.h"
#include "i2c.h"
#include "spi.h"
#include "usart.h"
#include "gpio.h"
@@ -28,7 +30,9 @@
#include <stdio.h>
#include "ch395f.h"
#include "gd5f2gq5ue.h"
#include "flashdb.h"
#include "tpafe5160.h"
#include "sd2506.h"
#include "rs485.h"
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
@@ -49,7 +53,10 @@
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* RS-485 通信实例UART5: PC12=TX, PD2=RX, PD0=DE */
rs485_handle_t g_rs485;
#define RS485_RX_BUF_SIZE 256
uint8_t g_rs485_rx_buf[RS485_RX_BUF_SIZE];
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
@@ -71,7 +78,6 @@ int main(void)
{
/* USER CODE BEGIN 1 */
uint8_t str[] = "Hello World\n";
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
@@ -92,95 +98,123 @@ int main(void)
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART1_UART_Init();
MX_SPI2_Init();
MX_SPI1_Init();
MX_I2C1_Init();
MX_UART4_Init();
MX_UART5_Init();
MX_USART2_UART_Init();
MX_USART3_UART_Init();
/* USER CODE BEGIN 2 */
char dbg[64];
uint8_t mac[6];
HAL_Delay(100);
ch395f_reset();
/* CH395F 硬件检测 */
ch395f_status_t ch395f_ret = ch395f_check_exist();
printf("[CH395F] SPI: %s\r\n",
(ch395f_ret == CH395F_STATUS_OK) ? "OK" : "FAIL");
/* [1/5] SPI 通信检测 */
sprintf(dbg, "[1/5] CH395F %s\r\n",
(ch395f_check_exist() == CH395F_STATUS_OK) ? "detected" : "ERROR: not detected");
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
printf("[CH395F] version: 0x%02X\r\n", ch395f_get_version());
/* [2/5] 芯片版本 */
sprintf(dbg, "[2/5] CH395F version: 0x%02X\r\n", ch395f_get_version());
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
if (ch395f_ret == CH395F_STATUS_OK) {
/* 1. 复位 */
ch395f_reset();
/* 配置 IP/网关/掩码 */
{
/* 2. 配置网络参数(必须在 INIT 之前INIT 会锁定协议栈参数) */
uint8_t ip[4] = {192, 168, 1, 100};
uint8_t gw[4] = {192, 168, 1, 1};
uint8_t mask[4] = {255, 255, 255, 0};
ch395f_set_ip_addr(ip);
ch395f_set_gwip_addr(gw);
ch395f_set_mask_addr(mask);
}
/* [3/5] 协议栈初始化 */
sprintf(dbg, "[3/5] Protocol stack init %s\r\n",
(ch395f_init() == CH395F_STATUS_OK) ? "OK" : "ERROR");
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
/* 3. 初始化协议栈(锁定 IP/GW/MASK 等参数) */
printf("[CH395F] init: %s\r\n",
(ch395f_init() == CH395F_STATUS_OK) ? "OK" : "FAIL");
/* [4/5] MAC 地址 */
ch395f_get_mac_addr(mac);
sprintf(dbg, "[4/5] MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
/* 4. 读取 MAC */
uint8_t mac[6];
ch395f_get_mac_addr(mac);
printf("[CH395F] MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
/* [5/5] 强制 100M 全双工后检测 PHY */
ch395f_set_phy(CH395F_PHY_100M_FULL);
HAL_Delay(3000);
{
uint8_t s = ch395f_get_phy_status();
const char *desc = (s == CH395F_PHY_DISCONN) ? "DISCONNECTED" :
(s == CH395F_PHY_100M_FULL) ? "100M FULL" :
(s == CH395F_PHY_100M_HALF) ? "100M HALF" :
(s == CH395F_PHY_10M_FULL) ? "10M FULL" :
(s == CH395F_PHY_10M_HALF) ? "10M HALF" : "RESERVED";
sprintf(dbg, "[5/5] PHY: 0x%02X (%s)\r\n", s, desc);
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
}
/* ===================== FlashDB KVDB 测试 ===================== */
{
uint8_t gd_mid, gd_did;
int ret;
/* 检测 GD5F2GQ5UE */
ret = gd5f2gq5ue_read_id(&gd_mid, &gd_did);
sprintf(dbg, "[GD5F] ID: MID=0x%02X DID=0x%02X %s\r\n",
gd_mid, gd_did,
(ret == GD5F_OK && gd_mid == 0xC8 && gd_did == 0x52) ? "OK" : "FAIL");
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
/* 初始化 FlashDB KVDB */
{
static struct fdb_kvdb kvdb;
ret = fdb_kvdb_init(&kvdb, "db", "fdb_kvdb1", NULL, NULL);
sprintf(dbg, "[FlashDB] KVDB init: %s\r\n",
(ret == FDB_NO_ERR) ? "OK" : "FAIL");
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
if (ret == FDB_NO_ERR) {
/* 写入测试 KV */
fdb_kv_set(&kvdb, "test_key", "hello_flashdb");
HAL_UART_Transmit(&huart1, (uint8_t*)"[FlashDB] KV set OK\r\n", 21, 1000);
/* 读取测试 KV */
char *val = fdb_kv_get(&kvdb, "test_key");
if (val) {
sprintf(dbg, "[FlashDB] KV get: %s\r\n", val);
} else {
sprintf(dbg, "[FlashDB] KV get: NULL\r\n");
}
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
}
/* 5. 强制 100M 全双工,建立 PHY 链路 */
ch395f_set_phy(CH395F_PHY_100M_FULL);
HAL_Delay(3000);
uint8_t phy = ch395f_get_phy_status();
const char *phy_str = "UNKNOWN";
switch (phy) {
case CH395F_PHY_DISCONN: phy_str = "DISCONNECT"; break;
case CH395F_PHY_10M_FULL: phy_str = "10M FULL"; break;
case CH395F_PHY_10M_HALF: phy_str = "10M HALF"; break;
case CH395F_PHY_100M_FULL: phy_str = "100M FULL"; break;
case CH395F_PHY_100M_HALF: phy_str = "100M HALF"; break;
}
printf("[CH395F] PHY: %s\r\n", phy_str);
}
/* GD5F 初始化测试 */
int ret = gd5f2gq5ue_init();
const char *gd5f_str = "UNKNOWN";
switch (ret) {
case GD5F_OK: gd5f_str = "OK"; break;
case GD5F_ERROR: gd5f_str = "ERROR"; break;
case GD5F_BUSY_TIMEOUT: gd5f_str = "BUSY TIMEOUT"; break;
case GD5F_ECC_ERROR: gd5f_str = "ECC ERROR"; break;
case GD5F_PROGRAM_FAIL: gd5f_str = "PROGRAM FAIL"; break;
case GD5F_ERASE_FAIL: gd5f_str = "ERASE FAIL"; break;
case GD5F_ID_MISMATCH: gd5f_str = "ID MISMATCH"; break;
}
printf("[GD5F] init: %s\r\n", gd5f_str);
/* TPAFE5160 ADC 测试 */
int tp_ret = tpafe5160_init();
printf("[TPAFE5160] init: %s\r\n",
(tp_ret == TPAFE5160_OK) ? "OK" : "TIMEOUT");
/* SD2506 RTC 初始化测试 */
int sd_ret = sd2506_init();
printf("[SD2506] init: %s\r\n",
(sd_ret == SD2506_OK) ? "OK" : "I2C ERROR");
if (sd_ret == SD2506_OK) {
/* 读取 ID */
uint8_t sd_id[8];
sd2506_get_id(sd_id);
printf("[SD2506] ID: %02X%02X%02X%02X%02X%02X%02X%02X\r\n",
sd_id[0], sd_id[1], sd_id[2], sd_id[3],
sd_id[4], sd_id[5], sd_id[6], sd_id[7]);
/* 读取当前时间 */
sd2506_time_t sd_time;
sd2506_get_time(&sd_time);
printf("[SD2506] time: %04d-%02d-%02d %02d:%02d:%02d (week %d)\r\n",
sd_time.year, sd_time.month, sd_time.day,
sd_time.hour, sd_time.minute, sd_time.second,
sd_time.week);
/* 读取温度 */
int8_t sd_temp;
sd2506_get_temperature(&sd_temp);
printf("[SD2506] temp: %d C\r\n", sd_temp);
/* 读取电池电压 */
uint16_t sd_vbat;
sd2506_get_battery_voltage(&sd_vbat);
printf("[SD2506] battery: %d.%02d V\r\n",
sd_vbat / 1000, (sd_vbat % 1000) / 10);
}
/* RS-485 初始化UART5 + PD0 方向控制) */
rs485_init(&g_rs485, &huart5, ST_DIR4_GPIO_Port, ST_DIR4_Pin);
printf("[RS485] init: OK (UART5, DE=PD0)\r\n");
/* 启动第一次 RS-485 接收 */
rs485_receive_start(&g_rs485, g_rs485_rx_buf, RS485_RX_BUF_SIZE);
/* 启动第一次转换CubeMX 已配置 BUSY EXTI 中断) */
tpafe5160_start_conv_irq();
/* USER CODE END 2 */
/* Infinite loop */
@@ -190,13 +224,21 @@ int main(void)
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
/* TPAFE5160 中断模式读取 */
if (tpafe5160_data_ready()) {
const int16_t *buf = tpafe5160_get_buf();
printf("[TPAFE5160] CH:");
for (int i = 0; i < 8; i++) {
printf(" %d", buf[i]);
}
printf("\r\n");
tpafe5160_clear_ready();
/* 启动下一次转换 */
tpafe5160_start_conv_irq();
}
/* 其他任务 */
HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);
HAL_GPIO_TogglePin(LED2_GPIO_Port, LED2_Pin);
HAL_GPIO_TogglePin(LED3_GPIO_Port, LED3_Pin);
HAL_GPIO_TogglePin(LED4_GPIO_Port, LED4_Pin);
HAL_GPIO_TogglePin(LED5_GPIO_Port, LED5_Pin);
HAL_GPIO_TogglePin(LED6_GPIO_Port, LED6_Pin);
//HAL_UART_Transmit(&huart1, str, strlen((char*)str), 1000);
HAL_Delay(500);
}
/* USER CODE END 3 */
@@ -248,7 +290,38 @@ void SystemClock_Config(void)
}
/* USER CODE BEGIN 4 */
/*
* HAL UART 扩展接收回调IDLE 空闲帧中断触发)
* 当 RS-485 总线空闲超过 1 个字符时间后触发
*/
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if (huart->Instance == UART5) {
rs485_rx_set_size(&g_rs485, Size);
/* TODO: 在此处处理接收到的 RS-485 数据
* g_rs485_rx_buf[0 .. Size-1] 为有效数据
* 例如rs485_transmit(&g_rs485, g_rs485_rx_buf, Size, 0);
*/
/* 重新开启接收 */
rs485_receive_start(&g_rs485, g_rs485_rx_buf, RS485_RX_BUF_SIZE);
}
}
/*
* HAL UART 错误回调
*/
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == UART5) {
/* STM32F4 通过读 SR + DR 清除 ORE/NE/FE/PE 错误标志 */
(void)huart->Instance->SR;
(void)huart->Instance->DR;
/* 重新开启接收 */
rs485_receive_start(&g_rs485, g_rs485_rx_buf, RS485_RX_BUF_SIZE);
}
}
/* USER CODE END 4 */
/**