GD32 combat 6__ serial read and write

purpose

Serial communication is very, very common form of communication, must master. You can grasp the following aspects serial communication:

  1. Serial communication theory, here we only study the asynchronous serial interface
  2. GD32 several common serial communication configuration

Asynchronous serial communication principles

1. Configuration

In understanding the principle, let's look at how to use the serial port, as shown below, simply select the correct serial number, the sending and receiving sides of the baud rate, parity, data bits, stop bits configured the same, so you can achieve two communicating parties.

Here Insert Picture Description

Then these parameters are representative of what the meaning of it?

Serial Number: uniquely identifies a serial port, a plurality of serial ports when the device is present, which can be used to identify each port.

Baud rate: number of data bits transmitted per second. It represents the data transmission rate in bps (bits per second). 115200bps example, it means the data can be transmitted 115200bits of 1s.

Check Digit:

Each even byte transfers throughout the process is the number of 1 bit is an even number (the number of check bits adjustment)
ODD each byte sent through the whole process is the number of 1 bit is an odd number (check adjusting the number of bits)
none no parity bit
space parity bit is always 0
Mark parity bit is always 1

Data Bits: 5678 a total of four choices, this is for historical reasons, as follows

5: telegraph transmission for the 26 English letters, sufficient 5

6: a telegraph, identifying case letters, adding a bit sensitive

7: a computer, ASCII code 7

8: a computer, DBCS code compatible with ASCII and support for double-byte Chinese

Stop bits:

Stop bit is counted by the length. Starting the counting of serial asynchronous communication, a unit time interval (a unit of time is the inverse of the baud rate), sequentially receiving the data bits and parity bits specified, and assembled into a parallel byte character; shall thereafter receiving the predetermined length of the stop bit is "1." Therefore, the stop bit is "1", its length is 1.5, maintaining the high level of the stop bit length 1.5 units of time. Generally speaking, stop bit 1, 1.5 units of three lengths of time.

2. Frame format

Here we look serial protocol frame format, as shown in

Here Insert Picture Description

A frame consists of four parts, a start bit + data bits + parity bit + stop bits, correspond exactly with the above configuration, wherein the start bit must be low, the stop bit must be high.

So far, the serial port is also generally understand how it happens.

3. Common standard serial port level

The following are several serial, but different standard level, which leads to differences in the application scenario, communication protocols and configurations are the same, the communication principle is the same, the same software, hardware differences.

TTL:

  1. FIG wiring

  2. 1 represents a logic high level, low level indicates a logical zero

     ![1536645105294](assets/1536739271596.png)
    

RS232 and RS485 contrast

  1. Immunity: RS485 interface is a balanced differential driver and receiver combination, good noise immunity. RS232 interface using a signal line and a return line to form a transmission signal in the form of a common ground, such co-prone transmission common mode interference.
  2. Transmission distance: maximum transmission standard RS485 interface distance is 1,200 m (9600bps), the fact up to 3000 meters. RS232 transmission distance is limited, the maximum transmission distance of 50 m standard value, in fact, can only be used at about 15 meters.
  3. Communication capabilities: RS-485 interface bus is to allow up to 128 transceivers, users can use a single RS-485 interface to easily set up a network device. Only one RS-232 communication.
  4. Transfer rate: the lower transmission rate RS-232, in asynchronous transmission, the baud rate is 20Kbps. Maximum data transmission rate of RS-485 is 10Mbps.
  5. Signal line: RS485 interfaces composed of half-duplex network, generally only two signal lines. RS-232 port is generally used only RXD, TXD, GND three lines.
  6. Electrical level values: RS-485 logic "1" voltage difference between the two lines + (2-6) V represents; logic "0" voltage difference between the two lines - (2-6) V represents . In the RS-232-C signal in any one of the voltage lines are negative logic. Namely: a logic "1", - 5- -15V; logic "0" + 5- + 15V.

4. How chip serial port function

Here Insert Picture Description

