You are on page 1of 114

Syllabus

GPIO Programming, Interfacing seven segment LED, LDR and MQ3 sensor with STM32F4xx, STM32F4xx:
Counters and Timers: Timer and Delay Generation, UART Programming, on chip ADC and Onchip DAC for
waveform generation.

Unit Objectives
1. To get Peripheral insights of STM32F407VG microcontroller.
2. To enhance the capabilities of students to interface various I/O devices and communication protocol
3. To interface sensors using ADC

Unit Mapping With COs :


1.Outcomes CO1: Understand basics of Embedded C Programming and usage of Embedded C
2. Configure the desired peripheral registers and study different software tools for programming microcontrollers.
3. Selection of proper sensors with an interfacing
4. Write C Programs for STM32F4xx Microcontroller Board CO6: Recognize the interfacing of real world sensors and standard buses. Will also
able to design different case studies.
Mapping With POs :
Books :

T3: 3. Shujen Chen, Muhammad Ali Mazidi, Eshragh Ghaemi, “STM32 Arm Programming for Embedded Systems: Using C Language with STM32”, Nucleo, Micro
DigitalEd., Illustrated Edition,2018.

R2: RM0390 Reference manual, STM32F446xx advanced Arm®-based 32-bit MCUs


RM0090:- Reference manual STM32F407/
CO311.5 Implement on chip peripherals and external peripherals with Cortex
M4 Based Microcontroller.
Q. Enlist features of STM32F4xx Processors.
Features of STM32F407XX
- ARM 32-bit Cortex-M4 CPU with FPU
- Adaptive real-time accelerator (ART Accelerator)
- 168 MHz maximum frequency, 210 DMIPS/1.25 DMIPS/MHz
- Memory protection unit(MPU)
Memories
- Up to 1 Mbyte of Flash memory
- Up to 192+4 Kbytes of SRAM
- Flexible static memory controller
(supports Compact Flash, SRAM, PSRAM, NOR, NAND memories)
LCD parallel interface, 8080/6800 modes
Clock, reset and supply management
- 1.7 V to 3.6 V application supply and I/Os
- POR, PDR, PVD and BOR
- 4 to 25 MHz crystal oscillator
- Internal 16 MHz factory-trimmed RC
- 32 kHz oscillator for RTC with calibration
- Internal 32 kHz RC with calibration
Low power
- Sleep, Stop, Standby modes
- VBAT supply for RTC,
20x32 bit backup registers + optional 4 KB backup SRAM
3 x 12-bit, 0.41 us A/D converters
- up to 24 channels
General-purpose DMA
- 16-stream DMA controller with centralized FIFOs and burst support
Up to 17 timers
- up to 12 16-bit and 2 32-bit timers up to 150 MHz
Debug mode
- Serial wire debug (SWD) & JTAG
- Cortex-M4 Embedded Trace Macrocell
Up to 140 I/O ports with interrupt capability
- Up to 136 fast I/Os up to 60 MHz
- Up to 138 5 V-tolerant I/Os
Up to 15 communication interfaces
- Up to 3 x I2C interfaces
- Up to 4 USARTs/2 UARTs (10.5 Mbit/s, ISO 7816, LIN, IrDA, modem control)
- Up to 3 SPIs (37.5 Mbits/s)
- 2 x CAN interfaces (2.0B Active)
- SDIO interface
Advanced connectivity
- USB 2.0 FS device/host/OTG controller with on-chip PHY
- USB 2.0 HS/FS device/host/OTG controller with dedicated DMA,
on-chip FS PHY and ULPI
- 10/100 Ethernet MAC with dedicated DMA
8 to 14-bit parallel camera interface up to 67.2 Mbytes/s
Cryptographic acceleration
- Hardware acceleration for AES 128, 192, 256, Triple DES, HASH (MD5, SHA-1)
Analog true random number generator
CRC calculation unit, 96-bit unique ID
RTC: subsecond accuracy, hardware calendar
1) 6- VDD,-1VDDA,1- VBAT,1-VRef(8)
2) 4-VSS,1-VSSA(5)
3) 1-BOOT0(1)
4) 2-VCAP_1&2(2)
5) 1-NRST(1)
6) Port-A:PA0-PA15(16)
7) Port-B: PB0-PB15(16)
8) Port-C: PC0-PC15(16)
9) Port-D: PD0-PD15(16)
10) Port-E: PE0-PE15(16)
11) Port-H: PH0-PH1(2)
Q. Explain GPIO_ODR and GPIO_BSRR of STM32F4xx with simple examples.
GPIO introduction
● Each general-purpose I/O port has four 32-bit configuration registers
● GPIOx_MODER, GPIOx_OTYPER, GPIOx_OSPEEDR and GPIOx_PUPDR
● Two 32-bit data registers (GPIOx_IDR and GPIOx_ODR),
● One 32-bit set/reset register (GPIOx_BSRR),
● One 32-bit locking register (GPIOx_LCKR)
● Two 32-bit alternate function selection register (GPIOx_AFRH and GPIOx_AFRL).
GPIO main features

• Up to 16 I/Os under control


• Output states: push-pull or open drain + pull-up/down
• Output data from output data register (GPIOx_ODR) or peripheral (alternate function
output)
• Speed selection for each I/O
• Input states: floating, pull-up/down
• Input data to input data register (GPIOx_IDR) or peripheral (alternate function input)
• Bit set and reset register (GPIOx_BSRR) for bitwise write access to GPIOx_ODR
• Each I/O port bit is freely programmable
Basic structure of a 5 V tolerant I/O port bit
GPIO
In the STM32 Arm, the GPIO ports are connected to AHB bus via AHB/APB1 and AHP/APB2 bridges

1. I/O port control registers


