3830 views|6 replies

23

Posts

0

Resources
The OP
 

【ST NUCLEO-G071RB Review】_04_UART Experiment [Copy link]

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
  1. 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:
  1. 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
  1. 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

图片7.png (75.26 KB, downloads: 0)

图片7.png

图片8.png (271.32 KB, downloads: 0)

图片8.png

图片9.png (237.06 KB, downloads: 0)

图片9.png

图片10.png (233.05 KB, downloads: 0)

图片10.png

图片11.png (93.41 KB, downloads: 0)

图片11.png

图片15.png (114.59 KB, downloads: 0)

图片15.png

图片16.png (205.92 KB, downloads: 0)

图片16.png
This post is from stm32/stm8

Latest reply

Can you please send me the project? I tried it and I don't know why the data can be sent successfully, but I can't receive it. I don't know why it's embarrassing.  Details Published on 2019-3-25 18:05
 

821

Posts

0

Resources
2
 
Good, I learned something!
This post is from stm32/stm8
 
 

23

Posts

0

Resources
3
 
lising posted on 2019-1-10 18:12 Good, I learned something!
Let's learn from each other. My method of directly configuring registers may seem a bit stupid.
This post is from stm32/stm8

Comments

Using registers can give you a more thorough understanding of the underlying layer, make your learning more solid, and make your code more concise. I personally feel that using libraries, especially CUBE, is faster and more convenient. Each has its own strengths.  Details Published on 2019-1-10 21:29
 
 

821

Posts

0

Resources
4
 
lvxinn2006 posted on 2019-1-10 20:43 Learn from each other. My method of directly configuring registers may seem stupid
Using registers can give you a more thorough understanding of the underlying layer, make your learning more solid, and make your code more concise. I personally feel that libraries, especially CUBE, are faster and more convenient. Each has its own strengths.
This post is from stm32/stm8
 
 
 

7422

Posts

2

Resources
5
 
Looking at the front reminds me of my school days, haha. Come on.
This post is from stm32/stm8
 
Personal signature

默认摸鱼,再摸鱼。2022、9、28

 
 

23

Posts

0

Resources
6
 
freebsder posted on 2019-1-10 22:38 Reading the previous part reminded me of my school days, haha. Come on.
Haha, it was written in the form of a school lab manual
This post is from stm32/stm8
 
 
 

11

Posts

0

Resources
7
 
Can you please send me the project? I tried it and I don't know why the data can be sent successfully, but I can't receive it. I don't know why it's embarrassing.
This post is from stm32/stm8
 
 
 

Just looking around
Find a datasheet?

EEWorld Datasheet Technical Support

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号
快速回复 返回顶部 Return list