GPIO operation is the most basic operation when using a microcontroller. Even if you are not careful during this operation, you will still fall into a pit.
For example: use two pins (PA00 and PA01) in the same GPIO port group for output, PA00 changes the output state in the main loop, and PA01 changes the output state through interrupts. Normally, PA00 only changes the output state in the main loop, while PA01 only changes the output state when an interrupt occurs. However, as the program runs longer or the frequency of PA00 output is increased in the main loop, it will be found that PA01, which should have completed the state change in the interrupt, will not change its state in some cases. By setting a breakpoint in the interrupt service program and debugging, it is found that the interrupt can enter normally and change the output state of PA01 normally. To analyze the cause of this situation, you can start with the DDL library provided by the official.
When the HGI MCU M0+ series chip operates the GPIO port output level, the DDL library provides the following two methods:
Method 1:
For more information, please contact angel.qi: 13827489351 (WeChat and mobile phone number are synchronized)
-
<p><font face="微软雅黑" size="3">/*********************************************************************************
-
** \brief GPIO IO output value write
-
**
-
** \param [in] enPort IO Port
-
** \param [in] enPin IO Pin
-
** \param [out] bVal output value
-
**
-
** \retval en_result_t Ok Setting successful
-
** Other values failed to set
-
*************************************************** ******************************/
-
en_result_t Gpio_WriteOutputIO(en_gpio_port_t enPort, en_gpio_pin_t enPin, boolean_t bVal)
-
{
-
SetBit(((uint32_t)&M0P_GPIO->PAOUT + enPort), enPin, bVal); return Ok;
-
}</font></p>
Method 2:
-
<p><font face="微软雅黑" size="3">/***********************************************************************************
-
** \brief GPIO IO settings
-
**
-
** \param [in] enPort IO Port
-
** \param [in] enPin IO Pin
-
**
-
** \retval en_result_t Ok Setting successful
-
** Other values failed to set
-
*************************************************** ******************************/
-
en_result_t Gpio_SetIO(en_gpio_port_t enPort, en_gpio_pin_t enPin)
-
{
-
SetBit(((uint32_t)&M0P_GPIO->PABSET + enPort), enPin, TRUE); return Ok;
-
}</font></p><p><font face="微软雅黑" size="3">
-
</font></p><p><font face="微软雅黑" size="3">/**********************************************************************************
-
** \brief GPIO IO clear
-
**
-
** \param [in] enPort IO Port
-
** \param [in] enPin IO Pin
-
**
-
** \retval en_result_t Ok Setting successful
-
** Other values failed to set
-
*************************************************** ******************************/
-
en_result_t Gpio_ClrIO(en_gpio_port_t enPort, en_gpio_pin_t enPin)
-
{
-
SetBit(((uint32_t)&M0P_GPIO->PABCLR + enPort), enPin, TRUE);</font></p><p><font face="微软雅黑" size="3"> return Ok;
-
}</font></p>
Method 1 is to operate the entire PxOUT register. Check the user manual for the description of this register as shown below:
When the corresponding bit of the PxOUT register is 1, the corresponding pin outputs a high level, otherwise it outputs a low level.
Method 2 is to set the corresponding bit of the register pin to 1 to complete the pin output high level operation. The register description is as follows:
The pin output low level operation is completed by clearing the corresponding position of the register pin to 1. The register description is as follows:
The abnormal output phenomenon mentioned above is due to the operation performed using method 1. In the main loop, the change of the PA00 output state is completed through the PAOUT register. If all pins of PORTA are at a low level, PA00 outputs a high level. The operation of method 1 is to write 0X0001 to the PAOUT register to achieve this. In the ARM assembly instruction, writing 0X0001 to PAOUT must be achieved with the help of general registers (r0~r7). When the CPU just completes the transfer of 0X0001 to the general register, an interrupt occurs. The CPU will save the general register and then respond to the interrupt. In the interrupt, PA01 outputs a high level and the PAOUT value is 0X0002, and then exits the interrupt. After exiting the interrupt, the CPU will restore the value of the general register before the interrupt (0X0001), and then continue to store the value of the general register into PAOUT. At this time, the value of PAOUT is 0X0001, only PA00 outputs a high level, and PA01 does not output a high level. This phenomenon is the competition-adventure phenomenon of the port.
When using the chip, you do not want this race-hazard phenomenon to occur. This phenomenon can be completely avoided by operating with method 2. Because method 2 operates on the bits of the register, only the corresponding bit is set or cleared each time the operation is performed, and the output result is not affected when the other bit values are 0.
Therefore, the editor recommends that you use method 2 when operating the GPIO port output during development.
|