We know the serial communication function is provided between the CPU and other devices, essentially moving the data from the other device to the MCU itself to memory, as shown above, to achieve the MCU serial function module division will do as above.

  1. GPIO

    Serial bus state, default is high, so output pull-Tx should be, the Rx input should be floating.

  2. Shifter

    We know that is a bit serial transmission, the shifter which can achieve serial transceiver.

  3. Data register

    For storing data to be transmitted and received, in fact, one byte long enough duplexer.

  4. clock

    Run the above procedure will need to run properly at a fixed clock, such as baud rate.

  5. Move data from the register to memory

    1. CPU mode, the CPU how to control data transfer between registers and memory data, for example, when the data register is empty, the data transfer memory to the register, i.e., the transmission process
    2. DMA mode, the process with the CPU, then why are there DMA it? Because the data movement involved in eliminating CPU, which means the CPU can get busy other things, efficiency naturally high.
  6. Status Register

    1. Under our rough thinking, during transmission across the serial port, to be sure there will be a variety of state, for example, receive data, data anomalies, frame error, data transmission is completed, the data register is empty, etc., which require status register stores.
    2. Under further in-depth thinking, when we need timely processing of the above-mentioned state, polling by the CPU is clearly too slow, so certainly needs to be interrupted, and then add a set of interrupt status register.
  7. Configuration Register

    Above so many representatives of different configurations, certainly you need a few set of configuration registers. For example, the interrupt enable control

feature design

If you understand the principles, then naturally know how to configure a serial port, and nothing more than to find the corresponding chip register from manual to configure it.

In the "serial port" example, we have contacted serial transmission function, and now we have this case re-depth to carry out reception serial port. Implement a Echo function, which writes data to the PC via the serial port GD32, GD32 and the data is returned intact to the PC.

Polling
VOID DRV_UART1_PollTest(VOID)
{
    U8 ch = 0;
    
    while (1)
    {
        if (USART_GetBitState(USART1, USART_FLAG_RBNE) != RESET)
        {
            ch = (U8)USART_DataReceive(USART1);
            UART1_SendChar(ch);
        }
    }
}

VOID DRV_UART1_PollInit(VOID)
{
    UART1_GpioInit();
    UART1_Config();
    USART_Enable(USART1, ENABLE);
}

Results shown in Figure

Here Insert Picture Description

Interrupt

Note: The interrupt priority part, I would have taken separate section analysis.

We must pay attention to the difference between the following two functions,

USART_GetBitState(USART1, USART_FLAG_RBNE)/* 非中断使用 */
USART_GetIntBitState(USART1, USART_INT_RBNE);/* 中断内使用 */

Interrupt processing code is as follows:

VOID USART1_IRQHandler(VOID)
{
    if (USART_GetIntBitState(USART1, USART_INT_RBNE) != RESET)
    {
        if (gUart1RxCount >= DRV_UART1_BUFLEN)
        {
            memset(gUart1RxBuf, 0, sizeof(gUart1RxBuf));
            gUart1RxCount = 0;
        }
        gUart1RxBuf[gUart1RxCount] = (U8)USART_DataReceive(USART1);
        gUart1RxCount++;
    }

    if (USART_GetIntBitState(USART1, USART_INT_IDLEF) != RESET)
    {
        gUart1RxBufFlag++;
    }
}

VOID DRV_UART1_InterruptTest(VOID)
{
    U8 rxCount = 0;

    while (1)
    {
        if (gUart1RxBufFlag > 0)
        {
            for (rxCount = 0; rxCount < gUart1RxCount; rxCount++)
            {
                UART1_SendChar(gUart1RxBuf[rxCount]);
            }
            memset(gUart1RxBuf, 0, sizeof(gUart1RxBuf));
            gUart1RxCount = 0;
            gUart1RxBufFlag = 0;
        }
    }
}

