When learning a new processor, the first program must be to light up the LED. It allows us to quickly and clearly understand the program structure of a processor. Learning 32 is no exception. First, the first program is to light up the LED. There are many kinds of programs to light up the LED. Here we use the library function to realize the flashing of the LED.
The development board I use is the elite version of the development board of Zhengdian Atom.
First, copy the project template we created earlier, and then name the folder LED.
Then open this project file. The first step is to create two blank pages and save them to the HARDWARE folder according to the method in my previous blog. One is named led.c and the other is named led.h. Then add these two files to the project in the keil MDK software. After adding, our project structure is as shown below.
After adding, don't forget to add the .h file path. Click the magic wand icon in the keil MDK software, then go to the c/c++ column and click the three dots behind include Paths.
After the above steps, find the HARDWARE folder and double-click the LED folder (please ignore the path I have already added). Note that when adding the path, you must be accurate to the last level folder.
In fact, you also need to add paths to several other folders. The specific methods are clearly explained in the incomplete manual provided in the official forum of Zhengdian Atom. You can take a look at it.
Attached is the official forum URL of Zhengdian Atom: http://www.openedv.com/thread-13912-1-1.html
After these basic tasks are completed, we can start writing programs.
First, write the following program in the led.h file
#ifndef __LED_H
#define __LED_H
#include"sys.h"
#define LED0 PBout(5)
void led_init(void);
#endif
(Note that at the end of each .c and .h file, we need to add a carriage return. This may be a BUG of the Keil MDK software itself. If you don't add it, there will be a warning when compiling)
The program in this .h file is used to define a led.h header file so that we can call it in the led.c file.
The declaration of the header file also has a fixed format, as follows:
#ifndef __LED_H
#define __LED_H
#endif
This means that if the led.h header file is not defined, we define a led.h header file, and then add #endif at the end to indicate that the definition is complete.
Then the #include "sys.h" in the led.h file calls the "sys.h" header file in the project. Each newly defined header file in the future will need to call this header file. This "'sys.h" header file defines some things needed by 32 programs. If you are interested, you can go into this header file and take a look.
#define LED0 PBout(5)
This statement is a macro definition. You can think of it as equivalent to the function of sbit in our 51 MCU, which is to replace the PB5 pin with LED0, and the PB5 pin is output, that is, the expression format is PBout(5)
Then write the program in the led.c file
#include"led.h"
void led_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
This led.c file mainly defines a GPIO port initialization program, which is to configure the GPIO port used to light up the LED. (Note that when defining a function, if there is no parameter to be passed, void must be written, that is, we must write led_init(void), otherwise there will be a warning in the compilation, but when calling the function, if there is no parameter to be passed, we do not need to write void, we can directly call led_init()) In addition, for 32, generally all configurations are implemented using structures, and the members in the structure represent the working mode of this function. Take our lighting up the LED this time, we use LED0, which is connected to the PB5 pin on the elite version of the positive point atom, that is, we need to configure the PB5 pin to work in a way that can light up the LED.
First we need to declare a structure GPIO_InitStructure
GPIO_InitTypeDef GPIO_InitStructure;
We can write any name for the GPIO_InitStructure structure, but we can only write the name GPIO_InitTypeDef in this way, because it is already defined in the firmware library, so we cannot change it at will. Note that the definition of the structure must be at the beginning of the function, and we cannot define variables in the middle of the function (in fact, all definitions must be at the beginning of the function, which is the same as the C language we learned at the beginning)
Then we need to turn on the GPIOB clock, because basically every part of 32 has its own independent clock. If we want a certain module to work, we must enable its clock. The function to enable the clock is also fixed. We only need to call this function and pass in the corresponding parameters. The original function is as follows
RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState NewState)
The first parameter of this function is to select which module's clock you want to enable, and the second parameter is to select whether to enable or not. Enabling is ENABLE, and disabling is DISABLE. (Here we use the APB2 bus, 32 also has the APB1 bus, APB2 is a high-speed bus, APB1 is a low-speed bus, some modules are connected to the APB1 bus, and some are connected to the APB2 bus, we should analyze the specific situation)
So now we want to use the PB5 pin, that is, we want to enable the GPIOB clock, so we have to write it as follows
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
Next we need to assign values to the members of the structure just defined.
First we enter GPIO_InitStructure, and then enter a dot "."
GPIO_InitStructure. At this time, the program will automatically display the member variables in this structure for you to choose (this is the same as our C language). In this structure, we need to configure three members, which are broken down into GPIO_Mode, GPIO_Pin, and GPIO_Speed.
Then we select GPIO_Mode, right-click and enter Go To Definition of "GPIO_Mode", then we will be transferred to a gpio.h file, in which we find the relevant definition of GPIO_Mode.
#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_Mode_AIN) || ((MODE) == GPIO_Mode_IN_FLOATING) || \
((MODE) == GPIO_Mode_IPD) || ((MODE) == GPIO_Mode_IPU) || \
((MODE) == GPIO_Mode_Out_OD) || ((MODE) == GPIO_Mode_Out_PP) || \
((MODE) == GPIO_Mode_AF_OD) || ((MODE) == GPIO_Mode_AF_PP))
We can see that GPIO has many working modes. We need to choose a specific working mode according to our actual needs. Here we want to light up the LED light, so we choose the push-pull output working mode, that is, select GPIO_Mode_Out_PP
Then the configuration of the other two structure members is similar, and the last three members are configured as follows
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
(Regarding GPIO_Speed, I actually don’t quite understand what it means. It seems to configure the maximum output speed of the GPIO port. Here we choose the maximum speed, which is 50MHz)
After assigning values to each member variable, we need to import these values into the structure. At this time, we need another function
GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
This function imports the members of the structure into the corresponding registers using the following function. (If you don't understand it for now, remember that you will use this function for every configuration in the future.) The first parameter of this function is the GPIO port you want to configure, and the second parameter is the name of the structure you just defined plus the symbol "&". The final program is as follows
GPIO_Init(GPIOB,&GPIO_InitStructure);
At this point, we have completed the initialization process of the GPIO port, and then we call it in the main function. Pay attention to the functions you define in the .c file, and don't forget to declare them in the .h file corresponding to this .c file. Here we define a function led_init(void) in led.c, so we need to declare this function in the led.h file. The led.h file is as follows
#ifndef __LED_H
#define __LED_H
#include "sys.h"
#define LED0 PBout(5)
void led_init(void);
#endif
Next, we operate in main.c, the program is as follows
#include "sys.h"
#include "delay.h"
#include "led.h"
int main(void)
{
led_heat();
delay_init();
while(1)
{
LED0=0;
delay_ms(100);
LED0=1;
delay_ms(100);
}
}
The first step is to add the header files used in our program
#include "sys.h"
#include "delay.h"
#include "led.h"
Among them, delay.h is also added when building the project template. It defines some delay functions. We usually add this delay.h file in the main function so that we can call the delay function at any time (in which .c file you call the corresponding function, you must add the .h file corresponding to this function to the current .c file. Maybe what I said is a bit confusing, and you will understand it slowly later).
Then write the main function. Note that the main function of 32 cannot be void main(void), it must be int main(void) (I don't know why)
In the main function, we first call the LED initialization function written in the led.c file, then call the delay function, and then write a while loop to let the LED continuously flip its state in the loop. The program is as follows
int main(void)
{
led_heat();
delay_init();
while(1)
{
LED0=0;
delay_ms(100);
LED0=1;
delay_ms(100);
}
}
So far, our program to light up the LED has been written. After compiling, if there are no errors, we can burn it to the development board for testing. If everything is correct, we can see that a small light on the development board will flash continuously, and the flashing interval is 100ms written in the while loop.
This concludes the LED lighting experiment!
Previous article:Watchdog in STM32
Next article:【STM32】Basic principles and library functions of SPI (general steps of SPI)
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Huawei's Strategic Department Director Gai Gang: The cumulative installed base of open source Euler operating system exceeds 10 million sets
- Download from the Internet--ARM Getting Started Notes
- Learn ARM development(22)
- Learn ARM development(21)
- Learn ARM development(20)
- Learn ARM development(19)
- Learn ARM development(14)
- Learn ARM development(15)
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- How do I delete a post?
- MSP430G2553 IO external interrupt description
- DIY low power Bluetooth, USB dual-mode mechanical keyboard—by jj1989
- Infrared remote control
- Let’s discuss the relationship between transformers and inductors again.
- 【Arduino】168 sensor module series experiments (218) --- 1.3 inch TFT display
- EEWORLD University ---- Introduction to the internal structure of FPGA (Intel official tutorial)
- EEWORLD University Hall----Live Replay: Keysight High-Speed Oscilloscope Basics and Keysight's New Oscilloscope Analysis
- Micropython-Editor that can embed Micropython
- ARM Cortex-M3 and Cortex-M4 Definitive Guide (3rd Edition)