本帖最后由 siabc 于 2013-10-27 17:14 编辑
用DMA将ADC的值传回来,只进行了通道一的采样。数据丢了八位,单步调试发现DMA的值位0xff,而直接读ADC->DR的值为0XFFF,调了两周了,后面直接抄的野火的例子还有问题。希望各位大神帮忙看下,感激不尽
#include "stm32f10x.h"
#include "delay.h"
#include "lcd.h"
//定义下面的两个值进行对照比较的
__IO uint16_t AD_Data;//DMA传回的值
unsigned short DATT;//直接读ADC寄存器的值
void GPIO_Configuration(void) //GPIO配置函数
{
GPIO_InitTypeDef GPIO_Struct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOA,ENABLE);
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//打开DMA的时钟,使能DMA传输
delay_us(3); //等待时钟稳定
GPIO_Struct.GPIO_Pin=GPIO_Pin_All;
GPIO_Struct.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Struct.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_Init(GPIOE,&GPIO_Struct);
GPIO_Init(GPIOD,&GPIO_Struct);
GPIO_Struct.GPIO_Pin=GPIO_Pin_1;//只采集ADC1的通道1
GPIO_Struct.GPIO_Mode=GPIO_Mode_AIN;
GPIO_Init(GPIOA,&GPIO_Struct);
}
void ADC_Configuration(void) //ADC配置函数
{
ADC_InitTypeDef ADC_Structure;
ADC_Structure.ADC_Mode=ADC_Mode_Independent;//独立模式
ADC_Structure.ADC_ScanConvMode=DISABLE;//单通道模式
ADC_Structure.ADC_ContinuousConvMode=ENABLE;//循环转换
ADC_Structure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//由软件促发
ADC_Structure.ADC_DataAlign=ADC_DataAlign_Right;//右对齐
ADC_Structure.ADC_NbrOfChannel=1;//通道数
ADC_Init(ADC1, &ADC_Structure);
RCC_ADCCLKConfig(RCC_PCLK2_Div6);//六分频
ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5);//ADC1,ADC通道1,规则采样顺序值为1,采样时间为239.5周期
ADC_DMACmd(ADC1,ENABLE);//使能ADC的DMA请求
ADC_Cmd(ADC1,ENABLE);//使能ADC1
ADC_ResetCalibration(ADC1);//使能复位校准,重置ADC1的校准寄存器
while(ADC_GetResetCalibrationStatus(ADC1));//等待复位校准结束,获取ADC1重置校准寄存器的状态,设置状态则等待
ADC_StartCalibration(ADC1); //开始ADC的校准状态
while(ADC_GetCalibrationStatus(ADC1));//等待校准完成
ADC_SoftwareStartConvCmd(ADC1,ENABLE);//使能指定的ADC1的软件转换启动功能
}
void DMA_Configuration(void) //DMA配置函数
{
DMA_InitTypeDef DMA_Stucture;
DMA_DeInit(DMA1_Channel1);//设置缺省值
DMA_Stucture.DMA_PeripheralBaseAddr=0x4001244C;//外设基地址ADC1
DMA_Stucture.DMA_MemoryBaseAddr=(u32)&AD_Data;//内存地址
DMA_Stucture.DMA_DIR=DMA_DIR_PeripheralSRC;
DMA_Stucture.DMA_BufferSize=1;
DMA_Stucture.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设地址不变
DMA_Stucture.DMA_MemoryInc=DMA_PeripheralInc_Disable;//内存地址不变
DMA_Stucture.DMA_PeripheralDataSize=DMA_MemoryDataSize_HalfWord; //外设数据为16位
DMA_Stucture.DMA_MemoryDataSize=DMA_MemoryDataSize_HalfWord;//从外设读到内存的数据的长度为两个字节16位
DMA_Stucture.DMA_Mode=DMA_Mode_Circular;//循环转换
DMA_Stucture.DMA_Priority=DMA_Priority_High;//通道1DMA优先级为高等
DMA_Stucture.DMA_M2M=DMA_M2M_Disable;//禁止由内存到内存的数据传输
DMA_Init(DMA1_Channel1,&DMA_Stucture);
DMA_Cmd(DMA1_Channel1,ENABLE);//使能DMA
}
int main(void)
{
u16 AD=0;
float temp;
GPIO_Configuration();
ADC_Configuration();
DMA_Configuration();
while(1)
{
while(1)
{
if(DMA_GetFlagStatus(DMA1_FLAG_TC1)==SET) //判断通道1传输完成
{
temp=(float)AD_DATA*(3.3/4096);//读用DMA传回的数,数值是少了八位
AD=(int)(temp*10+0.5);
Draw_ASCII(40,110,(AD/10+48),White,Black);//显示函数
Draw_ASCII(56,110,(AD%10+48),White,Black); //显示函数
DMA_ClearFlag(DMA1_FLAG_TC1);//清除通道1传输完成标志
break;
}
}
DATT=ADC1->DR;//不用DMA直接读ADC的寄存器,数值是正确的
temp=(double)DATT*(3.3/4096);
AD=(int)(temp*10+0.5);
Draw_ASCII(40,130,(AD/10+48),White,Black);//显示函数
Draw_ASCII(56,130,(AD%10+48),White,Black);//显示函数
delay_ms(300);
}
}
|