I am doing simple ADC test with potentiometer on STM32F103C8, it seems to work fine for 5 seconds or so, but then the whole uC just stops - even while loop stops doing what it is supposed to do(so I guess it doesn't even leave interrupt routine when it fails).
It probably has to do something with ADC initialization, but I can't see what exactly is wrong.
Below is my ADC.c with ADC initialization and my main.c(note that I outputting "1" and "2" just to monitor if it is still doing while loop stuff - and it doesn't, everything freezes)
If it is not initialization, then maybe it is hardware problem, but with such circuit I can't think of anything that can go wrong, board has capacitor for ADC and I even tried to put another one between signal and ground, nothing...
UPD
OK, Now I look like a total idiot... It turned out that it was not microcontroller that got stuck, but the LCD. I tried to change it to different LCD (it was 4x20, changed to 2x16) and it not halting now. I noticed that it is if I would fiddle the wires a little bit it would halt with bigger probability, so probably if the connection is not solid 100% of time LCD encounters some kind of internal error and got stuck, it does not happen with other LCD for some reason. Apparently vibration from me touching breadboard did something to connection and LCD freaked out. So whoever encounters same problem - try using different LCD, check the wiring(try to fiddle it to see if it affects anything), check if driver code is good, etc.
ADC.c
void ADC_init(void)
{
GPIO_InitTypeDef adcpin;
ADC_InitTypeDef MyADCinit;
///
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
adcpin.GPIO_Pin = GPIO_Pin_0;
adcpin.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOB, &adcpin);
////
////
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // Turn on ADC clock
////
/* Initialization of ADC */
MyADCinit.ADC_Mode = ADC_Mode_Independent;
MyADCinit.ADC_ScanConvMode = DISABLE;
MyADCinit.ADC_ContinuousConvMode = DISABLE;
MyADCinit.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
MyADCinit.ADC_DataAlign = ADC_DataAlign_Right;
MyADCinit.ADC_NbrOfChannel = 1;
ADC_Init(ADC1, &MyADCinit);
// specify channel we want to use
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_55Cycles5); // Rank - the order number by which scanning is done
// enable interrupts on ADC
NVIC_EnableIRQ(ADC1_2_IRQn);
// enable interrupts on the end of conversion
ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
// Turn on ADC
ADC_Cmd(ADC1, ENABLE);
}
main.c
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "HD44780.h"
#include "ADC.h"
#include
uint16_t data_adc;
char adcResult[4];
void ADC1_2_IRQHandler(void)
{
if (ADC_GetITStatus(ADC1, ADC_IT_EOC) == SET)
{
ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);
data_adc = ADC_GetConversionValue(ADC1);
LCD_GoTo(0,0);
sprintf(adcResult, "ADC = %d", data_adc);
LCD_SendText(adcResult);
LCD_SendText(" ");
}
}
int main (void)
{
RCC_Configuration(); // Configure the system clocks.
LCD_Init(); // Initialize the LCD.
LCD_Clear(); //Clear the LCD.
delay_ms(1000);
ADC_init();
while(1)
{
delay_ms(10);
ADC_SoftwareStartConvCmd(ADC1, ENABLE); // check functional state... wtf is that
LCD_GoTo(0,0);
LCD_SendText ("1");
delay_ms(100);
LCD_GoTo(0,0);
LCD_SendText ("2");
delay_ms(50);
}
}