This programming manual is providing the complete details of programming the STM32 Value-line discovery (a low-cost) evaluation board for Value-line of STM32 microcontrollers from STMicroelectronics.
Join this video course on udemy . Click here :
https://www.udemy.com/course/mastering-microcontroller-with-peripheral-driver-development/?couponCode=SLIDESHARE
In this course, the code is developed such a way that, It can be ported to any MCU you have at your hand.
If you need any help in porting these codes to different MCUs you can always reach out to me!
The course is strictly not bound to any 1 type of MCU. So, if you already have any Development board which runs with ARM-Cortex M3/M4 processor,
then I recommend you to continue using it.
But if you don’t have any Development board, then check out the below Development boards.
Join this video course on Udemy. Click the below link
https://www.udemy.com/embedded-system-programming-on-arm-cortex-m3m4/?couponCode=SLIDESHARE
This presentation course covers full architectural and internal details of one of the most famous processor ARM Cortex M3 and M4. Processor core, NVIC, Register set, Bus interfaces, AHB,APB,SYS BUS,Interrupts,memory fully explained.
Join this video course on udemy . Click here :
https://www.udemy.com/course/mastering-microcontroller-with-peripheral-driver-development/?couponCode=SLIDESHARE
In this course, the code is developed such a way that, It can be ported to any MCU you have at your hand.
If you need any help in porting these codes to different MCUs you can always reach out to me!
The course is strictly not bound to any 1 type of MCU. So, if you already have any Development board which runs with ARM-Cortex M3/M4 processor,
then I recommend you to continue using it.
But if you don’t have any Development board, then check out the below Development boards.
Join this video course on Udemy. Click the below link
https://www.udemy.com/embedded-system-programming-on-arm-cortex-m3m4/?couponCode=SLIDESHARE
This presentation course covers full architectural and internal details of one of the most famous processor ARM Cortex M3 and M4. Processor core, NVIC, Register set, Bus interfaces, AHB,APB,SYS BUS,Interrupts,memory fully explained.
This provides information related to ARM Cortex-M4 features , Modes, Registers etc. I have discussed importance of multiple stack pointers and privilege levels. STM32 Nucleo-L4R5ZI board is taken for this case study.
Join this video course on udemy . Click here :
https://www.udemy.com/course/mastering-microcontroller-with-peripheral-driver-development/?couponCode=SLIDESHARE
Learn bare metal driver development systems using Embedded C: Writing drivers for STM32 GPIO,I2C,SPI,USART from scratch
Software/Hardware used:
In this course, the code is developed such a way that, It can be ported to any MCU you have at your hand.
If you need any help in porting these codes to different MCUs you can always reach out to me!
The course is strictly not bound to any 1 type of MCU. So, if you already have any Development board which runs with ARM-Cortex M3/M4 processor,
then I recommend you to continue using it.
But if you don’t have any Development board, then check out the below Development boards.
ARM (Advance RISC Machine) is one of the most licensed and thus widespread processor cores in the world.Used especially in portable devices due to low power consumption and reasonable performance.Several interesting extension available like THUMB instruction set and Jazelle Java Machine.
Embedded C programming based on 8051 microcontrollerGaurav Verma
This lecture note covers the embedded 'c' programming constructs based on 8051 microcontroller. Although the same concepts can be used for other advanced microcontrollers with some modifications.
This provides information related to ARM Cortex-M4 features , Modes, Registers etc. I have discussed importance of multiple stack pointers and privilege levels. STM32 Nucleo-L4R5ZI board is taken for this case study.
Join this video course on udemy . Click here :
https://www.udemy.com/course/mastering-microcontroller-with-peripheral-driver-development/?couponCode=SLIDESHARE
Learn bare metal driver development systems using Embedded C: Writing drivers for STM32 GPIO,I2C,SPI,USART from scratch
Software/Hardware used:
In this course, the code is developed such a way that, It can be ported to any MCU you have at your hand.
If you need any help in porting these codes to different MCUs you can always reach out to me!
The course is strictly not bound to any 1 type of MCU. So, if you already have any Development board which runs with ARM-Cortex M3/M4 processor,
then I recommend you to continue using it.
But if you don’t have any Development board, then check out the below Development boards.
ARM (Advance RISC Machine) is one of the most licensed and thus widespread processor cores in the world.Used especially in portable devices due to low power consumption and reasonable performance.Several interesting extension available like THUMB instruction set and Jazelle Java Machine.
Embedded C programming based on 8051 microcontrollerGaurav Verma
This lecture note covers the embedded 'c' programming constructs based on 8051 microcontroller. Although the same concepts can be used for other advanced microcontrollers with some modifications.
This Presentation describes the ARM CORTEX M3 core processor with the details of the core peripherals. Soon a CORTEX base controller(STM32F100RBT6) ppt will be uploaded. For more information mail me at:gaurav.iitkg@gmail.com.
Généralités sur les périphériques du STM32Hajer Dahech
Lien Téléchargement pptx https://hajereducation.tn/peripheriques-stm32-simple-resume-presentation-powerpoint/
Généralités sur les périphériques du STM32
Merci , Thanks For watching Video
=====Subscribe == S'abonner
Playlist :STM32 :vidéos+Files+Code
The "Weather Monitoring using STM32" project is a sophisticated and versatile system designed to monitor and collect essential weather data in real-time. By integrating a range of sensors, including temperature, rain, moisture, and the BMP280 sensor, this project offers a comprehensive solution for weather enthusiasts, researchers, and agricultural applications
We are one of the best embedded systems training institute for advance courses. We are the pioneer of the embedded system training in Pune & Pcmc with the expertise of over 16 years. we are working in the field training & development of embedded systems & currently we are also working on live projects as per the requirements of clients. though we provide many different courses & training in embedded all aim at giving good practical knowledge to students as well help them in their career.
We are one of the best embedded systems training institute for advance courses. We are the pioneer of the embedded system training in Pune & Pcmc with the expertise of over 16 years. we are working in the field training & development of embedded systems & currently we are also working on live projects as per the requirements of clients. though we provide many different courses & training in embedded all aim at giving good practical knowledge to students as well help them in their career.
STONE Tech is a manufacturer of HMI display modules (Intelligent TFT LCD). We provide LCD modules/LCD Displays, Graphic LCM, smart Display LCD, TFT LCM, Custom LCD Module Display, and LCD panels. china LCD Manufacturers.
Instructions 3-5 pages double space research paper about Eric Sc.docxnormanibarber20063
Instructions
3-5 pages double space research paper about Eric Schmidt (Google)
High profile manager CEOs. Please include information about this person’s personal and professional background, management style and skills and research about why this person is (or is not) such an effective manager/leader. You should utilize at least three articles dated from 2008 to present as references.
Paper should contain the following:
· Title page
· An introduction3-5 pages (double-spaced, no more than 12 pt. font) of cited research in APA format.
· A conclusion
· Reference page in APA format (Including at least three articles on management dated from 2008 to present)
Paper should include three sections: the Title Page, Main Body, and References. An Abstract in not necessary for this paper.
EECE237/ATT00001.htm
__MACOSX/EECE237/._ATT00001.htm
EECE237/ATT00002.htm
__MACOSX/EECE237/._ATT00002.htm
EECE237/ATT00003.htm
__MACOSX/EECE237/._ATT00003.htm
EECE237/ATT00004.htm
__MACOSX/EECE237/._ATT00004.htm
EECE237/ATT00005.htm
__MACOSX/EECE237/._ATT00005.htm
EECE237/Lab 01 Notes.pdf
EECE 237 Lab 01 Setup Notes
Fall Semester 2016
I. Communicate with the Launchpad by PuTTY in your PC.
From Computer Management of your Microsoft Windows, check which COM port is
connected with your Launchpad.
For example, the following case (a PC running Windows 10) shows it is COM3.
Open PuTTY, choose “serial” for the connection mode. Set the “Serial Line” to the port you
are using, and set the “Speed” to 115200.
II. Tiva Software (TivaWare for C series)
http://www.ti.com/tool/sw-tm4c
Install “SW-TM4C-2.1.3.156”. The Keil RealView MDK is now ARMKeil MDK. If the installed
TivaWare locates in C:\ti, the example “Hello” project is in “C:\ti\TivaWare_C_Series-
2.1.3.156\examples\boards\ek-tm4c123gxl”.
http://www.ti.com/tool/sw-tm4c
__MACOSX/EECE237/._Lab 01 Notes.pdf
EECE237/Lab Preparation Notes.pdf
EECE 237 Lab 01 Preparation Notes
Fall Semester 2016
I. Install Keil Toolchain on your PC
The following steps describe installation of ARM Keil toolchain, the MDK ARM (MDK is the
abbreviation of Microcontroller Development Kit). It is highly recommended that you have access to a
PC or a laptop running Windows 7, 8, or 10. The functioning of the toolchain is not tested in Mac or
Linux boxes. Screenshots were captured from an installation in a Windows 10 PC.
1. Fill out the form at
https://www.keil.com/demo/eval/armv4.htm
Notice that we use version 4.74. Set your Company to California State University, Chico. Set your
device to TM4C123. It should not cost any money. You can select or not select whether you
want email from ARMKeil.
Submit the form after you finish it.
2. You will see a download link similar to the following:
Download the software MDK474.EXE.
3. Run the MDK474.EXE file. Install the application in some place that is easy to find, for example
C:\Keil or D:\Keil.
https://www.keil.com/de.
Computer Programming and MCUs Assembly Language STM32Cu.pdfableelectronics
Computer Programming and MCUs:
- Assembly Language
- STM32CubeIDE
- STM32F3DISCOVERY Board MCU
Objectives:
1. Create a function that can chase an LED around the LED circle. This means that only one LED
should be on, and the currently on LED will move either clockwise, or anti-clockwise around the
circle of LEDs. Provide a value to the function in R1 which selects whether the LED goes
clockwise or anti-clockwise. Provide a value to the function in R2 which selects how many LEDs
should be on at the same time (1 LED chasing, 2 LEDs chasing, etc).
2. Make a map between an ASCII character and a pattern of LEDs being on/off. Demonstrate this
with a function that uses an ASCII value stored in R1 to turn the LEDs on/off to show the pattern.
3. Use the discovery board user input button to step through the characters in an ASCII string and
show the LED patterns one at a time.
General Assumptions/hints:
- User Button located in GPIO port A (base address: 0x48000000)
- LEDs located in GPIO port E (base address: 0x48001000)
- LED circle located in GPIO port E, bits 8-15
- Use STM32F3-Reference-Manual-Large.pdf for register addresses/offsets
Basic steps:
1. Enable the clock for each I/O port we want to use
2. Setup GPIO Registers (Button = input, LEDs = output)
3. Read from input or write from output
STM32F3DISCOVERY Board MCU:
STM32CubeIDE:
P. Project Explorer x Thern arn no projects in ynur workspaca. To add a project: Create a mew
Makefile project in a directory centaining revisting cade Create a new C or Ct+ prodect Crate a
Naw STM37 prolact Craata a Naw StM37 Proinct fram an Fristing Create a project... timpert
projects... D itams selected.
First Steps Developing Embedded Applications using Heterogeneous Multi-core P...Toradex
Read our blog for the latest on demystifying the development of embedded systems using Heterogeneous Multicore Processing architecture powered SoCs! This might provide you with the jump start you need for your development. https://www.toradex.com/blog/first-steps-developing-embedded-applications-using-heterogeneous-multicore-processors
15LLP108_Demo4_LedBlinking.pdf1. Introduction In D.docxfelicidaddinwoodie
15LLP108_Demo4_LedBlinking.pdf
1. Introduction
In Demo3, we have learned how to read sensor values of light, temperature and humidity of a node
and output these values to the console. In this demonstration, we will use the code from Demo3 and
learn how to turn on/off the LEDs and make them blinking regularly on the sensor node XM1000,
meanwhile to count how many times the LED has blinked and output the count to the console.
2. Timer
In order to make the blue LED on the XM1000 sensor node to blink in every half second (i.e. On 0.5S
and Off 0.5S), we also need a timer. Follow the instructions in Demo3 for configure and reset a timer.
We aslo need to create an infinite while() loop so that it runs our functions repeatedly, such as
counting the times the LED has blinked, output the counter’s value and actually turn on or off the
LEDs to make it blinking.
Please follow timer and while() loop structure in Demo3.
3. LED Blinking
To get access to the LED functionalities in Contiki, we need to include the LED header file in the
source code:
#include "leds.h" // file is in directory /home/user/contiki/core/dev
After the process begin, we have to initialise the LEDs on the sensor node by calling the following
function:
leds_init(); // Initialise the LEDs
And finally we can turn on, off, or blink the LEDs by the following functions:
void leds_on(unsigned char leds);
void leds_off(unsigned char leds);
void leds_toggle(unsigned char leds);
void leds_invert(unsigned char leds);
For example, if you want to blink the Blue LED, yon need to call the toggle function as:
void leds_toggle(LEDS_BLUE); // Toggle the blue LED
4. Exercise
Modify the program from Demo3 with periodic timer to make the BLUE led blinking in every half
second, also to count the blinking times and output the counted number to the console.
Can your change the code so that the BLUE LED is lighted for 1 second and off for 0.5 second
periodically?
15LLP108 – Internet of Things and Applications
Lab Session 2: Demo 4 – LED Blinking
Prepared by Xiyu Shi
5. Source code
Here is the source code for reference
#include "contiki.h"
#include "leds.h"
#include <stdio.h> /* for printf() */
static struct etimer timer;
/*____________________________________________________*/
PROCESS(led_blinking_process, "LED Blinking Process");
PROCESS(LED_process, "LED process");
AUTOSTART_PROCESSES(&LED_process);
/*____________________________________________________*/
PROCESS_THREAD(LED_process, ev, data)
{
static int count = 0;
PROCESS_BEGIN();
etimer_set(&timer, CLOCK_CONF_SECOND/2); // 0.5S timer
leds_init(); // intialise the LEDs
while(1) {
PROCESS_WAIT_EVENT_UNTIL(ev==PROCESS_EVENT_TIMER); // wait for timer event
count++; // count the blinking times
process_start(&led_blinking_process, NULL); // to blink the BLUE Led
printf("Count: %d\n", count); // output the counte ...
The main aim of this project is to avoid the accident and death in the gas leakage explosion in house, hotels and industries. Domestically we use natural gas and it is very useful for burning purpose. If this gas is leaked in our kitchens, hotels or factories and not sensed in time, it may lead to fatal disaster, and may cause human and material loss. For this purpose we have developed “GAS LEAKAGE DETECTION SYSTEM”.
Advanced View of Atmega Microcontroller Projects List - ATMega32 AVR.pdfWiseNaeem
Most of the electronics geeks are asking the whole list of Atmega AVR projects PDF here we will share list every month as our projects are being updated on daily basis.
Advanced View of Atmega Microcontroller Projects List - ATMega32 AVR.pdfWiseNaeem
Most of the electronics geeks are asking the whole list of Atmega AVR projects PDF here we will share list every month as our projects are being updated on daily basis.
Similar to Programming the ARM CORTEX M3 based STM32F100RBT6 Value Line Discovery Board (20)
Forklift Classes Overview by Intella PartsIntella Parts
Discover the different forklift classes and their specific applications. Learn how to choose the right forklift for your needs to ensure safety, efficiency, and compliance in your operations.
For more technical information, visit our website https://intellaparts.com
Courier management system project report.pdfKamal Acharya
It is now-a-days very important for the people to send or receive articles like imported furniture, electronic items, gifts, business goods and the like. People depend vastly on different transport systems which mostly use the manual way of receiving and delivering the articles. There is no way to track the articles till they are received and there is no way to let the customer know what happened in transit, once he booked some articles. In such a situation, we need a system which completely computerizes the cargo activities including time to time tracking of the articles sent. This need is fulfilled by Courier Management System software which is online software for the cargo management people that enables them to receive the goods from a source and send them to a required destination and track their status from time to time.
Welcome to WIPAC Monthly the magazine brought to you by the LinkedIn Group Water Industry Process Automation & Control.
In this month's edition, along with this month's industry news to celebrate the 13 years since the group was created we have articles including
A case study of the used of Advanced Process Control at the Wastewater Treatment works at Lleida in Spain
A look back on an article on smart wastewater networks in order to see how the industry has measured up in the interim around the adoption of Digital Transformation in the Water Industry.
Immunizing Image Classifiers Against Localized Adversary Attacksgerogepatton
This paper addresses the vulnerability of deep learning models, particularly convolutional neural networks
(CNN)s, to adversarial attacks and presents a proactive training technique designed to counter them. We
introduce a novel volumization algorithm, which transforms 2D images into 3D volumetric representations.
When combined with 3D convolution and deep curriculum learning optimization (CLO), itsignificantly improves
the immunity of models against localized universal attacks by up to 40%. We evaluate our proposed approach
using contemporary CNN architectures and the modified Canadian Institute for Advanced Research (CIFAR-10
and CIFAR-100) and ImageNet Large Scale Visual Recognition Challenge (ILSVRC12) datasets, showcasing
accuracy improvements over previous techniques. The results indicate that the combination of the volumetric
input and curriculum learning holds significant promise for mitigating adversarial attacks without necessitating
adversary training.
Automobile Management System Project Report.pdfKamal Acharya
The proposed project is developed to manage the automobile in the automobile dealer company. The main module in this project is login, automobile management, customer management, sales, complaints and reports. The first module is the login. The automobile showroom owner should login to the project for usage. The username and password are verified and if it is correct, next form opens. If the username and password are not correct, it shows the error message.
When a customer search for a automobile, if the automobile is available, they will be taken to a page that shows the details of the automobile including automobile name, automobile ID, quantity, price etc. “Automobile Management System” is useful for maintaining automobiles, customers effectively and hence helps for establishing good relation between customer and automobile organization. It contains various customized modules for effectively maintaining automobiles and stock information accurately and safely.
When the automobile is sold to the customer, stock will be reduced automatically. When a new purchase is made, stock will be increased automatically. While selecting automobiles for sale, the proposed software will automatically check for total number of available stock of that particular item, if the total stock of that particular item is less than 5, software will notify the user to purchase the particular item.
Also when the user tries to sale items which are not in stock, the system will prompt the user that the stock is not enough. Customers of this system can search for a automobile; can purchase a automobile easily by selecting fast. On the other hand the stock of automobiles can be maintained perfectly by the automobile shop manager overcoming the drawbacks of existing system.
Hybrid optimization of pumped hydro system and solar- Engr. Abdul-Azeez.pdffxintegritypublishin
Advancements in technology unveil a myriad of electrical and electronic breakthroughs geared towards efficiently harnessing limited resources to meet human energy demands. The optimization of hybrid solar PV panels and pumped hydro energy supply systems plays a pivotal role in utilizing natural resources effectively. This initiative not only benefits humanity but also fosters environmental sustainability. The study investigated the design optimization of these hybrid systems, focusing on understanding solar radiation patterns, identifying geographical influences on solar radiation, formulating a mathematical model for system optimization, and determining the optimal configuration of PV panels and pumped hydro storage. Through a comparative analysis approach and eight weeks of data collection, the study addressed key research questions related to solar radiation patterns and optimal system design. The findings highlighted regions with heightened solar radiation levels, showcasing substantial potential for power generation and emphasizing the system's efficiency. Optimizing system design significantly boosted power generation, promoted renewable energy utilization, and enhanced energy storage capacity. The study underscored the benefits of optimizing hybrid solar PV panels and pumped hydro energy supply systems for sustainable energy usage. Optimizing the design of solar PV panels and pumped hydro energy supply systems as examined across diverse climatic conditions in a developing country, not only enhances power generation but also improves the integration of renewable energy sources and boosts energy storage capacities, particularly beneficial for less economically prosperous regions. Additionally, the study provides valuable insights for advancing energy research in economically viable areas. Recommendations included conducting site-specific assessments, utilizing advanced modeling tools, implementing regular maintenance protocols, and enhancing communication among system components.
CFD Simulation of By-pass Flow in a HRSG module by R&R Consult.pptxR&R Consult
CFD analysis is incredibly effective at solving mysteries and improving the performance of complex systems!
Here's a great example: At a large natural gas-fired power plant, where they use waste heat to generate steam and energy, they were puzzled that their boiler wasn't producing as much steam as expected.
R&R and Tetra Engineering Group Inc. were asked to solve the issue with reduced steam production.
An inspection had shown that a significant amount of hot flue gas was bypassing the boiler tubes, where the heat was supposed to be transferred.
R&R Consult conducted a CFD analysis, which revealed that 6.3% of the flue gas was bypassing the boiler tubes without transferring heat. The analysis also showed that the flue gas was instead being directed along the sides of the boiler and between the modules that were supposed to capture the heat. This was the cause of the reduced performance.
Based on our results, Tetra Engineering installed covering plates to reduce the bypass flow. This improved the boiler's performance and increased electricity production.
It is always satisfying when we can help solve complex challenges like this. Do your systems also need a check-up or optimization? Give us a call!
Work done in cooperation with James Malloy and David Moelling from Tetra Engineering.
More examples of our work https://www.r-r-consult.dk/en/cases-en/
Final project report on grocery store management system..pdfKamal Acharya
In today’s fast-changing business environment, it’s extremely important to be able to respond to client needs in the most effective and timely manner. If your customers wish to see your business online and have instant access to your products or services.
Online Grocery Store is an e-commerce website, which retails various grocery products. This project allows viewing various products available enables registered users to purchase desired products instantly using Paytm, UPI payment processor (Instant Pay) and also can place order by using Cash on Delivery (Pay Later) option. This project provides an easy access to Administrators and Managers to view orders placed using Pay Later and Instant Pay options.
In order to develop an e-commerce website, a number of Technologies must be studied and understood. These include multi-tiered architecture, server and client-side scripting techniques, implementation technologies, programming language (such as PHP, HTML, CSS, JavaScript) and MySQL relational databases. This is a project with the objective to develop a basic website where a consumer is provided with a shopping cart website and also to know about the technologies used to develop such a website.
This document will discuss each of the underlying technologies to create and implement an e- commerce website.
Programming the ARM CORTEX M3 based STM32F100RBT6 Value Line Discovery Board
1. STM32F100RB (ARM Cortex core) Programming Tutorial
Introduction
STM32VLDISCOVERY evaluation board
STM32 Value-line discovery board is a low-cost evaluation board for Value-line of STM32
microcontrollers from STMicroelectronics. Value line of STM32 microcontrollers are low cost
version of higher devices. It can run on 24MHz and don’t have some of peripherals available on
higher devices. On this board is soldered 64-pin value-line STM32 (with ARM Cortex-M3 core)
microcontroller and ST-Link debugger, so board is complete hardware needed to run programs
for STM32 devices! You only need USB cable for connection board to PC.
Of course, we need build some external hardware because on the STM32LVDISCOVERY are
mounted only two LEDs and two pushbuttons - one for RESET and one for user application
purposes. Discovery board has two long rows of pin headers and one short (between them) with
all important signals from microcontroller and power supply voltages. Due to this short
connector STM32VLDISCOVERY board cannot be placed on typical solder less board.
This tutorial shows you how to write applications for STM32 devices without use STM32
StdPeriph Library. This library in my opinion isn't best solution for writing apps for STM32 and
I show you that writing apps without this library is easy and fun. Although this tutorial is based
on STM32 Value Line micros and STM32VLDISCOVERY board in most cases can be also used
for other STM32F1 (mainstream) devices and other development boards.
2. Lesson 1 - First program. Blinking LED
For writing applications for STM32VLDISCOVERY board we need toolchain, which supports
STLink debugger and SWD protocol. Unfortunately at this moment OpenOCD debug tool do not
support SWD and STLink, so we can't use free tool chains. SWD protocol supports following
tool chains: MDK-ARM from Keil, EWARM from IAR and TrueSTUDIO form Atollic. In this
tutorial all examples will be shown for MDK-ARM.
Creating uVision project - step by step
To create new uVision project select "New uVision Project" command from menu "Project":
You will be asked for name and disk location for created project. Next, you must select device.
On STM32VLDISCOVERY board is installed STM32F100RBT6 device, so select
"STM32F100RB" option from dialog window:
3. After device selection uVision ask if add startup file to project tree:
If you click "Yes", in project tree will be present startup file, suitable for STM32F100RB
microcontroller:
After creating project, we can write application code. For this we must create a new C source
file. From "File" menu select "New" command:
4. After this will be created a new text file:
Now, let save this file as main.c:
5. And add it to project tree:
and pick main.c file from disk. File main.c should be in SourceGroup1:
6. We are ready to writing application source code. Let us write in main.c file following lines:
#include "stm32f10x.h"
int main(void)
{
do{
}while(1);
}
Save the file and select command "Build target" from "Project" menu. In the "Build output"
window will be written following messages:
Build target 'Target 1'
assembling startup_stm32f10x_md_vl.s...
compiling main.c...
C:KeilARMINCSTSTM32F10xstm32f10x.h(80): error: #35: #error directive: "Please select
first the target STM32F10x device used in your application (in stm32f10x.h file)"
Target not created
Note: We must defined, which type of STM32 microcontroller are used. So, go to the project
tree and click right mouse button on "Target1" folder icon, and select "Options for Target..."
command from context menu:
7. Next, go to "C/C++" tab and write in "Define" edit box "STM32F10X_MD_VL" string:
8. After this try build application again. Still errors occur in build output window :
Build target 'Target 1'
assembling startup_stm32f10x_md_vl.s...
compiling main.c...
C:main.c(7): warning: #1-D: last line of file ends without a newline
linking...
a.axf: Error: L6218E: Undefined symbol SystemInit (referred from startup_stm32f10x_md_vl.o).
Target not created
Note: In this case this is a linker error, that can't find symbol SystemInit. As we see, call for this
symbol came from startup file and this is call for SystemInit function. We can go for a few ways:
remove call for this function or write this function (may it be an empty function) or use function
supplied by STMicro in their device support for CMSIS library. We took last way, and use
stm32f10x_system.c file. We need to download STM32 StdPeriph library for STM32F10x
devices. In archive with this library is a folder "CMSIS", which we need to extract from the
archive. We need only the CMSIS folder. The STM32F10x_StdPeriph_Driver folder can be
deleted ;-).
Go to CMSISCM3DeviceSupportSTSTM32F10x subfolder, copy *.c and *.h files to folder
with your uVision project and add *.c files to the project tree.
9. Now, try to build project. In "Build output window should be written following text:
Build target 'Target 1'
assembling startup_stm32f10x_md_vl.s...
compiling main.c...
compiling system_stm32f10x.c...
linking...
Program Size: Code=808 RO-data=320 RW-data=20 ZI-data=1636
"prj1.axf" - 0 Error(s), 0 Warning(s).
SUCCES! We have first compiled application for STM32!
Let’s Blink LED
After successfully creating and compiling first empty project we can add some source code to
them. We want to blink LED LD4, which are connected to PC8 pin of STM32F100RBT6. So we
need to configure this pin as output. At this moment, You need to download from STMicro
website document called RM0041. In this Reference Manual are described all peripherals of
STM32F100 microcontrollers. Because this document has over 650 pages it impossible to copy
all informations to this website. So I will reference to this document and suitable chapters
concerning peripherals used in this tutorial. I will not reference to exact page, because after
updating document by ST Micro page numbers can be not actual. I will be referenced to sections,
figures and tables.
RCC configuration
Look at section 6 of RM0041, that concern about RCC (Reset and Clock Control) peripheral. In
section 6.2 Figure 8 shows clock tree on STM32F100 low and medium density microcontrollers.
Looks complicated, but almost all configurations are done by SystemInit function from
system_stm32f10x.c file. Clocks will be configured to obtain specified core speed. Remember
that - after reset all peripherals have disabled clock! So we need enable clock for every used
peripheral. Go to section 6.3.7 of Reference Manual. This section describes APB2ENR register
of RCC peripheral. This register is responsible for enabling clock signal for peripherals working
on APB2 bus. All GPIO peripherals works on APB2 bus, so this register are interesting for us.
Bits 2 to 8 are used to enable clock for each GPIO port (form GPIOA to GPIOG). We ned use
only GPIOC port, so we need set bit number 4 of APB2ENR register. How do it? Probably You
10. think about (1 << 4)? Right? That is wrong! Open document stm32f10x.h and search for bit
name - "IOPCEN". You should find some macro definitions, which one from them is:
#define RCC_APB2ENR_IOPCEN ((uint32_t)0x00000010) /*!< I/O port C clock enable */
What is it? It's a bitmask for IOPCEN bit! So we don't need bitwise shifting one by pin number,
we can use suitable bitmask! So, how will be looks first code line of us application? Probably
something like that:
#include "stm32f10x.h"
int main(void)
{
RCC_APB2ENR | = RCC_APB2ENR_IOPCEN;
do{
}while(1);
}
But this is wrong. After compiling application, compiler returns following error:
main.c(14): error: #20: identifier "RCC_APB2ENR" is undefined
Why? We use register name from Reference Manual, so why it is wrong? This is wrong, because
all peripherals are divided into structures that hold peripherals registers. These structures are
defined in stm32f10x.h file. So go to this file and search for "Peripheral_registers_structures"
string. You will see some of typedefs describing structures for all of peripherals. Each structure
holds all registers of peripheral. Naming scheme of peripheral structures are following:
PeriphName_TypeDef. So for RCC peripheral structure definitions with registers are
"RCC_TypeDef". So let's search for "RCC_TypeDef" string. We see, that registers name are
slightly different from names from Reference Manual. Names in structure are without part of
peripheral name. Register described in Reference Manual as RCC_APB2ENR in structure has
name APB2ENR. OK, now we need name of structure variable. So let search again for
RCC_TypeDef string. You should find following line:
#define RCC ((RCC_TypeDef *) RCC_BASE)
Now all are clear! In stm32f10x.h file is defined macro RCC that in fact are pointer dereference
to our RCC_TypeDef structure that resides at RCC_BASE address. If you search for
RCC_BASE string, you find another macro, that defines RCC_BASE as base address of RCC
peripheral in STM32F100 memory space. So now, we can use RCC macro as pointer to
11. structure, that holds all register of RCC peripheral. Now we can write correct code for set
IOPCEN bit in APB2ENR register of RCC peripheral:
#include "stm32f10x.h"
int main(void)
{
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
do{
}while(1);
}
Try to build application. Hooray! No errors! We have enabled clock for GPIOC peripheral and
we can configure GPIO for driving LED.
GPIO configuration
Now, go to Section 7 of RM0041. As you can read, each GPIO port has several registers to
configure and control input and output state of microcontroller pins. Most important information
for us is that each GPIO port has two 32-bit configuration registers: CRL and CRH. CRL register
is responsible for configuration of pins from 0 to 7 and CRH register is responsible for
configuration of pins form 8 to 15. So for each GPIO pin we have four configuration bits. Table
16 from RM0041 shows all possible configurations of GPIO pins. Because configuration
registers are slightly complicated, I prepared some macros for easier configuring GPIO ports on
STM32 microcontrollers. With this macros pin configuration are easy and clear to read. These
macros are in antilib_gpio.h file. Download this file, and save into folder with your application
project. Example configuration for PC8 pin that works as output looks like that:
GPIOC->CRH = (GPIOC->CRH & CONFMASKH(8)) | GPIOPINCONFH(8,
GPIOCONF(GPIO_MODE_OUTPUT2MHz, GPIO_CNF_OUTPUT_PUSHPULL));
Let me describe each element of this code line. GPIO->CRH mean of course access to
GPIOC_CRH register. We want change configuration only for PC8, so remaining bits of this
register should be unchanged. We realize that by reading contents of GPIO_CRH register and
clear bits responsible for PC8 configuration. Macro CONFMASKH (8) give bitmask for clearing
4 lowest bits: 0xFFFFFFF0. Clearing this 4 bits will be done by bitwise AND of register with
this bitmask. Next, we need to set configuration bits for PC8 suitable for driving LED. Output
12. should be work as push-pull output. And what is this megahertz? This specified slew rate on
outputs pin. For driving LED we don’t need fast edges of driving signals, so we use slowest slew
ratio for PC8.
Controlling output state of GPIO pins can be realized on two ways: by writing port value to ODR
(Output Data Register) register or by writing to BSRR (Bit Set/Reset Register) or BRR (Bit
Reset Register). Writing to ODR register modifies value of all pins of given GPIO port. Writing
to BSRR/BRR registers modifies state only this bits, that writing value has ones on bits position.
For example to set bit PC8 we can use following code:
GPIOC->BSRR = (1 << 8);
After execution of this line bit number 8 (and only this bit) of GPIOC will be set. Other bits
remain unchanged. Upper 16 bits of BSRR register can be used to clearing pin state:
GPIOC->BSRR = (1 << 24);
After execution of this line bit number 8 of GPIOC will be cleared. To resetting pin state we can
use BRR register too:
GPIOC->BRR = (1 << 8);
After execution of this line, bit number 8 will be cleared. If we want clear single bit using ODR
register, we must perform bitwise logical operations in Read-Modify-Write scheme:
GPIOC->ODR = GPIOC->ODR | (1 << 8);
but this operation is not atomic! After reading ODR state, his value can be changed (in interrupt
for example), and after write modified value we can lose this change. So better use atomic
operations with BSRR / BRR register.
Finally, let's blink the LED!
After getting all informations from above discussion, we can write our blinking LED application.
How to make a delay?
Simplest way to make a delay (let's call 'monkey delay') is loop counting some many times. Time
of this delay it's hard to define. Especially on ARM devices counting how CPU cycles loop will
be executed is difficult. Let's define variable named dly:
13. volatile uint32_t dly;
Short explain about two keywords before variable name. An 'volatile' keyword says to compiler
"Don't optimize access to this variable. Its value can change in any time of execution of
program". Second keyword defines size of variable - 32-bit unsigned integer. Now, let's do a
simple loop using this variable:
for(dly = 0; dly < 500000; dly++);
This code give us 500.000 loop cycles, that in effect give us some time of CPU spending in the
loop. Without keyword 'volatile' this code probably gives us no cycles and no time delay.
Complete code of blink LED application:
//=============================================================================
// STM32VLDISCOVERY tutorial
// Lesson 1. Blinking the LED.
// Copyright : Gaurav Verma, Assistant Professor, ECE Department.
// Jaypee Institute of Information Technology, Sector-62, Noida.
// e-mail : gaurav.iitkg@gmail.com
// Mobile No.: 9811506739
//=============================================================================
#include "stm32f10x.h"
#include "antilib_gpio.h"
//=============================================================================
// main function
//=============================================================================
int main(void)
{
volatile uint32_t dly;
RCC->APB2ENR |= RCC_APB2ENR_IOPCEN;
GPIOC->CRH = (GPIOC->CRH & CONFMASKH(8)) | GPIOPINCONFH(8,
GPIOCONF(GPIO_MODE_OUTPUT2MHz, GPIO_CNF_OUTPUT_PUSHPULL));
14. while (1)
{
for(dly = 0; dly < 500000; dly++);
GPIOC->BSRR = (1 << 8);
for(dly = 0; dly < 500000; dly++);
GPIOC->BRR = (1 << 8);
}
}
//=============================================================================
// End of file
//=============================================================================
How to make this code more universal? When LED diode will be connected to other pin, we
need modify in code all references to them. So let's use the preprocessor to define some macros
describing connected LED diode:
#define LED_BLUE_GPIO GPIOC
#define LED_BLUE_PIN 8
Now we can use defined macros in place to direct GPIO and pin number, but in case of configure
GPIO there is need to specify configuration register (low or high). We can do this like in
example:
#if (LED_BLUE_PIN > 7)
LED_BLUE_GPIO->CRH = (LED_BLUE_GPIO->CRH & CONFMASKH(LED_BLUE_PIN))
|GPIOPINCONFH(LED_BLUE_PIN,GPIOCONF(GPIO_MODE_OUTPUT2MHz,
GPIO_CNF_OUTPUT_PUSHPULL));
#else
LED_BLUE_GPIO->CRL = (LED_BLUE_GPIO->CRL & CONFMASKL(LED_BLUE_PIN))
| GPIOPINCONFL(LED_BLUE_PIN, GPIOCONF(GPIO_MODE_OUTPUT2MHz,
GPIO_CNF_OUTPUT_PUSHPULL));
15. #endif
The #if is preprocessor conditional directive, not the C language conditional instruction, so
before compilation the preprocessor depending on value of LED_BLUE_PIN choose proper
source code line and place them on source code file that will be compiled. Now, to turn LED on
we can use following sequence:
GPIOC->BSRR = (1 << LED_BLUE_PIN);
and for turn led OFF :
GPIOC->BRR = (1 << LED_BLUE_PIN);
Complete source code :
//=============================================================================
// STM32VLDISCOVERY tutorial
// Lesson 1. Blinking the LED.
// Copyright : Gaurav Verma, Assistant Professor, ECE Department.
// Jaypee Institute of Information Technology, Sector-62, Noida.
// e-mail : gaurav.iitkg@gmail.com
// Mobile No.: 9811506739
//=============================================================================
#include "stm32f10x.h"
#include "antilib_gpio.h"
//=============================================================================
// Defines
//=============================================================================
#define LED_BLUE_GPIO GPIOC
#define LED_BLUE_PIN 8
//=============================================================================
// main function
17. Lesson2. Reading the button
After blinking the LED, described in lesson 1, we can do another exercise - reading the button
state. On the STM32VLDISCOVERY board we have two buttons - one for resetting board (RST,
black) and one for user purpose (USER, blue). The USER button is connected to PA0 pin and
active states are high.
Creating project is similar to described in lesson 1. First thing to do to use this button is enable
clock for GPIO peripheral:
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN;
Remember that we use also GPIOC, so we need turn on clock for both GPIOA and GPIOC.
Next, let's do some defines for USER button:
#define SW_USER_GPIO GPIOA
#define SW_USER_PIN 0
and now we can configure GPIO to work as input:
#if (SW_USER_PIN > 7)
SW_USER_GPIO->CRH = (SW_USER_GPIO->CRH & CONFMASKH(SW_USER_PIN)) |
GPIOPINCONFH(SW_USER_PIN, GPIOCONF(GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOATING));
#else
SW_USER_GPIO->CRL = (SW_USER_GPIO->CRH & CONFMASKL(SW_USER_PIN)) |
GPIOPINCONFL(SW_USER_PIN, GPIOCONF(GPIO_MODE_INPUT,
GPIO_CNF_INPUT_FLOATING));
#endif
Now we can check in endless loop state of the button and turn LED on if is pressed:
while (1) {
if(SW_USER_GPIO->IDR & (1 << SW_USER_PIN))
LED_BLUE_GPIO->BSRR = (1 << LED_BLUE_PIN);
else
18. LED_BLUE_GPIO->BRR = (1 << LED_BLUE_PIN);
}
Complete code of example:
//=============================================================================
// STM32VLDISCOVERY tutorial
// Lesson 2. Reading from the switch.
// Copyright : Gaurav Verma, Assistant Professor, ECE Department.
// Jaypee Institute of Information Technology, Sector-62, Noida.
// e-mail : gaurav.iitkg@gmail.com
// Mobile No.: 9811506739
//=============================================================================
#include "stm32f10x.h"
#include "antilib_gpio.h"
//=============================================================================
// Defines
//=============================================================================
#define LED_BLUE_GPIO GPIOC
#define LED_BLUE_PIN 8
#define SW_USER_GPIO GPIOA
#define SW_USER_PIN 0
//=============================================================================
// main function
//=============================================================================
int main(void)
{
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN;
20. After flashing MCU and pressing down the USER button blue LED will be turned on, after
release the button LED will be turned off.
Lesson 3. Blinking with Timer.
As i wrote in lesson 1, this is not the best way to make a delay :
for(dly = 0; dly < 500000; dly++);
CPU wasting time to counting this loop, and also time of delay is hard to define. This kind of
delay is maybe good for first program, but not for professional applications. So let's try blinking
LED with use one of STM32's timers. Look into section 13 of RM0041 document. This section
describes general purpose timers TIM2 to TIM5. These timers are a 16-bit timer with 16-bit
prescaler. Now, look into STM32F100RBT6 datasheetto section 3 "Pinouts and pin description".
Look for PC8 and PC9 in table 4. As you see, this pin can be connected to channels 3 and 4 of
timer TIM3. So let's use in this lesson timer TIM3 to blinking LEDs.
Make timer alive
First thing which we do is make timer counting. First of all, we need enable clock for timer
TIM3:
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
Now, we can configure timer. Let's assume that we want change state of LED each one second.
How to do it? You must know input frequency which clocking the timer. Now, look into file
system_stm32f10x.c at fragment:
#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* #define SYSCLK_FREQ_HSE HSE_VALUE */
#define SYSCLK_FREQ_24MHz 24000000
#else
/* #define SYSCLK_FREQ_HSE HSE_VALUE */
/* #define SYSCLK_FREQ_24MHz 24000000 */
/* #define SYSCLK_FREQ_36MHz 36000000 */
/* #define SYSCLK_FREQ_48MHz 48000000 */
21. /* #define SYSCLK_FREQ_56MHz 56000000 */
#define SYSCLK_FREQ_72MHz 72000000
#endif
As we use Medium Density Value Line microcontroller (MD_VL) we have two options of
System Core Clock : equal to HSE (High Speed External source) and 24 MHz Default value in
file is SYSCLK_FREQ_24MHz. Based on this macro definition, functions from file
system_stm32f10x.c will configure clock system of microcontroller to achieve 24MHz system
core clock. So our system frequency is 24MHz. Same frequency clock all peripherals, including
timer TIM3. But, how our timer works? In simplest mode timer is counting from 0 to value
stored in ARR register, then count again from 0 to ARR. When counter value is equal to ARR
the UIF flag in SR register is set.
How count one second with this timer? 24MHz of clock give us about 41 nanoseconds of one
timer tick. So our timer should count 24 million times to measure one second. But timer is only
16-bits with 16-bits prescaler. Almost like 32-bit timer, but with some limitations. If we don't
need high timer resolution we can prescale timer clock, by 24 000 and counting elapsing
milliseconds. One second is 1000 milliseconds, so look at code:
TIM3->PSC = 23999; // Set prescaler to 24 000 (PSC + 1)
TIM3->ARR = 1000; // Auto reload value 1000
TIM3->CR1 = TIM_CR1_CEN;// Enable timer
This is the simplest timer configuration. We set prescaler to 24k (remember - prescaler is PSC +
1) and auto reload register to 1000. Next, we enable the timer. From now, timer should be
counting. When timer achieve ARR value, the UIF flag will be set. So now we need chceck this
flag value, and toggle LED state, when flag is set (counter count to 1000). Code for check flag
and toggle LED:
if(TIM3->SR & TIM_SR_UIF)
{
TIM3->SR &= ~TIM_SR_UIF;
LED_BLUE_GPIO->ODR ^= (1 << LED_BLUE_PIN);
22. }
But when check this flag? Now, we check this flag in endless loop:
while (1) {
if(TIM3->SR & TIM_SR_UIF)
{
TIM3->SR &= ~TIM_SR_UIF;
LED_BLUE_GPIO->ODR ^= (1 << LED_BLUE_PIN);
}
}
Of course, this is not the best way to do this, but at this moment try this. Complete source code :
//=============================================================================
// STM32VLDISCOVERY tutorial
// Lesson 3. Blinking LED with Timer.
// Copyright : Gaurav Verma, Assistant Professor, ECE Department.
// Jaypee Institute of Information Technology, Sector-62, Noida.
// e-mail : gaurav.iitkg@gmail.com
// Mobile No.: 9811506739
//=============================================================================
#include "stm32f10x.h"
#include "antilib_gpio.h"
//=============================================================================
// Defines
//=============================================================================
#define LED_BLUE_GPIO GPIOC
#define LED_BLUE_PIN 8
23. //=============================================================================
// main function
//=============================================================================
int main(void)
{
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPCEN;
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
#if (LED_BLUE_PIN > 7)
LED_BLUE_GPIO->CRH = (LED_BLUE_GPIO->CRH & CONFMASKH(LED_BLUE_PIN)) |
GPIOPINCONFH(LED_BLUE_PIN, GPIOCONF(GPIO_MODE_OUTPUT2MHz,
GPIO_CNF_OUTPUT_PUSHPULL));
#else
LED_BLUE_GPIO->CRL = (LED_BLUE_GPIO->CRL & CONFMASKL(LED_BLUE_PIN)) |
GPIOPINCONFL(LED_BLUE_PIN, GPIOCONF(GPIO_MODE_OUTPUT2MHz,
GPIO_CNF_OUTPUT_PUSHPULL));
#endif
TIM3->PSC = 23999; // Set prescaler to 24 000 (PSC + 1)
TIM3->ARR = 1000; // Auto reload value 1000
TIM3->CR1 = TIM_CR1_CEN;// Enable timer
while (1) {
if(TIM3->SR & TIM_SR_UIF) // if UIF flag is set
{
TIM3->SR &= ~TIM_SR_UIF; // clear UIF flag
LED_BLUE_GPIO->ODR ^= (1 << LED_BLUE_PIN); // toggle LED state
}
}
}
//=============================================================================
// End of file
24. //=============================================================================
After flashing STM32VLDISCOVERY board blue LED should be change their state each every
second. As i wrote - this is not the best way to use timer. The better ways are interrupts,
described in next lesson.
Lesson4. Blinking with timer interrupts
In lesson 3 we use timer TIM3 to measure time for blinking the LED, but shown method was not
perfect due to polling timer update flag. In this lesson we learn how to use timer interrupts for
blinking LED.
STM32 interrupts basics
Interrupt system of STM32 microcontrollers are described in section 8.1 of RM0041 document.
Now look into startup_stm32f10x_md_vl.s file. At line 61 (or one of their neighborhoods) is
defined vector table. This table consists from sequence of DCD (Define Constant Double word)
directive. Each of these directives defines address of handler for all interrupts on STM32
microcontroller, except the first element in this table, which is initial value of stack pointer. First
sixteen elements are reserved for vectors specific for Cortex-M3 core. Remaining positions can
be used by microcontroller vendor for their own interrupts vector. Now look at line 196. There is
defined DefauldHandler procedure, some exports functions name with WEAK keyword and
similar some of functions label. This is way to define 'default' functions, which are overrided by
definite it in other place of application. At line 281 there is only one assembler instruction:
B .
This is branch instruction to current line. It make endless loop. Now, if we don't define any
interrupt handler, all interrupt vectors will be pointed to this branch instruction. This prevents
from jumps to undefined locations when not handled interrupt occurs. Thanks to this, we can
define vectors only for used interrupts, without modifying vector table each time. How to define
our own interrupt handler? It is very simple:
void TIM3_IRQHandler(void)
{
// code of handler
}
25. When we define our handler, it's address will be placed on proper location in interrupts vectors
table. Define vector is one of things to make interrupt working. Next thing is enable interrupt in
NVIC (Nested Vectored Interrupt Controller). How do it? Like as this:
NVIC_EnableIRQ(TIM3_IRQn);
The last thing is enable peripheral to requests interrupt. For our timer we want enable update
event to generate an interrupt:
TIM3->DIER = TIM_DIER_UIE;
Now, we can place in interrupt handler our code for check flag and toggle LED state:
void TIM3_IRQHandler(void)
{
if(TIM3->SR & TIM_SR_UIF) // if UIF flag is set
{
TIM3->SR &= ~TIM_SR_UIF; // clear UIF flag
LED_BLUE_GPIO->ODR ^= (1 << LED_BLUE_PIN); // toggle LED state
}
}
Remember, interrupt flag must be cleared after enter to interrupt handler. Otherwise, interrupt
handler will be still executed.
Complete source code:
//=============================================================================
// STM32VLDISCOVERY tutorial
// Lesson 4. Blinking LED with Timer Interrupt.
// Copyright: Gaurav Verma, Assistant Professor, ECE Department.
// Jaypee Institute of Information Technology, Sector-62, Noida.
// e-mail : gaurav.iitkg@gmail.com
27. TIM3->CR1 = TIM_CR1_CEN; // Enable timer
NVIC_EnableIRQ(TIM3_IRQn); // Enable interrupt from TIM3 (NVIC level)
while (1) {}
}
//=============================================================================
// TIM3 Interrupt Handler
//=============================================================================
void TIM3_IRQHandler(void)
{
if(TIM3->SR & TIM_SR_UIF) // if UIF flag is set
{
TIM3->SR &= ~TIM_SR_UIF; // clear UIF flag
LED_BLUE_GPIO->ODR ^= (1 << LED_BLUE_PIN); // toggle LED state
}
}
//=============================================================================
// End of file
//=============================================================================
As we see, CPU execute endless loop that do nothing. But LED is blinking. Each every 1000
milliseconds state of LED is changing in the interrupt handler routine.
28. Lesson5. Blinking with timer hardware
After we successfully blink LED with interrupt from TIM3 we can do next step: blink LED only
with hardware - even without any single line of code! Of course, code for timer initialization will
be required, but blinking will be realized only by hardware. For do this, we use compare units of
timer TIM3. Now, go to section 13.3.8 of RM0041 document. There is described output compare
functionality of timer.
As you remember from previous lesson, two of discovery board LEDs can be connected to TIM3
channel 3 and 4. To connect LEDs to this channel we must configure PC8 and PC9 pin as
alternate function outputs. On PC8 and PC9 timer outputs are available only after remap. So we
need do full remap of TIM3 outputs. Now, go to section 7.4.2 of RM0041 document. There are
described register MAPR. As You see, to do full remap of TIM3 we need set both bits
TIM3_REMAP:
AFIO->MAPR = AFIO_MAPR_TIM3_REMAP; // Full TIM3 remap
To configure channel output for toggling on CH3 and CH4 output:
TIM3->CCMR2 = TIM_CCMR2_OC4M_0 | TIM_CCMR2_OC4M_1 |
TIM_CCMR2_OC3M_0 | TIM_CCMR2_OC3M_1; // Toggle output 3 & 4 on compare match
Now, we must enable compare on 3 & 4 channel :
TIM3->CCER = TIM_CCER_CC4E | TIM_CCER_CC3E;
and set compare values :
TIM3->CCR3 = 250; // Compare 4 with 250
TIM3->CCR4 = 500; // Compare 4 with 500
Complete source code :
//=============================================================================
// STM32VLDISCOVERY tutorial
// Lesson 5. Blinking LED with Timer Hardware.
// Copyright : Gaurav Verma, Assistant Professor, ECE Department.
// Jaypee Institute of Information Technology, Sector-62, Noida.
31. After flashing MCU both LEDs will be blinking with 500ms period with 250ms delay between
blue and green. And no code in endless loop and no interrupt!
Lesson6. Pulse Width Modulation (PWM)
In lesson 5 we learn how to blink led with Compare unit of timer TIM3. Compare unit can be
also used in pulse width modulation mode for brightness control of LED. Now, go to section
number 13.3.9 of RM0041 document.
Different PWM duty
Configuration of compare module is slightly different from previous example:
TIM3->CCMR2 = TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1 |
TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1; // PWM mode on channel 3 & 4
Now, CCR3 and CCR4 registers holds PWM duty value. Write initial duty value to registers:
TIM3->CCR3 = 0; // Start PWM duty for channel 3
TIM3->CCR4 = 500; // Start PWM duty for channel 4
Each time when timer reloads new value we want to change current PWM duty in both channels.
So in interrupt handler from TIM3 we well be change duty on both channels. On CH3 we
increase duty by 1% each time, on CH4 we decrease duty by 1% each time:
void TIM3_IRQHandler(void)
{
if(TIM3->SR & TIM_SR_UIF) // if UIF flag is set
{
TIM3->SR &= ~TIM_SR_UIF; // clear UIF flag
TIM3->CCR3 += 5; // increase ch3 duty
if(TIM3->CCR3 == 500) // if maximum
TIM3->CCR3 = 0; // set to zero
32. TIM3->CCR4 -= 5; // decrease ch4 duty
if(TIM3->CCR4 == 0) // if minimum
TIM3->CCR4 = 500; // set to maximum
}
}
Complete source code :
//=============================================================================
// STM32VLDISCOVERY tutorial
// Lesson 6. Pulse Width Modulation.
// Copyright: Gaurav Verma, Assistant Professor, ECE Department.
// Jaypee Institute of Information Technology, Sector-62, Noida.
// e-mail : gaurav.iitkg@gmail.com
// Mobile No.: 9811506739
//=============================================================================
#include "stm32f10x.h"
#include "antilib_gpio.h"
//=============================================================================
// Defines
//=============================================================================
#define LED_BLUE_GPIO GPIOC
#define LED_BLUE_PIN 8
#define LED_GREEN_GPIO GPIOC
#define LED_GREEN_PIN 9
//=============================================================================
// main function
//=============================================================================
34. TIM3->CCMR2 = TIM_CCMR2_OC4M_2 | TIM_CCMR2_OC4M_1 |
TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1; // PWM mode on channel 3 & 4
TIM3->CCER = TIM_CCER_CC4E | TIM_CCER_CC3E; // Enable compare on channel 3 & 4
TIM3->CR1 = TIM_CR1_CEN; // Enable timer
TIM3->DIER = TIM_DIER_UIE; // Enable update interrupt (timer level)
NVIC_EnableIRQ(TIM3_IRQn); // Enable interrupt from TIM3 (NVIC level)
while (1) {}
}
//=============================================================================
// TIM3 Interrupt Handler
//=============================================================================
void TIM3_IRQHandler(void)
{
if(TIM3->SR & TIM_SR_UIF) // if UIF flag is set
{
TIM3->SR &= ~TIM_SR_UIF; // clear UIF flag
TIM3->CCR3 += 5; // increase ch3 duty
if(TIM3->CCR3 == 500) // if maximum
TIM3->CCR3 = 0; // set to zero
TIM3->CCR4 -= 5; // decrease ch4 duty
if(TIM3->CCR4 == 0) // if minimum
TIM3->CCR4 = 500; // set to maximum
}
}
//=============================================================================
// End of file
//=============================================================================
35. Lesson 7 Analog to digital converter (ADC)
Every STM32 microcontroller has at least one 12-bit analog to digital converter. In
STM32F100RBT6 microcontroller there are one ADC with 16 input channels. In this example
we use one of analog input of MCU to control PWM duty of LED brightness (described in lesson
6). Now, we must connect external potentiometer to STM32VLDISCOVERY board like on
the schematic.
ADC peripheral is described in section 10 of RM0041 document. So read this section now.
Now, I will introduce next part of "AntiLib" project: antilib_adc.h. In this file are some intuitive
macros for easier configuration of ADC peripheral. There are macros that define sample time:
#define SAMPLE_TIME_1_5 0
#define SAMPLE_TIME_7_5 1
#define SAMPLE_TIME_13_5 2
#define SAMPLE_TIME_28_5 3
#define SAMPLE_TIME_41_5 4
#define SAMPLE_TIME_55_5 5
#define SAMPLE_TIME_71_5 6
#define SAMPLE_TIME_239_5 7
and shifting macros for each channel :
#define ADC_SAMPLE_TIME0(x) (x << 0)
#define ADC_SAMPLE_TIME9(x) (x << 27)
#define ADC_SAMPLE_TIME10(x) (x << 0)
#define ADC_SAMPLE_TIME17(x) (x << 21)
With this macros configuration of sample time for channels are clear and readable:
ADC1->SMPR2 = ADC_SAMPLE_TIME0(SAMPLE_TIME_239_5);
To define length of sequence is prepared macro:
36. #define ADC_SEQUENCE_LENGTH(x) (x << 20)
This macro shift macro parameter by 20 bits. Sequence lenght is numbered from 0. For only one
channel in sequence configuration looks like this :
ADC1->SQR1 = ADC_SEQUENCE_LENGTH(0); // One channel in sequence
I'm prepare also macros for definig each sequence channels :
// SQR3
#define ADC_SEQ1(x) (x << 0)
#define ADC_SEQ2(x) (x << 5)
#define ADC_SEQ6(x) (x << 25)
// SQR2
#define ADC_SEQ7(x) (x << 0)
#define ADC_SEQ12(x) (x << 25)
// SQR1
#define ADC_SEQ13(x) (x << 0)
#define ADC_SEQ16(x) (x << 15)
Complete configuration of ADC peripheral:
ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_CONT; // Turn on ADC, enable continues mode
ADC1->SQR1 = ADC_SEQUENCE_LENGTH(0); // One channel in sequence
ADC1->SQR3 = ADC_SEQ1(0); // ADC channel 0 is first in sequence
ADC1->SMPR2 = ADC_SAMPLE_TIME0(SAMPLE_TIME_239_5); // sample time for first channel
ADC1->CR1 = ADC_CR1_EOCIE; // Enable interrupt form End Of Conversion
NVIC_EnableIRQ(ADC1_IRQn); // Enable interrupt form ACD1 peripheral
ADC1->CR2 |= ADC_CR2_ADON; // Turn on conversion
Now we can define handler for interrupt from ADC End of Conversion:
37. void ADC1_IRQHandler (void)
{
if(ADC1->SR & ADC_SR_EOC)
{
TIM3->CCR3 = ADC1->DR; // Copy value of analog input to PWM duty register
}
}
Complete source code of example:
//=============================================================================
// STM32VLDISCOVERY tutorial
// Lesson 7. Analog to Digital Convertor.
// Copyright: Gaurav Verma, Assistant Professor, ECE Department.
// Jaypee Institute of Information Technology, Sector-62, Noida.
// e-mail : gaurav.iitkg@gmail.com
// Mobile No.: 9811506739
//=============================================================================
#include "stm32f10x.h"
#include "antilib_gpio.h"
#include "antilib_adc.h"
//=============================================================================
// Defines
//=============================================================================
#define LED_BLUE_GPIO GPIOC
#define LED_BLUE_PIN 8
#define AIN0_GPIO GPIOA
#define AIN0_PIN 0
//=============================================================================
39. TIM3->CCMR2 = TIM_CCMR2_OC3M_2 | TIM_CCMR2_OC3M_1; // PWM mode on channel 3
TIM3->CCER = TIM_CCER_CC3E; // Enable compare on channel 3
TIM3->CR1 = TIM_CR1_CEN; // Enable timer
ADC1->CR2 = ADC_CR2_ADON | ADC_CR2_CONT; // Turn on ADC, enable continues mode
ADC1->SQR1 = ADC_SEQUENCE_LENGTH(0); // One channel in sequence
ADC1->SQR3 = ADC_SEQ1(0); // ADC channel 0 is first in sequence
ADC1->SMPR2 = ADC_SAMPLE_TIME0(SAMPLE_TIME_239_5); // sample time for first channel
ADC1->CR1 = ADC_CR1_EOCIE; // Enable interrupt form End Of Conversion
NVIC_EnableIRQ(ADC1_IRQn); // Enable interrupt form ACD1 peripheral
ADC1->CR2 |= ADC_CR2_ADON; // Turn on conversion
while (1) {}
}
//=============================================================================
// ADC1 Interrupt handler
//=============================================================================
void ADC1_IRQHandler (void)
{
if(ADC1->SR & ADC_SR_EOC)
{
TIM3->CCR3 = ADC1->DR;
}
}
//=============================================================================
// End of file
//=============================================================================
Changing value of analog input should change LED brightness.
40. Lesson8. Communication with USART
In this lesson i show you the simplest way to use USART for communication with other device
(for example your PC).
USART configuration
USART peripheral is described in section 23 of RM0041 document. There is lot of data to read,
but for simple asynchronous communication we don't need read whole chapter. Main features are
described in sections from 23.3.1 to 23.3.4. To use USART peripheral we must enable clock for
it, and for GPIO used by peripheral. It is obvious, but sometimes easy to forget. USART1, which
are used in this lesson, is connected to APB2 bus, and use GPIOA (by default). Code for enable
clock for USART1 and GPIOA:
RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_USART1EN;
After enabling clock for USART1 peripheral, we can configure it. What we need to do? At this
moment we need two things: enable usart transmitter, and sets baudrate. Enabling transmitter is
done by setting UE (USART enable) and TE (transmitter enable) bits in CR1 register of
USART1 peripheral :
USART1->CR1 = USART_CR1_UE | USART_CR1_TE;
In RM0041 document there is shown sophisticated way to calculate USART baudrate. There is
mantissa and fractional part of divider, but forget about them! Calculating baudrate is easier than
shown in reference manual. So how to calculate value of BRR register? Just divide peripheral
clock by baudrate! We want configure USART for communication with transmission speed
equal to 115200 bits per second. It’s done by one line :
USART1->BRR = (SystemCoreClock / 115200);
What is SystemCoreClock? This is variable sets by SystemInit function that holds current system
frequency. By default, APB2 bus clock is equal to system frequency; we can use it to calculate
baudrate.
Sending single character
In this lesson I show simplest way to sending data - using pooling. Before write data to DR
register, we check state of TXE (transmitter empty) flag. When this flag is clear, we can't write to
DR register. High value of this flag mean that is no data in transmit buffer (previous data just be
sent or there is first transmission) and we can write new data to send. So let's create function
dedicated to sending one byte via USART:
41. void USART_PutChar(uint8_t ch)
{
while(!(USART1->SR & USART_SR_TXE));
USART1->DR = ch;
}
Sending text
When we can send single character we can write function for sending typical for C language
null-terminated strings. Null terminated string is character array, that last element has value zero.
Empty string has one element - value zero. So before sending character we must check if
character has different value than zero. If this condition is true, we can send first character and
increment pointer to prepare next character to send. Repeat this in loop until pointer will be
pointed to character value zero.
void USART_PutString(uint8_t * str)
{
while(*str != 0)
{
USART_PutChar(*str);
str++;
}
}
Now, we are ready to send text by USART:
USART_PutString(text); // argument is pointer variable
USART_PutString("Some text to send"); // argument is constant string
44. USART_TX_GPIO->CRL = (USART_TX_GPIO->CRL & CONFMASKL(USART_TX_PIN)) |
GPIOPINCONFL(USART_TX_PIN, GPIOCONF(GPIO_MODE_OUTPUT2MHz,
GPIO_CNF_AFIO_PUSHPULL));
#endif
USART1->CR1 = USART_CR1_UE | USART_CR1_TE;
USART1->BRR = (SystemCoreClock / 115200);
while (1)
{
USART_PutString(text);
for(dly = 0; dly < 1000000; dly++);
}
}
//=============================================================================
// End of file
//=============================================================================
Effect of this code:
45. Lesson9. Analog to digital converter (ADC) with Direct Memory Access (DMA)
In lesson 7 I introduce analog to digital converter, that measure voltage on one analog input. For
measure voltage on more than one input the best way is use DMA for automatic transfer data
from ADC to memory. Direct memory access is a mechanism that allows to transferring data
between memories without usage of CPU.
ADC configuration
In comparison to ADC configuration from lesson 7, we must enabled two new modes in ADC
peripheral: SCAN mode and DMA mode. Scan mode allows for automatic scanning selected
channels without interaction from CPU. After conversion of each channel immediately starts
new conversion of next channel in sequence. We can scan up to 16 regular channels in the
sequence. In scan mode there is risk of overwrite data from previous conversion, because all
conversion results are stored in this same data register (DR). For this reason in connection with
SCAN mode are used DMA mode, that allows for automatic storage of conversion values in data
memory after each conversion.
ADC1->CR2 = ADC_CR2_ADON | // turn on ADC
ADC_CR2_CONT | // enable continues mode
ADC_CR2_DMA; // enable DMA mode
ADC1->CR1 = ADC_CR1_SCAN; // enable scan mode
Configuration of ADC sequencer:
ADC1->SQR1 = ADC_SEQUENCE_LENGTH(3); // four channels in sequence
ADC1->SQR3 = ADC_SEQ1(0) | // channel 0 is first in sequence
ADC_SEQ2(1) | // channel 1 is second in sequence
ADC_SEQ3(2) | // channel 2 is third in sequence
ADC_SEQ4(3) ; // channel 3 is fourth in sequence
ADC1->SMPR2 = ADC_SAMPLE_TIME0(SAMPLE_TIME_239_5) | // sample time for first channel in
sequence
ADC_SAMPLE_TIME1(SAMPLE_TIME_239_5) | // sample time for second channel in sequence
ADC_SAMPLE_TIME2(SAMPLE_TIME_239_5) | // sample time for third channel in sequence
46. ADC_SAMPLE_TIME3(SAMPLE_TIME_239_5) ; // sample time for fourth channel in sequence
Variable for storing conversion values :
vu16 AIN[4]; // 4 locations
DMA configuration
Before we use DMA for transferring data between two areas of memory space of STM32
microcontroller, we have to say to DMA peripheral some informations, like as : source address
(data register of ADC), destination address (table for conversions results), number of transfers
(amount of scanned input channels).
DMA1_Channel1->CPAR = (uint32_t)(&(ADC1->DR)); // peripheral (source) address
DMA1_Channel1->CMAR = (uint32_t)AIN; // memory (destination) address
DMA1_Channel1->CNDTR = 4; // 4 transfers
DMA1_Channel1->CCR |= DMA_CCR1_CIRC | // circular mode enable
DMA_CCR1_MINC | // memory increment mode enable
DMA_CCR1_MSIZE_0 | // memory size 16 bits
DMA_CCR1_PSIZE_0; // peripheral size 16 bits
DMA1_Channel1->CCR |= DMA_CCR1_EN ; // Enable channel
Sending conversion results
For sending result we use code from lesson 8.
do{
sprintf(str, "0:%dtt1:%dtt2:%dtt3:%dr", AIN[0], AIN[1], AIN[2], AIN[3]);
USART_PutString(str);
for(dly = 0; dly < 1000000; dly++);
}while(1);