打印

求助 HC32L136K8TK ADC 引脚,采集不到电压,无变化

[复制链接]
56|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
doghead|  楼主 | 2025-2-11 11:21 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 doghead 于 2025-2-11 11:30 编辑

/******************************************************************************
* Copyright (C) 2017, Xiaohua Semiconductor Co.,Ltd All rights reserved.
*
* 此软件为小华半导体股份有限公司所有并发布。
*/

#include "adc.h"          // ADC 相关头文件
#include "gpio.h"         // GPIO 相关头文件
#include "bgr.h"          // BGR (带隙基准) 相关头文件
#include "stdio.h"        // 标准输入输出 (printf)
#include "uart.h"         // UART (串口) 相关头文件
#include "sysctrl.h"      // 系统控制相关头文件 (时钟等)

#define VCC 3.3f           // 供电电压

// 全局变量,用于存储 ADC 转换结果 (声明为 volatile,防止优化)
volatile uint32_t u32AdcRestult0;  // PC00
volatile uint32_t u32AdcRestult1;  // PC01

// 函数声明
void App_AdcPortInit(void);   // 初始化 ADC 端口 (GPIO)
void App_AdcInit(void);       // 初始化 ADC 模块
void App_AdcJqrCfg(void);     // 配置 ADC 队列扫描模式 (JQR)
void App_PortInit(void);      // 初始化 UART 端口 (GPIO)
void App_UartCfg(void);       // 配置 UART 模块
float ConvertToVoltage(uint32_t sensorValue); // 将 ADC 值转换为电压
void delay_ms(uint32_t ms);    // 简单的毫秒延时函数

// 主函数
int main(void) {
    App_AdcPortInit();      // 初始化 ADC 端口
    App_AdcInit();          // 初始化 ADC 模块
    App_AdcJqrCfg();        // 配置 ADC 队列扫描
    App_PortInit();         // 初始化 UART 端口
    App_UartCfg();          // 配置 UART 模块

    __enable_irq();         // 使能全局中断

    while (1) {
        Adc_JQR_Start();    // 启动 ADC 队列扫描转换
        delay_ms(500);      // 延时 500 毫秒

        float voltage0 = ConvertToVoltage(u32AdcRestult0);     // 转换通道 0 电压 (PC00)
        float voltage1 = ConvertToVoltage(u32AdcRestult1);     // 转换通道 1 电压 (PC01)


        // 打印 ADC 值和对应的电压值
        printf("ADC Channel 0 (PC00): %lu -> Voltage: %.3f V\n", u32AdcRestult0, voltage0);
        printf("ADC Channel 1 (PC01): %lu -> Voltage: %.3f V\n", u32AdcRestult1, voltage1);
    }
}

// ADC 中断处理函数
void Adc_IRQHandler(void) {
    if (TRUE == Adc_GetIrqStatus(AdcMskIrqJqr)) {        // 检查是否是 JQR 中断
        Adc_ClrIrqStatus(AdcMskIrqJqr);                    // 清除 JQR 中断标志

        // ************************ 调试代码 **************************
        uint32_t localResult0   = Adc_GetJqrResult(AdcJQRCH0MUX); // 直接读取 ADC 结果寄存器 (PC00)
        uint32_t localResult1   = Adc_GetJqrResult(AdcJQRCH1MUX); // 直接读取 ADC 结果寄存器 (PC01)

        // 在中断中打印 ADC 值,用于调试
        printf("Interrupt: PC00=%lu, PC01=%lu\n", localResult0, localResult1);
        // ************************ 调试代码 **************************

        u32AdcRestult0   = localResult0;  // 将局部变量的值赋给全局变量 (PC00)
        u32AdcRestult1   = localResult1;  // 将局部变量的值赋给全局变量 (PC01)
    }
}

// 初始化 ADC 端口 (GPIO)
void App_AdcPortInit(void) {
    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE);    // 使能 GPIO 外设时钟

    // 将PC00和PC01配置为AIN8和AIN9

    Gpio_SetAnalogMode(GpioPortC, GpioPin0);    // PC0 作为 AIN8 (ADC 输入)
    Gpio_SetAnalogMode(GpioPortC, GpioPin1);    // PC1 作为 AIN9 (ADC 输入)
}

// 初始化 ADC 模块
void App_AdcInit(void) {
    stc_adc_cfg_t stcAdcCfg;         // ADC 配置结构体
    DDL_ZERO_STRUCT(stcAdcCfg);       // 初始化结构体

    Sysctrl_SetPeripheralGate(SysctrlPeripheralAdcBgr, TRUE); // 使能 ADC/BGR 外设时钟
    Bgr_BgrEnable();                                          // 使能 BGR (带隙基准)

    stcAdcCfg.enAdcMode         = AdcScanMode;              // 扫描模式
    stcAdcCfg.enAdcClkDiv       = AdcMskClkDiv1;            // ADC 时钟分频:1
    stcAdcCfg.enAdcSampCycleSel = AdcMskSampCycle8Clk;      // 采样周期:8 个时钟周期
    stcAdcCfg.enAdcRefVolSel    = AdcMskRefVolSelAVDD;      // 参考电压:AVDD (VCC)
    stcAdcCfg.enAdcOpBuf        = AdcMskBufDisable;         // 关闭 OP BUF
    stcAdcCfg.enInRef           = AdcMskInRefDisable;       // 关闭内部参考电压
    stcAdcCfg.enAdcAlign        = AdcAlignRight;            // 转换结果右对齐
    Adc_Init(&stcAdcCfg);                                   // 初始化 ADC
}