2. I/O port data registers
3. I/O data bitwise handling

Imp:- Data Register and Direction Register

Address Name Description


0x00 GPIOx_MODER GPIOx Port Mode(Direction) Register
0x04 GPIOx_OTYPER Output Type Register
0x08 GPIOx_OSPEEDR Output Speed Register
0x0C GPIOx_PUDR Pull-Up / Down Register
0x10 GPIOx_IDR Port Input Data Register
0x14 GPIOx_ODR Port Output Data Register
0x18 GPIOx_BSRR Bit Set / Reset Register
GPIO: GPIOx_MODER

• GPIOx_MODER which stands for GPIO Mode


Register.

These bits are written by software to configure the I/O direction mode. For eg:- pins 0 and 1 of PORT A as OUTPUT

00: Input (reset state)


01: General purpose output mode
10: Alternate function mode
11: Analog mode (reset state)
Selecting an alternate function (AFR) on STM32F40xx
For pins 0 to 7, the GPIOx_AFRL[31:0] register For pins 8 to 15, the GPIOx_AFRH[31:0]
selects the dedicated alternate function register selects the dedicated alternate function
Bits [31:0] – AFRLy : Alternate function selection for port X and bit Y, (y = 0 … 7)

AFRLy Selection:
0000: AF0 (Alternate Function 0) 1000: AF8 (Alternate Function 8)
0001: AF1 (Alternate Function 1) 1001: AF9 (Alternate Function 9)
0010: AF2 (Alternate Function 2) 1010: AF10 (Alternate Function 10)
0011: AF3 (Alternate Function 3) 1011: AF11 (Alternate Function 11)
0100: AF4 (Alternate Function 4) 1100: AF12 (Alternate Function 12)
0101: AF5 (Alternate Function 5) 1101: AF13 (Alternate Function 13)
0110: AF6 (Alternate Function 6) 1110: AF14 (Alternate Function 14)
0111: AF7 (Alternate Function 7) 1111: AF15 (Alternate Function 15)
Bits [31:0] – AFRHy : Alternate function selection for port X and bit Y, (y = 0 … 7)

AFRHy Selection:
0000: AF0 (Alternate Function 0) 1000: AF8 (Alternate Function 8)
0001: AF1 (Alternate Function 1) 1001: AF9 (Alternate Function 9)
0010: AF2 (Alternate Function 2) 1010: AF10 (Alternate Function 10)
0011: AF3 (Alternate Function 3) 1011: AF11 (Alternate Function 11)
0100: AF4 (Alternate Function 4) 1100: AF12 (Alternate Function 12)
0101: AF5 (Alternate Function 5) 1101: AF13 (Alternate Function 13)
0110: AF6 (Alternate Function 6) 1110: AF14 (Alternate Function 14)
0111: AF7 (Alternate Function 7) 1111: AF15 (Alternate Function 15)
GPIO- Port Output Register (GPIOx_ODR)

• The output register in STM Arm is called GPIO port output data register (GPIOx_ODR)
GPIO port input data register (GPIOx_IDR)

If the pin is high, it returns a ‘1’ and if the pin is low, it returns a ‘0’.
GPIO port bit set/reset register (GPIOx_BSRR)
GPIO port output speed register (GPIOx_OSPEEDR)
GPIO: Clock Enable of the Peripheral Registers (RCC_AHB1ENR)

• To conserve power, Arm microcontrollers have ways of either slowing down the peripheral circuit clock or stopping the
clock altogether.

• By default clock to peripheral is disabled coming out of power-on reset.


• So need to enable it from RCC (Reset and Clock Control) registers. RCC_AHB1ENR (AHB1 Enable Register)
STM32 DISCOVERY BOARD
Q.Draw an interfacing diagram and write a C program to blink LEDs connected to
Pin numbers (Port D) PD12,13,14 and 15 using STM32F4xx Controller.
Interfacing Diagram
Program:- Toggling an LED in C

Ref: [1]
Reading an Input from Push Button using STM32 ARM

C Code:
Q.Draw an interfacing diagram and write a C program to blink LEDs connected to Pin
numbers PC0,2,3,PE3,PB0,1,2,10 using STM32F4xx Controller.
Interfacing Diagram
#include "main.h"
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
while (1)
{
HAL_GPIO_WritePin(Led4_GPIO_Port, Led4_Pin, 0);
HAL_GPIO_WritePin(GPIOC, Led1_Pin|Led2_Pin|Led3_Pin, 0);
HAL_GPIO_WritePin(GPIOB, Led5_Pin|Led66_Pin|Led7_Pin|Led8_Pin,0);
HAL_Delay(1000);
HAL_GPIO_WritePin(Led4_GPIO_Port, Led4_Pin, 1);
HAL_GPIO_WritePin(GPIOC, Led1_Pin|Led2_Pin|Led3_Pin, 1);
HAL_GPIO_WritePin(GPIOB, Led5_Pin|Led66_Pin|Led7_Pin|Led8_Pin,1);
HAL_Delay(1000);
}
}
Q. Draw an interfacing diagram and write a C program to interface “7-Segment” with
STM32F4xx controller and display the count digit “0” to “F” on Segment1.
Interfacing with Seven Segment Display
#include "main.h"

