本帖最后由 潇湘残狼 于 2016-6-14 16:52 编辑
今天做了一个很简单的F407的ADC采集实验,程序横简单,可是在调试程序的时候出现了问题,main函数竟然循环了3次(main函数会循环吗?)。程序的功能本是产生一个PWM波,然后通过ADC1的通道5单次采集,一共采集10次,每采集一次将值转换并发送给串口显示。可是实验现象却发送了30次,且前10次的数据完全不对,后20次的数据就是采集的数据,是正确的数据。为什么会这样呢?菜鸟求教@原子哥 。为了检测adc的工作,直接给ADC输入3.3V。代码如下:[mw_shl_code=c,true]主程序:
//STM32F41¤3ìÄ£°å-¿aoˉêy°æ±¾
//¼¼êõÖ§3Ö£o
www.openedv.com
//TIME:2016/06/08
//@:UESTC
//×÷Õß: xiaoming
//3ìDòDT¸ÄóëêμÑé1 pwm2¨êμÑé
#include "stm32f4xx.h"
#include "delay.h"
#include "usart.h"
#include "pwm.h"
#include "dma.h"
#include "adc.h"
int main(void)
{
/*****
@: pwm0=~pwm1=12.5Hz 50%duty
@£oTIM1_CH1-PE9
@£oTIM1_CH1N-PE8
******/
int i=10;
float AD_value;
u16 temp;
u32 acc=1343;
u32 psc=9999; //cnt_clk=168M/psc
u32 duty=(acc-1)/2;
u16 death_time=0xC0; //1.52us
TIM1_PWM_Init(acc,psc,death_time); //Tout=((arr+1)*(psc+1))/Tclk Tclk=1/168M
TIM_SetCompare1(TIM1,duty); //duty is 50%
delay_init(168);
myadc_Init();
delay_ms(1000);
while(i--)
{
uart_init(115200);
temp=Get_Adc_Average(ADC_Channel_5);
printf("
-AD: %d
",temp);
AD_value=(float)temp*(3.3/4096);
//printf("
-ADC×a»»ÖμÎa: %.3f
",AD_value);
if(i==10) printf("
---HJ");
}
printf("
---");
return 0;
}
ADC程序:
#include "adc.h"
#include "sys.h"
#include "stm32f4xx.h"
#include "delay.h"
/*
*@ Inition the ADC1_channel5-map PA5
*@ entrance parameters: none
*@ export parameters: none
*/
void myadc_Init(void)
{
GPIO_InitTypeDef GPIO_InitTypestruct;
ADC_CommonInitTypeDef ADC_CommonInitstruct;
ADC_InitTypeDef ADC_InitTypestruct;
/***step1: enable the periph clock and IO clock*****/
RCC_APB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
/***step2: Init the IO suit to ADC1_CHANNEI1********/
GPIO_InitTypestruct.GPIO_Pin=GPIO_Pin_5;
GPIO_InitTypestruct.GPIO_Mode=GPIO_Mode_AN;
GPIO_InitTypestruct.GPIO_PuPd=GPIO_PuPd_NOPULL;
//GPIO_InitTypestruct.GPIO_Speed=GPIO_Speed_100MHz;
//GPIO_InitTypestruct.GPIO_OType=GPIO_OType_PP;
GPIO_Init(GPIOA,&GPIO_InitTypestruct);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);
/***step3: Init the ADC common inition**************/
ADC_CommonInitstruct.ADC_Mode=ADC_Mode_Independent;
ADC_CommonInitstruct.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;
ADC_CommonInitstruct.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled; //?
ADC_CommonInitstruct.ADC_Prescaler=ADC_Prescaler_Div4; //clearing the realtionship of ADC_Prescale_DIV and sys_core_clk or APB2 CLK
ADC_CommonInit(&ADC_CommonInitstruct);
/***step4£oADC1 Init********************************/
ADC_InitTypestruct.ADC_Resolution=ADC_Resolution_12b;
ADC_InitTypestruct.ADC_ScanConvMode=DISABLE;
ADC_InitTypestruct.ADC_ContinuousConvMode=DISABLE;
ADC_InitTypestruct.ADC_ExternalTrigConvEdge=ADC_ExternalTrigConvEdge_None;
ADC_InitTypestruct.ADC_DataAlign=ADC_DataAlign_Right;
ADC_InitTypestruct.ADC_NbrOfConversion=1;
//ADC_InitTypestruct.ADC_ExternalTrigConv= //becase not enable external trigconv
ADC_Init(ADC1,&ADC_InitTypestruct);
ADC_Cmd(ADC1, ENABLE);
}
/*****************************/
u16 Get_Adc(u8 ch)
{
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_480Cycles );
ADC_SoftwareStartConv(ADC1);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));
//ADC_ClearFlag(ADC1,ADC_FLAG_EOC);
return ADC_GetConversionValue(ADC1);
}
/********************************/
u16 Get_Adc_Average(u8 ch)
{
u16 temp_val=0;
temp_val=Get_Adc(ch);
delay_ms(100);
return temp_val;
} [/mw_shl_code]
如果我在主程序中不加while(1);的话,主程序不是执行的末尾就结束了,退出了吗?为什么你认为会继续跑呢?谢谢
一周热门 更多>