2015-02-04 6 views
3

Я изучаю программирование АЦП на STM32 F103x и начинаю с простейшего случая - одного преобразования. Измеряется значение внутреннего датчика температуры (подключено к ADC1) и отправляется в COM-порт с помощью USART. Цель кажется ясной, но когда я пытаюсь загрузить исходный код в flash, он не отправляет никаких данных на COM-порт. Функция USART работает хорошо, я предполагаю, что проблемы возникают из конфигурации АЦП отчасти потому, что я подвешивали в цикле ожидания полного превращения:Однократное преобразование АЦП на STM32

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

Вот мой исходный код до сих пор.

/* 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

Я не буду изобретать колесо здесь, указывая, что вы висете в одном из этих трех петель while(). Сделайте некоторый вывод перед каждым из них, тогда вы узнаете, где вы висите.

Если у вас есть отладчик (он присутствует на каждом борте развития ST, и, возможно, вы используете его для загрузки программы), не стесняйтесь использовать его :)

+0

Спасибо за ваш комментарий. Вы правы, я застрял в шаге: вопль для преобразования завершен: while (ADC_GetFlagStatus (ADC1, ADC_FLAG_EOC) == RESET); Я понятия не имею, что происходит с исходным кодом :( – lft

3

Я попытаюсь объяснить, что происходит с исходным кодом.

1- определение деактивизации равно нулю: typedef enum {DISABLE = 0, ENABLE =! DISABLE} FunctionalState;

2- так, когда вы пишете «ADC_InitStructure.ADC_ExternalTrigConv = DISABLE;» вы на самом деле присвоить его к нулю, как это «ADC_InitStructure.ADC_ExternalTrigConv = 0;

3- это означает, что ваш назначая EXTSEL в ADC_CR2 регистре нулю

4-если EXTSEL равен нулю, преобразование АЦП зависит от таймеров. чтобы начать

5-если вы хотите адъютантом быть запущен с помощью программного обеспечения, EXTSEL должен быть 0x000E0000;.

6- и, как вы можете догадаться, значение «ADC_ExternalTrigConv_None» определяется как 0x000E0000;

так что while (ADC_GetFlagStatus (ADC1, ADC_FLAG_EOC) == RESET); код будет зависеть здесь, потому что он зависит от запуска таймеров, он не может закончиться, если он не запущен.