目的是使用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;
}
}