前几天小试了下,用STM32做了个万用表,采集电压电流电阻并液晶显示。 期间遇到一个最大的问题应该就是,要开启多个AD通道,结合DMA传输,小结下 下面是我对AD的配置,还有DMA void DMA_ADC_Config() { /* DMA channel1 configuration ----------------------------------------------*/ DMA_DeInit(DMA_Channel1);//复位DMA通道x DMA_InitStructure.DMA_PeripheralBaseAddr = ADC_DR_Address;//定义 DMA通道外设基地址=ADC1_DR_Address 源 //AD采集到的数据存放的寄存器 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_RegularConvertedValueTab;//定义DMA通道存储器地址,内存中的数据 目的 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//指定外设为源地址 DMA_InitStructure.DMA_BufferSize = 4;//定义DMA缓冲区大小4,4路AD,最后采集到的数值放在4位数组中 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//当前外设寄存器地址不变 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//当前存储器地址递增 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//定义外设数据宽度16位 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//定义存储器数据宽度16位 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA通道操作模式位环形缓冲模式 DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMA通道优先级高 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//禁止DMA通道存储器到存储器传输 DMA_Init(DMA_Channel1, &DMA_InitStructure);//初始化DMA通道1 DMA_Cmd(DMA_Channel1, ENABLE);//使能DMA通道1 }
void ADC1_config() { /* ADC1 configuration ------------------------------------------------------*/ ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//AD转换模式 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_InitStructure.ADC_NbrOfChannel = 4;//转换通道为通道4,4个通道来回扫描 ADC_Init(ADC1, &ADC_InitStructure); /* ADC1 regular channel14 configuration */ //ADC1选择信道14|15,采集次序1,采样时间55.5个周期 ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_55Cycles5); //通道14,PC4 扫面顺序1 ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 2, ADC_SampleTime_55Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 3, ADC_SampleTime_55Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 4, ADC_SampleTime_55Cycles5); }
DMA其实开一个就够了,它可以定义缓冲区大小,然后配置成 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//当前存储器地址递增
这样就可以传递多个数据,我是定义了一个数组 vu16 ADC_RegularConvertedValueTab[4]; AD采集到的值放在寄存器ADC_DR_Address ((u32)0x4001244C)中, 每次采集好后DMA把数据取到数组中,接下去配置AD的时候采用扫描模式 ADC_InitStructure.ADC_ScanConvMode = ENABLE;//使能扫描,多通道 多个通道在下面开启,并配置顺序 ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 1, ADC_SampleTime_55Cycles5); //通道14,PC4 扫面顺序1 ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 2, ADC_SampleTime_55Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 3, ADC_SampleTime_55Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 4, ADC_SampleTime_55Cycles5); 这样AD就来回采集通道 14 15 6 4 结合DMA后把数据存在刚才定义的数组中。 以上是心得,下面是一些疑问 1.在配置GPIO的时候我把AD口配成了输出模式,但是后来我把这段注释掉,采集还是一样没错误。难道可以不用配的? 2.AD有两个大的模式,一个是规则一个是注入,看了很久还是不明白这两个到底具体各代表什么 3.学习板光盘上面的DEMO烧进去,好像一直跳的很厉害,不知道如何才能稳下来,我是采用多次取值采用平均值,效果还可以,但是好像比较耗资源。
|