In this post we are going to read ADC1 channel 10 on GPIO PC0 on STM32F4 Discovery board. First of all we will set the Clock PLL to run the discovery board on full speed with 168Mhz frequency. Later we initialize the USART with the baudrate of 230400 Kbps and finally we initialize the ADC and read the ADC and convert that 12 bit value (which goes from 0 to 4096) to string and transmit this string to Serial Terminal followed by one line break and carriage return.
Here is the complete code for it.
#include "stm32f4xx.h"
#include <stdio.h>
/*************************************************
* timer 2 interrupt handler
*************************************************/
void TIM2_IRQHandler(void)
{
// clear interrupt status
if (TIM2->DIER & 0x01) {
if (TIM2->SR & 0x01) {
TIM2->SR &= ~(1U << 0);
}
}
GPIOD->ODR ^= (1 << 13);
}
void delay(volatile uint32_t);
void uart_init(void);
void uart_tx(unsigned char x);
void init_ADC(void)
{
RCC->AHB1ENR|=RCC_AHB1ENR_GPIOCEN; //GPIOC clock enable
GPIOC->MODER|=(3u<<(2*0)); //ADC input pin is analogue mode
RCC->APB2ENR|=RCC_APB2ENR_ADC1EN; //ADC clock enable
ADC1->SQR1&=~ADC_SQR1_L; //set number of conversions per sequence to 1
ADC1->SQR3&=~ADC_SQR3_SQ1; //clear channel select bits
ADC1->SQR3|=10; //set channel
ADC1->CR1 &= ~ADC_CR1_SCAN; //SCAN mode disabled
ADC1->CR2 &= ~ADC_CR2_CONT; //Disable continuous conversion
ADC1->SMPR1 |= ADC_SMPR1_SMP10;
ADC1->CR2|=ADC_CR2_ADON; //enable ADC
}
unsigned short read_adc(void)
{
ADC1->CR2|=ADC_CR2_SWSTART; //start ADC conversion
while((ADC1->SR&ADC_SR_EOC)==0){__NOP();} //wait for ADC conversion complete
return ADC1->DR; //return converted value
}
void TIM2_Configuration(void){
// enable TIM2 clock (bit0)
RCC->APB1ENR |= (1 << 0);
TIM2->PSC = 1749; //FOR DISCOVERY
//TIM2->PSC = 1874; //FOR NECLUEO
TIM2->ARR = 10000;
// Update Interrupt Enable
TIM2->DIER |= (1 << 0);
// enable TIM2 IRQ from NVIC
NVIC_EnableIRQ(TIM2_IRQn);
// Enable Timer 2 module (CEN, bit0)
TIM2->CR1 |= (1 << 0);
}
int main(void)
{
RCC->APB1ENR |= RCC_APB1ENR_PWREN; //enable power interface clock source
PWR->CR |= PWR_CR_VOS;
#define PLL_N 168 //SYSTEM CLOCK SPEED (FCY (MHz))
#define PLL_N 180 //SYSTEM CLOCK SPEED (FCY (MHz))
#define HSI 16000000 //INTERAL OSC FREQUENCY
#define PLL_M (HSI/2000000) //Fcy = Fxtal x PLL_N/(PLL_P x PLL_M)
#define PLL_P 2
#define PLL_Q 7
// HCLK = SYSCLK / 1
RCC->CFGR |= RCC_CFGR_HPRE_DIV1; //CORE CLOCK = 180MHZ
// PCLK2 = HCLK / 2
RCC->CFGR |= RCC_CFGR_PPRE2_DIV4; //PERIPHERAL CLOCK 2 = 180MHZ/4 = 45MHZ, THIS IS BECAUSE THE SPI MODULES (AND POSSIBLY OTHERS) DO NOT OPERATE PROPERLY WHEN PCLK > 42MHZ
// PCLK1 = HCLK / 4
RCC->CFGR |= RCC_CFGR_PPRE1_DIV4; //PERIPHERAL CLOCK 1 = 180MHZ/4 = 45MHZ, THIS IS BECAUSE THE SPI MODULES (AND POSSIBLY OTHERS) DO NOT OPERATE PROPERLY WHEN PCLK > 42MHZ
// Configure the main PLL
RCC->PLLCFGR = PLL_M | (PLL_N << 6) | (((PLL_P >> 1) -1) << 16) | (PLL_Q << 24);
// Enable the main PLL
RCC->CR |= RCC_CR_PLLON;
// Wait till the main PLL is ready
while(!(RCC->CR & RCC_CR_PLLRDY));
// Configure Flash prefetch, Instruction cache, Data cache and wait state
FLASH->ACR = FLASH_ACR_ICEN |FLASH_ACR_DCEN |FLASH_ACR_LATENCY_5WS;
// Select the main PLL as system clock source
RCC->CFGR &=~ RCC_CFGR_SW;
RCC->CFGR |= RCC_CFGR_SW_PLL;
// Wait till the main PLL is used as system clock source
while ((RCC->CFGR & RCC_CFGR_SWS ) != RCC_CFGR_SWS_PLL);
SystemCoreClockUpdate();
RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
/* Make Pin 12 output (MODER: bits 25:24) */
// Each pin is represented with two bits on the MODER register
// 00 - input
// 01 - output
// 10 - alternate function
GPIOD->MODER &= GPIO_MODER_MODER13;
GPIOD->MODER |= GPIO_MODER_MODER13_0;
GPIOD->ODR |= (1 << 13); // Toggle LED
uart_init();
init_ADC();
TIM2_Configuration();
const uint8_t brand[] = "Hello world\n\r";
while(1)
{
char str[10];
unsigned int volts = read_adc();
// GPIOD->ODR ^= (1 << 13); // Toggle LED
uart_tx(((volts/10000)%10)+48);
uart_tx(((volts/1000)%10)+48);
uart_tx(((volts/100)%10)+48);
uart_tx(((volts/10)%10)+48);
uart_tx(((volts)%10)+48);
uart_tx('\r');
uart_tx('\n');
// slow down
//
delay(300);
}
}
// A simple and not accurate delay function
// that will change the speed based on the optimization settings
void delay(volatile uint32_t s)
{
long i=0;
for(s; s>0; s--){
for(i=0;i<16800;i++){}
__asm("NOP");
}
}
void uart_init(void){
// enable USART2 clock, bit 17 on APB1ENR
RCC->APB1ENR |= (1 << 17);
// enable GPIOA clock, bit 0 on AHB1ENR
RCC->AHB1ENR |= (1 << 0);
// set pin modes as alternate mode 7 (pins 2 and 3)
GPIOA->MODER &= 0xFFFFFF0F; // Reset bits 10-15 to clear old values
GPIOA->MODER |= 0x000000A0; // Set pin 2/3 to alternate func. mode (0b10)
// set pin modes as high speed
GPIOA->OSPEEDR |= 0x000000A0; // Set pin 2/3 to high speed mode (0b10)
// choose AF7 for USART2 in Alternate Function registers
GPIOA->AFR[0] |= (0x7 << 8); // for pin 2
GPIOA->AFR[0] |= (0x7 << 12); // for pin 3
// usart2 word length M, bit 12
//USART2->CR1 |= (0 << 12); // 0 - 1,8,n
// usart2 parity control, bit 9
//USART2->CR1 |= (0 << 9); // 0 - no parity
// usart2 tx enable, TE bit 3
USART2->CR1 |= (1 << 3);
// usart2 rx enable, RE bit 2
USART2->CR1 |= (1 << 2);
// baud rate = fCK / (8 * (2 - OVER8) * USARTDIV)
// for fCK = 42 Mhz, baud = 115200, OVER8 = 0
// USARTDIV = 42Mhz / 115200 / 16
// = 22.7864 22.8125
// we can also look at the table in RM0090
// for 42 Mhz PCLK, OVER8 = 0 and 115.2 KBps baud
// we need to program 22.8125
// Fraction : 16*0.8125 = 13 (multiply fraction with 16)
// Mantissa : 22
// 12-bit mantissa and 4-bit fraction
//==== 45Mhz / 230400 / 16 => 195.3125
//==== 42Mhz / 230400 / 16 => 11.393229
//------------ USART2->BRR |= (22 << 4); //FOR 115200 BAUD RATE
//------------ USART2->BRR |= 13;
//--------@42Mhz------------------
USART2->BRR |= (11 << 4); //THIS IS FOR 230400 BAUD RATE
USART2->BRR |= 6;
//---- @45Mhz ----------------
//USART2->BRR |= (12 << 4);
//USART2->BRR |= 3;
//-----------------------------
// enable usart2 - UE, bit 13
USART2->CR1 |= USART_CR1_UE;
}
void uart_tx(unsigned char x){
USART2->DR = x;
// wait for transmit complete
while(!(USART2->SR & (1 << 6)));
}
Code language: PHP (php)