本帖最后由 xld0932 于 2023-2-19 17:27 编辑
在极海的官网上,还没有发布APM32F107VC芯片的数据手册和用户手册,所以就先参考官方的SDK软件包的示例功能来对APM32F107和这MINI Board进行熟悉了……在官方最新的APM32F10x_SDK_V1.8软件包中ADC实现了模拟看门狗、连续采样模式、DMA方式、双ADC单元采样、以及多通道扫描采样这几个示例功能,在DAC中实现了噪声波形和DAC输出电压,ADC再进行采样的功能……我们对照DAC_ADC的功能进行熟悉和测试……
首先是配置ADC:将PA0配置为ADC功能的模拟采样端口引脚、然后对ADC1的功能参数进行初始化配置,因为只使用了一个ADC采样通道,所以配置为独立通道采样,使能连续采样模式,这样在开始ADC采样后,就会不停的去循环采样这一个通道的ADC数值了;不使用ADC触发采样的功能,采样的ADC结果使用右对齐的方式……然后将ADC通道的采样时间配置为ADC_SAMPLETIME_239CYCLES5,并使能ADC采样完成/结束的中断功能,最后使能并开始ADC采样,参考代码如下:
/*!
* [url=home.php?mod=space&uid=247401]@brief[/url] ADC Init
*
* @param None
*
* @retval None
*
*/
void ADC_Init(void)
{
ADC_Config_T ADC_ConfigStruct;
GPIO_Config_T GPIO_ConfigStruct;
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);
GPIO_ConfigStructInit(&GPIO_ConfigStruct);
GPIO_ConfigStruct.pin = GPIO_PIN_0;
GPIO_ConfigStruct.speed = GPIO_SPEED_50MHz;
GPIO_ConfigStruct.mode = GPIO_MODE_ANALOG;
GPIO_Config(GPIOA, &GPIO_ConfigStruct);
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_ADC1);
ADC_Reset(ADC1);
ADC_ConfigStructInit(&ADC_ConfigStruct);
ADC_ConfigStruct.mode = ADC_MODE_INDEPENDENT;
ADC_ConfigStruct.scanConvMode = DISABLE;
ADC_ConfigStruct.continuosConvMode = ENABLE;
ADC_ConfigStruct.externalTrigConv = ADC_EXT_TRIG_CONV_None;
ADC_ConfigStruct.dataAlign = ADC_DATA_ALIGN_RIGHT;
ADC_ConfigStruct.nbrOfChannel = 1;
ADC_Config(ADC1, &ADC_ConfigStruct);
ADC_ConfigRegularChannel(ADC1, ADC_CHANNEL_0, 1, ADC_SAMPLETIME_239CYCLES5);
ADC_EnableInterrupt(ADC1, ADC_INT_EOC);
NVIC_EnableIRQRequest(ADC1_2_IRQn, 1, 1);
ADC_Enable(ADC1);
ADC_EnableSoftwareStartConv(ADC1);
}
其次是配置DAC:将PA4配置为DAC功能的模拟输出端口引脚,然后对DAC的功能参数进行初始化配置,不使用触发的方式和自生成的波形、配置输出BUFFER使能及DAC_LFSR_MASK_BIT11_1的功能位,最后使能DAC,参考代码如下……
/*!
* [url=home.php?mod=space&uid=247401]@brief[/url] DAC Init
*
* @param None
*
* @retval None
*
*/
void DAC_Init(void)
{
DAC_Config_T DAC_ConfigStruct;
GPIO_Config_T GPIO_ConfigStruct;
RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);
GPIO_ConfigStructInit(&GPIO_ConfigStruct);
GPIO_ConfigStruct.pin = GPIO_PIN_4;
GPIO_ConfigStruct.mode = GPIO_MODE_ANALOG;
GPIO_Config(GPIOA, &GPIO_ConfigStruct);
RCM_EnableAPB1PeriphClock(RCM_APB1_PERIPH_DAC);
DAC_ConfigStructInit(&DAC_ConfigStruct);
DAC_ConfigStruct.trigger = DAC_TRIGGER_NONE;
DAC_ConfigStruct.outputBuffer = DAC_OUTPUT_BUFFER_ENBALE;
DAC_ConfigStruct.waveGeneration = DAC_WAVE_GENERATION_NONE;
DAC_ConfigStruct.maskAmplitudeSelect = DAC_LFSR_MASK_BIT11_1;
DAC_Config(DAC_CHANNEL_1, &DAC_ConfigStruct);
DAC_Enable(DAC_CHANNEL_1);
}
最后我们看一下在ADC通道采样完成中断函数中的处理:通过DAC_ConfigChannel1Data函数配置DAC通道引脚输出不同电压值,为下次的ADC采样作准备;然后ADC读取上次ADC转换完成的转换结果,将其换算成对应的电压值,将其通过串口把结果打印出来……根据换算的电压值对其电压所处的范围进行判断,然后通过LED显示其对应的状态……最后清除此次的ADC中断标志位,ADC将继续下一循的采样处理,参考代码数下:
/*!
* [url=home.php?mod=space&uid=247401]@brief[/url] This function handles ADC interrupt Handler
*
* @param None
*
* @retval None
*
* @note
*/
void ADC1_2_IRQHandler(void)
{
uint16_t ADC_Data = 0;
uint16_t Voltage = 0;
DAC_ConfigChannel1Data(DAC_ALIGN_12BIT_R, DAC_Data);
DAC_Data = (DAC_Data + 0x7F) % 0x0FFF;
if (ADC_ReadStatusFlag(ADC1, ADC_FLAG_EOC))
{
ADC_Data = ADC_ReadConversionValue(ADC1);
Voltage = (ADC_Data * 3300) / 4095;
printf("\r\nVoltage : %d mV\r\n", Voltage);
if (Voltage > 2000) /* Voltage greater than 2000mv */
{
LED_Enable(2, ENABLE);
LED_Enable(3, DISABLE);
}
else if (Voltage < 800) /* Voltage less than 800mv */
{
LED_Enable(2, DISABLE);
LED_Enable(3, ENABLE);
}
else /* 800mv <= Voltage <= 2000 */
{
LED_Enable(2, ENABLE);
LED_Enable(3, ENABLE);
}
for(uint32_t i = 0; i < 0xFFFFF; i++)
{
}
ADC_ClearStatusFlag(ADC1, ADC_FLAG_EOC);
}
}
测试时我们将编译无误的程序下载到开发板,然后将PA0的ADC采样引脚与PA4的DAC输出引脚通过排线进行短接在一起,这样才能够正常测试其功能,通过LED灯的显示状态查看运行结果……
软件工程源代码:
Project_ADC_DAC.zip
(483.83 KB)
|