本帖最后由 ljmf5 于 2017-1-21 10:56 编辑
前几天,发现STM32的ADC还有双模式,就自己学了一下。基本上能实现对同一通道的慢速交叉采样。这里使用软件触发,硬件触发还没想明白怎么搞
第一次发分享帖,心中还有点小兴奋
下面直接贴代码,工程文件见附件,要做这个的坛友们可以互相学习一下,也还有些问题没搞清楚
[mw_shl_code=c,true]#include "stm32f10x.h"
#include "stm32f10x_adc.h"
#include "stm32f10x_dma.h" //我写代码,总是要添加这些固件库头文件,不知道哪里有疏漏?
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "dma.h"
#include "ad.h"
#include "timer.h"
//DMA的内存地址
u32 DMA_buffer;
int main(void)
{
delay_init();
uart_init(9600);
DMA_initial(DMA1_Channel1, (u32)&ADC1->DR, (u32)&DMA_buffer, 1);
ADC12_init();
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
// ADC_SoftwareStartConvCmd(ADC2, ENABLE); // 这一句无论是否添加,输出的结果是一样的,
//具体也不知道会不会有什么运行机制上的差别?
DMA_start(DMA1_Channel1,1);
printf("1111
");
while(1)
{
printf("2222
");
DMA_start(DMA1_Channel1,1);
while(DMA_GetFlagStatus(DMA1_FLAG_TC1)) //等待DMA传输完成
{
DMA_ClearFlag(DMA1_FLAG_TC1); //清楚中断完成标志
printf("ADC1:%d, %f
", ADC1->DR, ADC1->DR*3.3/4096);
printf("ADC2:%d, %f
",ADC2->DR,ADC2->DR*3.3/4096);
printf("DMA_buffer:%d, %f
",DMA_buffer, (DMA_buffer)*3.3/4096);
printf("ADC1:%d, %f
",DMA_buffer&0x0000ffff, (DMA_buffer&0x0000ffff)*3.3/4096);
printf("ADC2:%d, %f
",((DMA_buffer>>16)&0x0000ffff),((DMA_buffer>>16)&0x0000ffff)*3.3/4096);
printf("
--------------------------------------------------
");
}
}
}
[/mw_shl_code]
[mw_shl_code=c,true]void ADC12_init(void)
{
//通道IO初始化
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
//使能PA、ADC1时钟和ADC2时钟,最开始忘记了使能ADC2的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_ADC1|RCC_APB2Periph_ADC2, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //PA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度为50MHz
GPIO_Init(GPIOA, &GPIO_InitStructure); //根据设定参数初始化GPIOA0
//复位ADC1,并设置ADC分频因子
ADC_DeInit(ADC1);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//6分频,72/6=12MHz
//ADC1相关参数配置
ADC_InitStructure.ADC_ScanConvMode= DISABLE; //只有1个通道,不在通道件切换
ADC_InitStructure.ADC_ContinuousConvMode= DISABLE; //连续扫描
ADC_InitStructure.ADC_DataAlign= ADC_DataAlign_Right;//右对齐
ADC_InitStructure.ADC_ExternalTrigConv= ADC_ExternalTrigConv_None;//不使用外部触发
ADC_InitStructure.ADC_Mode= ADC_Mode_SlowInterl;//规则通道 慢速交叉模式
ADC_InitStructure.ADC_NbrOfChannel= 1;//只有1个通道,不需要设置规则通道组的次序
ADC_Init(ADC1, &ADC_InitStructure);
//配置ADC1采样时间及RANK等相关参数
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_7Cycles5);
//复位ADC2,并设置ADC分频因子
ADC_DeInit(ADC2);
// RCC_ADCCLKConfig(RCC_PCLK2_Div6);//6分频,72/6=12MHz
//ADC2相关参数配置
ADC_InitStructure.ADC_ScanConvMode= DISABLE; //只有1个通道,不在通道件切换
ADC_InitStructure.ADC_ContinuousConvMode= DISABLE; //连续扫描
ADC_InitStructure.ADC_DataAlign= ADC_DataAlign_Right;//右对齐
ADC_InitStructure.ADC_ExternalTrigConv= ADC_ExternalTrigConv_None;//不使用外部触发
ADC_InitStructure.ADC_Mode= ADC_Mode_SlowInterl;//规则通道 慢速交叉模式
ADC_InitStructure.ADC_NbrOfChannel= 1;//只有1个通道,不需要设置规则通道组的次序
ADC_Init(ADC2, &ADC_InitStructure);
//配置ADC2采样时间及RANK等相关参数
ADC_RegularChannelConfig(ADC2, ADC_Channel_0, 1, ADC_SampleTime_7Cycles5);
//使能ADC1的DMA传输
ADC_DMACmd(ADC1, ENABLE);
//使能并校准ADC1
ADC_Cmd(ADC1, ENABLE);//使能ADC1
ADC_ResetCalibration(ADC1);//复位校准ADC1
while(ADC_GetResetCalibrationStatus(ADC1));//等待复位校准ADC1
ADC_StartCalibration(ADC1);//校准ADC1
while(ADC_GetCalibrationStatus(ADC1));//等待校准ADC1
//使能并校准ADC2
ADC_Cmd(ADC2, ENABLE);//使能ADC2
ADC_ResetCalibration(ADC2);//复位校准ADC2
while(ADC_GetResetCalibrationStatus(ADC2));//等待复位校准ADC2
ADC_StartCalibration(ADC2);//校准ADC1
while(ADC_GetCalibrationStatus(ADC2));//等待校准ADC2
//使能ADC2外部触发转换
ADC_ExternalTrigConvCmd(ADC2, ENABLE);//不加这个就会导致数据错误,
//ADC2->DR 和DMA_buffer>>16均有问题,而且这两个值还不相等
//不知道这是为什么?
}[/mw_shl_code]
[mw_shl_code=c,true]
#include "dma.h"
#include "stm32f10x_dma.h" //这里也是,不添加就会提示错误?
extern u32 DMA_buffer;
//DMA1--通道1--ADC1
//外设基地址ADC1->DR
//内存基地址
void DMA_initial(DMA_Channel_TypeDef* DMAy_Channelx, u32 cpar, u32 cmar, u16 count)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//开启DMA时钟
DMA_DeInit(DMAy_Channelx);
DMA_InitStructure.DMA_M2M= DMA_M2M_Disable; //非内存到内存
DMA_InitStructure.DMA_DIR= DMA_DIR_PeripheralSRC;//外设为数据源
DMA_InitStructure.DMA_PeripheralBaseAddr= cpar; //外设数据地址
DMA_InitStructure.DMA_PeripheralDataSize= DMA_PeripheralDataSize_Word; //外设的数据尺寸为字,即32位
DMA_InitStructure.DMA_PeripheralInc= DMA_PeripheralInc_Disable; //外设地址不自增
DMA_InitStructure.DMA_MemoryBaseAddr= cmar; //内存数据存储地址
DMA_InitStructure.DMA_MemoryDataSize= DMA_MemoryDataSize_Word; //DMA接收的数据尺寸为字,即32位
DMA_InitStructure.DMA_MemoryInc= DMA_MemoryInc_Disable; //DMA内存接受地址不自增
DMA_InitStructure.DMA_Mode= DMA_Mode_Normal ;//DMA工作在正常缓存模式
DMA_InitStructure.DMA_BufferSize= count; //设置接收的数据量为1
DMA_InitStructure.DMA_Priority= DMA_Priority_Medium;//中等优先级
DMA_Init(DMA1_Channel1, &DMA_InitStructure);
}
void DMA_start(DMA_Channel_TypeDef* DMAy_Channelx, u16 count)
{
DMA_Cmd(DMAy_Channelx, DISABLE);
DMA_SetCurrDataCounter(DMAy_Channelx, count);
DMA_Cmd(DMAy_Channelx, ENABLE);
}
[/mw_shl_code]
一周热门 更多>