VOID DRV_UART1_InterruptInit(VOID)
{
    UART1_GpioInit();
    UART1_Config();
    UART1_NvicConfiguration();
    USART_Enable(USART1, ENABLE);
    USART_INT_Set(USART1, USART_INT_RBNE, ENABLE);
    USART_INT_Set(USART1, USART_INT_IDLEF, ENABLE);
}
DMA mode

Note: DMA detail I would have taken separate section analysis, just write here an example of a polling DMA mode.

static VOID UART1_DmaRxConfig(IN U8 *buf, IN U32 len)
{
    DMA_InitPara DMA_InitStructure;
    
    DMA_Enable(DMA1_CHANNEL5, DISABLE);
    
    /* USART1 RX DMA1 Channel (triggered by USART1 Rx event) Config */
    DMA_DeInit(DMA1_CHANNEL5);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (U32) &(USART1->DR);
    DMA_InitStructure.DMA_MemoryBaseAddr = (U32)buf;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PERIPHERALSRC;
    DMA_InitStructure.DMA_BufferSize = len;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE;
    DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PERIPHERALDATASIZE_BYTE;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MEMORYDATASIZE_BYTE;
    DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL;
    DMA_InitStructure.DMA_Priority = DMA_PRIORITY_VERYHIGH;
    DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE;
    DMA_Init(DMA1_CHANNEL5, &DMA_InitStructure);
    DMA_Enable(DMA1_CHANNEL5, ENABLE);
}

VOID DRV_UART1_DmaInit(VOID)
{
    UART1_GpioInit();
    UART1_Config();
    RCC_AHBPeriphClock_Enable(RCC_AHBPERIPH_DMA1, ENABLE);
    UART1_DmaRxConfig(gUart1RxBuf, DRV_UART1_BUFLEN);
    USART_Enable(USART1, ENABLE);
    USART_DMA_Enable(USART1, (USART_DMAREQ_TX | USART_DMAREQ_RX), ENABLE);
}

static VOID UART1_DmaSend(IN U8 *buf, IN U32 len)
{
    DMA_InitPara DMA_InitStructure;

    DMA_Enable(DMA1_CHANNEL4, DISABLE);

    /* USART1_Tx_DMA_Channel (triggered by USART1 Tx event) Config */
    DMA_DeInit(DMA1_CHANNEL4);
    DMA_InitStructure.DMA_PeripheralBaseAddr = (U32) &(USART1->DR);
    DMA_InitStructure.DMA_MemoryBaseAddr = (U32)buf;
    DMA_InitStructure.DMA_DIR = DMA_DIR_PERIPHERALDST;
    DMA_InitStructure.DMA_BufferSize = len;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE;
    DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE;
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PERIPHERALDATASIZE_BYTE;
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MEMORYDATASIZE_BYTE;
    DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL;
    DMA_InitStructure.DMA_Priority = DMA_PRIORITY_VERYHIGH;
    DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE;
    DMA_Init(DMA1_CHANNEL4, &DMA_InitStructure);
    
    DMA_Enable(DMA1_CHANNEL4, ENABLE);
    while (DMA_GetBitState(DMA1_FLAG_TC4) == RESET)
    {
    }
}

VOID DRV_UART1_DmaTest(VOID)
{
    while (1)
    {
        if (USART_GetBitState(USART1, USART_FLAG_IDLEF) != RESET)
        {
            UART1_DmaSend(gUart1RxBuf, DRV_UART1_BUFLEN);
            memset(gUart1RxBuf, 0, DRV_UART1_BUFLEN);
            UART1_DmaRxConfig(gUart1RxBuf, DRV_UART1_BUFLEN);
            USART_DataReceive(USART1); /* 清除USART_FLAG_IDLEF */
        }
    }
}

to sum up

Is a very common serial communications bus, you must master. If the above principles and examples to understand, and I believe a window with a virtual GPIO port is not difficult.

Code path

https://github.com/YaFood/GD32F103/tree/master/TestUART

Guess you like

Origin blog.csdn.net/qq_17854661/article/details/91878328