CH32V003F4P6 检测电池的AD值,AD值不会变

目的是使用AD值来检测电池电压的变化  

检测IO是PA1  AD通道是AD1

用万用表测试分压电阻两端的电压是实时变化的

但是我用串口输出AD值却一直都是固定的值没有怎么变化

代码如下:


#include "debug.h"


unsigned char bat_cishu=0; //电池AD累加次数

unsigned int  ad_bat_sum=0;//电池AD累加总值

unsigned int  advlue_bat=0;//电池AD最终平均值

unsigned char b_batad=0;

unsigned int AD_temp=0;//电池AD采样值 一次

unsigned char count100ms=0;

/* Global define */



/* Global Variable */


/*********************************************************************

 * @fn      USARTx_CFG

 *

 * @brief   Initializes the USART2 & USART3 peripheral.

 *

 * @return  none

 */


void dida_time_init(void)//滴答时钟初始化

{

    NVIC_EnableIRQ(SysTicK_IRQn);//使能系统时钟中断 中断编码12

    SysTick->SR &= ~(1 << 0);//系统计数状态寄存器 STK_SR

    SysTick->CMP =SystemCoreClock/1000-1;//设置计数器  0.1ms=10000-1    1ms=1000-1

    SysTick->CNT = 0;//当前计数器的值

    SysTick->CTLR = 0x0f;//系统定时器设置 STK_CTLR

}


void USARTx_CFG(void)//串口初始化

{

    GPIO_InitTypeDef  GPIO_InitStructure = {0};

    USART_InitTypeDef USART_InitStructure = {0};


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD , ENABLE);//使能GPIOD总线

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//使能串口1总线


    /* USART1 TX-->D.5   RX-->D.6 */

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_Init(GPIOD, &GPIO_InitStructure);//PD5复用输出


    /*本例并不需要实现接收功能,可以暂时不用配置PD6

        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;           //上拉输入

        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;

        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

        GPIO_Init(GPIOD,&GPIO_InitStructure);

   */


    USART_InitStructure.USART_BaudRate = 9600;//波特率

    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//数据位

    USART_InitStructure.USART_StopBits = USART_StopBits_1;//停止位

    USART_InitStructure.USART_Parity = USART_Parity_No;//无校验

    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//不开启流控

    USART_InitStructure.USART_Mode = USART_Mode_Tx ;//使能发送和使能接收


    USART_Init(USART1, &USART_InitStructure);//配置串口

    USART_Cmd(USART1, ENABLE);//开启串口

}


void ADC_Channel_Init( void )

{

    GPIO_InitTypeDef GPIO_InitStructure = {0};

    ADC_InitTypeDef ADC_InitStructure = {0};


    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE );

    RCC_APB2PeriphClockCmd( RCC_APB2Periph_ADC1, ENABLE );

    RCC_ADCCLKConfig( RCC_PCLK2_Div8 );


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init( GPIOA, &GPIO_InitStructure );

    ADC_DeInit(ADC1);//初始化ADC1


    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

    ADC_InitStructure.ADC_ScanConvMode = DISABLE;

    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;

    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

    ADC_InitStructure.ADC_NbrOfChannel = 1;

    ADC_Init( ADC1, &ADC_InitStructure );


    ADC_Calibration_Vol(ADC1, ADC_CALVOL_50PERCENT);

    ADC_Cmd( ADC1, ENABLE );


    ADC_ResetCalibration(ADC1);

    while(ADC_GetResetCalibrationStatus(ADC1));

    ADC_StartCalibration(ADC1);

    while(ADC_GetCalibrationStatus(ADC1));

}


u16 Get_ADC_Val( u8 ch )

{

    u16 val;


    ADC_RegularChannelConfig( ADC1, ch, 1, ADC_SampleTime_241Cycles );

    ADC_SoftwareStartConvCmd( ADC1, ENABLE );


    while( !ADC_GetFlagStatus( ADC1, ADC_FLAG_EOC ) );


    val = ADC_GetConversionValue( ADC1 );


    return val;

}


void bat_ad()//电池电量检测  

{

    if(b_batad)

    {

        b_batad=0;

        static unsigned char bat_finish; //平均标志位 1为执行完毕 0为还未完成

        static unsigned char ad_h,ad_l; //因为ad值为12位,串口发送只能发送8位 所以要发送2次 先发高8位 后发低8位

        ADC_Channel_Init();

        AD_temp=(Get_ADC_Val(ADC_Channel_1)+AD_temp*2)/3;

        __NOP();

        AD_temp=(Get_ADC_Val(ADC_Channel_1)+AD_temp*2)/3;

        bat_cishu++;

        if(bat_cishu<=16)

        {

            ad_bat_sum=ad_bat_sum+AD_temp;//累加16次 取平均值

            if(bat_cishu==16)

            {

                bat_cishu=0;

                advlue_bat=ad_bat_sum>>4;

                ad_bat_sum=0;

                bat_finish=1;

                ad_h = (advlue_bat&0xff00) >>8;

                ad_l =  advlue_bat&0x00ff;

            }

        }


        if(bat_finish)

        {

            bat_finish=0;

            USART_SendData(USART1, ad_h);//先发高八位

            while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)== RESET){}  //如果发送完成会结束循环 RESET=0

            USART_SendData(USART1, ad_l);//后发低八位

            while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)== RESET){}   //如果发送完成会结束循环 RESET=0

            if(advlue_bat>10)//低电压保护  实测参数

            {

                advlue_bat=0;

            }

        }

    }

}


int main(void)

{

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//配置中断

    dida_time_init();//滴答时钟初始化

    //IWDG_Feed_Init( IWDG_Prescaler_128, 4000);//看门狗 4s IWDG reset

    USARTx_CFG();


    while(1)

    {

        bat_ad();

    }

}


void SysTick_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));


void SysTick_Handler(void)//滴答时钟中断 1ms

{

    SysTick->SR = 0;

    count100ms++;

    if(count100ms>=50)

    {

        count100ms=0;

        b_batad=1;

    }


}


您好,请问是用我们提供的Demo板直接测试的还是自己做的板子,若是用的Demo板,注意要将晶振去掉,R5短接起来,如下图,系统主频配置使用内部晶振,后续沟通可邮箱(lzs@wch.cn)继续沟通。

image.png


是自己做的板子

原先主频是48M 后续更改了24M主频

AD值可以实时变动

但是电压低于3.3V以后,AD值保持不变


您好,ADC初始化部分按照下图修改一下,下图程序测试是没问题的

image.png


已解决,结合1.2V的AD值,做出函数

电压值=1.2*(3.3V基准AD值/1.2V基准AD值)


只有登录才能回复,可以选择微信账号登录