#include "gd32vf103.h"
#include "systick.h"
#include <stdint.h>
#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);
}
网友评论