void SSInit()
{
//enable the clock to the GPIOA,GPIOB,GPIOE and GPIOC
RCC->AHB1ENR |= (1<<0)|(1<<1)|(1<<2)|(1<<4); //ENABLE GPIOA,GPIOB,GPIOC,GPIOE

//make pins mode as GPIO OUTPUT (set bits as 0:1 i.e.2)


GPIOA->MODER |= (1<<8)|(1<<12);//PA4 ,PA6 as GPIO
GPIOB->MODER |= (1<<12)|(1<<14);//PB6,PB7
GPIOC->MODER |= (1<<12)|(1<<14);//PC6 and PC7 as GPIO
GPIOE->MODER |= (1<<0)|(1<<2)|(1<<4)|(1<<8)|(1<<10)|(1<<12);//PE0,PE1,PE2,PE4,PE5,PE6 as GPIO

//set pins speed as HIGH (1:0)


GPIOA->OSPEEDR |= (2<<8)|(2<<12);//PA4,PA6
GPIOB->OSPEEDR |= (2<<12)|(2<<14);//PB6,PB7
GPIOC->OSPEEDR |= (2<<12)|(2<<14);//PC6 and PC7
GPIOE->OSPEEDR |= (2<<0)|(2<<2)|(2<<4)|(2<<8)|(2<<10)|(2<<12);//PE0,PE1,PE2,PE4,PE5,PE6

//set initial values as HIGH (common cathode)


GPIOA->ODR &= 0x00;//PA4,PA6
GPIOB->ODR &=0x00;//PB6,PB7
GPIOC->ODR |= 0xFF;//PC6 and PC7
GPIOE->ODR |= 0xFF;//PE0,PE1,PE2,PE4,PE5,PE6
}
void SSDisplay(unsigned char val) //E
{ if(val & 0x10)
//A
GPIOE->ODR |= (1<<2);
if(val & 0x01)
else
GPIOC->ODR |= (1<<6);
else GPIOE->ODR &= ~(1<<2);
GPIOC->ODR &= ~(1<<6);
//F
//B if(val & 0x20)
if(val & 0x02) GPIOE->ODR |= (1<<4);
GPIOC->ODR |= (1<<7); else
else GPIOE->ODR &= ~(1<<4);
GPIOC->ODR &= ~(1<<7);
//G
//C if(val & 0x40)
if(val & 0x04) GPIOE->ODR |= (1<<5);
GPIOE->ODR |= (1<<0); else
else GPIOE->ODR &= ~(1<<5);
GPIOE->ODR &= ~(1<<0);
//DP
//D
if(val & 0x80)
if(val & 0x08)
GPIOE->ODR |= (1<<1); GPIOE->ODR |= (1<<6);
else else
GPIOE->ODR &= ~(1<<1); GPIOE->ODR &= ~(1<<6);
}
void SystemClock_Config(void);
int main(void)
{
unsigned char ssCode[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
unsigned int i;

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
SSInit();
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
GPIOA->ODR |= (1<<4); //enable segment 1

for(i=0;i<16;i++)
{
SSDisplay(ssCode[i]);
HAL_Delay(1000);
}
}
/* USER CODE END 3 */
}
Interfacing with Seven Segment Display
C Program to turn on two 7-seg digits alternatively.

Algorithm:-

1) Configure Port C as output port to drive the segments,


2) Configure Port B0-1 as output port to select the digits,
3) Write the pattern of numeral 7 on Port C,
4) Turn on the select pin to HIGH to activate the tens digit,
5) Delay for some time,
6) Write the pattern of numeral 5 on Port C,
7) Turn on the select pin to HIGH to activate the ones digit,
8) Delay for some time,
9) Repeat from step 3 to 8.
Q.Draw an interfacing diagram and write a C program to interface LDR sensor with
STM32F4xx Controller.
What is a Light Dependent Resistor?
● An LDR or Light Dependent Resistor is also known
as a photoresistor, photocell, photoconductor.

● It is one type of resistor whose resistance varies


depending on the amount of light falling on its
surface.

● When the light falls on the resistor, then the resistance


changes.

● These resistors are often used in many circuits where


it is required to sense the presence of light.

● Resistance will decrease when the light increases.


● That means, In the daytime, the output resistance will
be less compared to nighttime.
Working Principle of LDR
● This resistor works on the principle of photoconductivity.
● It is nothing but, when the light falls on its surface, then the
material conductivity reduces, and also the electrons in the
valence band of the device are excited to the conduction
band.
● These photons in the incident light must have energy
greater than the bandgap of the semiconductor material.
This makes the electrons jump from the valence band to
conduction.
● These devices depend on the light, when light falls on the
LDR then the resistance decreases, and increases in the
dark.
● So, when light falls on LDR: STM32 will Read Input = low “0”
● when no light falls on LDR: STM32 will Read Input = high “1”
● The figure shows the curve between Resistance Vs Light
Intensity curve for a particular light-dependent resistor.
Interfacing with Light Dependent Resistor (LDR)
#include "main.h"
#include "lcd.h"
#include <stdio.h>
ADC_HandleTypeDef hadc1;
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);

int main(void)
{
unsigned char buf[16];
unsigned int val;

/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();

/* Configure the system clock */


SystemClock_Config();

/* Initialize all configured peripherals */


MX_GPIO_Init();
MX_ADC1_Init();
/* USER CODE BEGIN 2 */
lcd_init();
/* USER CODE END 2 */

/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
lcd_clear();
lcd_displayString(1,1,"LDR");

HAL_ADC_Start(&hadc1);
if (HAL_ADC_PollForConversion(&hadc1,10)== HAL_OK)
{
val = HAL_ADC_GetValue(&hadc1);
val = val*3.3;
sprintf(buf,"%4.0d mv",val);
lcd_displayString(2,1,buf);
}
//HAL_ADC_Stop(&hadc1);
HAL_Delay(2000);
}
/* USER CODE END 3 */
}
Q.Draw an interfacing diagram and write a C program to interface MQ3 sensor with
STM32F4xx Controller.
Interfacing with MQ3 (Alcohol Gas Sensor )

