下面是PY32F030/003/002A/PY32C61xx 各ADC通道切换并采集的程序!
首先我们先看看采集函数怎么写,这里直接使用寄存器操作:
uint16_t GetAdc12Bit(uint32_t channel)
{
ADC1->CR |= (1<<4);// 停止 ADC
ADC1->CHSELR =(1<<channel);//选择通道
ADC1->CR |= (1<<0);//使能 ADC
ADC1->CR |= (1<<2);//启动 ADC, 同HAL_ADC_Start();
while(!(ADC1->ISR & ADC_ISR_EOC));//等待转换完成,同HAL_ADC_PollForConversion();
return ADC1 -> DR;//返回采样值,同HAL_ADC_GetValue();
}
随后看看ADC的初始化函数,通道我们是不需要配置的,因为上面那个函数可以选:
void ADC_Init(void)
{
ADC_ChannelConfTypeDef sConfig = {0};
/* 先复位ADC值 */
__HAL_RCC_ADC_FORCE_RESET();
__HAL_RCC_ADC_RELEASE_RESET();
/*ADC校准*/
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_ASYNC_HSI_DIV2; //设置ADC时钟
if (HAL_ADC_Init(&hadc) != HAL_OK)
{
Error_Handler();
}
if (HAL_ADCEx_Calibration_Start(&hadc) != HAL_OK) //AD校准
{
Error_Handler();
}
/** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
*/
hadc.Instance = ADC1;
hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV1; //ADC_CLOCK_SYNC_PCLK_DIV2; ADC_CLOCK_SYNC_PCLK_DIV4
hadc.Init.Resolution = ADC_RESOLUTION_12B; //设置ADC采样位数
hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT; //右对齐
hadc.Init.ScanConvMode = ADC_SCAN_DIRECTION_FORWARD; //扫描方向设置
hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV; //ADC_EOC_SINGLE_CONV:单次采样 ; ADC_EOC_SEQ_CONV:序列采样
hadc.Init.LowPowerAutoWait = ENABLE; //ENABLE=读取ADC值后,开始下一次转换 ; DISABLE=直接转换
hadc.Init.ContinuousConvMode = DISABLE; //ENABLE=连续模式, DISABLE=单次模式
hadc.Init.DiscontinuousConvMode = DISABLE; //非连续转换模式设置
hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START; //触发模式设置
hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; //外部触发沿设置
hadc.Init.DMAContinuousRequests = DISABLE; //DMA连续模式设置
hadc.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; //ADC_OVR_DATA_OVERWRITTEN=过载时覆盖,ADC_OVR_DATA_PRESERVED=保留旧值
hadc.Init.SamplingTimeCommon=ADC_SAMPLETIME_13CYCLES_5; //设置采样周期
if (HAL_ADC_Init(&hadc) != HAL_OK) //初始化ADC
{
Error_Handler();
}
}
msp.c文件中补充IO初始化函数:
void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
//=============
//PA0/1/2初始化
//=============
if (hadc->Instance == ADC1)
{
/* Peripheral clock enable */
__HAL_RCC_ADC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**ADC GPIO Configuration
PA0 ------> ADC_IN0
PA1 ------> ADC_IN1
PA4 ------> ADC_IN5
*/
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
}
然后看看就是main.c函数怎么写,初始化ADC后,只需要传入需要转换的通道就可以了:
uint16_t adc_value[3];
int main(void)
{
HAL_Init(); //初始化systick
SystemClock_Config(); //时钟初始化
ADC_Init(); //ADC初始化
DEBUG_USART_Config(); //UART初始化
while (1)
{
adc_value[0] = GetAdc12Bit(ADC_CHANNEL_0);
adc_value[1] = GetAdc12Bit(ADC_CHANNEL_1);
adc_value[2] = GetAdc12Bit(ADC_CHANNEL_4);
}
}
-----------------------------------------------------------分割线-------------------------------------------------------------
类似的,下面是PY32002B/PY32C64xx 各ADC通道切换并采集的程序!
uint16_t adc_buf[4];
uint16_t GetADCValue(uint32_t ADC_Channel)
{
LL_ADC_Disable(ADC1);
/* 设定ADC的采样通道*/
LL_ADC_REG_SetSequencerChannels(ADC1, ADC_Channel);
/* ADC使能*/
APP_AdcEnable();
/* ADC 开始转换 */
LL_ADC_REG_StartConversion(ADC1);
while(LL_ADC_IsActiveFlag_EOC(ADC1) != 1);
return LL_ADC_REG_ReadConversionData12(ADC1);
}
static void APP_AdcConfig(void)
{
__IO uint32_t wait_loop_index = 0;
LL_ADC_InitTypeDef ADC_Init;
LL_ADC_REG_InitTypeDef LL_ADC_REG_InitType;
/* Enable ADC clock */
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_ADC1);
LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOA);
LL_IOP_GRP1_EnableClock(LL_IOP_GRP1_PERIPH_GPIOB);
/* Configure PA7 pin in analog input mode */
LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_7, LL_GPIO_MODE_ANALOG);
LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_1, LL_GPIO_MODE_ANALOG);
/* Initialize partical features of ADC instance */
ADC_Init.Clock=LL_ADC_CLOCK_SYNC_PCLK_DIV4;
ADC_Init.DataAlignment=LL_ADC_DATA_ALIGN_RIGHT;
ADC_Init.LowPowerMode=LL_ADC_LP_MODE_NONE;
ADC_Init.Resolution=LL_ADC_RESOLUTION_12B;
LL_ADC_Init(ADC1,&ADC_Init);
/* Sampling time 239.5 ADC clock cycles */
LL_ADC_SetSamplingTimeCommonChannels(ADC1, LL_ADC_SAMPLINGTIME_41CYCLES_5);
/* Initialize partical features of ADC instance */
LL_ADC_REG_InitType.ContinuousMode=LL_ADC_REG_CONV_SINGLE;
LL_ADC_REG_InitType.Overrun=LL_ADC_REG_OVR_DATA_OVERWRITTEN;
LL_ADC_REG_InitType.SequencerDiscont=LL_ADC_REG_SEQ_DISCONT_DISABLE;
LL_ADC_REG_InitType.TriggerSource=LL_ADC_REG_TRIG_SOFTWARE;
LL_ADC_REG_Init(ADC1,&LL_ADC_REG_InitType);
LL_ADC_REG_SetSequencerChannels(ADC1, LL_ADC_CHANNEL_0|LL_ADC_CHANNEL_4|LL_ADC_CHANNEL_VREFINT|LL_ADC_CHANNEL_TEMPSENSOR);//
/* Enable internal conversion channel */
LL_ADC_SetCommonPathInternalCh(__LL_ADC_COMMON_INSTANCE(ADC1),LL_ADC_PATH_INTERNAL_VREFINT|LL_ADC_PATH_INTERNAL_TEMPSENSOR);
// /* Set vrefbuffer voltage to 1.5V */
// LL_ADC_SetVrefBufferVoltage(ADC1,LL_ADC_VREFBUF_1P5V);
// /* Enable Vrefbuffer output */
// LL_ADC_EnableVrefBufferVoltage(ADC1);
/* Delay for VREFINT stabilization time */
wait_loop_index = ((LL_ADC_DELAY_VREFINT_STAB_US * (SystemCoreClock / (100000 * 2))) / 10);
while(wait_loop_index != 0)
{
wait_loop_index--;
}
}
int main(void)
{
/* Enable SYSCFG clock and PWR clock */
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_SYSCFG);
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
/* Configure Systemclock */
APP_SystemClockConfig();
/* Initialize USART(for printf use) */
BSP_USART_Config();
/* Enable ADC1 clock */
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_ADC1);
/* Configure ADC parameters */
APP_AdcConfig();
/* ADC automatic self-calibration */
APP_AdcCalibrate();
// AD_1V5 = HW32_REG(0x1FFF002C);
APP_AdcEnable();
printf("ok\r\n");
while (1)
{
#if 1 //全通道配置
LL_ADC_REG_StartConversion(ADC1);//ADC 开始转换
for(uint16_t i=0;i<4;i++)
{
while(LL_ADC_IsActiveFlag_EOC(ADC1) != 1);//等待转换完成
adc_buf[i] = LL_ADC_REG_ReadConversionData12(ADC1);
}
printf("CH0 PB1:%d\r\n",adc_buf[0]);
printf("CH4 PA7:%d\r\n",adc_buf[1]);
printf("TEMPSENSOR:%d\r\n",__LL_ADC_CALC_TEMPERATURE(3300,adc_buf[2],LL_ADC_RESOLUTION_12B));
printf("VRF:%d\r\n",1200*4095/adc_buf[3]);
#else //单通道切换
printf("CH0 PB1:%d\r\n",GetADCValue(LL_ADC_CHANNEL_0));
printf("CH4 PA7:%d\r\n",GetADCValue(LL_ADC_CHANNEL_4));
printf("VRF:%d\r\n",1200*4095/GetADCValue(LL_ADC_CHANNEL_VREFINT));
printf("TEMPSENSOR:%d\r\n",__LL_ADC_CALC_TEMPERATURE(3300,GetADCValue(LL_ADC_CHANNEL_TEMPSENSOR),LL_ADC_RESOLUTION_12B));
#endif
printf("\r\n");
LL_mDelay(100);
}
}
完结撒花✿✿ヽ(°▽°)ノ✿
>>>【点击进入,普冉PY32仿真烧录工具】https://blog.csdn.net/weixin_65738402/article/details/139574735