Initial commit: CCU621_M firmware project with BLE debug link support.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-07-08 17:28:36 +08:00
commit 9ceb218f80
1597 changed files with 724159 additions and 0 deletions
+303
View File
@@ -0,0 +1,303 @@
#include "gd32h7xx.h"
#include "adc_temp.h"
#include <string.h>
#include <math.h>
#include "usart.h"
#include "sys_drv_init.h"
#include "gd32h7xx_dma.h"
/* 忙等待延时函数 */
static void delay_ms(uint32_t ms)
{
/* 使用固定的时钟频率 600MHz 来计算延时,避免 SystemCoreClock 未初始化的问题 */
for(volatile uint32_t i = 0; i < (600000000 / 4000) * ms; i++)
{
__NOP();
}
}
/* ADC2 DMA连续采样缓冲:DMA中断只负责“完成标记”,数据处理放在 get_adc_data()。 */
#define ADC_TEMP_DMA_PERIPH DMA1
#define ADC_TEMP_DMA_CH DMA_CH0
#define ADC_TEMP_DMA_IRQN DMA1_Channel0_IRQn
#define ADC_TEMP_DMA_SAMPLE_CNT (16U)
static __IO uint32_t g_adc_dma_buf[ADC_TEMP_DMA_SAMPLE_CNT];
static volatile uint32_t g_adc_dma_frame_cnt;
__IO uint32_t adc_value[4];
void init_adc(void)
{
dma_single_data_parameter_struct dma_init_struct;
/* GPIO时钟使能 */
rcu_periph_clock_enable(RCU_GPIOC);
/* ADC时钟使能 */
rcu_periph_clock_enable(RCU_ADC2);
/* DMA时钟使能 */
rcu_periph_clock_enable(RCU_DMA1);
/* GPIO参数配置*/
gpio_mode_set(GPIOC, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, GPIO_PIN_2);
/* ADC初始化 -- 根据数据手册,ADC2_IN0--PC2端子仅能使用ADC2第0个通道 */
adc_deinit(ADC2);
/* ADC时钟配置 */
adc_clock_config(ADC2, ADC_CLK_SYNC_HCLK_DIV6);
/* 单通道连续转换 + DMA */
adc_special_function_config(ADC2, ADC_SCAN_MODE, DISABLE);
adc_special_function_config(ADC2, ADC_CONTINUOUS_MODE, ENABLE);
/* 转换结果(12/14位)存放在 32 位寄存器的低 16 位中 */
adc_data_alignment_config(ADC2, ADC_DATAALIGN_RIGHT);
/* ADC 通道配置(规则通道组,单通道) */
adc_channel_length_config(ADC2, ADC_REGULAR_CHANNEL, 1);
/* 配置规则通道序列,决定 ADC 在转换时,对 PC2 引脚电压进行采样的时间长度*/
adc_regular_channel_config(ADC2, 0, ADC_CHANNEL_0, 240);
/* 禁用外部触发*/
adc_external_trigger_config(ADC2, ADC_REGULAR_CHANNEL, EXTERNAL_TRIGGER_DISABLE);
/* DMA配置:ADC2 regular data -> g_adc_dma_buf[] (循环) */
dma_deinit(ADC_TEMP_DMA_PERIPH, ADC_TEMP_DMA_CH);
dma_single_data_para_struct_init(&dma_init_struct);
dma_init_struct.request = DMA_REQUEST_ADC2;
dma_init_struct.periph_addr = (uint32_t)&ADC_RDATA(ADC2);
dma_init_struct.periph_inc = DMA_MEMORY_INCREASE_DISABLE;
dma_init_struct.memory0_addr = (uint32_t)g_adc_dma_buf;
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_32BIT;
dma_init_struct.circular_mode = DMA_CIRCULAR_MODE_ENABLE;
dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
dma_init_struct.priority = DMA_PRIORITY_HIGH;
dma_init_struct.number = ADC_TEMP_DMA_SAMPLE_CNT;
dma_single_data_mode_init(ADC_TEMP_DMA_PERIPH, ADC_TEMP_DMA_CH, &dma_init_struct);
dma_interrupt_enable(ADC_TEMP_DMA_PERIPH, ADC_TEMP_DMA_CH, DMA_INT_HTF);
dma_interrupt_enable(ADC_TEMP_DMA_PERIPH, ADC_TEMP_DMA_CH, DMA_INT_FTF);
nvic_irq_enable(ADC_TEMP_DMA_IRQN, 6U, 0U);
/* 使能 ADC2 模块 */
adc_enable(ADC2);
/* wait for ADC stability */
delay_ms(1);
/* 配置校准模式,偏移量校准,用于纠正 ADC 自身的零点误差 */
adc_calibration_mode_config(ADC2, ADC_CALIBRATION_OFFSET);
/* 配置校准次数 */
adc_calibration_number(ADC2, ADC_CALIBRATION_NUM1);
/*执行校准 */
adc_calibration_enable(ADC2);
/* 启动DMA与ADC连续转换 */
memset((void *)g_adc_dma_buf, 0, sizeof(g_adc_dma_buf));
g_adc_dma_frame_cnt = 0U;
dma_channel_enable(ADC_TEMP_DMA_PERIPH, ADC_TEMP_DMA_CH);
adc_dma_mode_enable(ADC2);
adc_dma_request_after_last_enable(ADC2);
adc_software_trigger_enable(ADC2, ADC_REGULAR_CHANNEL);
}
uint32_t adc_channel_sample(uint8_t channel)
{
uint32_t timeout = 1000000U;
/* 重新配置规则通道 */
adc_regular_channel_config(ADC2, 0U, channel, 240);
/* 软件触发转换 */
adc_software_trigger_enable(ADC2, ADC_REGULAR_CHANNEL);
/* 等待转换结束 */
while(!adc_flag_get(ADC2, ADC_FLAG_EOC)){
if (timeout-- == 0U) {
return 0U;
}
}
/* 清除标志 */
adc_flag_clear(ADC2, ADC_FLAG_EOC);
/* 读取结果并返回 */
return (adc_regular_data_read(ADC2));
}
void DMA1_Channel0_IRQHandler(void)
{
if (SET == dma_interrupt_flag_get(ADC_TEMP_DMA_PERIPH, ADC_TEMP_DMA_CH, DMA_INT_FLAG_HTF)) {
dma_interrupt_flag_clear(ADC_TEMP_DMA_PERIPH, ADC_TEMP_DMA_CH, DMA_INT_FLAG_HTF);
g_adc_dma_frame_cnt++;
}
if (SET == dma_interrupt_flag_get(ADC_TEMP_DMA_PERIPH, ADC_TEMP_DMA_CH, DMA_INT_FLAG_FTF)) {
dma_interrupt_flag_clear(ADC_TEMP_DMA_PERIPH, ADC_TEMP_DMA_CH, DMA_INT_FLAG_FTF);
g_adc_dma_frame_cnt++;
}
}
void select_temp_channel(uint8_t flag_set)
{
//温度采集选通,
/*
OUT8、OUT7设置为高电平,A枪正温度
OUT8设置为高电平,OUT7设置为低电平,A枪负温度
OUT8设置为低电平,OUT7设置为高电平,B枪正温度
OUT8、OUT7设置为低电平,B枪负温度
*/
if(flag_set == 0)
{
TEMP_MULT_CTRA(1);
TEMP_MULT_CTRB(1);
TEMP_MULT_CTRC(1);
}
else if(flag_set == 1)
{
TEMP_MULT_CTRA(0);
TEMP_MULT_CTRB(1);
TEMP_MULT_CTRC(1);
}
else if(flag_set == 2)
{
TEMP_MULT_CTRA(1);
TEMP_MULT_CTRB(0);
TEMP_MULT_CTRC(1);
}
else if(flag_set == 3)
{
TEMP_MULT_CTRA(0);
TEMP_MULT_CTRB(0);
TEMP_MULT_CTRC(1);
}
else if(flag_set == 4)
{
TEMP_MULT_CTRA(1);
TEMP_MULT_CTRB(1);
TEMP_MULT_CTRC(0);
}
else if(flag_set == 5)
{
TEMP_MULT_CTRA(0);
TEMP_MULT_CTRB(1);
TEMP_MULT_CTRC(0);
}
else if(flag_set == 6)
{
TEMP_MULT_CTRA(1);
TEMP_MULT_CTRB(0);
TEMP_MULT_CTRC(0);
}
else if(flag_set == 7)
{
TEMP_MULT_CTRA(0);
TEMP_MULT_CTRB(0);
TEMP_MULT_CTRC(0);
}
}
double double_Vol_to_resistance(double vol)
{
double ret = 0;
//BL1117-50CX输出+5V_Tem,可通过测量VOL_Vin2校准+5V_Tem,Rt=3kΩ*Vo/+5V_Tem-Vo
ret = (3000 * vol) / (5.04 - vol);
return ret / 1000.0;
}
double PT1000_Vol_To_Temperature(double vol)
{
// 定义PT1000常数
double R;
const double R0 = 1000.0; // 0°C时的电阻值
const double A = 3.9083e-3; // IEC751系数
const double B = -5.775e-7;
const double C = -4.183e-12; // 负温度区系数
// 计算电阻值(kΩ单位)
R = double_Vol_to_resistance(vol);
/* 校准系数(保持kΩ单位) */
if (R > 1.219)
{
R = R * 1.01778; // 高温区补偿
}
else if (R > 1)
{
R = R * 1.00395; // 常温区补偿
}
else
{
R = R * 0.98884; // 低温区补偿
}
// 转换为Ω单位
double R_ohm = R * 1000.0;
// 计算温度
if (R_ohm >= R0)
{
// 正温度区使用二次方程
double discriminant = A * A - 4 * B * (1 - R_ohm / R0);
return (-A + sqrt(discriminant)) / (2 * B);
}
else
{
// 负温度区使用牛顿迭代法
const int max_iter = 100; // 最大迭代次数
const double tol = 1e-6; // 收敛误差
double T = -50.0; // 初始温度估计值
for (int i = 0; i < max_iter; i++)
{
double T2 = T * T;
double T3 = T2 * T;
// Callendar-Van Dusen方程
double f = R0 * (1 + A * T + B * T2 + C * (T - 100) * T3) - R_ohm;
// 检查是否收敛
if (fabs(f) < tol)
{
return T;
}
// 导数计算
double df = R0 * (A + 2 * B * T + C * (4 * T3 - 300 * T2));
// 避免除零错误
if (fabs(df) < 1e-10)
{
break;
}
// 牛顿迭代法更新
T -= f / df;
}
// 返回收敛值
return T;
}
}
uint32_t get_adc_data(void)
{
uint64_t sum = 0U;
uint32_t i;
/* 仅处理DMA中断已写入的采样数据,不触发硬件采样。 */
for (i = 0U; i < ADC_TEMP_DMA_SAMPLE_CNT; i++)
{
sum += g_adc_dma_buf[i];
// printf("data = %d\n", g_adc_dma_buf[i]);
}
return (uint32_t)(sum / ADC_TEMP_DMA_SAMPLE_CNT);
}
uint32_t adc_readval(void)
{
float ret, temp_data = 0.0f;
ret = (get_adc_data() * 3.0f) / 4095.0f;
temp_data = PT1000_Vol_To_Temperature(ret);
return temp_data;
}
void adc_test(uint8_t i)
{
float val_value;
(void)i;
delay_ms(1000);
adc_value[0] = adc_channel_sample(ADC_CHANNEL_0);
val_value = (adc_value[0] * 3.0f) / 4095.0f;
(void)val_value;
}