• Gas Sensor(MQ3) module is useful for gas leakage detection (in home and industry).
• It is suitable for detecting Alcohol, Benzine, CH4, Hexane, LPG, CO.
• It is a low cost semiconductor sensor which can detect the presence of alcohol
gases at concentrations from 0.05 mg/L to 10 mg/L

• Due to its high sensitivity and fast response time, measurements can be taken as soon as
possible.
• The sensitivity of the sensor can be adjusted by using the potentiometer
MQ3 Alcohol Sensor
● MQ3 is one of the most commonly used sensors
in the MQ sensor series.
● It is a Metal Oxide Semiconductor (MOS) type of
sensor.
● Metal oxide sensors are also known as
Chemiresistors, because sensing is based on the
change of resistance of the sensing material
when exposed to alcohol.
Operating voltage 5V ● So by placing it in a simple voltage divider
Load resistance 200 KΩ
network, alcohol concentrations can be detected.
● MQ3 alcohol sensor works on 5V DC and draws
Heater resistance 33Ω ± 5%
around 800mW. It can detect Alcohol
Heating consumption <800mw concentrations anywhere from 25 to 500 ppm.
Sensing Resistance 1 MΩ – 8 MΩ

Concentration Scope 25 – 500 ppm

Preheat Time Over 24 hour


Internal structure of MQ3 Alcohol Sensor
● MQ3 is a heater-driven sensor. That’s why it is enclosed
in two layers of fine stainless steel mesh called an
Anti-explosion network.
● It ensures that heater element inside the sensor will not
cause an explosion, as we are sensing flammable gas
(alcohol).
● It also provides protection for the sensor and filters out
suspended particles so that only gaseous elements are
able to pass inside the chamber.
● This is what the sensor looks like when outer mesh is
removed.
● The star-shaped structure is formed by the sensing
element and six connecting legs that extend beyond the
Bakelite base.
● Out of six, two leads (H) are responsible for heating the
sensing element and are connected via a
Nickel-Chromium coil ( a well known conductive alloy).
● The remaining four leads (A & B) responsible for output
signals are connected using Platinum Wires.
● These wires are connected to the body of the sensing
element and convey small changes in the current that
passes through the sensing element.
● The tubular sensing element is made up of Aluminum
Oxide (AL2O3) based ceramic and has a coating of Tin
Dioxide (SnO2).
● The Tin Dioxide is the most important material being
sensitive towards alcohol.
● However, the ceramic substrate only increases the
heating efficiency and ensures that the sensor area is
continuously heated to the working temperature.

● The Nickel-Chromium coil and Aluminum Oxide based ceramic forms a Heating
System; while Platinum wires and coating of Tin Dioxide forms a Sensing System.
How MQ3 Alcohol Sensor Works?
● When SnO2 semiconductor layer is heated at high temperature, oxygen is adsorbed
on the surface.
● In clean air, electrons from the conduction band in tin dioxide are attracted to oxygen
molecules. This form an electron depletion layer just below the surface of SnO2
particles and forms a potential barrier.
● As a result, the SnO2 film becomes highly resistive and prevents electric current flow.
● In the presence of alcohol, however, the surface density of adsorbed oxygen decreases
as it reacts with the alcohols; which lowers the potential barrier.
● Electrons are then released into the tin dioxide, allowing current to flow freely
through the sensor.
MQ3 Alcohol Sensor Module Pinout

Pin Name Description

VCC This pin powers the module, typically the


operating voltage is +5V
GND Used to connect the module to system ground
Digital This pin provides a digital representation of
Out (DO) the presence of alcohol., by setting a threshold
value using the potentiometer
Analog Provides analog output voltage in
Out (AO) proportional to the concentration of alcohol.
Features of MQ-3 Alcohol Sensor Specifications of MQ-3 Gas Sensor

● Sensor Type - Semiconductor ● Power requirements: 5 VDC @ ~165 mA (heater on) /


● Easy SIP header interface ~60 mA (heater off)
● Compatible with most of the ● Current Consumption: 150mA
microcontrollers ● DO output: TTL digital 0 and 1 ( 0.1 and 5V)
● Low-power standby mode ● AO output: 0.1- 0.3 V (relative to pollution), the
● Requires heater voltage maximum concentration of a voltage of about 4V
● Good sensitivity to alcohol gas ● Detecting Concentration: 0.05-10mg/L Alcohol
● Fast response and High sensitivity ● Interface: 1 TTL compatible input (HSW), 1 TTL
● Long life and low cost compatible output (ALR)
● Requires simple Drive circuit ● Heater consumption: less than 750mW
● Operating temperature: 14 to 122 °F (-10 to 50°C)
● Load resistance: 200kΩ
● Sensitivity S: Rs(in air)/Rs(0.4mg/L Alcohol)≥5
● Sensing Resistance Rs: 2KΩ-20KΩ(in 0.4mg/l alcohol)
● Dimensions: 32 x 22 x 16 mm
#include "main.h" while (1)
#include "lcd.h" {
#include <stdio.h> lcd_clear();
ADC_HandleTypeDef hadc1; lcd_displayString(1,1,"ADC");
void SystemClock_Config(void);
static void MX_GPIO_Init(void); HAL_ADC_Start(&hadc1);
static void MX_ADC1_Init(void); if (HAL_ADC_PollForConversion(&hadc1,10)== HAL_OK)
int main(void) {
{ val = (float)HAL_ADC_GetValue(&hadc1);
unsigned char buf[16]; // final = ((float)val)*0.8;
float val; // val = (unsigned int)final;
float final; sprintf(buf,"%2.0f mv",val);

/* Reset of all peripherals, Initializes the Flash lcd_displayString(2,1,buf);


interface and the Systick. */ }
HAL_Init(); HAL_ADC_Stop(&hadc1);
HAL_Delay(1000);
}
/* Configure the system clock */ /* USER CODE END 3 */
SystemClock_Config(); }

