K. S. SCHOOL OF ENGINEERING & MANAGEMENT # 15, Mallasandra, Off Kanakapura Road, Bangalore-560109, Karnataka, India.
DEPARTMENT OF ELECTRONICS & COMMUNICATION ENGINEERING
Embedded Embedded Controllers Lab Manual Sub Code: 15ECL67 Sem : VI Prepared by
Mr. Ravikiran B. A. Asst. Professor, Dept of ECE
Table of Contents About the STM32F103RB microcontroller.
.............................................. 1
Part A: Experiments written using Embedded C 1. Display of Message using Internal UART ................................................. 5 2. DC Motor Interface ............................................................................ ............................................................................7 3. Stepper Motor Interface .......................................................................9 4. Waveform Generation using DAC ........................................................ 11 5. Keypad and LCD Interface ................................................................. 17 6. PWM Generation using Internal PWM
................................................. 21
7. LED control using External Interrupts .................................................. 24 8. 7-Segment LED Display ..................................................................... 27 9. Switch Control of Buzzer, Relay and LED .............................................. 30 10. Temperature Measurement using ADC
................................................. 32
Part B: Exercises with Programs written using ALP Code 11. ALP to Find the Sum of First 10 Numbers .............................................. 35 12. ALP to Find the Product of two 16-bit Numbers
...................................... 36
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
About the STM32F103RB microcontroller.
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 STM32F103RB MCU, supports Arduino and ST morpho connectivity.
STM32 Key Features • • •
STM32 microcontroller in LQFP64 package External SMPS to generate Vcore logic supply (only available on '-P' suffixed boards) 1 user LED shared with Arduino™
• •
1 user and 1 reset push-buttons 32.768 kHz LSE crystal oscillator
Board expansion connectors:
Arduino™ Uno V3
ST Morpho extension pin headers for full access to all STM32 I/O's
External SMPS experimentation dedicated connector Flexible power-supply options: ST-LINK USB VBUS or external sources On-board ST-LINK/V2-1 debugger/programmer with USB re-enumeration capability.
STM32F103RB Features: • • •
•
•
• • • •
ARM® 32-bit Cortex®-M3 CPU Core – Core – 72 72 MHz maximum frequency, Single-cycle Single-cycle multiplication and hardware division Memories 64 or 128 Kbytes of Flash memory 20 Kbytes of SRAM Clock, reset and supply management: 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, bit, 1 μs A/D converters converters (up to 16 channels) channels) Conversion range: 0 to 3.6 V Dual-sample Dual-sample and hold capability Temperature sensor Peripherals supported: timers, ADC, SPIs, I2Cs and USARTs Up to 80 fast I/O ports – ports – 26/37/51/80 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) (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 modem control) Up to 2 SPIs (18 Mbit/s) CAN interface (2.0B Active) USB 2.0 full-speed full -speed interface
Dept of ECE, KSSEM
1
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
The STM32F103RB has 51 GPIO pins available to the user, in 4 groups – groups – Port 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. The basic GPIO setup procedure is as follows:
Step 1: Configure the Clock Register for the Port to be Used In this step, we are configuring the clock registers, and enabling the clock registers for the specific GPIO ports that we will be using. The Register structure is as shown: APB2 Peripheral Clock Control Register: (RCC_APB2ENR):
Dept of ECE, KSSEM
2
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
Step 2: Configure the Port Configuration Registers. Once the Port has been enabled, and the clock registers configured for the same, the next step is to specify the particular pins that would be used, and also indicate the t he mode and configuration for each of the pins. This is done by setting or resetting the corresponding bits in the Port configuration Register. The Port Configuration Register consists of two 32-bit registers – GPIOx_CRL GPIOx_CRL (Pin 0 – 0 – Pin Pin 7) and GPIOx_CRH (Pin 8 – 8 – Pin Pin 15). Each pin in the register is configured using 4 consecutive bits.
The structure of the CRH and CRL registers is as shown:
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: For instance, consider Pin 0 in CRL (bits 0 to 3):
The Pin configuration and Mode selection bits are as shown:
Dept of ECE, KSSEM
3
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
Step 3: Write data into the Data Register (ODR) Once the ports and pins have been configured, we now can read data into the microcontroller through the input pins, or write data from the microcontroller through the output data pins, by making use of the Data Register. The Data Register is 32 bits long, out of which the lower 16 bits are usable. Each of these bits (150) indicate the status of the signal on the corresponding GPIO pins in the selected port. An Example of the Port Output Data Register (GPIOx_ODR) is as shown:
In our kit, there are some 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)
Dept of ECE, KSSEM
4
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
PROGRAM 1 Display of Message using Internal UART Aim: To Display “Hello World” message using Internal UART Theory:
A universal asynchronous asynchronous receiver-transmitter receiver-transmitter (UART) is a computer hardware device for asynchronous for asynchronous serial communication communication in which the data format and transmission speeds are configurable. The electric signaling levels and methods are handled by a driver circuit external to the UART. In UART communication, two UARTs communicate directly with each other. The transmitting UART converts parallel data from a controlling device like a CPU into serial form, transmits it in serial to the receiving UART, which then converts the serial data back into parallel data for the receiving device. Only two wires are needed to transmit data between two UARTs. Data flows from the Tx pin of the transmitting UART to the Rx pin of the receiving UART. UARTs transmit data asynchronously, which means there is no clock signal to synchronize the output of bits from the transmitting UART to the sampling of bits by the receiving UART. Instead of a clock signal, the transmitting UART adds start and stop bits to t o the data packet being transferred. These bits define the beginning beginning and and end of the data packet so the receiving UART knows knows when when to start reading reading the bits. When the receiving UART detects a start bit, it starts t o read the incoming bits at a specific frequency frequency known as the baud rate. Baud rate is a measure of the speed of data transfer, expressed in bits per second (bps). Both UARTs must operate at about the same baud rate. The baud rate between the transmitting and receiving UARTs can only differ by about 10% before the timing of bits gets too far off. Both UARTs must be configured to transmit and receive the same data packet structure.
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 back into parallel form and removes the start bit, parity bit, bi t, and stop bits. Finally, the receiving UART transfers the data packet in parallel to the data data bus on the receiving 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.
Dept of ECE, KSSEM
5
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
C - CODE: #include #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 USART_PutChar(uint8_t ch) //USART Print Subroutine { while(!(USART2->SR while(!(USART2->SR & USART_SR_TXE)); USART_SR_TXE)); USART2->DR = ch; // Write text to USART Data Register } void USART_PutString(uint8_t USART_PutString(uint8_t * str) { while(*str != 0) { USART_PutChar(*str); USART_PutChar(*str); //Send string str++; } } int main(void) { RCC->APB2ENR = RCC_APB2ENR_IOPAEN RCC_APB2ENR_IOPAEN ; //IO port declaration RCC->APB1ENR = RCC_APB1ENR_USART2EN; RCC_APB1ENR_USART2EN; //USART declaration GPIOA->CRL GPIOA->CR L = 0x00004B00; //0100 ->3 1011 ->2 0000->1 0000->0 USART2->CR1 = USART_CR1_UE | USART_CR1_TE; USART_CR1_TE; USART2->BRR = (SystemCoreClock / (9600*2)); (9600*2)); // baud rate change while (1) { USART_PutString(text); delay(10); } } void delay(int time) { int i,j; for(i=0;i<=time;i++) { for(j=0;j<=72000;j++); } } 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.
Dept of ECE, KSSEM
6
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
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 i n tools, toys, and appliances. appliances.
The very basic construction basic construction of a DC motor contains a current a current carrying armature which is connected to the supply end through commutator segments segments and brushes. The armature is placed in between north south poles of a permanent permanent or an electromagnet 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, perpendicularly, then the conductor conductor experiences experiences a force in the direction direction mutually mutually perpendicular perpendicular to both the direction of field and the current carrying conductor. In a typical DC motor, there are permanent magnets magnets on the outside and a spinning armature on the inside. The permanent 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. electromagnet. The brushes handle this change in polarity. They make contact with two spinning electrodes attached attached to the armature and flip the magnetic polarity of the electromagnet as it spins. Motor Driver L293D
A motor driver is an integrated circuit chip which is usually used to control motors. L293D is a dual H-bridge 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.
Dept of ECE, KSSEM
7
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
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" 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 Pin 8-11 as O/P GPIOC->ODR = 0x0000; // Clear ODR // Use DC Motor Control on Pins 10-11 while (1) { GPIOC->ODR = 0x0100; delay(300); GPIOC->ODR = 0x0000; delay(30); GPIOC->ODR = 0x0200; delay(300); GPIOC->ODR = 0x0000; delay(30); }
// Rotate // stop // Reverse Direction Direction // Stop
} RESULT: Upon execution of the program the DC motor connected to the kit is seen to rotate in both clockwise and anticlockwise directions alternatively.
Dept of ECE, KSSEM
8
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
PROGRAM 3 Stepper Motor Interface 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 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 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. 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 t eethed 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++); } }
Dept of ECE, KSSEM
9
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
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.
Dept of ECE, KSSEM
10
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
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; architectures; the suitability of 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 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 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. The connections to the STM32F103RB is as shown:
MOSI
MOSI
MISO
MISO
SCK
STM32F103RB
SCK
MCP4921
The STM32F103RB communicates with the MCP4921 DAC through SPI protocol, which involves 4 logical signal lines: 1. Master Output Slave Input (MOSI) – (MOSI) – Data Data flows from Master to Slave 2. Master Input Slave Output (MISO) – (MISO) – Data Data flows from Slave to t o Master 3. Chip Select (CS) – (CS) – Low Low on this pin selects a particular chip 4. SCK – SCK – Serial Serial Clock – Clock – Used Used to synchronize data transfer transfer In the Kit, the connections to the DAC IC are as follows: Vcc – Vcc – 3.3 3.3 V of the Arduino Header GND – GND – GND GND of Arduino Header MOSI – MOSI – MOSI MOSI pin (Arduino Header D11 pin) CS – CS – Analog Analog I/O pin A2 of Arduino Header SCK – SCK – SCK SCK Pin of Arduino Header (D13)
Dept of ECE, KSSEM
11
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
The Output is taken from Vout and GND pins of the DAC Chip, which are connected to the leads of the CRO unit. The Write Command Register of the DAC chip is as shown:
We see that the first 4 bits (15-12) are the control bits, while t he 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 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 SPI1_Transfer(uint8_t data); //8-bit SPI data uint16_t DAC_write(uint16_t); DAC_write(uint16_t); //16-bit value to DAC void int_spi() //SPI Configuration { //Configure SPI:Enable SPI:Enable AFIO | SPI1 SPI1 | IOPA RCC->APB2ENR = 0x0001 | 0x1000 | 0x0004; //0x1005 //0x1005 GPIOA->CRL= 0xB4B30000; // DAC Pinouts //PA4 -> CS (Analog O/P) = 0011 (3) //PA5 -> SCK (Alt Fn O/P) = 1011 (B) //PA6 -> MISO (Floating Input) = 0100 (4) //PA7 -> MOSI (Alt Fn O/P) = 1011 (B) SPI1->CR1=0x00000374; }
Dept of ECE, KSSEM
12
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
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; } } } uint8_t SPI1_Transfer(uint8_t SPI1_Transfer(uint8_t data) //SPI1 Data Transfer Subroutine { SPI1->DR = data; // Write data to be transmitted to the SPI data register while (!(SPI1->SR & (0x0002))); // Wait until transmit complete while (!(SPI1->SR & (0x0001))); // Wait until receive complete while (SPI1->SR & (0x0080)); // Wait until SPI is not busy anymore return SPI1->DR; // Return received data from SPI data register } void DelayMs(int time) //Delay Subroutine { int i,j; for(i=0;i<=time;i++) { for(j=0;j<=3900;j++); } } void select() { GPIOA->BRR = 0x0010; } void deselect() { GPIOA->BSRR = 0x0010; } uint16_t DAC_write(uint16_t DAC_write(uint16_t valueDAC) {
Dept of ECE, KSSEM
//DAC Write Subroutine
13
Embedded Controller Control ler Lab (15ECL67)
uint16_t temp; uint8_t t; // Send Higher order Byte temp = valueDAC; temp = temp|0x7000; temp|0x7000; select(); t = ((temp >> 8) & 0xff); SPI1_Transfer(t);
6th Sem ECE
KSSEM, Bangalore
//Declare 16-bit Value temp //Declare 8-bit value t
// Data to be written // Prepend 4 control bits to data // select MCP4921 //Shift MS bytes to LS bytes // Write MS byte to DAC via SPI
// Send Lower Order Byte t = valueDAC; //Load only LSB 8 bits to value SPI1_Transfer(t); //Write LSB byte to DAC deselect(); // Deselect MCP4921 }
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); DAC_write(uint16_t); //16-bit value to DAC void int_spi() //SPI Configuration { //Configure SPI:Enable SPI:Enable AFIO | SPI1 SPI1 | IOPA RCC->APB2ENR = 0x0001 | 0x1000 | 0x0004; //0x1005 //0x1005 GPIOA->CRL= 0xB4B30000; // DAC Pinouts //PA4 -> CS (Analog O/P) = 0011 (3) //PA5 -> SCK (Alt Fn O/P) = 1011 (B) //PA6 -> MISO (Floating Input) = 0100 (4) //PA7 -> MOSI (Alt Fn O/P) = 1011 (B) SPI1->CR1=0x00000374; } int main() { int i,j; int_spi(); deselect(); while(1) { // Code to generate Square Waveform DAC_write(4095); DelayMs(2); DAC_write(0);
Dept of ECE, KSSEM
14
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
DelayMs(2); } } uint8_t SPI1_Transfer(uint8_t SPI1_Transfer(uint8_t data) //SPI1 Data Transfer Subroutine { SPI1->DR = data; // Write data to be transmitted to the SPI data register while (!(SPI1->SR & (0x0002))); // Wait until transmit complete while (!(SPI1->SR & (0x0001))); // Wait until receive complete while (SPI1->SR & (0x0080)); // Wait until SPI is not busy anymore return SPI1->DR; // Return received data from SPI data register } void DelayMs(int time) //Delay Subroutine { int i,j; for(i=0;i<=time;i++) { for(j=0;j<=3900;j++); } } void select() { GPIOA->BRR = 0x0010; } void deselect(){ GPIOA->BSRR = 0x0010; } uint16_t DAC_write(uint16_t DAC_write(uint16_t valueDAC) //DAC Write Subroutine { uint16_t temp; //Declare 16-bit Value temp uint8_t t; //Declare 8-bit value t // Send Higher order Byte temp = valueDAC; temp = temp|0x7000; temp|0x7000; select(); t = ((temp >> 8) & 0xff); SPI1_Transfer(t);
// Data to be written // Prepend 4 control bits to data // select MCP4921 //Shift MS bytes to LS bytes // Write MS byte to DAC via SPI
// Send Lower Order Byte t = valueDAC; //Load only LSB 8 bits to value SPI1_Transfer(t); //Write LSB byte to DAC deselect(); // Deselect MCP4921 }
Dept of ECE, KSSEM
15
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
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.
Dept of ECE, KSSEM
16
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
PROGRAM 5 Keypad and LCD Interface
Aim: To write a program to Interface a 4x4 keyboard ke yboard 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 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 t he values you're reading when you read. • There's also a display contrast pin (Vo), power supply pins (+5V and Gnd) and LED Backlight -) pins that you can use to power the LCD, control the display contrast, and (Bklt+ and BKlt -)
turn on and off the LED backlight, respectively.
4x4 Matrix Keypad Typically one port pin is required to read a digital input into the controller. When there are a lot of digital inputs that have to be read, it is not feasible to allocate one pin for each of them. This is when a matrix keypad arrangement arrangement is used to reduce the pin count. Therefore, the number of pins that are required to interface a given number of inputs decreases with increase in the order of t he matrix. 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 l ogic, the button press can be detected.
Dept of ECE, KSSEM
17
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
The first step involved in interfacing the matrix keypad 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 llogic ogic 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
Keypad Connections are as follows: Keypad Columns: KEYPAD_PIN_COL0 -> PC.7 KEYPAD_PIN_COL2 -> PC.5 Keypad Rows: KEYPAD_PIN_ROW0 ->PC.3 KEYPAD_PIN_ROW2 ->PC.1
KEYPAD_PIN_COL1 -> PC.6 KEYPAD_PIN_COL3 -> PC.4 KEYPAD_PIN_ROW1 ->PC.2 KEYPAD_PIN_ROW3 ->PC.0
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 – libraries – the the libraries “keypad4x4“keypad4x4simultaneous-scanning.h”” and “keypad4x4-simultaneous-scanning. simultaneous-scanning.h “keypad4x4-simultaneous-scanning.c” c” which maps the keypad buttons to the pins, and a library “delay.c” to include delay subroutines.
Dept of ECE, KSSEM
18
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
C - CODE: #include #include "stm32f10x "st m32f10x.h" .h" #include "keypad4x4-simultaneo "keypad4x4-simultaneous-scanning.h" us-scanning.h" int i,j,t; static int ini_lcd=0; uint8_t key; void delay(int time) { for(i=0;i<=time;i++) { int j; for(j=0;j<=64000;j++); } } void command_lcd(unsigned char cmd) { GPIOC->ODR = 0x2000; // rs=0 en=1 0010 0000 0000 0000 t=(cmd<<8)& (0xFF00); GPIOB->ODR = t; delay(10); GPIOC->ODR = 0x0000; // rs=0 rw=0 en=0 } void data_lcd(unsigned char data) { GPIOC->ODR = 0x3000; t=(data<<8)& (0xFF00); GPIOB->ODR = t; delay(10); GPIOC->ODR = 0x1000; delay(10); }
// rs=1 rw=0 en=1 0011 0000 0000 0000
// rs=1 rw=0 en=0 0001 0000 0000 0000
void lcd_ini() //Function to prepare the LCD and get it ready { command_lcd(0x38); // for using 2 lines lines and 16x2 matrix of LCD delay(20); command_lcd(0x0F); command_lcd(0x0F); // turn display ON, cursor blinking delay(20); command_lcd(0x01); //clear screen delay(20); command_lcd(0x80); // bring cursor to position position 1 of line 1 delay(20); } void string_lcd(unsigned char* t) { while(*t != '\0')
Dept of ECE, KSSEM
19
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
{ data_lcd(*t); t++; } } int main(void) { //RCC - Reset and Clock Control // 0x14 in binary = 00010100 = [0001][0100] [0001][0100] = [IOPF IOPE IOPD IOPC IOPB IOPA Res. AFIO] RCC ->APB2ENR |= 0x10 | 0x08; //CRH - Port Configuration Register High *pins 8-15 GPIOC ->CRH= 0x00110000; //for RS and ES //CRL- Port Configuration Register High *pins 8-15 GPIOB ->CRH = 0x11111111; //for LCD KeypadInit(); if(ini_lcd==0) lcd_ini(); ini_lcd++; command_lcd(0x80); string_lcd("Tenet Tech"); command_lcd(0xC0); string_lcd("Press Key-> "); while(1) { key = KeypadGetKey(); // Display pressed char to LCD if (key != KEYPAD_NO_PRESSED) KEYPAD_NO_PRESSED) { command_lcd(0xCC); data_lcd(key); delay(5); command_lcd(0x01); //clear screen } } }
OUTPUT: We see that, upon execution, execution, the 16x2 LCD Display indicates the button 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.
Dept of ECE, KSSEM
20
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
PROGRAM 6 PWM Generation using Internal PWM
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 modulation technique t echnique 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 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 describes the amount of time the signal is in a high hi gh (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 t he 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. The PWM frequency can be calculated by:
= _ + 1 – 1 _ = _ =
Hence, the total time period of the pulse (Ton + Toff ) is calculated as:
Where Timer Clock = 7.2 MHz. If PWM frequency = 1 kHz, we get:
Dept of ECE, KSSEM
(To be specified in TIM2 Config).
21
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
In order to calculate the On_Time for generating the PWM pulse with the given duty cycle, we use the equation:
+ 1 ∗ _ ) − 1 __ = (_ 100
So, for 25% duty cycle, we get:
+ 1 ∗ 25 − 1 = __= 7199 100 + 1 ∗ 50 − 1 = __= 7199 100
So, for 50% duty cycle, we get:
So, for 75% duty cycle, we get:
+ 1 ∗ 25 − 1 = __= 7199 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" "stm32f10x_rcc.h" #include "stm32f10x_gpio.h" "stm32f10x_gpio.h" #include "stm32f10x_tim.h" "stm32f10x_tim.h" void PWM_Init(void); void Delay(int time) //Delay Subroutine { int i,j; for(i=0;i<=time;i++) { for(j=0;j<=72000;j++); } } int main(void) { PWM_Init(); int i = 0; while (1) { while(i<=5399) while(i<=5399) { TIM2->CCR1 = i; i+=100; Delay(10); }
Dept of ECE, KSSEM
// Initialize PWM
//Cycle On-Time from 0-75% //Write On-Time value to TIM2 CCR //Increment On-Time by 100
22
Embedded Controller Control ler Lab (15ECL67)
i=0;
6th Sem ECE
KSSEM, Bangalore
//Reset to 0
} } void PWM_Init() //PWM Initialization Subroutine { // Initialization Structure TIM_TimeBaseInitTypeDef TIM_TimeBaseInitTypeD ef TIM_TimeBaseInitStruct; TIM_OCInitTypeDef TIM_OCInitStruct; GPIO_InitTypeDef GPIO_InitStruct; // Step 1: Initialize TIM2 RCC_APB1PeriphClockCmd(RCC_APB1Periph_T RCC_APB1PeriphClock Cmd(RCC_APB1Periph_TIM2, IM2, ENABLE); TIM_TimeBaseInitStruct.TIM_Prescaler TIM_TimeBaseInitStruct. TIM_Prescaler = 10; TIM_TimeBaseInitStruct.TIM_Period TIM_TimeBaseInitStruct. TIM_Period = 7199; TIM_TimeBaseInitStruct.TIM_ClockDivision TIM_TimeBaseInitStruct. TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInitStruct.TIM_CounterMode TIM_TimeBaseInitStruct. TIM_CounterMode = TIM_CounterMode_Up TIM_CounterMode_Up;; TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct); TIM_Cmd(TIM2, ENABLE); // Start TIM2 // Step 2: Initialize PWM // Common PWM settings TIM_OCInitStruct.TIM_OCMode TIM_OCInitStruct.TIM_OC Mode = TIM_OCMode_PWM1; TIM_OCInitStruct.TIM_OutputState TIM_OCInitStruct.TIM_Ou tputState = TIM_OutputState_Enab TIM_OutputState_Enable; le; TIM_OCInitStruct.TIM_OCPolarity TIM_OCInitStruct.TIM_OC Polarity = TIM_OCPolarity_High; TIM_OCPolarity_High; // Initialize PWM value with duty cycle of 0% TIM_OCInitStruct.TIM_Pulse TIM_OCInitStruct.TIM_Pu lse = 0; TIM_OC1Init(TIM2, &TIM_OCInitStruct); TIM_OC1PreloadConfig(TIM2, TIM_OC1PreloadConfi g(TIM2, TIM_OCPreload_Enable); // Step 3: Initialize GPIOA (PA0) // Initialize PA0 as push-pull alternate function (PWM output) for LED RCC->APB2ENR=0x04; RCC->APB2ENR=0x04; // Use LED brightness as indicator GPIOA->CRL=0x0A; }
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.
Dept of ECE, KSSEM
23
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
PROGRAM 7 LED control using External Interrupts
Aim: To write a program to demonstrate the use of an external interrupt to toggle an LED On/Off. Theory: In system programming, an interrupt is a signal to the processor emitted by hardwar e hardwar e or software indicating an event that needs immediate attention. An interrupt alerts the processor to a high-priority condition requiring the interruption of the current code the processor is executing. The processor responds by suspending its current activities, saving its state, and executing a function called an interrupt handler (or an interrupt service routine, ISR) to deal with the event. This interruption i s temporary, and, after the interrupt handler finishes, the processor resumes normal activities. The act of initiating a hardware interrupt is referred to as an i nterrupt request (IRQ). 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. levels. The The external external interrupt/event controller consists of 19 edge detector lines used used to generate generate interrupt/event requests. Each line can be independently configured to select the trigger event (rising edge, falling edge, both) and can be masked 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" "stm32f10x_rcc.h" #include "stm32f10x_gpio.h" "stm32f10x_gpio.h" #include "stm32f10x_exti.h" "stm32f10x_exti.h" void DelayMs(int time) //Delay Subroutine { int i,j; for(i=0;i<=time;i++) { for(j=0;j<=64000;j++); } } void EXTI9_5_Init(void); void wait(unsigned int nCount);
Dept of ECE, KSSEM
24
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
void EXTI9_5_IRQHandler(void) EXTI9_5_IRQHandler(void) //Interrupt Handler { // Checks whether the interrupt is from EXTI12 or not if (EXTI_GetITStatus(EXT (EXTI_GetITStatus(EXTI_Line6)) I_Line6)) { // Blink LED on PA9 5 times tim es int i; for (i = 0; i < 5; i++) { GPIOA->BSRR = GPIO_Pin_9; GPIO_Pin_9; DelayMs(30); GPIOA->BRR = GPIO_Pin_9; DelayMs(30); } EXTI_ClearITPendingBit(EXTI_Line6); } } int main(void) { EXTI9_5_Init(); // Initialize exernal exernal interrupt interrupt RCC ->APB2ENR |= 0x04; GPIOA ->CRH = 0x00000011; 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; // Initialize PB6 as input with pull-up resistor RCC_APB2PeriphClockCmd(RCC_APB2Periph_G RCC_APB2PeriphClock Cmd(RCC_APB2Periph_GPIOC, PIOC, ENABLE); GPIO_InitStruct.GPIO_Pin GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6; GPIO_InitStruct.GPIO_Mode GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; GPIO_InitStruct.GPIO_Speed GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Speed_2MHz; GPIO_Init(GPIOC, &GPIO_InitStruct); // Initialize PB6 to EXTI RCC_APB2PeriphClockCmd(RCC_APB2Periph_AF RCC_APB2PeriphClock Cmd(RCC_APB2Periph_AFIO, IO, ENABLE); GPIO_EXTILineConfig(GPIO_PortSo GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, urceGPIOC, GPIO_PinSource6); GPIO_PinSource6);
Dept of ECE, KSSEM
25
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
// Initialize EXTI line 6 for PB6 EXTI_InitStruct.EXTI_Line EXTI_InitStruct.EXTI_Lin e = EXTI_Line6; EXTI_InitStruct.EXTI_Mode EXTI_InitStruct.EXTI_Mo de = EXTI_Mode_Interrupt; EXTI_InitStruct.EXTI_Trigger EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling; EXTI_Trigger_Falling; EXTI_InitStruct.EXTI_LineCmd EXTI_InitStruct.EXTI_Lin eCmd = ENABLE; EXTI_Init(&EXTI_InitStruct); // Initialize NVIC for EXTI9_5 IRQ channel NVIC_InitStruct.NVIC_IRQChannel NVIC_InitStruct.NVIC_IRQChan nel = EXTI9_5_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd NVIC_InitStruct.NVIC_IRQChan nelCmd = ENABLE; NVIC_Init(&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.
Dept of ECE, KSSEM
26
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
PROGRAM 8 7-Segment LED Display
Aim: To write a program to display the Hex digits 0 t o 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 display device for displaying decimal numerals that is an alternative to the more complex dot-matrix displays. Sevensegment 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 it s connection pins being brought straight straight out of the rectangular rectangular plastic package. These These individually LED 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 generated on the display. This then allows us to display each each of the ten decimal decimal digits 0 through to 9 on the same 7-segment 7-segment display. 7-segement 7-segement LED displays are of two types: Common Anode (CA), where all the anode connections of the LED segments are joined together to logic “1”. The individual segments are illuminated by applying a ground, logic “0” or “LOW” signal via a suitable current limiting resistor resistor to the Cathode of the particular segment. This is the type used in our kit. Common Cathode (CC), where all the cathode connections of the LED segments are joined together to logic “0” or ground. The individual segments are illuminated by application of a “HIGH”, “HIGH”, or logic “1” signal via a current limiting resistor to forward bias the i ndividual Anode terminals
Dept of ECE, KSSEM
27
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
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 t able 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 0 1 2 3 4 5 6 7 8 9 A B C D E F
DP 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
G 1 1 0 0 0 0 0 1 0 0 0 0 1 0 0 0
F 1 1 1 1 0 0 0 1 0 0 0 0 0 1 0 0
E 0 1 0 1 1 1 0 1 0 1 0 0 0 0 0 0
D 0 1 0 0 1 0 0 1 0 0 1 0 0 0 0 1
C 0 0 1 0 0 0 0 0 0 0 0 0 1 0 1 1
B 0 0 0 0 0 1 1 0 0 0 0 1 1 0 1 1
A 0 1 0 0 1 0 0 0 0 0 0 1 0 1 0 0
Hex C0 F9 A4 B0 99 92 82 F8 80 90 88 83 C6 A1 86 8E
NOTE: In our kit, in order to ensure that the 7-Segment 7-Segment LEDs are operational, jumpers should be switched to the 7-Segment side, rather than the 16x2 LCD side.
C - CODE: #include void delay(int time) //Delay Subroutine { int i,j; for(j=0;j<=time;j++) { for(i=0;i<=72000;i++); } } int main() { RCC->APB2ENR = 0x08;
Dept of ECE, KSSEM
//Port B
28
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
GPIOB->CRH=0X11111111; GPIOB->CRH=0X11111111; //Enable all pins GPIOB->ODR = 0x00000000; 0x00000000; //Clear LED Display delay(100); while(1) { GPIOB->ODR = 0xC000; //Hex for displaying 0 delay(100); GPIOB->ODR = 0xF900; 0xF900; // Hex for displaying 1 delay(100); GPIOB->ODR = 0xA400; // Hex for displaying 2 delay(100); GPIOB->ODR = 0xB000; // Hex for displaying 3 delay(100); GPIOB->ODR = 0x9900; // Hex for displaying 4 delay(100); GPIOB->ODR = 0x9200; // Hex for displaying 5 delay(100); GPIOB->ODR = 0x8200; // Hex for displaying 6 delay(100); GPIOB->ODR = 0xf800; // Hex for displaying 7 delay(100); GPIOB->ODR = 0x8000; // Hex for displaying 8 delay(100); GPIOB->ODR = 0x9000; // Hex for displaying 9 delay(100); GPIOB->ODR = 0x8800; // Hex for displaying A delay(100); GPIOB->ODR = 0x8300; // Hex for displaying B delay(100); GPIOB->ODR = 0xC600; // Hex for displaying C delay(100); GPIOB->ODR = 0xa100; // Hex for displaying D delay(100); GPIOB->ODR = 0x8600; // Hex for displaying E delay(100); GPIOB->ODR = 0x8e00; // Hex for displaying F delay(100); } }
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.
Dept of ECE, KSSEM
29
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
PROGRAM 9 Switch Control of Buzzer, Relay and LED
AIM: To write a program to Interface a simple Switch and display its stat us 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 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 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 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 #include "stm32f10x.h" // device device header header file 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;
Dept of ECE, KSSEM
30
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
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 #include "stm32f10x.h" // device device header header file int main(void) { RCC ->APB2ENR |= 0x10 0x10 ; // PORT-C 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); } else { GPIOC ->BSRR = ~(1<<3); }
//Turn Buzzer ON
//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.
Dept of ECE, KSSEM
31
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
PROGRAM 10 Temperature Measurement using ADC
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 analog signals such as electric current into digital values. Two 12-bit analog-to-digital converters are embedded into STM32F103xx performance performance line devices devices and each ADC shares up to 16 external external channels, performing 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 – 0 – 3.6V 3.6V DC, and the ADC power supply operating range is 2.4V – 2.4V – 3.6V 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 simultaneously or with some (literally negligible) delay. Two ADC units mutually working together as if they are a single unit.
A/D conversion can be: Single Conversion. One sample conversion at a given instant. sample collection and and conversion. Continuous Conversion. Non-stop sample conversion of some channels in a group. Discontinuous Conversion. Conversion. Sequential conversion Scan Conversion. Sequential Sequential sampling and converting of an array of channels one after another.
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 i ntervals), the corresponding digital value for the measured analog input is by:
== ∗∗ 3.43 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 data to the serial serial window, and as as a result, a serial window monitoring monitoring application application like PuTTy has to be used.
Dept of ECE, KSSEM
32
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
C - CODE: #include #include "stm32f10x.h" #include "stm32f10x_rcc.h" "stm32f10x_rcc.h" #include "stm32f10x_gpio.h" "stm32f10x_gpio.h" #include "stm32f10x_adc.h" "stm32f10x_adc.h" int USART_PutChar(int ch); void delay(int time); struct __FILE { int handle;}; FILE __stdout; FILE __stdin; int fputc(int c, FILE *f) //USART Character Write subroutine { return (USART_Put ( USART_PutChar(c)); Char(c)); } void _ttywrch(int c) { USART_PutChar(c); }
//This function writes a character to the console
// Creating GPIO and ADC objects GPIO_InitTypeDef myGPIO; ADC_InitTypeDef myADC; int USART_PutChar(int USART_PutChar(int ch) //Send Character to USART { while(!(USART2->SR while(!(USART2->SR & USART_SR_TXE)); USART_SR_TXE)); USART2->DR = ch; } void adc_config() //ADC Configuration Subroutine { //ADC1 setup myGPIO.GPIO_Pin = GPIO_Pin_0; //Set to pin 0 for Temperature myGPIO.GPIO_Mode myGPIO.GPIO_Mode = GPIO_Mode_AIN; //GPIO Analog Input GPIO_Init(GPIOA, &myGPIO); //Set to A0 RCC_ADCCLKConfig (RCC_PCLK2_Div6); //clock for ADC (max 14MHz, 72/6=12MHz) RCC_APB2PeriphClockCmd(RCC_APB2Perip RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, h_ADC1, ENABLE); //enable ADC clock myADC.ADC_ContinuousConvMode myADC.ADC_ContinuousConvMo de = ENABLE; myADC.ADC_NbrOfChannel myADC.ADC_NbrOfChan nel = 1; ADC_RegularChannelConfig(ADC1, ADC_RegularChannelConf ig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); ADC_SampleTime_55Cycles5); //PA0 as Input ADC_Init(ADC1, &myADC);
Dept of ECE, KSSEM
33
Embedded Controller Control ler Lab (15ECL67) ADC_Cmd(ADC1, ENABLE);
6th Sem ECE
KSSEM, Bangalore
//Enable ADC
//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 getADC(void) { return ADC_GetConversionValue(ADC1); ADC_GetConversionValue(ADC1); }
//Acquire Analog Value at pin //Return Converted Value
int main(void) { float x; RCC->APB2ENR = RCC_APB2ENR_IOPAEN ; RCC->APB1ENR = RCC_APB1ENR_USART2EN; RCC_APB1ENR_USART2EN; GPIOA->CRL GPIOA->CR L = 0x00004B00; // 0100 ->3 1011 ->2 0000->1 0000->0 USART2->CR1 = USART_CR1_UE | USART_CR1_TE; 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); } } void delay(int time) { int i,j; for(i=0;i<=time;i++) { for(j=0;j<=72000;j++); } }
//Delay Subroutine
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.
Dept of ECE, KSSEM
34
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
ALP to Find the Sum of First 10 Numbers
CODE: AREA RESET, DATA, READONLY EXPORT __Vectors __Vectors DCD 0x20001000 ; stack pointer value when stack is empty DCD Reset_Handler 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
Dept of ECE, KSSEM
35
Embedded Controller Control ler Lab (15ECL67)
6th Sem ECE
KSSEM, Bangalore
ALP to Find the Product of two 16-bit Numbers CODE:
AREA RESET, DATA, READONLY EXPORT __Vectors __Vectors DCD 0x20001000 DCD Reset_Handler Reset_Handler
; stack pointer value when stack is empty ; reset vector
ALIGN AREA MYCODE, CODE, READONLY ENTRY EXPORT Reset_Handler Reset_Handler
again
MOV R0, 0x4 MOV R1, 0x1 MUL R3, R0, R1 halt B halt
Dept of ECE, KSSEM
; R0 accumulates total
; infinite loop to stop computation
36