// 配置 ADC 队列扫描模式 (JQR)
void App_AdcJqrCfg(void) {
    stc_adc_jqr_cfg_t stcAdcJqrCfg;   // JQR 配置结构体
    DDL_ZERO_STRUCT(stcAdcJqrCfg);     // 初始化结构体

    stcAdcJqrCfg.bJqrDmaTrig = FALSE;  // 关闭 DMA 触发
    stcAdcJqrCfg.u8JqrCnt    = 2;      // 扫描 2 个通道.  Crucially changed to 2
    Adc_JqrModeCfg(&stcAdcJqrCfg);    // 配置 JQR 模式


    Adc_CfgJqrChannel(AdcJQRCH0MUX, AdcExInputCH8);   // 通道 0: AIN8  (PC00)
    Adc_CfgJqrChannel(AdcJQRCH1MUX, AdcExInputCH9);   // 通道 1: AIN9  (PC01)


    Adc_EnableIrq();                              // 使能 ADC 中断
    EnableNvic(ADC_IRQn, IrqLevel3, TRUE);      // 使能 NVIC 中断 (设置优先级)
}

// 将 ADC 值转换为电压
float ConvertToVoltage(uint32_t sensorValue) {
    float maxADCValue = 4095.0f;                // 12 位 ADC 最大值
    return (float)sensorValue * VCC / maxADCValue; // 计算电压
}

// UART fputc 重定向,用于 printf
int fputc(int ch, FILE *f) {
    Uart_SendDataPoll(M0P_UART0, (uint8_t)ch); // 使用轮询发送 UART 数据
    return ch;
}

// 初始化 UART 端口 (GPIO)
void App_PortInit(void) {
    stc_gpio_cfg_t stcGpioCfg;       // GPIO 配置结构体
    DDL_ZERO_STRUCT(stcGpioCfg);     // 初始化结构体

    Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio, TRUE); // 使能 GPIO 外设时钟

    stcGpioCfg.enDir = GpioDirOut;    // TX 引脚配置为输出
    Gpio_Init(GpioPortA, GpioPin9, &stcGpioCfg);
    Gpio_SetAfMode(GpioPortA, GpioPin9, GpioAf1); // PA9 作为 UART0 TX

    stcGpioCfg.enDir = GpioDirIn;     // RX 引脚配置为输入
    Gpio_Init(GpioPortA, GpioPin10, &stcGpioCfg);
    Gpio_SetAfMode(GpioPortA, GpioPin10, GpioAf1); // PA10 作为 UART0 RX
}

// 配置 UART 模块
void App_UartCfg(void) {
    stc_uart_cfg_t  stcCfg;          // UART 配置结构体
    DDL_ZERO_STRUCT(stcCfg);         // 初始化结构体

    Sysctrl_SetPeripheralGate(SysctrlPeripheralUart0, TRUE); // 使能 UART0 外设时钟

    stcCfg.enRunMode = UartMskMode3;      // 模式 3
    stcCfg.enStopBit = UartMsk1bit;       // 1 位停止位
    stcCfg.enMmdorCk = UartMskEven;       // 偶校验
    stcCfg.stcBaud.u32Baud = 9600;        // 波特率 9600
    stcCfg.stcBaud.enClkDiv = UartMsk8Or16Div; // 时钟分频
    stcCfg.stcBaud.u32Pclk = Sysctrl_GetPClkFreq(); // 获取 PCLK 频率
    Uart_Init(M0P_UART0, &stcCfg);        // 初始化 UART

    Uart_ClrStatus(M0P_UART0, UartRC);     // 清除接收标志
    Uart_EnableIrq(M0P_UART0, UartRxIrq);  // 使能接收中断

    //Uart_SetTransMode(M0P_UART0, UartMskTx); // 使能 UART 发送
    Uart_EnableIrq(M0P_UART0,UartTxIrq); // (错误! 不要使用此行!)
}

// 简单的毫秒延时函数
void delay_ms(uint32_t ms) {
    volatile uint32_t i, j;
    for (i = 0; i < ms; i++) {
        for (j = 0; j < 8000; j++); // 调整循环次数以获得准确延时
    }
}


MCU.png (366.57 KB )

MCU

MCU

使用特权

评论回复

相关帖子

沙发
doghead|  楼主 | 2025-2-11 20:40 | 只看该作者
求求了, 咋没人 啊!!!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

2

帖子

0

粉丝