/* Initialize all configured peripherals */


MX_GPIO_Init();
MX_ADC1_Init();
lcd_init();
T IME R & C O U N T E R
STM32F4 Timer Peripherals

● Basic Timer (Simple timer) • General Purpose Timer


● TIM2,TIM3,TIM4,TIM5
● TIM6 andTIM7
● Can be generic counter and internally connected to DAC ● Input capture, output compare, PWM, one
pulse mode
● 16-bit counter ● 16-bit (TIM3/4) or 32-bit (TIM2/5) counter

•General Purpose Timer • Advanced Control Timer


● TIM1 and TIM8
• TIM9 to TIM14 ● Input capture, output compare, PWM, one
• Input capture, output compare, PWM, one pulse mode pulse mode 16-bit counter
• 16-bit counter ● Additional control for driving motor or other
devices

The main block of the programmable timer is a 16-bit/32-bit counter with its related auto-reload register

In addition to that an 24 bit system timer(SysTick) – standard in all Cortex M4 Microcontrollers


STM32F407 Programmable Timers

• There are 14 Timers :- Vary with


counter, width, max size and clock
General-Purpose TIMx timer features
General-purpose TIMx timer features include:
• 16-bit (TIM3 and TIM4) or 32-bit (TIM2 and TIM5) up, down, up/down auto-reload counter.
• 16-bit programmable prescaler used to divide (also “on the fly”) the counter clock frequency by
any factor between 1 and 65536.

• Up to 4 independent channels for:


• – Input capture
• – Output compare
• – PWM generation (Edge- and Center-aligned modes)
• – One-pulse mode output
Timers in STM32F4xx:- Basic timing function
STM32F407 Programmable Timers
• RCC_APB1ENR and APB2ENR registers are used to enable or disable the clock to individual TIMx timers.
• Bits 8-0 of RCC_APB1ENR register are used to enable the clock to some of TIMx timers.

• Without the clock enabled, the CPU will not be able to communicate with the timer.

RCC_APB1ENR

RCC_APB2ENR

For example, we can use the following code to enable the clock to TIM2: RCC->APB1ENR |= 1; /* enable TIM2 clock */
Timers in STM32F4xx:- Basic Registers
• There are 14
Registers

Important Registers available in all 14 Timers


Timers in STM32F4xx:- CONTROL 1 Register (CR1)
Using the CR1 (Control 1) register, we can control the counter direction, one shot, or disable/enable.

Some of the CR1 register bits


CEN (Counter Enable, D0): enables or disables the counter. When the CEN bit is set, the timer starts to count. It counts up
or down depending on the DIR bit.

DIR (Direction, D4): This bit configures the Timer/Counter as an up or down counter.
• If the DIR bit is 0, the timer counts up.
• If the DIR bit is 1, the counter counts down.

Eg:- Find the value for CR1 register, to enable the TIM2 for up counter.

ANS:- TIM2_CR1 = 0b010001 = 0x0011


Timers in STM32F4xx:- TIMxSR (Status Register)

UIF (D0): This is like overflow flag in other microcontrollers. When the timer counts down from a starting value and
reaches 0, the UIF is set high.
STM32F407 Programmable Timers
Timers in STM32F4xx :- Delay Generation
Example:- Using TIM2, show the code that makes a delay of 20 ms.
Assume SYSCLK =16 MHz.

Given Data:-
SYSCLK =16 MHz
Delay = 20 ms

Need to Find? :- N = TIMx_CNT register (Count need to Load to


generate 20 ms delay)

Solution:-
• delay = N × M / SYSCLK
• N = delay × SYSCLK / M = 0.020 sec × 16 MHz / M = 320,000 / M
Initialization Code:
• If we choose the prescaler (PSC) to divide by 64, RCC->APB1ENR |= 1; /* enable TIM2 clock */
TIM2->PSC = 64 - 1; /*divided by 64 */
• N = 320,000 / 64 = 5,000
TIM2->ARR = 5000 - 1; /* divided by 5000*/
TIM2->CNT = 0;
TIM2->CR1 = 1; /* enable timer2 */
#include "stm32f4xx.h" // Device header

int main()
{
//Configure PA5 as ouput to drive LED
RCC->AHB1ENR |=0x00000008;// Enable GPIOD Clock
GPIOD->MODER &=0x55000000;//Set pin to OUTPUT Mode
GPIOD->MODER |=0x55000000;

/*Configure TIM2 to wrap around at 1Hz*/

RCC->APB1ENR |=1;/*Enable TIM2 Clock*/


TIM2->PSC =1600-1;/*divide by 1600*/
TIM2->ARR =10000-1;/*divide by 10000*/
TIM2->CNT =0; /*Clear timer counter*/
TIM2->CR1 =1;/*Enable TIM2*/
while(1)
{
while(!(TIM2->SR & 1)) {} /*wait until UIF Set*/
TIM2->SR &= ~1;/*Clear UIF*/
GPIOD->ODR^= 0x0000F000;/*Toggle LED*/
}
}
Timers in STM32F4xx :- Timing Diagram
Timer:- System Tick Timer
• Every Arm Cortex-M comes with a System tick timer.
• System tick timer allows the system to initiate an action on a periodic basis.

• This action is performed internally at a fixed rate without external signal.


• The SysTick is a 24-bit down counter driven by the processor clock (AHB clock, the clock that feeds the CPU).
• It counts from an initial value down to 0.
• When it reaches 0, in the next clock, it underflows and it raises a flag called COUNT and reloads the initial value
and starts over again.

• We can set the initial value to a value between 0x000000 to 0xFFFFFF


