对at的双重adc进行测试本来打算一上午解决的,结果弄了三天,adc+dma一直有问题,最后发现自己的果然是自己菜把函数写错了,但是改正之后依旧不正常,最后发现在程序跑飞了
先来简单的讲解一下双重adc
at有 2 个或以上 ADC 模块的产品中,可以使用双 ADC 模式,双重adc模式包括:
─ 同步注入模式
─ 同步规则模式
─ 快速交叉模式
─ 慢速交叉模式
─ 交替触发模式
─ 独立模式
还有可以用下列方式组合使用上面的模式:
─ 同步注入模式 + 同步规则模式
─ 同步规则模式 + 交替触发模式
─ 同步注入模式 + 交叉模式
同时双重模式一般速率太快必须使用dma(注:只有 ADC1 和 ADC3 拥有 DMA 功能。由 ADC2 转化的数据可以通过双 ADC 模式,利用 ADC1 的 DMA 功能传输。)
本人使用的双重adc快速交叉模式 (每个模式对应的图不同,请自行查询手册)
at的ADC 的输入时钟不得超过 28 MHz,将采样速度开到1.5clk时,adc速率高达2M,如果再配合双重模式那是相当的nice
但在我以前stm32的代码移植到at上时,程序一直出现问题,串口根本不输出任何数据
结果仿真后发现他凉在了
然后在网上查阅了大量资料以后依然没有解决,程序已经被改的乱七八糟。最后我干脆将两个adc的校验直接删除后,一切都正常的,当时我就自闭了,然后通过不断修改发现将adc1的开启校验放在adc2的复位校准后代码居然正常了(单纯在初始化后加延时不起作用)
我又重新对stm32的程序进行检测,发现一样程序at32有问题的地方stm32没有,将stm32的程序下载到at32中(大部分程序都可以)也出现了的问题。
同时说一下其它一些重要问题,网上很多朋友遇到的。
要想开启双重模式必须要开启adc2的触发源 ADC_ExternalTrigConvCtrl(ADC2, ENABLE);
暂时粘贴部分代码,文件被修改的比较乱,后面整理后上传
ADC_InitType ADC_InitStructure;
RCC_APB2PeriphClockCmd(Adc1_Clk|Adc2_Clk, ENABLE ); //ʹÄÜADC1ͨµÀʱÖÓ
ADC_Reset(ADC1); //¸´Î»ADC1,½«ÍâÉè ADC1 µÄÈ«²¿¼Ä´æÆ÷ÖØÉèΪȱʡֵ
ADC_Reset(ADC2);
ADC_InitStructure.ADC_Mode = ADC_Mode_FastInterl;
ADC_InitStructure.ADC_ScanMode = DISABLE;
ADC_InitStructure.ADC_ContinuousMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrig = ADC_ExternalTrig_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NumOfChannel = 1;
ADC_Init(ADC1, &ADC_InitStructure);
//ADC1 regular channel14 configuration
ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_1_5);
//Enable ADC1 DMA
ADC_DMACtrl(ADC1, ENABLE);
//ADC2 configuration
ADC_InitStructure.ADC_Mode = ADC_Mode_FastInterl;
ADC_InitStructure.ADC_ScanMode = DISABLE;
ADC_InitStructure.ADC_ContinuousMode = ENABLE;
ADC_InitStructure.ADC_ExternalTrig = ADC_ExternalTrig_None;
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NumOfChannel = 1;
ADC_Init(ADC2, &ADC_InitStructure);
//ADC2 regular channel14 configuration
ADC_RegularChannelConfig(ADC2, ADC_Channel_0, 1, ADC_SampleTime_1_5);
ADC_ExternalTrigConvCtrl(ADC2, ENABLE);
//Enable ADC1
ADC_Ctrl(ADC1, ENABLE);
//Enable ADC1 reset calibaration register
ADC_RstCalibration(ADC1);
//Check the end of ADC1 reset calibration register
while(ADC_GetResetCalibrationStatus(ADC1));
// //Enable ADC2
ADC_Ctrl(ADC2, ENABLE);
//Enable ADC2 reset calibaration register
ADC_RstCalibration(ADC2);
//Check the end of ADC2 reset calibration register
while(ADC_GetResetCalibrationStatus(ADC2));
//Start ADC1 calibaration
ADC_StartCalibration(ADC1);
//Check the end of ADC1 calibration
while(ADC_GetCalibrationStatus(ADC1));
//Start ADC2 calibaration
ADC_StartCalibration(ADC2);
//Check the end of ADC2 calibration
while(ADC_GetCalibrationStatus(ADC2));
//Start ADC1 Software Conversion
ADC_SoftwareStartConvCtrl(ADC1, ENABLE);
ADC_SoftwareStartConvCtrl(ADC2, ENABLE);
|