【原创】【原创】【原创】【原创】stm32f407stm32f407stm32f407stm32f407之之之之ADCADCADCADC与与与与DMADMADMADMA2012-05-0116:31:00|分类:stm32|标签:stm32cortex-m4dmaprintfadc|字号大中小订阅昨天调试了stm32f407的ADC功能,因为那个恼人的printf函数问题这篇ADC文章一直没有发表出来,今天5.1归来抽空补上。功能为实现ADC的单通道电压采集,并实现DMA数据管理,同时加了ADC看门狗功能,并用printf函数通过串口返回采集值与换算后的实际电压值。代码如下:/************************************************************Copyright(C),2012-2022,yin.FileName:main.cAuthor:小枣年糕Date:2012\05\01Description:ADC3DMAprintfVersion:V3.0IDE:MDK4.22aHardWare:stm32F407IGHSE=25MPLL=168MHistory:V1.0***********************************************************/#includestm32f4xx.h#includestdio.h/*定义ADC3的数据寄存器地址,DMA功能要用到外设的数据地址*ADC3的数据地址为外设基地址+偏移地址,基地址在RM0090Reference*manual(参考手册)的地址映射表里,为0x40012200,ADC_DR*偏移地址为0x4C,故实际地址为0x40012200+0x4C=0x4001224C*/#defineADC3_DR_Addr((uint32_t)0x4001224C)__IOuint16_tADCoverVaule;//uint16_tBuffer2[]={0x1122};//这个是我进行内存测试用的,程序没用到voidGPIO_Config(void);voidADC_Config(void);voidUSART_Config(void);voidUSART6_Puts(char*str);voidDMA_Config(void);voidNVIC_Config(void);voidDelay(uint32_tnCount);/*printf函数重定向*/intfputc(intch,FILE*f);intGetKey(void);main(){/*在主函数main之前通过调用启动代码运行了SystemInit函数,而这个函数位于system_stm32f4xx.c”。程序运行起始于启动文件的第175行(LDRR0,=SystemInit)。sys时钟为HSE频率/PLL_M*PLL_N/PLL_P,定义HSE为25M,则sys时钟频率为168M*/GPIO_Config();ADC_Config();USART_Config();DMA_Config();NVIC_Config();GPIO_SetBits(GPIOG,GPIO_Pin_6);//关闭LEDADC_SoftwareStartConv(ADC3);//如果不是外部触发则必须软件开始转换while(1){Delay(0x0ffffff);//printf(sizeofintis%d\n,sizeof(int));//测试可知32位系统的int占4个字节printf(ADCoverVaule=%04XVolVaule=%dmV\n,ADCoverVaule,ADCoverVaule*3300/4096);//串口输出电压值/*因为DMA工作是独立于CPU之外的,所以在DMA工作的同时CPU可以做其他事*/}}/*************************************************Function:voidGPIO_Config(void)Description:GPIO配置函数Input:无Output:无Return:无*************************************************/voidGPIO_Config(void){GPIO_InitTypeDefGPIO_InitStructure;/*使能GPIOC\GPIOF\GPIOG时钟*/RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC|RCC_AHB1Periph_GPIOG|RCC_AHB1Periph_GPIOF,ENABLE);GPIO_StructInit(&GPIO_InitStructure);/*初始化GPIOG的Pin_6为LED输出*/GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;//指定第六引脚GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT;//模式为输出GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//频率为快速GPIO_Init(GPIOG,&GPIO_InitStructure);//调用IO初始化函数/*初始化GPIOG的Pin_9为模拟量输入*/GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AN;GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_NOPULL;GPIO_Init(GPIOF,&GPIO_InitStructure);/*配置GPIOC_Pin6为TX输出*/GPIO_InitStructure.GPIO_Pin=GPIO_Pin_6;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;//设置为复用,必须为AF,OUT不行GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOC,&GPIO_InitStructure);/*配置GPIOC_Pin7为RX输入*/GPIO_InitStructure.GPIO_Pin=GPIO_Pin_7;GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF;//这也必须为复用,与M3不同!GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOC,&GPIO_InitStructure);/*GPIO引脚复用功能设置*/GPIO_PinAFConfig(GPIOC,GPIO_PinSource6,GPIO_AF_USART6);//这相当于M3的开启复用时钟,只配置复用的引脚,GPIO_PinAFConfig(GPIOC,GPIO_PinSource7,GPIO_AF_USART6);//}/*************************************************Function:voidADC_Config(void)Description:ADC配置函数Input:无Output:无Return:无*************************************************/voidADC_Config(void){ADC_InitTypeDefADC_InitStructure;ADC_CommonInitTypeDefADC_CommonInitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3,ENABLE);//开ADC时钟ADC_DeInit();ADC_InitStructure.ADC_Resolution=ADC_Resolution_12b;//精度为12位ADC_InitStructure.ADC_ScanConvMode=DISABLE;//扫描转换模式失能,单通道不用ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;//连续转换使能ADC_InitStructure.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;//不用外部触发,软件触发转换ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_T1_CC1;ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//数据右对齐,低字节对齐ADC_InitStructure.ADC_NbrOfConversion=1;//规定了顺序进行规则转换的ADC通道的数目ADC_Init(ADC3,&ADC_InitStructure);ADC_CommonInitStructure.ADC_Mode=ADC_Mode_Independent;//独立模式ADC_CommonInitStructure.ADC_Prescaler=ADC_Prescaler_Div4;//分频为4,f(ADC3)=21MADC_CommonInitStructure.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled;//失能DMA_MODEADC_CommonInitStructure.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;//两次采样间隔5个周期ADC_CommonInit(&ADC_CommonInitStructure);ADC_RegularChannelConfig(ADC3,ADC_Channel_7,1,ADC_SampleTime_15Cycles);//规则通道配置,1表示规则组采样顺序//ADC_ITConfig(ADC3,ADC_IT_EOC,ENABLE);//使能ADC转换结束中断ADC_Cmd(ADC3,ENABLE);//使能ADC3/*********************ADC看门狗配置***************************/ADC_AnalogWatchdogCmd(ADC3,ADC_AnalogWatchdog_SingleRegEnable);ADC_AnalogWatchdogThresholdsConfig(ADC3,0x0E8B,0x0555);//阈值设置。高:3V低:1VADC_AnalogWatchdogSingleChannelConfig(ADC3,ADC_Channel_7);ADC_ITConfig(ADC3,ADC_IT_AWD,ENABLE);ADC_DMACmd(ADC3,ENABLE);//使能ADC3的DMAADC_DMARequestAfterLastTransferCmd(ADC3,ENABLE);//单通道模式下上次转换完成后DMA请求允许,也就是持续DMA}/*************************************************Function:voidUSART_Config(void)Description:USART配置函数Input:无Output:无Return:无*************************************************/voidUSART_Config(void){USART_InitTypeDefUSART_InitStructure;USART_ClockInitTypeDefUSART