找回密码
 立即注册
查看: 354|回复: 4

STC8H8K64U 加载STC8_MDU16_V1.0.LIB 导致ADC转换值出现偏差

[复制链接]

1

主题

3

回帖

21

积分

新手上路

积分
21
发表于 2024-9-4 17:52:39 | 显示全部楼层 |阅读模式
void Pm_init()
{
    char i;
    P3_MODE_OUT_PP(GPIO_Pin_4); // P52:电源控制;
    P4_MODE_IO_PU(GPIO_Pin_2);  // LED电源控制;
    // P5_MODE_IO_PU(GPIO_Pin_2); // P52:电源控制;
    P5_MODE_IN_HIZ(GPIO_Pin_4); // P54:ADC_CH2;
    GPIO_EXTERN_PWND = 1;
    GPIO_LED_PWND    = 0;
    EADC             = 0;
    ADCTIM           = 0x3f; // 设置ADC内部时序
    ADCEXCFG         = 0x07;
    ADCCFG           = 0x0f; // 设置ADC时钟为系统时钟/2/16
    ADC_CONTR        = 0;
    delay_ms(5);
    ADC_CONTR = ADC_POWER;
    delay_ms(5);

    ADC_CONTR |= ADC_CH15; // 使能ADC模块
    for (i = 0; i < 5; i++) {
        PowerManagement_McuVcc = (256L * CHIP_BGV / Pm_ReadADC()) / 10;
        if (labs(PowerManagement_McuVcc - LDO_OUT) < 20) {
            break;
        }
    };

    ADC_CONTR = ADC_POWER | ADC_CH2 | ADC_EPWMT;

    PowerManagement_BatAD  = Pm_ReadADC();
    PowerManagement_BatVcc = (uint32_t)PowerManagement_McuVcc * PowerManagement_BatAD * (BAT_R39 + BAT_R40) / (BAT_R40 * 256);
    // 电量检测 2秒刷新一次
    EADC      = 1;
    PWMA_PSCR = PWM_PRESCALER;
    PWMA_CR2  = 0x20; // 更新事件为TRGO,可用于触发ADC
    PWMA_ARR  = PWM_RELOAD;
    // PWMA_IER  = 0x01;
    PWMA_CR1 = 0x01; // 设置CEN启动PWMA定时器,实时触发ADC
}


void ADC_ISR_Handler(void) interrupt ADC_VECTOR
{
    ADC_CONTR &= ~ADC_FLAG;           // 清中断标志
    PowerManagement_BatAD  = ADC_RES; // 读取ADC结果
    PowerManagement_BatVcc = (uint32_t)PowerManagement_McuVcc * PowerManagement_BatAD * (BAT_R39 + BAT_R40) / (BAT_R40 * 256);
}



加载STC8_MDU16_V1.0.LIB编译运行,ADC转换结果是正常的,值为156,转换电压6.16V
不加载STC8_MDU16_V1.0.LIB编译运行,ADC转换结果偏低且不稳定,AD值为116左右,转换电压在4.5V左右。不知道是什么原因...



回复

使用道具 举报 送花

  • 打卡等级:偶尔看看III
  • 打卡总天数:50
  • 最近打卡:2025-04-30 22:59:03

73

主题

5882

回帖

1万

积分

超级版主

积分
12073
发表于 2024-9-5 11:28:45 | 显示全部楼层
不应该把?ADC模块是独立外设,MDU16是一个计算单元,不相关的啊。
回复 支持 反对

使用道具 举报 送花

1

主题

3

回帖

21

积分

新手上路

积分
21
发表于 2024-9-5 14:12:52 | 显示全部楼层
整个工程,咋也没改,就是带不带MDU16的区别差别;我目前手上三块板子,运行不带MDU16的编译的固件,两块转换结果不准;只要换上带MDU16的固件就好了。  我也想不通...   
芯片版本从哪看?会不会是芯片版本不一样?
截图202409051358465260.jpg
回复 支持 反对

使用道具 举报 送花

1

主题

3

回帖

21

积分

新手上路

积分
21
发表于 2024-9-5 14:18:56 | 显示全部楼层
fqmc0*** 发表于 2024-9-5 14:12
整个工程,咋也没改,就是带不带MDU16的区别差别;我目前手上三块板子,运行不带MDU16的编译的固件,两块转 ...

我总的4块板子;一块开发板样品,我是从微信芯安商铺上购买的芯片;后面三块是客户试产的,具体从哪个渠道采购的目前我也不清楚。
回复 支持 反对

使用道具 举报 送花

1

主题

3

回帖

21

积分

新手上路

积分
21
发表于 2024-9-6 17:42:04 | 显示全部楼层
梁*** 发表于 2024-9-5 11:28
不应该把?ADC模块是独立外设,MDU16是一个计算单元,不相关的啊。

代码整理下,可以了,现在加不加载都一样;
uint8_t Pm_ReadADC(uint8_t nAdcCH)
{
    ADC_CONTR = (ADC_CONTR & 0xf0) | ADC_START | nAdcCH;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    while (!(ADC_CONTR & ADC_FLAG)); // 查询ADC完成标志
    ADC_CONTR &= ~ADC_FLAG;          // 清完成标志
    return ADC_RES;
}

void Pm_init()
{
    char i;
    P5_MODE_IN_HIZ(GPIO_Pin_4); // P54:ADC_CH2;
    EADC      = 0;
    ADCTIM    = 0x3f; // 设置ADC内部时序
    ADCEXCFG  = 0x07;
    ADCCFG    = 0x0f; // 设置ADC时钟为系统时钟/2/16
    ADC_CONTR = 0x80;
   
    for (i = 0; i < 5; i++) {
        PowerManagement_McuVcc = (256L * CHIP_BGV / Pm_ReadADC(ADC_CH15)) / 10;
        if (labs(PowerManagement_McuVcc - LDO_OUT) < 20) {
            break;
        }
    };

    PowerManagement_BatAD  = Pm_ReadADC(ADC_CH2);
    PowerManagement_BatVcc = (uint32_t)PowerManagement_McuVcc *
    PowerManagement_BatAD * (BAT_R39 + BAT_R40) / (BAT_R40 * 256);

    ADC_CONTR = ADC_POWER | ADC_CH2 | ADC_EPWMT;
    // 电量检测 2秒刷新一次
    EADC      = 1;
    PWMA_PSCR = PWM_PRESCALER;
    PWMA_CR2  = 0x20; // 更新事件为TRGO,可用于触发ADC
    PWMA_ARR  = PWM_RELOAD;
    // PWMA_IER  = 0x01;
    PWMA_CR1 = 0x01; // 设置CEN启动PWMA定时器,实时触发ADC
}
回复 支持 反对

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 02:36 , Processed in 0.165054 second(s), 74 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表