读取adc


#include "gd32vf103.h"
#include "systick.h"
#include 
#include "lcd/lcd.h"

#define ANALOG_PORT GPIOA
#define ANALOG_PIN GPIO_PIN_3
#define ANALOG_CHANNEL ADC_CHANNEL_3

#define RED_LED_PIN GPIO_PIN_13
#define RED_LED_PORT GPIOC

void init_ADC_example();

int main(void)
{
    uint16_t analog_read = 0;

    /* config ADC */
    /* 配置 ADC */
    init_ADC_example();

    Lcd_Init(); // init OLED
    LCD_Clear(BLACK);
    // 显示汉字“中景园”
    LCD_ShowChinese(24, 0, 0, 16, YELLOW);
    LCD_ShowChinese(48, 0, 1, 16, RED);
    LCD_ShowChinese(72, 0, 2, 16, GREEN);
    // 图型变量
    u16 x = 0;
    u16 y = 48;

    /* initiate the gpio for the red led on the longan board */
    /* 初始化 GPIO 用于闪烁红色 LED */
    rcu_periph_clock_enable(RCU_GPIOC);
    gpio_init(RED_LED_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, RED_LED_PIN);

    /* This loop generates a software based PWM signal which has a duty cycle based on the read analog value 
       (if you need an actual PWM signal though check the PWM example where it's done in hardware instead) */
    while (1)
    {
        /* Read analog value on pin */
        /* 读取引脚上的模拟值 */
        // analog_read = ADC_RDATA(ADC0);
        analog_read = adc_regular_data_read(ADC0);

        /* LCD 显示 */
        LCD_ShowNum(80, 16, analog_read,4, MAGENTA);
        LCD_DrawPoint(x, y - 10 * analog_read / 100, BLUE);
        if (x > 159)
        {
            LCD_Clear(BLACK);
            // LCD_DrawRectangle(0,40,159,80,WHITE);
            x = 0;
        }
        x++;

        /* Red LED on */
        /* 点亮 LED */
        // gpio_bit_write(RED_LED_PORT, RED_LED_PIN, 0);

        /* If ADC reads a high voltage delay for a longer time */
        /* 如果 ADC 读取高电压延迟较长时间 */
        delay_1us(analog_read);

        /* Red LED off */
        /* 关闭 LED */
        // gpio_bit_write(RED_LED_PORT, RED_LED_PIN, 1);

        /* Delay for longer if ADC reads a low voltage */
        /* 如果 ADC 读取低电压,则延迟更长 */
        // delay_1us(4096 - analog_read);
    }
}

void init_ADC_example()
{
    /* enable GPIOC clock */
    /* 打开 GPIO_C 时钟 */
    rcu_periph_clock_enable(RCU_GPIOC);
    /* Initialize the GPIO that will be used for ADC. A0-A7 and B0-B1 are connected to an ADC-channel each. */
    /* 初始化将用于 ADC 的 GPIO。 A0-A7 和 B0-B1 分别连接到一个 ADC 通道 */
    gpio_init(ANALOG_PORT, GPIO_MODE_AIN, GPIO_OSPEED_50MHZ, ANALOG_PIN);
    /* enable ADC clock */
    /* 打开 ADC 时钟 */
    rcu_periph_clock_enable(RCU_ADC0);

    /* Select the clock frequency that will be used for the ADC core. Refer to README for more info on what to select. */
    /* 选择将用于 ADC 内核的时钟频率。有关选择内容的更多信息,请参阅自述文件 */
    // 108mhz 8分频 13mhz  采样周期 239.5+12.5 =252 个时钟周期 除以 13mhz = 19.38us 频率为 51587.3hz
    rcu_adc_clock_config(RCU_CKADC_CKAPB2_DIV8);

    /* Reset ADC0 configuration. GD32VF103 has two internal ADCs (ADC0, ADC1). */
    /* 重置 ADC_0 通道, 此芯片有两个 ADC 通道  */
    adc_deinit(ADC0);

    /* Set the ADCs to work independently. Refer to the manual for the different parallel modes available. */
    /* 将 ADC 设置为独立工作。有关可用的不同并行模式,请参阅手册 */
    adc_mode_config(ADC_MODE_FREE);

    /* Set the conversion mode to continuous. Continious mode lets the ADC take measurements continiously without
       an external trigger. */
    /* 将转换模式设置为连续。连续模式让 ADC 连续进行测量,而无需一个外部触发器。 */
    adc_special_function_config(ADC0, ADC_CONTINUOUS_MODE, ENABLE);

    /* Sets where padding is applied to the measurement. Data alignment right puts padding bits above MSB */
    /* 设置将填充应用于测量的位置。数据对齐右将填充位置于 MSB 之上 */
    adc_data_alignment_config(ADC0, ADC_DATAALIGN_RIGHT);

    /* Selects how many channels to convert each time. This can be used to "queue" multiple channels. Here just one channel is selected. */
    /* 选择每次转换多少个频道。这可用于“排队”多个频道。这里只选择了一个频道 */
    adc_channel_length_config(ADC0, ADC_REGULAR_CHANNEL, 1);

    /* Set the channel as the first "queued" conversion each time the ADC is activated. */
    /* 每次激活 ADC 时将通道设置为第一个“排队”转换,设置 adc 采周期*/
    adc_regular_channel_config(ADC0, 0, ANALOG_CHANNEL, ADC_SAMPLETIME_239POINT5);
    // 配置分辨率 12位
    adc_resolution_config(ADC0,ADC_RESOLUTION_12B);

    /* Since we are using continious conversion we do not want to use an external trigger. */
    /* 由于我们使用的是连续转换,我们不想使用外部触发器 */
    adc_external_trigger_source_config(ADC0, ADC_REGULAR_CHANNEL, ADC0_1_EXTTRIG_REGULAR_NONE);
    adc_external_trigger_config(ADC0, ADC_REGULAR_CHANNEL, ENABLE);

    /**
     * @brief ADC 校准过程
     * 内部的模拟校准通过设置 ADC_CTL1 寄存器的 RSTCLB 位来重置。
     * 1. 确保ADCON=1;
     * 2. 延迟14个ADCCLK以等待ADC稳定;
     * 3. 设置RSTCLB (可选的);
     * 4. 设置CLB=1;
     * 5. 等待直到CLB=0。
     */
    /* Enable ADC.*/
    /* 打开 ADC */
    adc_enable(ADC0); //  ADC_CTL1(adc_periph) |= (uint32_t)ADC_CTL1_ADCON;

    /* Let ADC stabilize */
    /* 让ADC稳定 */
    delay_1ms(1); // 第二步 等 ADC 稳定,最少14个 ADC 时钟周期

    /* Calibrates the ADC against an internal source. */
    /* 根据内部源校准 ADC */
    adc_calibration_enable(ADC0); // 第三、四、五步完成校准

    /* Start converting */
    /* 开始转换 */
    adc_software_trigger_enable(ADC0, ADC_REGULAR_CHANNEL);
}

你可能感兴趣的:(读取adc)