单通道ADC采样实验
main.c
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./USMART/usmart.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/ADC/adc.h"
int main(void)
{
uint16_t adcx;
float temp;
HAL_Init(); /* ³õʼ»¯HAL¿â */
sys_stm32_clock_init(RCC_PLL_MUL9); /* ÉèÖÃʱÖÓ, 72Mhz */
delay_init(72); /* ÑÓʱ³õʼ»¯ */
usart_init(115200); /* ´®¿Ú³õʼ»¯Îª115200 */
led_init(); /* ³õʼ»¯LED */
lcd_init(); /* ³õʼ»¯LCD */
adc_init(); /* ³õʼ»¯ADC */
lcd_show_string(30, 50, 200, 16, 16, "STM32", RED);
lcd_show_string(30, 70, 200, 16, 16, "ADC TEST", RED);
lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
lcd_show_string(30, 110, 200, 16, 16, "ADC1_CH1_VAL:", BLUE);
lcd_show_string(30, 130, 200, 16, 16, "ADC1_CH1_VOL:0.000V", BLUE); /* ÏÈÔڹ̶¨Î»ÖÃÏÔʾСÊýµã */
while (1)
{
adcx = adc_get_result_average(ADC_ADCX_CHY, 10); /* »ñȡͨµÀ5µÄת»»Öµ£¬10´Îȡƽ¾ù */
lcd_show_xnum(134, 110, adcx, 5, 16, 0, BLUE); /* ÏÔʾADCC²ÉÑùºóµÄÔʼֵ */
temp = (float)adcx * (3.3 / 4096); /* »ñÈ¡¼ÆËãºóµÄ´øСÊýµÄʵ¼Êµçѹֵ£¬±ÈÈç3.1111 */
adcx = temp; /* ¸³ÖµÕûÊý²¿·Ö¸øadcx±äÁ¿£¬ÒòΪadcxΪu16ÕûÐÎ */
lcd_show_xnum(134, 130, adcx, 1, 16, 0, BLUE); /* ÏÔʾµçѹֵµÄÕûÊý²¿·Ö£¬3.1111µÄ»°£¬ÕâÀï¾ÍÊÇÏÔʾ3 */
temp -= adcx; /* °ÑÒѾÏÔʾµÄÕûÊý²¿·ÖÈ¥µô£¬ÁôÏÂСÊý²¿·Ö£¬±ÈÈç3.1111-3=0.1111 */
temp *= 1000; /* СÊý²¿·Ö³ËÒÔ1000£¬ÀýÈ磺0.1111¾Íת»»Îª111.1£¬Ï൱ÓÚ±£ÁôÈýλСÊý¡£ */
lcd_show_xnum(150, 130, temp, 3, 16, 0X80, BLUE); /* ÏÔʾСÊý²¿·Ö£¨Ç°Ãæת»»ÎªÁËÕûÐÎÏÔʾ£©£¬ÕâÀïÏÔʾµÄ¾ÍÊÇ111. */
LED0_TOGGLE();
delay_ms(100);
}
adc.c
#include "./BSP/ADC/adc.h"
#include "./SYSTEM/delay/delay.h"
ADC_HandleTypeDef g_adc_handle; /* ADC¾ä±ú */
/**
* @brief ADC³õʼ»¯º¯Êý
* @note ±¾º¯ÊýÖ§³ÖADC1/ADC2ÈÎÒâͨµÀ, µ«ÊDz»Ö§³ÖADC3
* ÎÒÃÇʹÓÃ12λ¾«¶È, ADC²ÉÑùʱÖÓ=12M, ת»»Ê±¼äΪ: ²ÉÑùÖÜÆÚ + 12.5¸öADCÖÜÆÚ
* ÉèÖÃ×î´ó²ÉÑùÖÜÆÚ: 239.5, Ôòת»»Ê±¼ä = 252 ¸öADCÖÜÆÚ = 21us
* @param ÎÞ
* @retval ÎÞ
*/
void adc_init(void)
{
g_adc_handle.Instance = ADC_ADCX; /* Ñ¡ÔñÄĸöADC */
g_adc_handle.Init.DataAlign = ADC_DATAALIGN_RIGHT; /* Êý¾Ý¶ÔÆ뷽ʽ£ºÓÒ¶ÔÆë */
g_adc_handle.Init.ScanConvMode = ADC_SCAN_DISABLE; /* ·ÇɨÃèģʽ£¬½öÓõ½Ò»¸öͨµÀ */
g_adc_handle.Init.ContinuousConvMode = DISABLE; /* ¹Ø±ÕÁ¬Ðøת»»Ä£Ê½ */
g_adc_handle.Init.NbrOfConversion = 1; /* ¸³Öµ·¶Î§ÊÇ1~16£¬±¾ÊµÑéÓõ½1¸ö¹æÔòͨµÀÐòÁÐ */
g_adc_handle.Init.DiscontinuousConvMode = DISABLE; /* ½ûÖ¹¹æÔòͨµÀ×é¼ä¶Ïģʽ */
g_adc_handle.Init.NbrOfDiscConversion = 0; /* ÅäÖüä¶ÏģʽµÄ¹æÔòͨµÀ¸öÊý£¬½ûÖ¹¹æÔòͨµÀ×é¼ä¶Ïģʽºó£¬´Ë²ÎÊýºöÂÔ */
g_adc_handle.Init.ExternalTrigConv = ADC_SOFTWARE_START; /* ´¥·¢×ª»»·½Ê½£ºÈí¼þ´¥·¢ */
HAL_ADC_Init(&g_adc_handle); /* ³õʼ»¯ */
HAL_ADCEx_Calibration_Start(&g_adc_handle); /* У׼ADC */
}
/**
* @brief ADCµ×²ãÇý¶¯£¬Òý½ÅÅäÖã¬Ê±ÖÓʹÄÜ
´Ëº¯Êý»á±»HAL_ADC_Init()µ÷ÓÃ
* @param hadc:ADC¾ä±ú
* @retval ÎÞ
*/
void HAL_ADC_MspInit(ADC_HandleTypeDef *hadc)
{
if(hadc->Instance == ADC_ADCX)
{
GPIO_InitTypeDef gpio_init_struct;
RCC_PeriphCLKInitTypeDef adc_clk_init = {0};
ADC_ADCX_CHY_CLK_ENABLE(); /* ʹÄÜADCxʱÖÓ */
ADC_ADCX_CHY_GPIO_CLK_ENABLE(); /* ¿ªÆôGPIOʱÖÓ */
/* ÉèÖÃADCʱÖÓ */
adc_clk_init.PeriphClockSelection = RCC_PERIPHCLK_ADC; /* ADCÍâÉèʱÖÓ */
adc_clk_init.AdcClockSelection = RCC_ADCPCLK2_DIV6; /* ·ÖƵÒò×Ó6ʱÖÓΪ72M/6=12MHz */
HAL_RCCEx_PeriphCLKConfig(&adc_clk_init); /* ÉèÖÃADCʱÖÓ */
/* ÉèÖÃAD²É¼¯Í¨µÀ¶ÔÓ¦IOÒý½Å¹¤×÷ģʽ */
gpio_init_struct.Pin = ADC_ADCX_CHY_GPIO_PIN; /* ADCͨµÀIOÒý½Å */
gpio_init_struct.Mode = GPIO_MODE_ANALOG; /* Ä£Äâ */
HAL_GPIO_Init(ADC_ADCX_CHY_GPIO_PORT, &gpio_init_struct);
}
}
/**
* @brief ÉèÖÃADCͨµÀ²ÉÑùʱ¼ä
* @param adcx : adc¾ä±úÖ¸Õë,ADC_HandleTypeDef
* @param ch : ͨµÀºÅ, ADC_CHANNEL_0~ADC_CHANNEL_17
* @param stime: ²ÉÑùʱ¼ä 0~7, ¶ÔÓ¦¹ØϵΪ:
* @arg ADC_SAMPLETIME_1CYCLE_5, 1.5¸öADCʱÖÓÖÜÆÚ ADC_SAMPLETIME_7CYCLES_5, 7.5¸öADCʱÖÓÖÜÆÚ
* @arg ADC_SAMPLETIME_13CYCLES_5, 13.5¸öADCʱÖÓÖÜÆÚ ADC_SAMPLETIME_28CYCLES_5, 28.5¸öADCʱÖÓÖÜÆÚ
* @arg ADC_SAMPLETIME_41CYCLES_5, 41.5¸öADCʱÖÓÖÜÆÚ ADC_SAMPLETIME_55CYCLES_5, 55.5¸öADCʱÖÓÖÜÆÚ
* @arg ADC_SAMPLETIME_71CYCLES_5, 71.5¸öADCʱÖÓÖÜÆÚ ADC_SAMPLETIME_239CYCLES_5, 239.5¸öADCʱÖÓÖÜÆÚ
* @param rank: ¶àͨµÀ²É¼¯Ê±ÐèÒªÉèÖõIJɼ¯±àºÅ,
¼ÙÉèÄ㶨Òåchannle1µÄrank=1£¬channle2 µÄrank=2£¬
ÄÇô¶ÔÓ¦ÄãÔÚDMA»º´æ¿Õ¼äµÄ±äÁ¿Êý×éAdcDMA[0] ¾ÍiÊÇchannle1µÄת»»½á¹û£¬AdcDMA[1]¾ÍÊÇͨµÀ2µÄת»»½á¹û¡£
µ¥Í¨µÀDMAÉèÖÃΪ ADC_REGULAR_RANK_1
* @arg ±àºÅ1~16£ºADC_REGULAR_RANK_1~ADC_REGULAR_RANK_16
* @retval ÎÞ
*/
void adc_channel_set(ADC_HandleTypeDef *adc_handle, uint32_t ch, uint32_t rank, uint32_t stime)
{
ADC_ChannelConfTypeDef adc_ch_conf;
adc_ch_conf.Channel = ch; /* ͨµÀ */
adc_ch_conf.Rank = rank; /* ÐòÁÐ */
adc_ch_conf.SamplingTime = stime; /* ²ÉÑùʱ¼ä */
HAL_ADC_ConfigChannel(adc_handle, &adc_ch_conf); /* ͨµÀÅäÖà */
}
/**
* @brief »ñµÃADCת»»ºóµÄ½á¹û
* @param ch: ͨµÀÖµ 0~17£¬È¡Öµ·¶Î§Îª£ºADC_CHANNEL_0~ADC_CHANNEL_17
* @retval ÎÞ
*/
uint32_t adc_get_result(uint32_t ch)
{
adc_channel_set(&g_adc_handle , ch, ADC_REGULAR_RANK_1, ADC_SAMPLETIME_239CYCLES_5); /* ÉèÖÃͨµÀ£¬ÐòÁкͲÉÑùʱ¼ä */
HAL_ADC_Start(&g_adc_handle); /* ¿ªÆôADC */
HAL_ADC_PollForConversion(&g_adc_handle, 10); /* ÂÖѯת»» */
return (uint16_t)HAL_ADC_GetValue(&g_adc_handle); /* ·µ»Ø×î½üÒ»´ÎADC1¹æÔò×éµÄת»»½á¹û */
}
/**
* @brief »ñȡͨµÀchµÄת»»Öµ£¬È¡times´Î,È»ºóƽ¾ù
* @param ch : ͨµÀºÅ, 0~17
* @param times : »ñÈ¡´ÎÊý
* @retval ͨµÀchµÄtimes´Îת»»½á¹ûƽ¾ùÖµ
*/
uint32_t adc_get_result_average(uint32_t ch, uint8_t times)
{
uint32_t temp_val = 0;
uint8_t t;
for (t = 0; t < times; t++) /* »ñÈ¡times´ÎÊý¾Ý */
{
temp_val += adc_get_result(ch);
delay_ms(5);
}
return temp_val / times; /* ·µ»Øƽ¾ùÖµ */
}