Modo de conversación continua ADC con STM32F411RE sin DMA

0

Hola, tengo un código con bibliotecas periféricas STM32 en las que puedo convertir en valor de modo continuo desde el canal 0 de ADC con el microcontrolador STM32F411RE en la placa NUCLEO-F411RE. Después de cada conversión en interrupción, me gustaría enviar continuamente el valor convertido por USART a la computadora de mi PC, pero hay un problema. Sólo hay dos conversaciones y nada más. Veo dos valores convertidos en el terminal v1.9b. En mi código no uso un DMA. Tal vez sea necesario cuando convierto datos en modo contiunous? No lo sé. En mi opinión no lo es.

A continuación muestro el código de mi programa:

#include "stm32f4xx.h"
void send_char(char c)
{
 while (USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
 USART_SendData(USART2, c);
}

int __io_putchar(int c)
{
    if (c=='\n')
    send_char('\r');

    send_char(c);
 return c;
}

void ADC_IRQHandler() {

      ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);
      uint16_t conv_result;
      conv_result = ADC_GetConversionValue(ADC1);
      printf("Adc = %d V_conv = %f\n",conv_result,conv_result * 3.3f / 4096.0f);


}
int main(void)
{

    // podłączenie zegara taktującego na przetwornik ADC
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
    // zegar dla UART
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
    // zegar dla portu A
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);


    USART_InitTypeDef uart;
    GPIO_InitTypeDef gpio;
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);
    GPIO_StructInit(&gpio);
    gpio.GPIO_Pin = GPIO_Pin_2;
    gpio.GPIO_Mode = GPIO_Mode_AF;
    GPIO_Init(GPIOA, &gpio);
    gpio.GPIO_Pin = GPIO_Pin_3;
    gpio.GPIO_Mode = GPIO_Mode_AF;
    GPIO_Init(GPIOA, &gpio);
    gpio.GPIO_Pin = GPIO_Pin_0;
    gpio.GPIO_Mode = GPIO_Mode_AN;
    gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOA, &gpio);
    USART_StructInit(&uart);
    uart.USART_BaudRate = 9600;
    USART_Init(USART2, &uart);
    USART_Cmd(USART2, ENABLE);

    // inicjalizacja przetwornika ADC
    ADC_InitTypeDef adc;
    // Struktura, która zawiera informacje o wspólnej konfiguracji dla paru przetworników ADC, ale
    // na płytce F411RE jest tylko jeden przetwornik
    ADC_CommonInitTypeDef ADC_CommonInitStructure;
    ADC_StructInit(&adc);
    ADC_CommonStructInit(&ADC_CommonInitStructure);
    NVIC_InitTypeDef NVIC_InitStructure;


    // ustawienie częstotliwości przetwornika na 25 MHZ
    ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div4;
    // wyłączenie DMA
    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
    ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
    // opóźnienie pomiędzy dwoma konwersjami w liczbie cykli
    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
    ADC_CommonInit(&ADC_CommonInitStructure);
    // tryb ciągły działania przetwornika
    adc.ADC_ContinuousConvMode = ENABLE;
    adc.ADC_ScanConvMode = DISABLE;
    adc.ADC_Resolution = ADC_Resolution_12b;
    adc.ADC_DataAlign = ADC_DataAlign_Right;
    // The total number of channels to be converted in sequence is specified by:
    adc.ADC_NbrOfConversion= 1;
    adc.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
    adc.ADC_ExternalTrigConv = 0;
    ADC_Init(ADC1, &adc);

    //ADC_RegularChannelConfig(ADC1,ADC_Channel_17,1,ADC_SampleTime_480Cycles);
    ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_84Cycles);
    // This call enables the end-of-conversion flag after each channel
    ADC_EOCOnEachRegularChannelCmd(ADC1, ENABLE);

    /* Enable ADC interrupts */
    ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);

    /* Configure NVIC */
    NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
    NVIC_Init(&NVIC_InitStructure);
    // uruchomienie przetwornika
    ADC_Cmd(ADC1,ENABLE);
    ADC_TempSensorVrefintCmd(ENABLE);
    ADC_SoftwareStartConv(ADC1);
    for(;;){

    }
}

La imagen de los datos recibidos del puerto COM3 se ve así:

No sé por qué no funciona correctamente. Tal vez podría habilitar el modo DMA en el modo de conversación continua? Me gustaría recibir ayuda;) Saludos cordiales

    

0 respuestas

Lea otras preguntas en las etiquetas