第六章 AT32F403A替换stm32f103 ADC+DMA测试
前言
此文章是使用AT32F403A的开发板去跑stm32f103的ADC+DMA代码的测试情况。
通过在循环中定时打印adc的值
硬件
硬件方面使用的是雅特力官方发布的AT32F403A开发板,开发板上面还板载了一个ATLINK_EZ的仿真器,ATLINK_EZ还有一个串口的功能,硬件上是接到了MCU的串口1上。这个ATLINK_EZ可以掰下来使用。
如下图是开发板pcb图(左边的就是ATLINK_EZ):
如果仿真工具使用的是jlink的,那可以使用jtag或者swd接口就可以,根据开发板的电路接好线即可。
软件
测试使用的软件是stm32f103的3.5标准库的工程代码。想快速验证的可以下正点、野火等的代码回来再根据自己外设的硬件的设计稍微修改就可以进行测试,就是库是stm32F103的3.5标准库的。
软件相关部分:
使用ADC1,采集通道1,2,3的值,使用dma1来进行搬运。其中通道1和通道3短接到vcc,通道2短接gnd。
相关代码如下:
int main(void)
{
u8 i=0;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置中断优先级分组为组2:2位抢占优先级,2位响应优先级
delay_init(); //延时函数初始化
uart1_init(115200); //串口初始化为115200
Adc_Dma_Init(); //ADC DMA初始化
printf ("AT32F403A 替换 sxx32 ADC DMA 测试!!\r\n");
while(1)
{
for(i=0;i<3;i++)
{
printf ("ADC_Channel_%d val: %02x",i,dmavaldata[i]);
printf("\r\n");
}
printf("\r\n");
printf("\r\n");
delay_ms(1000);
}
}
void Adc_Dma_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
DMA_InitTypeDef DMA_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE ); //使能ADC1通道时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE); //使能DMA1通道时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //adc时钟分频设置,72/6=12M
//PA1,2,3 作为模拟通道输入引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(GPIOA, &GPIO_InitStructure);
DMA_DeInit(DMA1_Channel1);
DMA_StructInit(&DMA_InitStruct);
DMA_InitStruct.DMA_PeripheralBaseAddr =(uint32_t)&ADC1->DR;
DMA_InitStruct.DMA_MemoryBaseAddr =(uint32_t)dmavaldata; /*这里强转为(uint32_t)类型,是因为在结构体DMA_InitStruct里面,成员DMA_MemoryBaseAddr是uint32_t类型的*/
DMA_InitStruct.DMA_DIR =DMA_DIR_PeripheralSRC;
DMA_InitStruct.DMA_PeripheralInc =DMA_PeripheralInc_Disable;
DMA_InitStruct.DMA_MemoryInc =DMA_MemoryInc_Enable;
DMA_InitStruct.DMA_PeripheralDataSize =DMA_PeripheralDataSize_HalfWord;
DMA_InitStruct.DMA_MemoryDataSize =DMA_MemoryDataSize_HalfWord;
DMA_InitStruct.DMA_BufferSize =3;
DMA_InitStruct.DMA_M2M =DMA_M2M_Disable;
DMA_InitStruct.DMA_Mode =DMA_Mode_Circular;
DMA_InitStruct.DMA_Priority =DMA_Priority_High;
DMA_Init(DMA1_Channel1,&DMA_InitStruct);
// 7,使能DMA1通道1
DMA_Cmd(DMA1_Channel1, ENABLE);
ADC_DeInit(ADC1); //复位ADC1
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 3; //顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 3, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道,采样时间为239.5周期
ADC_DMACmd(ADC1,ENABLE); //使能adc dma
ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
ADC_ResetCalibration(ADC1); //使能复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
ADC_StartCalibration(ADC1); //开启AD校准
while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能
}
测试结果
通过看串口助手的log,程序已经运行起来,采样到的值也和我们硬件的接线对应上了:
总结
从测试来看,AT32F403A是可以直接的跑stm32f103的ADC的代码,在使用上一致。
特别需要注意的是,AT32的adc的模块的输入电压最高是3.3+0.3v,高于这个值的电压输入,采集的结果肯定不对,甚至会影响到所有的通道,以及ADC的io是3.3v的电压,高的电压输入还可能导致其他的问题。
本文仅供于学习、测试使用。
有什么问题的可加qq群技术交流。
资源: