This post was last edited by lvxinn2006 on 2019-1-11 08:55 The development board evaluated in this eventST NUCLEO-G071RB is provided by STMicroelectronics. Thanks to STMicroelectronics for its support for EEWorld's evaluation! https://www.stmcu.com.cn/Product/pro_detail/cat_code/STM32G0/family/81/sub_family/261/layout/product 【Purpose】 · Masterthe configuration method of GPIO multiplexing function
· Master the use of USART interrupt
· Understand the basic principles of USART serial port use
【Experimental environment】
· NUCLEO-G071RB development board
· Keil MDK-ARM(Keil uVision 5.25.2.0)
· Keil.STM32G0xx_DFP.1.0.0.pack
【Experimental materials】
· NUCLEO-G071RB development board schematic diagram
· STM32G071x8/xB Data Sheet
· STM32G071 chip user reference manual
【ExperimentalAnalysis】
· View the schematic diagram
In NUCLEO-G071RB, the most convenient UART serial port is UART2, which is directly connected to the ST_LINK's virtual serial port. The schematic diagram is as follows:
Now let's take UART2 as an example to realize the serial port communication step by step. According to the PORT in the schematic diagram, you can find the GPIO pins corresponding to the TX and RX pins, TX-->PA2, RX-->PA3, as shown in the following figure: 397830· View the STM32G071 chip user reference manual Enable GPIO clock As in the previous experiment, you need to turn on the clock before using the GPIO port. Here GPIOA is used, so you need to change the position of RCC_IOPENR0 to 1. The principle is shown in the figure below: 397831 Setting the GPIO pin function After turning on the GPIOA clock, set the GPIO function, that is, set the GPIOA_MODER register. According to the reference manual, MODE The DER register is defined as follows: 397832 corresponds to the PA2 and PA3 pins at 5:4 and 7:In the description of the bit segment, we can see that 00 is the input mode, 01 is the general output mode, and 10 is the multiplexing function mode. According to the application requirements, we need to use PA2 and PA3 as To use the Tx and Rx of UART, we need to configure MODER[5:4][7:6] to 10, that is, the multiplexing function mode (AF) When the MODER register is configured to AF mode, the AFRL and AFRH registers are needed to further set the pin functions. The register definitions are as follows: 397833 In this register, every 4 bits control one pin. The function of the PA2 pin is located in the four bits at 11:8, and the function of the PA3 pin is located in the four bits at 15:12. There are 8 bits in each of the 4 bits, 0000~0111. =宋体] combinations represent 8 functions of the pins. Here, the corresponding values are represented by AF0~AF8. The value corresponding to each pin has different functions. The following table describes the functions corresponding to the pin AF values. Among them, AF1 of PA2 represents USART2_TX, AF1 of PA3 represents the USART2_RX function. 397863 So far, we have basically determined the configuration method of the AF register. We need to configure 11:8 as 0x1 (0001:AF1) and 15:12 as 0x1 (0001:AF1).
In this way, the pin functions of PA2 and PA3 are configured. Next, we need to configure the USART peripheral module.
EnableUSART2clock
The USART is connected to the system'sAPBbus, so theUSARTclock control, inAPBENR1, is shown in the following figure:
You need to set the[17]bit of the register to enableUSART2clock.
EnableUSART2module
USARTregisters are quite large, but most of the default parameters have met the requirements. We don't need to set many registers. First, we need to configureCR1register, focusing on setting the three data bits shown in the figure below:
[ The two bits in the register are used to enable Tx and Rx, the bit 0 is used to enable the USART device, and the bit 5 is used to enable the receive data interrupt. Set the baud rate 397867 397867 397868 For details on the calculation method, see the document. Based on the document, I summarized a formula that can be used directly in the code: //Baudrate = Fclk/(16*USARTDIV) //USARTDIV = Fclk / Baudrate / 16 // = 16000000 / 115200 / 16 // = 8.68
temp = SystemCoreClock * 100 / baud / 16;
brr = ((temp / 100)<<4) | ((temp%100) * 16 / 100) + (((temp%100) * 16 / 100)%100)/50;
USART2->BRR = brr;
Serial port initialization function implementation
- void UART2_Init(int baud) { uint32_t temp; uint32_t brr; RCC->IOPENR |= (1<<0); //Enable GPIOA RCC->APBENR1 |= (1<<17); //Enable USART2 GPIOA->MODER &= ~((0x3<<4) | (0x3<<6)); //PA2 PA3 GPIOA->MODER |= (0x2<<4) | (0x2<<6); //PA2 PA3 GPIOA->AFR[0] &= ~((0xFUL<<12) | (0xFUL<<8)); //PA2 Tx PA3 Rx GPIOA->AFR[0] |= (0x1<<12) | (0x1<<8); //PA2 Tx PA3 Rx temp = SystemCoreClock * 100 / baud / 16; brr = ((temp / 100)<<4) | ((temp%100) * 16 / 100) + (((temp%100) * 16 / 100)%100)/50; USART2->BRR = brr; USART2->CR1 |= (1<<0) //UE=1 USART Enable | (1<<3 ) //TE=1 Transmitter Enable | (1<<2); //RE=1 Revicer Enable USART2->CR1 |= (1<<5); //enable RXNEIE NVIC_EnableIRQ(USART2_IRQn); }
复制代码Data transmission
Data transmission mainly uses theTDRregister. When writing data to theTDRregister, the data will be sent out through theTxDpin, and once the transmission is completed, the completion status will be reflected in theISRregister. The encapsulated transmission function is as follows:
- void UART2_PutChar(int data) { while((USART2->ISR&(1u<<7)) == 0); //Wait TXE=1 USART2->TDR = data; } Enable USART interrupts. Enable interrupts and use the NVIC_EnableIRQ() function provided by CMSIS directly. NVIC_EnableIRQ(USART2_IRQn); Data Reception When the RxD pin receives data, the data will be saved in the RDR register. If the RXNE bit is set in CR1, an interrupt will be triggered when data is received. The received data can be processed in the interrupt handler. Code #define UART2_RBUF_SIZE 64 volatile uint32_t UARTStatus; volatile uint8_t UARTTxEmpty = 1; volatile uint8_t UARTBuffer[UART2_RBUF_SIZE]; volatile uint32_t UARTCount = 0; volatile uint32_t UART_op = 0; void USART2_IRQHandler(void) //interrupt handling function{ if (USART2->ISR & (1<<5)){ //Received dataUARTBuffer[UARTCount++] = USART2->RDR; if (UARTCount >= UART2_RBUF_SIZE) { UARTCount = 0; /* buffer overflow */ } } } int UART2_GetChar(uint8_t *ch) { if(UART_op != UARTCount) { *ch = UARTBuffer[UART_op]; UART_op ++; if(UART_op >= UART2_RBUF_SIZE) UART_op = 0; return 1; } return 0; }
复制代码Main function
- int main(void) { uint8_t ch; UART2_Init(115200); printf ("Welcom to EEWORLD!\n"); printf ("Your input will be echo!\n"); while(1){ if ( UART2_GetChar(&ch)){ UART2_PutChar(ch); } } }
复制代码【Experimental phenomenon】
After the development board is reset, it will print out two sentences, and then send Any data sent from the receiving area will be reflected in the receiving area, the effect is as follows:
The next experiment uses Serial port + hyperterminal to achieve a simple Tetris game. This content is contributed by EEWORLD forum user lvxinn2006 Original. If you want to reprint or use it for commercial purposes, you must obtain the author's consent and indicate the source