Working of System Tick Timer

• The down counter is named as STCVR (SysTick Current Value Register)


• The clock source is chosen using the CLKSOURCE bit of STCSR (SysTick Control & Status Register)

• Need to configure bits from STCTRL (SysTick Control and Status)


• EN 0 Bit: When the ENABLE bit is set the counter initializes the STCVR (SysTick Current Value Register)
with the value of the STRVR (SysTick Reload Value Register)
Counters in STM32F4xx :- Basic Operation
• In Counter mode the timer is counting
the number of external input pulses.
• A Prescaler for the external signal is
available to divide the external signal by
1, 2, 4, or 8.
• The counter wraps around when the
value matches the ARR on the up count
and set to the value of ARR when down
count to 0. PA0
• It sets the UIF (Update interrupt flag)
when the count wraps around. It sets
CCxIF (Capture Compare Interrupt
Flag) when the value matches the CCRx
register.
Interfacing Diagram
UA R T
1. Introduction To UART
Universal Asynchronous Receiver/Transmitter or UART for short represents the hardware
circuitry (module) being used for serial communication. UART is sold/shipped as a
standalone integrated circuit (IC) or as an internal module within microcontrollers. In this
tutorial, we’re actually concerned with the internal UART module within STM32
Microcontrollers.

There are actually two forms of UART hardware as follows:

● UART – Universal Asynchronous Receiver/Transmitter


● USART – Universal Synchronous/Asynchronous Receiver/Transmitter

The Synchronous type of transmitters generates the data clock and sends it to the receiver
which works accordingly in a synchronized manner. On the other hand, the Asynchronous
type of transmitter generates the data clock internally. There is no incoming serial clock signal,
so in order to achieve proper communication between the two ends, both of them must be
using the same baud rate.
UART in STM32F4xx
The universal synchronous asynchronous receiver transmitter (USART) offers a
flexible means of full-duplex
data exchange with external equipment requiring an industry standard

• It supports synchronous one-way communication


• half-duplex single wire communication.
• It also supports the LIN (local interconnection network),
• Smartcard Protocol
• IrDA (infrared data association) SIR ENDEC specifications
• modem operations (CTS/RTS). It allows multiprocessor communication.
UART Block Diagram

Register Name Register Function


USART_SR Status Register
USART_ISR USART interrupt and status
USART_DR Data Register
USART_BRR Baud Rate Register
USART_CR1 Control Register 1
USART_CR2 Control Register 2
USART_CR3 Control Register 3
UART:- Data Framing
UART:- RCC_CFGR (Clock Configuration Register)

Bits 1:0 SW: System clock switch Bits 7:4 HPRE: AHB prescaler
00: HSI oscillator selected as system clock 0xxx: system clock not divided
01: HSE oscillator selected as system clock 1000: system clock divided by 2
10: PLL selected as system clock 1001: system clock divided by 4
11: not allowed 1010: system clock divided by 8
1011: system clock divided by 16
1100: system clock divided by 64
1101: system clock divided by 128
1110: system clock divided by 256
1111: system clock divided by 512
UART: RCC_CR (RCC Control Register)
The HSI clock signal is generated from an internal 16 MHz RC oscillator and can be used directly as a system clock
RCC_CR is used to set the clock for UART

Bit 0:- 0:HSI oscillator OFF


1: HSI oscillator ON

By default Peripheral Clock is disabled:


So, From RCC_APB1ENR register, D17 bit is used to enable the clock to the USART2
UART: Baud rate register (USART_BRR)
BAUD register (USART_BRR) is a 32-bit register but only the lower 16 bits are used.
UART: Control register 1 (USART_CR1)

Bit 13 UE: USART enable


Bit 10 PCE: Parity control enable
Bit 7 TXEIE: TXE interrupt enable
Bit 5 RXNEIE: RXNE Receive interrupt enable
Bit 3 TE: Transmitter enable
Bit 2 RE: Receiver enable
UART: Control register 1 (USART_CR1)

Bit 13 UE: USART enable


Bit 10 PCE: Parity control enable
Bit 7 TXEIE: TXE interrupt enable
Bit 5 RXNEIE: RXNE Receive interrupt enable
Bit 3 TE: Transmitter enable
Bit 2 RE: Receiver enable
UART: Status register (USART_SR)

Bit 7 TXE: Transmit data register empty


This bit is set by hardware when the content of the TDR register has been transferred into the shift
register. 0: Data is not transferred to the shift register
1: Data is transferred to the shift register)

Bit 6 TC: Transmission complete:- 0: Transmission is not complete, 1: Transmission is complete

Bit 5 RXNE: Read data register not empty: 0: Data is not received, 1: Received data is ready to be
read.
UART: Data register (USART_DR)

• Bits 31:9 Reserved, must be kept at reset value


• Bits 8:0 DR[8:0]: Data value

• Contains the Received or Transmitted data character, depending on whether it is read from or written to.
UART :- Baud Rate Generation
The baud rate for the receiver and transmitter (Rx and Tx) are both set to the same value as programmed in
the Mantissa and Fraction values of USARTDIV

Baud Rate =

When OVER8=0, the fractional part is coded on 4 bits


When OVER8=1, the fractional part is coded on 3 bits
Example1 :- For SYSCLK = 16MHZ, And for Baud Rate = 9600 with OVER8 = 0 ?
Soln:-
USARTDIV = Fck / 16 x Baud
16MHz / 16 x 9,600 = 104.166.
Now, 104 = 0x68 for upper 12-bits.
For fraction part, 0.166 x 16 = 2.656 ͌ = 0x03

