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