Documente Academic
Documente Profesional
Documente Cultură
Sem : VI
Prepared by
Mr. Ravikiran B. A.
Asst. Professor, Dept of ECE
Table of Contents
The kit used in our lab experiments is built around the STM32 Nucleo-64 board, which is based
on the STM32 Microcontroller, manufactured by ST Microelectronics. We use a ARM Cortex-M3
72 MHz, 128-KB Flash, 20-KB SRAM. STM32 Nucleo-64 development board with
STM32F103RB MCU, supports Arduino and ST morpho connectivity.
STM32F103RB Features:
• ARM® 32-bit Cortex®-M3
• CPU Core – 72 MHz maximum frequency,
Single-cycle multiplication and hardware division
• Memories
64 or 128 Kbytes of Flash memory
20 Kbytes of SRAM
• Clock, reset and supply management:
2.0 to 3.6 V application supply and I/Os
4-to-16 MHz crystal oscillator
Internal 8 MHz factory-trimmed RC
Internal 40 kHz RC
32 kHz oscillator for RTC with calibration
• 2 x 12-bit, 1 μs A/D converters (up to 16 channels)
Conversion range: 0 to 3.6 V
Dual-sample and hold capability
Temperature sensor
• Peripherals supported: timers, ADC, SPIs, I2Cs and USARTs
• Up to 80 fast I/O ports – 26/37/51/80 I/Os, all mappable on 16 external interrupt vectors and almost
all 5 V-tolerant
• 7 timers – Three 16-bit timers, each with up to 4 IC/OC/PWM or pulse counter and quadrature
(incremental) encoder input, 16-bit, motor control PWM timer, 2 watchdog
• Up to 9 communication interfaces
Up to 2 x I2C interfaces (SMBus/PMBus)
Up to 3 USARTs (ISO 7816 interface, LIN, IrDA capability, modem control)
Up to 2 SPIs (18 Mbit/s)
CAN interface (2.0B Active)
USB 2.0 full-speed interface
The STM32F103RB has 51 GPIO pins available to the user, in 4 groups – Port A (16 pins), Port
B (16 Pins), Port C (16 Pins) and Port D (3 Pins).
The general workflow for creating and downloading a complete project on Keil are as follows:
1. Create a New uVision Project
2. Set up the Target configuration by choosing the right device (STM32F103RB)
3. Choose the appropriate Device libraries necessary for that particular project.
4. Create a new Source File in the relevant file format (.c, .cpp, etc)
5. Write the program into the source file.
6. Translate and Build the Program once debugging is done.
7. Download the compiled program onto the target hardware and run.
For each pin in the CRL or CRH register, there are 4 bits, which have to be set or reset depending
on the mode and speed of operation of the pins as shown:
In our kit, there are some pre-connected peripherals, whose port and pin connections are given:
(NOTE: These numbers are specific to the kit used in our lab only)
PROGRAM 1
Display of Message using Internal UART
The UART that is going to transmit data receives the data from a data bus. The data bus is used to
send data to the UART by another device like a CPU, memory, or microcontroller. Data is transferred
from the data bus to the transmitting UART in parallel form. After the transmitting UART gets the
parallel data from the data bus, it adds a start bit, a parity bit, and a stop bit, creating the data packet.
Next, the data packet is output serially, bit by bit at the Tx pin. The receiving UART reads the data
packet bit by bit at its Rx pin. The receiving UART then converts the data back into parallel form and
removes the start bit, parity bit, and stop bits. Finally, the receiving UART transfers the data packet in
parallel to the data bus on the receiving end.
NOTE: In our experiment, we start PuTTY on the computer, set the communication mode to Serial,
include the right COM port number (as seen from the Device Manager), and run the program.
C - CODE:
#include <stdio.h>
#include "stm32f10x.h"
uint8_t text [] = "Hello World \n\r\n\r"; // Text to be displayed
void delay(int time);
void USART_PutChar(uint8_t ch) //USART Print Subroutine
{
while(!(USART2->SR & USART_SR_TXE));
USART2->DR = ch; // Write text to USART Data Register
}
void USART_PutString(uint8_t * str)
{
while(*str != 0)
{
USART_PutChar(*str); //Send string
str++;
}
}
int main(void)
{
RCC->APB2ENR = RCC_APB2ENR_IOPAEN ; //IO port declaration
RCC->APB1ENR = RCC_APB1ENR_USART2EN; //USART declaration
GPIOA->CRL = 0x00004B00; //0100 ->3 1011 ->2 0000->1 0000->0
USART2->CR1 = USART_CR1_UE | USART_CR1_TE;
USART2->BRR = (SystemCoreClock / (9600*2)); // baud rate change
while (1)
{
USART_PutString(text);
delay(10);
}
}
OUTPUT:
Hello World
RESULT:
We see that upon executing this code, the text defined in the program is sent from the
Microcontroller via UART, and the message can then be viewed on a serial window using a program
such as PuTTy or TeraTerm.
PROGRAM 2
DC Motor Interface
Aim: To write a program to Interface and Control a DC Motor with the ARM controller
Theory:
A DC motor is any of a class of rotary electrical machines that converts direct current electrical
energy into mechanical energy. DC motors were the first type widely used, since they could be powered
from existing direct-current lighting power distribution systems. A DC motor's speed can be controlled
over a wide range, using either a variable supply voltage or by changing the strength of current in its
field windings. Small DC motors are used in tools, toys, and appliances.
The very basic construction of a DC motor contains a current carrying armature which is connected
to the supply end through commutator segments and brushes. The armature is placed in between north
south poles of a permanent or an electromagnet as shown in the diagram above.
As soon as we supply direct current in the armature, a mechanical force acts on it due to
electromagnetic effect of the magnet. If a current carrying conductor is placed in a magnetic field
perpendicularly, then the conductor experiences a force in the direction mutually perpendicular to both
the direction of field and the current carrying conductor. In a typical DC motor, there are
permanent magnets on the outside and a spinning armature on the inside. The permanent magnets are
stationary, so they are called the stator. The armature rotates, so it is called the rotor.
The armature contains an electromagnet. When electricity flows into this electromagnet, it creates
a magnetic field in the armature that attracts and repels the magnets in the stator. So the armature spins
through 180 degrees. To keep it spinning, we have to change the poles of the electromagnet. The brushes
handle this change in polarity. They make contact with two spinning electrodes attached to the armature
and flip the magnetic polarity of the electromagnet as it spins.
A motor driver is an integrated circuit chip which is usually used to control motors. L293D is
a dual H-bridge motor driver integrated circuit (IC). Motor drivers act as current amplifiers since
they take a low-current control signal and provide a higher-current signal. This higher current signal
is used to drive the motors. L293D contains two inbuilt H-bridge driver circuits. In its common
mode of operation, two DC motors can be driven simultaneously, both in forward and reverse
direction. The motor operations of two motors can be controlled by input logic at pins 2 & 7 and
10 & 15. Input logic 00 or 11 will stop the corresponding motor. Logic 01 and 10 will rotate it in
clockwise and anticlockwise directions, respectively.
NOTE: In the kit used in our experiment, we first need to ensure that the jumpers are connected to
the first 4 pins at the DC Motor side. The DC Motor is to be connected to the M1 port.
C - CODE:
#include "stm32f10x.h"
int main(void)
{
RCC ->APB2ENR |= 0x10; // Port C
GPIOC ->CRH = 0x1111; // Enable Pin 8-11 as O/P
GPIOC->ODR = 0x0000; // Clear ODR
RESULT:
Upon execution of the program the DC motor connected to the kit is seen to rotate in both clockwise
and anticlockwise directions alternatively.
PROGRAM 3
Aim: To write a program to Interface a Stepper motor and rotate it in clockwise and anti-clockwise
directions.
Theory:
A stepper motor or step motor or stepping motor is a brushless DC electric motor that divides a
full rotation into a number of equal steps. Unlike a brushless DC motor which rotates continuously
when a fixed DC voltage is applied to it, a step motor rotates in discrete step angles. The Stepper Motors
therefore are manufactured with steps per revolution of 12, 24, 72, 144, 180, and 200, resulting in
stepping angles of 30, 15, 5, 2.5, 2, and 1.8 degrees per step. The stepper motor can be controlled with
or without feedback.
Stepper motors work on the principle of electromagnetism. There is a soft iron or magnetic rotor
shaft surrounded by the electromagnetic stators. The rotor and stator have poles which may be teethed
or not depending upon the type of stepper. When the stators are energized the rotor moves to align itself
along with the stator (in case of a permanent magnet type stepper) or moves to have a minimum gap
with the stator (in case of a variable reluctance stepper). This way the stators are energized in a sequence
to rotate the stepper motor.
Stepper motors are used in a number of applications where precise control of rotation angles are
required, for instance, in robotics, 3D printers, disk drives, etc. They are also very commonly used in
speed control applications in automation and robotics applications.
Despite their applications, they have a few limitations including reduced efficiency, limited high
speed torque and no feedback (unlike servo motors).
NOTE: In our kit, the Stepper Motor is connected to Pins 8-11 of Port C as Output. The jumper pins
should be on the Stepper Motor side of the pins.
C - CODE:
#include "stm32f10x.h"
void delay(int time) // Delay Subroutine
{
int i,j;
for(i=0;i<=time;i++)
{
for(j=0;j<=72000;j++);
}
}
int main(void)
{
RCC ->APB2ENR |= 0x10; // Port C
GPIOC ->CRH = 0x1111; //Enable Pins 8-11
GPIOC->ODR = 0x0000; // Clear ODR
while (1)
{
// Clockwise Rotation
GPIOC->ODR = 0x0100;
delay(50);
GPIOC->ODR = 0x0200;
delay(50);
GPIOC->ODR = 0x0400;
delay(50);
GPIOC->ODR = 0x0800;
delay(50);
// Anticlockwise Rotation
GPIOC->ODR = 0x0800;
delay(50);
GPIOC->ODR = 0x0400;
delay(50);
GPIOC->ODR = 0x0200;
delay(50);
GPIOC->ODR = 0x0100;
delay(50);
}
}
RESULT:
Upon execution of the program, it is observed that the Stepper motor connected to the microcontroller
rotates in the clockwise direction for one cycle, and then rotates in the anticlockwise direction in the
next cycle.
PROGRAM 4
Waveform Generation using DAC
Aim: To write a program to Interface a DAC and generate Triangular and Square waveforms
Theory:
In electronics, a digital-to-analog converter (DAC, D/A, D2A, or D-to-A) is a system that converts
a digital signal into an analog signal. There are several DAC architectures; the suitability of a DAC for
a particular application is determined by figures of merit including: resolution, maximum sampling
frequency and others. Digital-to-analog conversion can degrade a signal, so a DAC should be specified
that has insignificant errors in terms of the application.
DACs are commonly used in music players to convert digital data streams into analog audio
signals. They are also used in televisions and mobile phones to convert digital video data into analog
video signals which connect to the screen drivers to display monochrome or color images.
ST32F103RB used in our kit does not have a built-in DAC module. So, we use an external DAC
chip, MCP4921, a 12-bit DAC with SPI Interface in Slave Mode, for this experiment. The MCP4921
DAC can be used in single or dual channel mode. However, we will be using a single channel. It also
provides an option of using unity or 2x gain output. The MCP4921 provides a high accuracy and low
noise performance.
MOSI MOSI
MISO MISO
𝐶𝑆 𝐶𝑆
SCK SCK
STM32F103RB MCP4921
The STM32F103RB communicates with the MCP4921 DAC through SPI protocol, which involves
4 logical signal lines:
1. Master Output Slave Input (MOSI) – Data flows from Master to Slave
2. Master Input Slave Output (MISO) – Data flows from Slave to Master
3. Chip Select (CS) – Low on this pin selects a particular chip
4. SCK – Serial Clock – Used to synchronize data transfer
The Output is taken from Vout and GND pins of the DAC Chip, which are connected to the
leads of the CRO unit.
We see that the first 4 bits (15-12) are the control bits, while the last 12 bits (D11-D0) are the
data bits.
Bit 15 = 0, since we are writing to DACA.
Bit 14 = 1, since we are using VREF Input Buffer
Bit 13 = 1 since we are selecting unity output gain
Bit 12 = 1 since we are using the DAC in output power down mode.
During our program the first 4 bits are kept as 0111 (Hex 0x7), while the data is written to the
rest of the 12 bits.
C - CODE:
1. Triangular Waveform:
#include "stm32f10x.h"
void select(); // Select DAC
void deselect(); // Deselect DAC
void DelayMs(int time);
uint8_t SPI1_Transfer(uint8_t data); //8-bit SPI data
uint16_t DAC_write(uint16_t); //16-bit value to DAC
int main()
{
int i,j;
int_spi();
deselect();
while(1)
{
// Code to generate Triangular Waveform
i = 0;
while ( i != 4000 )
{
DAC_write(i);
i= i+100;
}
while ( i != 0 )
{
DAC_write(i);
i= i-100;
}
}
}
}
void select() {
GPIOA->BRR = 0x0010;
}
void deselect() {
GPIOA->BSRR = 0x0010;
}
2. Square Waveform
#include "stm32f10x.h"
void select(); // Select DAC
void deselect(); // Deselect DAC
void DelayMs(int time);
uint8_t SPI1_Transfer(uint8_t data); //8-bit SPI data
uint16_t DAC_write(uint16_t); //16-bit value to DAC
int main()
{
int i,j;
int_spi();
deselect();
while(1)
{
// Code to generate Square Waveform
DAC_write(4095);
DelayMs(2);
DAC_write(0);
DelayMs(2);
}
}
}
void select() {
GPIOA->BRR = 0x0010;
}
void deselect(){
GPIOA->BSRR = 0x0010;
}
OUTPUT WAVEFORMS:
1. Triangular Waveform:
2. Square Waveform:
OUTPUT: We observe that, upon execution of the program, triangular and square waveforms are
displayed on the CRO, which is connected to the output of the DAC unit.
PROGRAM 5
Keypad and LCD Interface
Aim: To write a program to Interface a 4x4 keyboard and display the key code on an LCD.
Theory:
A liquid crystal display (LCD) is a flat panel display, electronic visual display, or video display that uses the
light modulating properties of liquid crystals (LCs). LCs does not emit light directly.
The STM library allows a controller board to control Liquid Crystal displays (LCDs) based on the Hitachi
HD44780 (or a compatible) chipset, which is found on most text-based LCDs. The library works with in either
4- or 8-bit mode (i.e. using 4 or 8 data lines in addition to the RS, enable, and, optionally, the RW control lines).
The LCDs have a parallel interface, meaning that the microcontroller has to manipulate several interface pins at
once to control the display. The interface consists of the following pins:
• A register selects (RS) pin that controls where in the LCD's memory you're writing data to. You can
select either the data register, which holds what goes on the screen, or an instruction register, which is
where the LCD's controller looks for instructions on what to do next.
• A Read/Write (R/W) pin that selects reading mode or writing mode
• An Enable pin that enables writing to the registers
• 8 data pins (D0 -D7). The states of these pins (high or low) are the bits that you're writing to a register
when you write, or the values you're reading when you read.
• There's also a display contrast pin (Vo), power supply pins (+5V and Gnd) and LED Backlight
(Bklt+ and BKlt-) pins that you can use to power the LCD, control the display contrast, and
turn on and off the LED backlight, respectively.
Initially all switches are assumed to be released. So there is no connection between the rows and columns.
When any one of the switches are pressed, the corresponding row and column are connected (short circuited).
This will drive that column pin (initially high) low. Using this logic, the button press can be detected.
The first step involved in interfacing the matrix keypad is to write all logic 0’s to the rows and all logic 1’s
to the columns. Now the software has to scan the pins connected to columns of the keypad. If it detects a logic 0
in any one of the columns, then a key press was made in that column. Once the column corresponding to the key
pressed is located, the next thing that the software has to do is to start writing logic 1’s to the rows sequentially
(one after the other) and check if those columns becomes high. The logic is that if a button in that row was pressed,
then the value written to that row will be reflected in the corresponding column as they are short circuited.
Once the pressed key is detected, the software sends a couple of values indicating the corresponding row and
column number, indicating the button pressed.
In our kit:
LCD connections are as follows:
VSS & K -> Gnd VDD & A -> VCC 5V V0 -> 10k pot center terminal
RS -> PC.12 EN -> PC.13
D0-> PB.8 D1-> PB.9 D2-> PB.10 D3-> PB.11
D4-> PB.12 D5-> PB.13 D6-> PB.14 D7-> PB.15
NOTE:
In the kit, ensure that the jumpers are connecting the 4x4 keypad side, as well as the 16x2 LCD Display
side. This is important to ensure that both the keypad and LCD Display are being used in the
experiment.
While writing the code, do not forget to include the extra libraries – the libraries “keypad4x4-
simultaneous-scanning.h” and “keypad4x4-simultaneous-scanning.c” which maps the keypad buttons to
the pins, and a library “delay.c” to include delay subroutines.
C - CODE:
#include <stdio.h>
#include "stm32f10x.h"
#include "keypad4x4-simultaneous-scanning.h"
int i,j,t;
static int ini_lcd=0;
uint8_t key;
{
data_lcd(*t);
t++;
}
}
int main(void)
{
OUTPUT:
We see that, upon execution, the 16x2 LCD Display indicates the button pressed, on the 4x4 pushbutton
grid. Whenever a button is pressed in the keypad, the corresponding button number is displayed on the LCD
display.
PROGRAM 6
Aim: To generate PWM waveform using the Internal PWM module of ARM controller and vary its
duty cycle.
Theory:
Pulse-width modulation (PWM), or pulse-duration modulation (PDM), is a modulation technique
used to encode a message into a pulsing signal. Although this modulation technique can be used to
encode information for transmission, its main use is to allow the control of the power supplied to
electrical devices, especially to inertial loads such as motors.
A PWM signal consists of two main components that define its behavior: a duty cycle and a
frequency. The duty cycle describes the amount of time the signal is in a high (on) state as a percentage
of the total time of it takes to complete one cycle. The frequency determines how fast the PWM
completes a cycle, and therefore how fast it switches between high and low states. By cycling a digital
signal off and on at a fast enough rate, and with a certain duty cycle, the output will appear to behave
like a constant voltage analog signal when providing power to devices.
PWM signals are used for a wide variety of control applications. Their main use is for controlling
DC motors but it can also be used to control valves, pumps, hydraulics, and other mechanical parts.
The STM32 Family processors include general purpose timers with PWM function that can handle
four channels of independently controlled duty cycles. There are three general purpose 16-bit Timers,
each with up to 4 PWM inputs, and a 16-bit motor control PWM timer. Here, we use the General
Purpose timer, TIM2 to generate PWM pulse.
TIM2 is connected to APB1 bus that has default system clock of 72MHz. So, the frequency of TIM2
is 72MHz. If we use a prescaler value of 10 (To be specified in TIM2 Configuration), the clock timer
will have a frequency of 72 MHz/10 = 7.2 MHz.
In order to calculate the On_Time for generating the PWM pulse with the given duty cycle, we use
the equation:
(𝑇𝐼𝑀𝐸_𝑃𝑒𝑟𝑖𝑜𝑑 + 1) ∗ 𝑑𝑢𝑡𝑦_𝑐𝑦𝑐𝑙𝑒
𝑇𝐼𝑀𝐸_𝑃𝑢𝑙𝑠𝑒_𝑂𝑛 = ( ) − 1
100
NOTE: In our Kit, the PWM Output is taken at PA0, where the CRO leads are connected. This
experiment has a code which varies the duty cycle of the PWM wave from 0-75%.
If a constant Duty Cycle has to be maintained, replace the while loop with a single value of i
corresponding to the required duty cycle as calculated above.
C - CODE:
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_tim.h"
void PWM_Init(void);
int main(void)
{
PWM_Init(); // Initialize PWM
int i = 0;
while (1)
{
while(i<=5399) //Cycle On-Time from 0-75%
{
TIM2->CCR1 = i; //Write On-Time value to TIM2 CCR
i+=100; //Increment On-Time by 100
Delay(10);
}
i=0; //Reset to 0
}
}
void PWM_Init() //PWM Initialization Subroutine
{
// Initialization Structure
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
TIM_OCInitTypeDef TIM_OCInitStruct;
GPIO_InitTypeDef GPIO_InitStruct;
OUTPUT:
Upon Execution of the program, it is observed that the CRO displays a PWM pulse train. The Duty
Cycle of the PWM pulse train varies from 0% to 75%, and this process repeats.
PROGRAM 7
Aim: To write a program to demonstrate the use of an external interrupt to toggle an LED
On/Off.
Theory:
There are two types of interrupts: hardware interrupts and software interrupts. Hardware interrupts
are used by devices to communicate that they require attention from the operating system. Unlike the
software type, hardware interrupts are asynchronous and can occur in the middle of instruction
execution. A software interrupt is caused either by an exceptional condition in the processor itself, or a
special instruction in the instruction set which causes an interrupt when it is executed. Software interrupt
instructions can function similarly to subroutine calls and are used for a variety of purposes, such as to
request services from device drivers, like interrupts sent to and from a disk controller to request reading
or writing of data to and from the disk.
The STM32F103xx performance line embeds a nested vectored interrupt controller able to handle
up to 43 maskable interrupt channels (not including the 16 interrupt lines of Cortex®-M3) and 16
priority levels. The external interrupt/event controller consists of 19 edge detector lines used to generate
interrupt/event requests. Each line can be independently configured to select the trigger event (rising
edge, falling edge, both) and can be masked independently. A pending register maintains the status of
the interrupt requests. The EXTI can detect an external line with a pulse width shorter than the Internal
APB2 clock period. Up to 80 GPIOs can be connected to the 16 external interrupt lines.
C - CODE:
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_exti.h"
void EXTI9_5_Init(void);
void wait(unsigned int nCount);
int main(void)
{
EXTI9_5_Init(); // Initialize exernal interrupt
RCC ->APB2ENR |= 0x04;
GPIOA ->CRH = 0x00000011;
while (1)
{
GPIOA->BRR = GPIO_Pin_8; //Default Blink LED
DelayMs(50);
GPIOA->BSRR = GPIO_Pin_8;
DelayMs(50);
}
}
void EXTI9_5_Init()
{
// Initalization struct
GPIO_InitTypeDef GPIO_InitStruct;
EXTI_InitTypeDef EXTI_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
OUTPUT:
We see that upon execution, the LED 1 keeps blinking by default, indicating normal operation. When
Pushbutton 2 is pressed, the LED 1 stops blinking, and LED 2 blinks 5 times, denoting interrupt
operation. Once this is done, LED 1 resumes blinking.
PROGRAM 8
Aim: To write a program to display the Hex digits 0 to F on a 7-segment LED interface, with
an appropriate delay in between.
Theory:
A seven-segment display (SSD), or seven-segment indicator, is a form of electronic display device
for displaying decimal numerals that is an alternative to the more complex dot-matrix displays. Seven-
segment displays are widely used in digital clocks, electronic meters, and other electronic devices for
displaying numerical information.
The 7-segment display, consists of seven LEDs arranged in a rectangular fashion as shown. Each of
the seven LEDs is called a segment because when illuminated the segment forms part of a numerical
digit (both Decimal and Hex) to be displayed. An additional 8th LED is sometimes used within the
same package thus allowing the indication of a decimal point, (DP) when two or more 7-segment
displays are connected together to display numbers greater than ten.
Each one of the seven LEDs in the display is given a positional segment with one of its connection
pins being brought straight out of the rectangular plastic package. These individually LED pins are
labelled from a through to g representing each individual LED. The other LED pins are connected
together and wired to form a common pin.
So, by forward biasing the appropriate pins of the LED segments in a particular order, some
segments will be light and others will be dark allowing the desired character pattern of the number to
be generated on the display. This then allows us to display each of the ten decimal digits 0 through to 9
on the same 7-segment display.
Depending upon the decimal digit to be displayed, the particular set of LEDs is forward biased. For
instance, to display the numerical digit 0, we will need to light up six of the LED segments
corresponding to a, b, c, d, e and f. Thus the various digits from 0 through 9 can be displayed using a
7-segment display as shown.
Then for a 7-segment display, we can produce a truth table giving the individual segments that need
to be illuminated in order to produce the required decimal digit from 0 through 9 as shown below.
Digit DP G F E D C B A Hex
0 1 1 1 0 0 0 0 0 C0
1 1 1 1 1 1 0 0 1 F9
2 1 0 1 0 0 1 0 0 A4
3 1 0 1 1 0 0 0 0 B0
4 1 0 0 1 1 0 0 1 99
5 1 0 0 1 0 0 1 0 92
6 1 0 0 0 0 0 1 0 82
7 1 1 1 1 1 0 0 0 F8
8 1 0 0 0 0 0 0 0 80
9 1 0 0 1 0 0 0 0 90
A 1 0 0 0 1 0 0 0 88
B 1 0 0 0 0 0 1 1 83
C 1 1 0 0 0 1 1 0 C6
D 1 0 1 0 0 0 0 1 A1
E 1 0 0 0 0 1 1 0 86
F 1 0 0 0 1 1 1 0 8E
NOTE: In our kit, in order to ensure that the 7-Segment LEDs are operational, jumpers should be
switched to the 7-Segment side, rather than the 16x2 LCD side.
C - CODE:
#include <stm32f10x.h>
int main()
{
RCC->APB2ENR = 0x08; //Port B
Result:
Upon execution of the program, the 7-Segment LED Display indicates hexadecimal numbers
from 0-F and cycles through them with a small delay in between.
PROGRAM 9
AIM: To write a program to Interface a simple Switch and display its status through Relay,
Buzzer and LED.
Theory:
BUZZER
Piezo buzzer is an electronic device commonly used to produce sound. Light weight, simple
construction and low price make it usable in various applications like car/truck reversing indicator,
computers, call bells etc. Piezo buzzer is based on the inverse principle of piezo electricity discovered
in 1880 by Jacques and Pierre Curie. It is the phenomena of generating electricity when mechanical
pressure is applied to certain materials and the vice versa is also true. Such materials are called piezo
electric materials. Piezo electric materials are either naturally available or manmade. Piezo ceramic is
class of manmade material, which poses piezo electric effect and is widely used to make disc, the heart
of piezo buzzer. When subjected to an alternating electric field they stretch or compress, in accordance
with the frequency of the signal thereby producing sound.
RELAY
A relay is an electrically operated switch. Many relays use an electromagnet to mechanically operate
a switch, but other operating principles are also used, such as solid-state relays. Relays are used where
it is necessary to control a circuit by a separate low-power signal, or where several circuits must be
controlled by one signal.
A type of relay that can handle the high power required to directly control an electric motor or other
loads is called a contactor. Solid-state relays control power circuits with no moving parts, instead using
a semiconductor device to perform switching. Relays with calibrated operating characteristics and
sometimes multiple operating coils are used to protect electrical circuits from overload or faults.
Magnetic latching relays require one pulse of coil power to move their contacts in one direction, and
another, redirected pulse to move them back. Repeated pulses from the same input have no effect.
Magnetic latching relays are useful in applications where interrupted power should not be able to
transition the contacts.
NOTE: In our kit, the Relay is connected to Pin 2 of Port C, Buzzer to Pin 3 of Port C, Push Button 1
is connected to Pin 4 of Port C, and Push Button 2 is connected to Pin 5 of Port C.
Hence, PC2 and PC3 have to be configured as outputs and PC4 and PC5 have to be configured as
Inputs.
C - CODE:
1. Relay Control
int main(void)
{
RCC ->APB2ENR |= 0x10 ; // PORT-C peripheral clock selected
// Set PC2 (Relay) as Output, and PC5 (Push Button 2) as Input
GPIOC ->CRL = 0x00400100;
while (1)
{
if((GPIOC ->IDR & (1<<5)) == 0 ) // Read the Push button data register
{
GPIOC ->BSRR = ~(1<<2); // Turn Relay On
}
else
{
GPIOC ->BSRR = (1<<2); // Turn Relay Off
}
}
}
2. Buzzer Control
int main(void)
{
RCC ->APB2ENR |= 0x10 ; // PORT-C peripheral clock selected
// Set PC3 (Buzzer) as Output, and PC4 (Push Button 1) as Input
GPIOC ->CRL = 0x00041000;
while (1)
{
if(GPIOC->IDR & GPIO_IDR_IDR4 )
{
GPIOC ->BSRR = (1<<3); //Turn Buzzer ON
}
else
{
GPIOC ->BSRR = ~(1<<3); //Turn Buzzer OFF
}
}
}
OUTPUT:
We observe that when Pushbutton 1 is pressed, the Buzzer is turned on, and when the button is
released, the buzzer turns off. When Push button 2 is pressed, the Relay is turned on, and the LED
glows. When the push button 2 is released, the Relay and LED are turned off.
PROGRAM 10
Aim: To write a program to measure Ambient temperature using a sensor and SPI ADC IC.
Theory:
Analog to Digital Converters (ADCs) are electronic devices that convert continuous analog signals such as
electric current into digital values. Two 12-bit analog-to-digital converters are embedded into STM32F103xx
performance line devices and each ADC shares up to 16 external channels, performing conversions in single-shot
or scan modes. An analog watchdog feature allows very precise monitoring of the converted voltage of one, some
or all selected channels. An interrupt is generated when the converted voltage is outside the programmed
thresholds. The Maximum ADC conversion rate is 1MHz and more than 2MHz in some STM32 families. It has
an A/D conversion range of 0 – 3.6V DC, and the ADC power supply operating range is 2.4V – 3.6V DC.
In the STM32 line of controllers, there are two modes of operation primarily. These are:
Independent mode. It is just as the typical ADC use. Each ADC unit is operating on its own and without any
mutual dependency.
Dual mode. In this mode two ADCs are converted simultaneously or with some (literally negligible) delay.
Two ADC units mutually working together as if they are a single unit.
To start A/D conversion, an ADC unit needs to be stimulated with a trigger signal:
Software Trigger. A/D conversion as per demand from coded program.
Hardware Trigger. A/D conversion as per hardware events like external interrupts or timer events.
In our code, we use our ADC 1 in independent mode, with continuous conversion occurring, with a software
trigger.
Since the analog signal can take values from 0-3.3 V, and since the ADC resolution is 12 bits (4096 intervals), the
corresponding digital value for the measured analog input is by:
3.3 𝑉
𝐷𝑖𝑔𝑖𝑡𝑎𝑙 𝑉𝑎𝑙𝑢𝑒 = 𝐴𝑛𝑎𝑙𝑜𝑔 𝑉𝑎𝑙𝑢𝑒 ∗ 4095
NOTE: In our kit, the LM35 Temperature Sensor Module has to be connected to the Temp section. UART
protocol is used to transmit the data to the serial window, and as a result, a serial window monitoring application
like PuTTy has to be used.
C - CODE:
#include <stdio.h>
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_adc.h"
//Calibrate ADC
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
ADC_Cmd(ADC1, ENABLE); //Enable ADC to work
int main(void)
{
float x;
RCC->APB2ENR = RCC_APB2ENR_IOPAEN ;
RCC->APB1ENR = RCC_APB1ENR_USART2EN;
GPIOA->CRL = 0x00004B00; // 0100 ->3 1011 ->2 0000->1 0000->0
USART2->CR1 = USART_CR1_UE | USART_CR1_TE;
USART2->BRR = (SystemCoreClock / (9600*2)); // baud rate change
adc_config(); //configure ADC
while(1)
{
x = getADC()*3.3/4095.0; //Get analog value and convert to volts, 12bit ADC
float temp= x/0.01; // Convert to Temperature
printf("Temperature Value-> %.2f\n\r",temp);
delay(40);
}
}
RESULTS:
Upon execution of the program, it is observed that the temperature value sensed by the LM35 unit is displayed
continuously in the Serial Monitoring window, which can be viewed using a suitable application like PuTTY.
CODE:
AREA RESET, DATA, READONLY
EXPORT __Vectors
__Vectors
DCD 0x20001000 ; stack pointer value when stack is empty
DCD Reset_Handler ; reset vector
ALIGN
AREA MYCODE, CODE, READONLY
ENTRY
EXPORT Reset_Handler
Reset_Handler
MOV R0, #0 ; R0 accumulates total
MOV R1, #10 ; R1 counts from 10 down to 1
again ADD R0, R0, R1
SUBS R1, R1, #1
BNE again
halt B halt ; infinite loop to stop computation
CODE:
AREA RESET, DATA, READONLY
EXPORT __Vectors
__Vectors
DCD 0x20001000 ; stack pointer value when stack is empty
DCD Reset_Handler ; reset vector
ALIGN
AREA MYCODE, CODE, READONLY
ENTRY
EXPORT Reset_Handler
Reset_Handler
MOV R0, 0x4 ; R0 accumulates total
MOV R1, 0x1
again MUL R3, R0, R1
halt B halt ; infinite loop to stop computation