ARM嵌入式学习日记(6)

单通道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;        /* ·µ»Øƽ¾ùÖµ */
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值