Example 2:- For SYSCLK = 16MHZ, And for Baud Rate = 19200 with OVER8 = 0 ?
Soln:-
USARTDIV = Fck / 16 x Baud
16MHz / 16 x 19,200 = 52.08.
Now, 52 = 0x034 for upper 12-bits.
For fraction part, 0.08 x 16 = 1.28 and we use 1 for lower 4-bits.
Steps to configure USART2 for transmitting data

• 1) Enable the Clock to GPIOA.


• 2) Enable the Clock to USART2.
• 3) Select the peripheral function AF7 for PA2 (USART2_TxD) pin using the GPIO_MODER and GPIO_AFRL
registers.
• 4) Set the baud rate for USART2 using USART2_BRR register.
• 5) Configure the CR1 (Control 1) register for oversampling rate, character size (8-bit or 9-bit) and enabling transmit
(TE).

• 6) Configure the CR2 (Control 2) register for number of stop bit(s) and so on.
• 7) Configure the CR3 (Control 3) register for no hardware flow control and so on.
• 8) Enable USART2 after configuration complete

• 9) Wait until the TXE (Transmit Empty) bit of the USART_SR register is set.
C Code to configure USART2 for transmitting data
#include "stm32F4xx.h"
void USART2_init(void);
void USART2_write(int c);
int main (void) { /* Write a character to USART2 */
USART2_init(); /* initialize USART2 */ void USART2_write (int ch) {
while(1) { /* Loop forever */ while (!(USART2->SR & 0x0080)) {} // wait until Tx
USART2_write('Y’); //Transmit Character buffer empty
USART2_write('e'); USART2->DR = (ch & 0xFF);
USART2_write('s'); }
}}
void USART2_init (void) {
RCC->AHB1ENR |= 1; /* Enable GPIOA clock */
RCC->APB1ENR |= 0x20000; /* Enable USART2 clock */

/* Configure PA2 for USART2_TX */


GPIOA->AFR[0] &= ~0x0F00;
GPIOA->AFR[0] |= 0x0700; /* alt7 for USART2 */
GPIOA->MODER &= ~0x0030;
GPIOA->MODER |= 0x0020; /* enable alternate function for PA2 */
USART2->BRR = 0x0683; /* 9600 baud @ 16 MHz */
USART2->CR1 = 0x0008; /* enable Tx, 8-bit data */
USART2->CR2 = 0x0000; /* 1 stop bit */
USART2->CR3 = 0x0000; /* no flow control */
USART2->CR1 |= 0x2000;/* enable USART2 */
}
ADC
Q. State features of ADC. Write a C program to convert analog value to digital using on
chip ADC of STM32F4xx controller.
STM32f4xx: on chip-Analog-to-digital converter (ADC)

• The 12-bit ADC is a successive approximation analog-to-digital converter.


• It has up to 18 multiplexed channels allowing it to measure signals from 16 external sources, two internal
sources

ADC main features


• 12-bit, 10-bit, 8-bit or 6-bit configurable resolution
• Single and continuous conversion modes

• Interrupt generation at the end of conversion


• The STM32F4xx Arm chip has three on-chip ADC modules: the ADCs are designated as ADC1 (master), ADC2 (slave)
and ADC3 (slave).
Block Diagram of ADC
Register Name Register Function
ADC_SR (Status Register)
ADC_CR1 (Control Register1)
ADC_CR2 (Control Register2)
ADC_SMPR1 ADC sample time register 1
ADC_SMPR2 ADC sample time register 2

ADC_DR (Data Register)

RCC_APB2ENR |= 0x00000100; /* enable clock for ADC1


*/
Conversion Clock for ADC

• SYSCLK clock source by AHB by APB Prescalar , Then given to


ADC
Conversion Time for ADC
time to sample the input
signal

conversion time

time to do the conversion

• A sample and hold circuit is added between the input signal and the converter.
The number of clock cycles for sampling time can be programmed using ADC_SMPRx (Sample Time Register)

register. We have two ADC_SMPRx registers to covers all the 18 ADC channels.

• ADC_SMPR2 is used for channels 0 to 9


• ADC_SMPR1 is used for channels 10 to 18.
ADC sample time register (ADC_SMPR1) to set sampling time

000: 3 cycles 100: 84 cycles


001: 15 cycles 101: 112 cycles
010: 28 cycles 110: 144 cycles
011: 56 cycles 111: 480 cycles

• In the conversion phase, the analog input is converted to binary numbers.


• In this phase, the number of clocks required depends on ADC resolution namely the number of bits of the binary
output 6, 8, 10, or 12.

• For example, if we use the default of 3 clock cycle for sample time with the 8-bit ADC resolution, the total
number of clocks needed for ADC conversion is 11 clocks.
Analog input pin assignment (GPIO_MODER Register)

GPIO_MODER

• 00: Input (reset state)


• 01: General purpose output mode
• 10: Alternate function mode
• 11: Analog mode

ADC-H/W Pins
Channel Allocation
ADC_DR (ADC Data Register)
• Upon the completion of a conversion, the result is placed in the DATA registers.
• Its 32 bit, only the lower 12 bits are used and upper 18 bits are unused.
Control 1 (ADC_CR1) Register

• RES bits (D25-D24) of ADC_CR1 register to select 6, 8, 10, or 12- bit ADC resolution.
• Bit 5 EOCIE: Interrupt enable for EOC

• Bits 4:0 AWDCH[4:0]: Analog watchdog channel select bits


Control 2 (ADC_CR2) register

Bit 0 ADON: A/D Converter ON / OFF


Bit 1 CONT: Continuous conversion
Bit 10 EOCS: End of conversion selection
Bit 11 ALIGN: Data alignment (0: Right , 1: Left)

• ALIGN bit in CR2 register allows the binary output result of ADC conversion to be moved to the left
ADC regular sequence register 3 (ADC_SQR3)

ADC1->SQR3 = 1; /* conversion sequence starts at ch 1 regular sequence register*/


ADC_SR(ADC Status) Register

Bit 5: OVR Overrun This bit is set by hardware when data are lost.
This happens if we do not read the result of the last conversion from the Data Register (ADC_DR).

Bit 1: EOC End of Conversion -


• This bit is set by ADC itself at the end of each conversion of a channel.
• It is cleared by software or by reading the ADC_DR (ADC Data) register.
• By polling this flag, we know if the conversion is complete and we can read the value in the DATA
register.

We can use EOCIE (EOC Interrupt enable) bit in ADC_CR1 register to enable the interrupt option
Algorithm:- Configuring ADC and reading ADC channel

1. Enable ADC clock to ADC in RCC_APB2ENR register.


2.Configure ADC right adjusted result (ALIGN), free running conversion (CONT, continuous conversion) using
ADC_CR2 register.

3. Using ADC_CR1 register, select the resolution and the analog input channel.
4. Use GPIOx_MODER register to configure input pin for analog input channel.
5. Using ADC_CR2 register Enable the ADC (ADON) and START (SWSTART) to start the conversion.
6. Monitor the EOC flag in the ADC_SR register for end-of-conversion.
7. When the EOC flag goes HIGH, read the ADC data result from the ADC_DR register and save it.
8. Repeat steps 6 through 7 for the next conversion.
C Program to Read ADC
#include "stm32f4xx.h"
int main (void) {
int result;
/* set up pin PA5 for LED */
RCC->AHB1ENR |= 1; /* enable GPIOA clock */
GPIOA->MODER &=~0x00000C00; /* clear pin mode */
GPIOA->MODER |= 0x00000400; /* set pin to output mode */
/* set up pin PA1 for analog input */
RCC->AHB1ENR |= 1; /* enable GPIOA clock */
GPIOA->MODER |= 0xC; /*PA1 analog */
while (1) {
/* setup ADC1 */
ADC1->CR2 |= 0x40000000; /* start a conversion */
RCC->APB2ENR |= 0x00000100; /* enable ADC1 clock */
while(!(ADC1->SR & 2)) {} /* wait for conv complete */
ADC1->CR2 = 0; /* SW trigger */ result = ADC1->DR; /* read conversion result */
ADC1->SQR3 = 1; /* conversion sequence starts at ch 1 */ if (result & 0x100)
ADC1->SQR1= 0; /* conversion sequence length 1 */ GPIOA->BSRR = 0x00000020; /* turn on LED */
ADC1->CR2 |= 1; /* enable ADC1 */ else
GPIOA->BSRR = 0x00200000; /* turn off LED */ }
}
DAC
Features of DAC

• Two DAC converters: one output channel each as DAC1 and DAC2.
• They are available at the analog out pins “PA4 and PA5” for chan1 and chan2
• Left or right data alignment in 12-bit mode
• Synchronized update capability
• Noise-wave generation
• Triangular-wave generation
• Dual DAC channel for independent or simultaneous conversions
• DMA capability for each channel
• DMA underrun error detection
STM32F4xx DAC Block Diagram

The DAC integrates two output buffers that can be used to reduce the output impedance, and to drive external loads
directly without having to add an external operational amplifier.
Vref should be at 1.8 V ≤ VREF+ ≤ VDDA
The output voltage from the DAC can be calculated using the following formula:
DAC_CR (DAC Control Register)

The most important bit in DAC_CR is the enable bit.

Bit 0 EN1: DAC channel1 enable ; where 0: DAC channel1 disabled, 1: DAC channel1 enabled
Bit 1 BOFF1: DAC channel1 output buffer disable
Bits 5:3 TSEL1[2:0]: DAC channel1 trigger selection
DAC Data Holding Registers (DAC_DHR)
• There are 8 registers according to Data Holding Position
• For eg: - DAC channel1 12-bit right-aligned data holding register (DAC_DHR12R1)

• DAC channel1 12-bit left aligned data holding register (DAC_DHR12L1)

• Writing new data into DAC holing register starts a conversion.


• Data stored in the DAC_DHRx register are automatically transferred to the Data Output registers (DAC_DOR) register
after one clock cycle.
• The Digital inputs are converted to output voltages on a linear conversion between 0 and VREF+
DAC- Data Output registers (DAC_DOR) register
• Data stored in the DAC_DHRx register are automatically transferred to the Data Output registers (DAC_DOR) register
after one clock cycle.
• The Digital inputs are converted to output voltages on a linear conversion between 0 and VREF+

Enabling Clock to DAC


• To save power no clock is fed to DAC upon Reset.
• To use the on-chip, DAC we must enable the clock to DAC using RCC APB1 peripheral clock enable register
(RCC_APB1ENR)
C program to generate a step waveform using DAC

• Solution:- The loop counter i is incremented every iteration and written into the DAC_DHR register to create
the 4 steps.

[2]. DAC Waveform


C Program to Read DAC #include "stm32f4xx.h"

void delay(void)
{
volatile int i;
for(i=0;i<5000;i++);
}

int main(void)
{
uint32_t DAC_OUT[4]={0,1241,2482,3723};
uint8_t i=0;
int data;
RCC->AHB1ENR|=1;
GPIOA->MODER |=0x00000300;
RCC->APB1ENR |=1<<29;/*Enable DAC Clock*/
DAC->CR|=1;;/*Enable DAC */
while(1)
{
DAC->DHR12R1=DAC_OUT[i++];
if(i==4)
{
i=0;
}
delay();
}
}
REFERENCES

• [1] https://ezcontents.org/stm32f4-discovery-blink-led-osx
• [2] https://deepbluembedded.com/
THANK YOU

You might also like