1, Experiment 1 programming ideas
Use the serial port debugging assistant to print out and receive data
Serial port receiving and sending
(characters are sent in the serial port assistant. Set the number of hexadecimal display to be numbers)
Overall idea:
1. Enable RX and TX pins GPIO clock and USART clock;
2. Initialize GPIO and multiplex GPIO to USART;
3. Configure USART parameters;
4. Configure interrupt controller and enable USART to receive interrupt;
5. Enable USART;
6. Receive interrupt service function in USART to receive and send data.
bap_usart.c
The structure is defined at the beginning of the function
1. Open serial port GPIO clock
2. Turn on the serial peripheral clock
3. Configure the GPIO of USART Rx to push-pull multiplexing mode
4. Configure GPIO of USART Tx to float input mode (what happens externally and what level is generated)
5. Configure serial port operating parameters
Baud rate, pin array duration (8 bits), stop bit (1 bit), check bit (no is used), hardware flow control (none is used), working mode. Send and receive together (both receive and send are enabled), and complete serial port initialization configuration
(if the received data is not empty, an interrupt is generated, and the data is sent to the computer in the interrupt function)
6. Serial port interrupt priority configuration
[interrupt source (IRQn_Type; in header file), priority grouping (preemptive priority, sub priority, enable interrupt, initialize and configure NVIC)]
7. Enable serial port receive priority
(then write the interrupt service function in stm32f10x_it.c)
Interrupt service function implementation function: send data to the single chip microcomputer in the serial port debugging assistant (or external equipment). The single chip microcomputer detects that the received data register is not empty, resulting in an interrupt
In the interrupt service function, check whether the flag bit is really empty, receive the data to the new variable, and then return the data to the sender by the sending function
8. Enable serial port
Send data to the upper computer: two formal parameters of the function (specify the serial port and the data sent by 8-bit unit8_t)
The formal parameters (data 16 bits) of the called function will be forcibly converted to 8 bits
Serial port control RGB lamp
Comment on interrupt function and interrupt service function
main.c
Defining variables: receiving data
Print with function printf() (if this function is configured)
#ifndef __USART_H
#define __USART_H
#include "stm32f10x.h"
#include <stdio.h>
/**
- Serial port macro definition. Different serial ports have different buses and IO. These macros need to be modified during migration
- 1 - modify the macro of the bus clock, mount uart1 to apb2 bus, and mount other UARTS to apb1 bus
- 2 - modify GPIO macro
*/
2, Code parsing
bsp_usart.h
// Serial port 1-USART1 #define DEBUG_USARTx USART1 #define DEBUG_USART_CLK RCC_APB2Periph_USART1 #define DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd #define DEBUG_USART_BAUDRATE 115200 // USART GPIO pin macro definition #define DEBUG_USART_GPIO_CLK (RCC_APB2Periph_GPIOA) #define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd #define DEBUG_USART_TX_GPIO_PORT GPIOA #define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_9 #define DEBUG_USART_RX_GPIO_PORT GPIOA #define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_10 #define DEBUG_USART_IRQ USART1_IRQn #define DEBUG_USART_IRQHandler USART1_IRQHandler void USART_Config(void); void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch); void Usart_SendString( USART_TypeDef * pUSARTx, char *str); void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch); #endif /* __USART_H */
bap_usart.c
#include "bsp_usart.h" /*Configure nested vector interrupt controller NVIC*/ static void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; /* Nested vector interrupt controller group selection */ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /* Configure USART as interrupt source */ NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ; /* Preemption priority*/ NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; /* Sub priority */ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; /* Enable interrupt */ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; /* Initialize and configure NVIC */ NVIC_Init(&NVIC_InitStructure); } /*USART GPIO Configuration, working parameter configuration*/ void USART_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; // Open the clock of serial port GPIO DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE); // Turn on the clock of the serial peripheral DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE); // Configure the GPIO of USART Tx to push-pull multiplexing mode GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure); // Configure GPIO of USART Rx to float input mode GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure); // Configure the working parameters of the serial port // Configure baud rate USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE; // Configure pin data word length USART_InitStructure.USART_WordLength = USART_WordLength_8b; // Configure stop bit USART_InitStructure.USART_StopBits = USART_StopBits_1; // Configure check bit USART_InitStructure.USART_Parity = USART_Parity_No ; // Configure hardware flow control USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // Configure the working mode and send and receive together USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // Complete the initialization configuration of the serial port USART_Init(DEBUG_USARTx, &USART_InitStructure); // Serial port interrupt priority configuration NVIC_Configuration(); // Enable serial port to receive interrupt USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE); // Enable serial port USART_Cmd(DEBUG_USARTx, ENABLE); } /***************** Send a byte**********************/ void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch) { /* Send a byte of data to USART */ USART_SendData(pUSARTx,ch); /* The waiting to send data register is empty */ while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); } /****************** Send 8-bit array************************/ void Usart_SendArray( USART_TypeDef * pUSARTx, uint8_t *array, uint16_t num) { uint8_t i; for(i=0; i<num; i++) { /* Send a byte of data to USART */ Usart_SendByte(pUSARTx,array[i]); } /* Wait for sending to complete */ while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET); } /***************** Send string**********************/ void Usart_SendString( USART_TypeDef * pUSARTx, char *str) { unsigned int k=0; do { Usart_SendByte( pUSARTx, *(str + k) ); k++; } while(*(str + k)!='\0'); /* Wait for sending to complete */ while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET) {} } /***************** Send a 16 digit number**********************/ void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch) { uint8_t temp_h, temp_l; /* Take out the top eight */ temp_h = (ch&0XFF00)>>8; /* Take out the lower eight bits */ temp_l = ch&0XFF; /* Send high eight bits */ USART_SendData(pUSARTx,temp_h); while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); /* Send lower octet */ USART_SendData(pUSARTx,temp_l); while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); } ///Redirect the c library function printf to the serial port. After resetting, use the printf function int fputc(int ch, FILE *f) { /* Send a byte of data to the serial port */ USART_SendData(DEBUG_USARTx, (uint8_t) ch); /* Wait for sending to complete */ while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET); return (ch); } ///Redirect the c library function scanf to the serial port. After rewriting, you can use scanf, getchar and other functions int fgetc(FILE *f) { /* Wait for serial port input data */ while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET); return (int)USART_ReceiveData(DEBUG_USARTx); }
main.c
#include "stm32f10x.h" #include "bsp_usart.h" int main(void) { /*Initialize USART configuration mode to 115200 8-N-1 and interrupt reception*/ USART_Config(); /* Send a string */ Usart_SendString( DEBUG_USARTx,"This is a serial port interrupt receiving echo experiment\n"); printf("Welcome to wildfire STM32 Development board\n\n\n\n"); while(1) { } }
3, Experiment 2 programming ideas
Serial port control RGB lamp
Comment on interrupt function and interrupt service function
main.c
Defining variables: receiving data
Print with function printf() (if this function is configured)
Overall idea:
1. Initialize and configure RGB color lamp GPIO;
2. Enable RX and TX pins GPIO clock and USART clock;
3. Initialize GPIO and multiplex GPIO to USART;
4. Configure USART parameters;
5. Enable USART;
6. Obtain the command input and control the RGB color lamp according to the command.
4, Code parsing
bsp_usart.h
#ifndef __USART_H #define __USART_H #include "stm32f10x.h" #include <stdio.h> /** * Serial port macro definition. Different serial ports have different buses. These macros need to be modified during transplantation */ #define DEBUG_USARTx USART1 #define DEBUG_USART_CLK RCC_APB2Periph_USART1 #define DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd #define DEBUG_USART_BAUDRATE 115200 // USART GPIO pin macro definition #define DEBUG_USART_GPIO_CLK (RCC_APB2Periph_GPIOA) #define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd #define DEBUG_USART_TX_GPIO_PORT GPIOA #define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_9 #define DEBUG_USART_RX_GPIO_PORT GPIOA #define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_10 #define DEBUG_USART_IRQ USART1_IRQn #define DEBUG_USART_IRQHandler USART1_IRQHandler void USART_Config(void); void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch); void Usart_SendString( USART_TypeDef * pUSARTx, char *str); void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch); #endif /* __USART_H */
bsp_usart.c
/*Redirect c library printf function to usart port*/ #include "bsp_usart.h" /*USART GPIO Configuration, working parameter configuration*/ void USART_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; // Open the clock of serial port GPIO DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE); // Turn on the clock of the serial peripheral DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE); // Configure the GPIO of USART Tx to push-pull multiplexing mode GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure); // Configure GPIO of USART Rx to float input mode GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure); // Configure the working parameters of the serial port // Configure baud rate USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE; // Configure pin data word length USART_InitStructure.USART_WordLength = USART_WordLength_8b; // Configure stop bit USART_InitStructure.USART_StopBits = USART_StopBits_1; // Configure check bit USART_InitStructure.USART_Parity = USART_Parity_No ; // Configure hardware flow control USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // Configure the working mode and send and receive together USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // Complete the initialization configuration of the serial port USART_Init(DEBUG_USARTx, &USART_InitStructure); // Enable serial port USART_Cmd(DEBUG_USARTx, ENABLE); } /***************** Send a character**********************/ void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch) { /* Send a byte of data to USART */ USART_SendData(pUSARTx,ch); /* The waiting to send data register is empty */ while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); } /***************** Send string**********************/ void Usart_SendString( USART_TypeDef * pUSARTx, char *str) { unsigned int k=0; do { Usart_SendByte( pUSARTx, *(str + k) ); k++; } while(*(str + k)!='\0'); /* Wait for sending to complete */ while(USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET) {} } /***************** Send a 16 digit number**********************/ void Usart_SendHalfWord( USART_TypeDef * pUSARTx, uint16_t ch) { uint8_t temp_h, temp_l; /* Take out the top eight */ temp_h = (ch&0XFF00)>>8; /* Take out the lower eight bits */ temp_l = ch&0XFF; /* Send high eight bits */ USART_SendData(pUSARTx,temp_h); while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); /* Send lower octet */ USART_SendData(pUSARTx,temp_l); while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET); } ///Redirect the c library function printf to the serial port. After resetting, use the printf function int fputc(int ch, FILE *f) { /* Send a byte of data to the serial port */ USART_SendData(DEBUG_USARTx, (uint8_t) ch); /* Wait for sending to complete */ while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET); return (ch); } ///Redirect the c library function scanf to the serial port. After rewriting, you can use scanf, getchar and other functions int fgetc(FILE *f) { /* Wait for serial port input data */ while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET); return (int)USART_ReceiveData(DEBUG_USARTx); }
main.c
/** ****************************************************************************** * @file main.c * @author fire * @version V1.0 * @date 2013-xx-xx * @brief Serial port interrupt receiving test ****************************************************************************** * @attention * * Experimental platform: Wildfire F103 domineering STM32 development board * Forum: http://www.firebbs.cn * TaoBao: https://fire-stm32.taobao.com * ****************************************************************************** */ #include "stm32f10x.h" #include "./led/bsp_led.h" #include "./usart/bsp_usart.h" static void Show_Message(void); int main(void) { char ch; /* Initialize RGB lights */ LED_GPIO_Config(); /* Initialize USART configuration mode to 115200 8-N-1 */ USART_Config(); /* Print instruction input prompt information */ Show_Message(); while(1) { /* Get character instruction */ ch=getchar(); printf("Characters received:%c\n",ch); /* Control the color of RGB color lights according to character instructions */ switch(ch) { case '1': LED_RED; break; case '2': LED_GREEN; break; case '3': LED_BLUE; break; case '4': LED_YELLOW; break; case '5': LED_PURPLE; break; case '6': LED_CYAN; break; case '7': LED_WHITE; break; case '8': LED_RGBOFF; break; default: /* If the command character is not specified, the prompt message will be printed */ Show_Message(); break; } } } /** * @brief Print instruction input prompt information * @param nothing * @retval nothing */ static void Show_Message(void) { printf("\r\n This is a command control through serial communication RGB Lantern experiment \n"); printf("use USART The parameters are:%d 8-N-1 \n",DEBUG_USART_BAUDRATE); printf("Control after the development board receives the instruction RGB For the color of colored lights, the corresponding instructions are as follows:\n"); printf(" instructions ------ Lantern color \n"); printf(" 1 ------ red \n"); printf(" 2 ------ green \n"); printf(" 3 ------ blue \n"); printf(" 4 ------ yellow \n"); printf(" 5 ------ purple \n"); printf(" 6 ------ young \n"); printf(" 7 ------ white \n"); printf(" 8 ------ Extinguish \n"); }
bsp_led.c
#include "./led/bsp_led.h" /*Initialize IO of control LED*/ void LED_GPIO_Config(void) { /*Define a GPIO_ Struct of inittypedef type*/ GPIO_InitTypeDef GPIO_InitStructure; /*Turn on the GPIO peripheral clock related to the LED*/ RCC_APB2PeriphClockCmd( LED1_GPIO_CLK | LED2_GPIO_CLK | LED3_GPIO_CLK, ENABLE); /*Select the GPIO pin to control*/ GPIO_InitStructure.GPIO_Pin = LED1_GPIO_PIN; /*Set pin mode to universal push-pull output*/ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /*Set the pin rate to 50MHz */ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /*Call the library function to initialize GPIO*/ GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure); /*Select the GPIO pin to control*/ GPIO_InitStructure.GPIO_Pin = LED2_GPIO_PIN; /*Call the library function to initialize GPIO*/ GPIO_Init(LED2_GPIO_PORT, &GPIO_InitStructure); /*Select the GPIO pin to control*/ GPIO_InitStructure.GPIO_Pin = LED3_GPIO_PIN; /*Call the library function to initialize GPIOF*/ GPIO_Init(LED3_GPIO_PORT, &GPIO_InitStructure); /* Turn off all led lights */ GPIO_SetBits(LED1_GPIO_PORT, LED1_GPIO_PIN); /* Turn off all led lights */ GPIO_SetBits(LED2_GPIO_PORT, LED2_GPIO_PIN); /* Turn off all led lights */ GPIO_SetBits(LED3_GPIO_PORT, LED3_GPIO_PIN); } void assert_failed(uint8_t* file, uint32_t line) { // Code executed when asserting an error LED1_ON; }
bsp_led.h
#ifndef __LED_H #define __LED_H #include "stm32f10x.h" /* Define the GPIO port of LED connection. The user only needs to modify the following code to change the LED pin of control */ // R-red #define LED1_GPIO_PORT GPIOB /* GPIO port*/ #define LED1_GPIO_CLK RCC_APB2Periph_GPIOB /* GPIO port clock*/ #define LED1_GPIO_PIN GPIO_ Pin_ five /* GPIO connected to SCL clock line*/ // G-green #define LED2_GPIO_PORT GPIOB /* GPIO port*/ #define LED2_GPIO_CLK RCC_APB2Periph_GPIOB /* GPIO port clock*/ #define LED2_GPIO_PIN GPIO_Pin_0 /* GPIO connected to SCL clock line*/ // B-blue #define LED3_GPIO_PORT GPIOB /* GPIO port*/ #define LED3_GPIO_CLK RCC_APB2Periph_GPIOB /* GPIO port clock*/ #define LED3_GPIO_PIN GPIO_ Pin_ one /* GPIO connected to SCL clock line*/ //1 - off //0 - on #define ON 0 #define OFF 1 /* Control IO using standard firmware library*/ #define LED1(a) if (a) \ GPIO_SetBits(LED1_GPIO_PORT,LED1_GPIO_PIN);\ else \ GPIO_ResetBits(LED1_GPIO_PORT,LED1_GPIO_PIN) #define LED2(a) if (a) \ GPIO_SetBits(LED2_GPIO_PORT,LED2_GPIO_PIN);\ else \ GPIO_ResetBits(LED2_GPIO_PORT,LED2_GPIO_PIN) #define LED3(a) if (a) \ GPIO_SetBits(LED3_GPIO_PORT,LED3_GPIO_PIN);\ else \ GPIO_ResetBits(LED3_GPIO_PORT,LED3_GPIO_PIN) /* The method of directly operating registers controls IO */ #define digitalHi(p,i) {p->BSRR=i;} // Output is high #define digitalLo(p,i) {p->BRR=i;} // Output low level #Define digitaltoggle (P, I) {p - > ODR ^ = I;} / / output reverse status /* Define macros that control IO */ #define LED1_TOGGLE digitalToggle(LED1_GPIO_PORT,LED1_GPIO_PIN) #define LED1_OFF digitalHi(LED1_GPIO_PORT,LED1_GPIO_PIN) #define LED1_ON digitalLo(LED1_GPIO_PORT,LED1_GPIO_PIN) #define LED2_TOGGLE digitalToggle(LED2_GPIO_PORT,LED2_GPIO_PIN) #define LED2_OFF digitalHi(LED2_GPIO_PORT,LED2_GPIO_PIN) #define LED2_ON digitalLo(LED2_GPIO_PORT,LED2_GPIO_PIN) #define LED3_TOGGLE digitalToggle(LED3_GPIO_PORT,LED3_GPIO_PIN) #define LED3_OFF digitalHi(LED3_GPIO_PORT,LED3_GPIO_PIN) #define LED3_ON digitalLo(LED3_GPIO_PORT,LED3_GPIO_PIN) /* Basic color mixing, later advanced usage, use PWM to mix full-color color, and the effect is better */ //red #define LED_RED \ LED1_ON;\ LED2_OFF\ LED3_OFF //green #define LED_GREEN \ LED1_OFF;\ LED2_ON\ LED3_OFF //blue #define LED_BLUE \ LED1_OFF;\ LED2_OFF\ LED3_ON //Yellow (red + green) #define LED_YELLOW \ LED1_ON;\ LED2_ON\ LED3_OFF //Purple (red + blue) #define LED_PURPLE \ LED1_ON;\ LED2_OFF\ LED3_ON //Cyan (green + blue) #define LED_CYAN \ LED1_OFF;\ LED2_ON\ LED3_ON //White (red + Green + blue) #define LED_WHITE \ LED1_ON;\ LED2_ON\ LED3_ON //Black (all closed) #define LED_RGBOFF \ LED1_OFF;\ LED2_OFF\ LED3_OFF void LED_GPIO_Config(void); #endif /* __LED_H */