目的是使用AD值來檢測電池電壓的變化??
檢測IO是PA1? AD通道是AD1
用萬用表測試分壓電阻兩端的電壓是實時變化的
但是我用串口輸出AD值卻一直都是固定的值沒有怎么變化
代碼如下:
#include "debug.h"
unsigned char bat_cishu=0; //電池AD累加次數(shù)
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);//使能系統(tǒng)時鐘中斷 中斷編碼12
? ? SysTick->SR &= ~(1 << 0);//系統(tǒng)計數(shù)狀態(tài)寄存器 STK_SR
? ? SysTick->CMP =SystemCoreClock/1000-1;//設(shè)置計數(shù)器? 0.1ms=10000-1? ? 1ms=1000-1
? ? SysTick->CNT = 0;//當(dāng)前計數(shù)器的值
? ? SysTick->CTLR = 0x0f;//系統(tǒng)定時器設(shè)置 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復(fù)用輸出
? ? /*本例并不需要實現(xiàn)接收功能,可以暫時不用配置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;//數(shù)據(jù)位
? ? 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 ;//使能發(fā)送和使能接收
? ? 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為執(zhí)行完畢 0為還未完成
? ? ? ? static unsigned char ad_h,ad_l; //因為ad值為12位,串口發(fā)送只能發(fā)送8位 所以要發(fā)送2次 先發(fā)高8位 后發(fā)低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);//先發(fā)高八位
? ? ? ? ? ? while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)== RESET){}? //如果發(fā)送完成會結(jié)束循環(huán) RESET=0
? ? ? ? ? ? USART_SendData(USART1, ad_l);//后發(fā)低八位
? ? ? ? ? ? while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)== RESET){}? ?//如果發(fā)送完成會結(jié)束循環(huán) RESET=0
? ? ? ? ? ? if(advlue_bat>10)//低電壓保護? 實測參數(shù)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? 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;
? ? }
}