Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

BluePill ADC not working

@ADEngineer

New Member
I am trying to perform adc in stm32 bluepill. On debugging I receive this error in keil uvision5 community edition

Cannot access Memory (@ 0x08000000, Write, Acc Size: 1024 Byte)Error while accessing a target resource. Resource perhaps not available or a wrong access was attempted.*** error 57: illegal address (0x08000000)

#include "stm32f10x.h"

void ADC_Init(void);
uint16_t ADC_Read(void);

int main(void)
{
//Initialize HSE 8 MHz
//Enable HSE
RCC->CR |= RCC_CR_HSEON;
while(!(RCC->CR & RCC_CR_HSERDY));

//Configure Flash Latency
FLASH->ACR |= FLASH_ACR_LATENCY_2;

//Configure PLL
RCC->CFGR |= RCC_CFGR_PLLSRC_HSE; // RCC->CFGR |= 0x0001 0000;
RCC->CFGR |= RCC_CFGR_PLLMULL9; // RCC->CFGR |= 0x001C 0000;

//Enable PLL
RCC->CR |= RCC_CR_PLLON;
while(!(RCC->CR & RCC_CR_PLLRDY));

//Set PLL as System Clock
RCC->CFGR |= RCC_CFGR_SW_PLL;
while(!(RCC->CFGR & RCC_CFGR_SWS_PLL));

//Configure AHB, APB1, APB2 Prescaler
RCC->CFGR |= RCC_CFGR_HPRE_DIV1; // AHB Prescaler = 1 (72 MHz)
RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; // APB1 Prescaler = 2 (36 MHz max)
RCC->CFGR |= RCC_CFGR_PPRE2_DIV1; // APB2 Prescaler = 1 (72 MHz)

//Update System Core Clock variable
SystemCoreClock = 72000000;
uint16_t adc_value;

ADC_Init(); // Initialize ADC

while (1) {
adc_value = ADC_Read(); // Read ADC value from PA0
}
}

void ADC_Init(void) {
// 1. Enable clock for GPIOA and ADC1
RCC->APB2ENR |= (1 << 2); // Enable GPIOA clock
RCC->APB2ENR |= (1 << 9); // Enable ADC1 clock

// 2. Configure PA0 as analog mode
GPIOA->CRL &= ~(0xF << 0); // Clear bits (Analog mode = 0b0000)

// 3. Configure ADC
ADC1->SMPR2 |= (7 << 0); // Sampling time for channel 0: 239.5 cycles
ADC1->SQR1 &= ~(0xF << 20); // 1 conversion in regular sequence
ADC1->SQR3 |= (0 << 0); // Channel 0 is the first in sequence

// 4. Enable ADC
ADC1->CR2 |= (1 << 0); // Enable ADC
for (int i = 0; i < 10000; i++); // Small delay for stability

// 5. Start ADC Calibration
ADC1->CR2 |= (1 << 2); // Start calibration
while (ADC1->CR2 & (1 << 2)); // Wait until calibration is done

// 6. Enable Continuous Conversion Mode
ADC1->CR2 |= (1 << 1); // Continuous conversion mode
}

uint16_t ADC_Read(void) {
ADC1->CR2 |= (1 << 22); // Start conversion
while (!(ADC1->SR & (1 << 1))); // Wait for conversion to complete
return ADC1->DR; // Read ADC value
}
 
I don't have the details to hand - but I seem to remember that when enabling the ADC system clock, you need to wait for a ready signal of some sort before continuing with rest of the initialisation?
 

Latest threads

New Articles From Microcontroller Tips

Back
Top