2015-02-04 9 views
3

저는 STM32 F103x에서 ADC 프로그래밍을 공부하고 가장 간단한 경우부터 시작합니다 - 단일 변환. 내부 온도 센서 (ADC1에 연결된) 값이 측정되고 USART를 사용하여 COM 포트로 전송됩니다. 타겟이 명확 해 보이지만 플래시 할 소스 코드를 다운로드하려고하면 COM 포트에 데이터가 전송되지 않습니다.STM32에서 ADC 단일 변환

while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); //Wail for conversion complete 

가 여기에 지금까지 내 소스 코드 : USART 기능 내가 완전한 전환을 기다리는 루프에 걸려되고있어 때문에 문제가 ADC 구성 부분에서 오는 것 같아요, 잘 작동합니다.

/* Includes ------------------------------------------------------------*/ 
#include "stm32f10x.h" 
#include <stdio.h> 

    uint16_t AD_value; 
    const uint16_t V25 = 1750; //when V25=1.41V 
    const uint16_t Avg_Slope = 5; //when avg_slc 
    uint16_t TemperatureC; 

//Define output device 
PUTCHAR_PROTOTYPE 
{ 
    USART_SendData(USART1, (uint8_t) ch); 
    while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) 
    {} 
    return ch; 
} 

void Usart1Init(void) 
{ 
    GPIO_InitTypeDef GPIO_InitStructure; 
    USART_InitTypeDef USART_InitStructure; 

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); 

    /* COnfig PA9 for USART Tx as alternate function push-pull */ 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_Init(GPIOA, &GPIO_InitStructure); 

    /* COnfig PA10 for USART Rx as input floating */ 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
    GPIO_Init(GPIOA, &GPIO_InitStructure); 

    /* USARTx configured as follow: 
     - BaudRate = 9600 baud 
     - Word Length = 8 Bits 
     - One Stop Bit 
     - No parity 
     - Hardware flow control disabled (RTS and CTS signals) 
     - Receive and transmit enabled 
    */ 
    USART_InitStructure.USART_BaudRate = 9600; 
    USART_InitStructure.USART_WordLength = USART_WordLength_8b; 
    USART_InitStructure.USART_StopBits = USART_StopBits_1; 
    USART_InitStructure.USART_Parity = USART_Parity_No; 
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; 
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; 

    /* USART configuration */ 
    USART_Init(USART1, &USART_InitStructure); 
    USART_Cmd(USART1, ENABLE); 

} 

int main(void) 
{ 

    ADC_InitTypeDef ADC_InitStructure; 
    Usart1Init(); 

    RCC_ADCCLKConfig(RCC_PCLK2_Div6); //ADCCLK = PCLK22/6 = 72/6=12MHz 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); //Enable ADC1 Clock 

    /* ADC1 configuration */ 
    ADC_DeInit(ADC1); //Power-on default 
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //Independent conversion mode (single) 
    ADC_InitStructure.ADC_ScanConvMode = DISABLE; //Convert single channel only 
    ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //Convert 1 time 
    ADC_InitStructure.ADC_ExternalTrigConv = DISABLE; //No external triggering 
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //Right 12-bit data alignment 
    ADC_InitStructure.ADC_NbrOfChannel = 1; //single channel conversion 
    ADC_Init(ADC1, &ADC_InitStructure); 
    ADC_TempSensorVrefintCmd(ENABLE); //wake up temperature sensor 
    ADC_Cmd(ADC1, ENABLE); //Enable ADC1 
    ADC_ResetCalibration(ADC1); //Enable ADC1 reset calibration register 
    while(ADC_GetResetCalibrationStatus(ADC1)); //check the end of ADC1 reset calibration register 
    ADC_StartCalibration(ADC1); //Start ADC1 calibration 
    while(ADC_GetCalibrationStatus(ADC1)); //Check the end of ADC1 calibration 
    ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_1Cycles5); //Select 1.5 cycles conversion for channel 16 
    ADC_SoftwareStartConvCmd(ADC1, ENABLE); //Start ADC1 software conversion 
    while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); //Wail for conversion complete 
    AD_value = ADC_GetConversionValue(ADC1); //Read ADC value 
    ADC_ClearFlag(ADC1, ADC_FLAG_EOC); //Clear EOC flag 

    printf("\r\n ADC value: %d \r\n", AD_value); 
    TemperatureC = (uint16_t)((V25-AD_value)/Avg_Slope+25); 
    printf("Temperature: %d%cC\r\n", TemperatureC, 176); 
    while (1) 
    {} 
} 

모든 아이디어를 높이 평가합니다!

답변

2

문제가 해결 :) 사용하는 것을 망설이지 말라! 외부 트리거를 사용하지 않는 것은 내 잘못입니다. 대신 사용하는 :

ADC_InitStructure.ADC_ExternalTrigConv = DISABLE; 

이 이렇게 될 갈까요 :

ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; 

바보 무엇!

0

나는이 세 바퀴 중 하나에 매달려있다는 소리로 바퀴를 발명하지 않겠다. 각각의 출력을하기 전에 출력을 만들어 어디에서 매달리고 있는지 알 수 있습니다.

당신은 디버거가있는 경우 (이 모든 ST 개발 보드에 존재하는, 그리고 아마도 당신이 프로그램을 다운로드하는 데 사용)가

+0

의견을 보내 주셔서 감사합니다. 당신 말이 맞아요, 전 단계에 갇혀 있어요 : 변환 완료를위한 통곡 : while (ADC_GetFlagStatus (ADC1, ADC_FLAG_EOC) == RESET); 소스 코드에서 어떤 일이 벌어지고 있는지 전혀 알지 못합니다. ( – lft

3

나는 소스 코드에서 어떤 일이 벌어지고 있는지 설명하려고 노력할 것이다.

1의 정의는 0입니다. typedef enum {DISABLE = 0, ENABLE =! DISABLE} FunctionalState;

2- 그래서 "ADC_InitStructure.ADC_ExternalTrigConv = DISABLE;"이라고 쓰면 실제로이 "ADC_InitStructure.ADC_ExternalTrigConv = 0처럼 0으로 지정,

3 이것이 당신이 제로에 등록 ADC_CR2의 EXTSEL을 할당하는 것을 의미 EXTSEL가 제로

경우 4, ADC가 변환이 타이머에 따라 달라집니다. 시작

5-경우 ADC가 소프트웨어에 의해 시작하려면, EXTSEL는 0x000E0000이어야합니다.

,

6- 당신은 "ADC_ExternalTrigConv_None"의 값 0x000E0000으로 정의를 추측 할 수로 그래서 while (ADC_GetFlagStatus (ADC1, ADC_FLAG_EOC) == RESET); 코드는 타이머가 시작되도록 지정했기 때문에 여기에서 중단됩니다. 시작되지 않으면 종료 할 수 없습니다.