dumbking 发表于 2021-7-26 07:53

zigbee串口通信

# 一、串口通信原理

## 1.什么是UART

​      UART : Universal AsynchronousReceiver/Transmitter通用异步收发器       
​        一种常用也是最简单的串行数据传输协议。数据线只需要两根就可以实现全双工。
​        Tx:发送数据线
​        Rx:接收数据线
​                A                B
​                Tx <-----------> Rx
​                Rx <-----------> Tx
​                GND<-----------> GND

## 2.上位机与下位机

​           模块之间的通信,根据其在系统中的功能与作用可分为上位机 与 下位机。

上位机:
        把处理性能强的计算机称为上位机。数据的统一处理都在上位机完成。
               
下位机:
        把数据采集和发送的终端,处理性能单一的计算机,称为下位机。
            

一般一个上位机会对应多个下位机,这种模式可以使数据处理的更加全面,同时也大大降低成本。

## 3.UART数据帧

UART protocol串口协议
        串口发送和接收数据是以帧为单位,Frame
       

        1帧(Frame) = 1start bit(起始位) + 5~9bits数据位 + 0/1bit校验位 + stop bits(0.5,1,1.5)停止位
        起始位:一个周期的低电平
        数据位:5~9bits数据位,具体是多少bits,需要双方协商,并且传送先传送最低位(LSB)
        校验位:
                0bit:没有校验
                1bit:有校验
                        奇校验:数据位+校验位的这一段数据里的1的个数是奇数。
                        偶校验:数据位+校验位的这一段数据里的1的个数是偶数。
        停止位:高电平
               
                1个停止位
                               
        Baudrate(波特率):传输速率,即没一个秒传输了多少个bit位
                4800
                9600
                115200bps: bits per second

# 二、串口配置

## 1.        串口初始化相关的结构体halUARTCfg_t

```c
typedef struct
{
bool                configured;//是否设置串口
uint8               baudRate; //波特率设置
bool                flowControl;//控制流设置
uint16            flowControlThreshold;//RX缓存安全字节数(了解)
uint8               idleTimeout;//RX来数据超时时间(了解)
halUARTBufControl_t rx;//接收数据长度
halUARTBufControl_t tx;//发送数据长度
bool                intEnable;//中断使能
uint32            rxChRvdTime;//接收数据时间
halUARTCBack_t      callBackFunc;//回调函数
}halUARTCfg_t;
```

## 2. 串口初始化示例

```c
static void InitUart(void)
{
        halUARTCfg_t   uartConfig;
        uartConfig.configured         = TRUE;//
        uartConfig.baudRate             = HAL_UART_BR_38400;
        uartConfig.flowControl          = FALSE;
        uartConfig.flowControlThreshold = 64;
        uartConfig.rx.maxBufSize      = 128;
        uartConfig.tx.maxBufSize      = 128;
        uartConfig.idleTimeout          = 6;   
        uartConfig.intEnable            = TRUE;               
        uartConfig.callBackFunc         = SerialApp_CallBack;   
        HalUARTOpen (SERIAL_APP_PORT, &uartConfig);   
}
```

## 3.串口实现

​      串口的读操作函数为HalUARTRead(),主要功能是读取上位机通过串口发送至设备节点的数据。

​        uint16 HalUARTRead(uint8 port, uint8 *buf, uint16 len)
​        @port:串口端口的设置,可以设置为串口0或串口1;
​        @buf:数据缓冲区;
​        @len:数据长度。
​        返回值:实际成功读取的字节数

串口的**读**操作函数为**HalUARTRead()**,主要功能是读取上位机通过串口发送至设备节点的数据。

```c
uint16 HalUARTRead(uint8 port, uint8 *buf, uint16 len)
{
 
#if (HAL_UART_DMA == 1)
if (port == HAL_UART_PORT_0)return HalUARTReadDMA(buf, len);
#endif
#if (HAL_UART_DMA == 2)
if (port == HAL_UART_PORT_1)return HalUARTReadDMA(buf, len);
#endif
#if (HAL_UART_ISR == 1)
if (port == HAL_UART_PORT_0)return HalUARTReadISR(buf, len);
#endif
#if (HAL_UART_ISR == 2)
if (port == HAL_UART_PORT_1)return HalUARTReadISR(buf, len);
#endif
 
#if HAL_UART_USB
return HalUARTRx(buf, len);
#else
return 0;
#endif
}
```

串口的**写**操作函数为**HalUARTWrite()**,主要功能是实现向上位机或其他设备通过串口发送数据。
        uint16 HalUARTWrite(uint8 port, uint8 *buf, uint16 len)
        @port:串口端口的设置,可以设置为串口0或串口1;
        @buf:数据缓冲区;
        @len:数据长度。
        返回值:实际成功发送的字节数

```c
uint16 HalUARTWrite(uint8 port, uint8 *buf, uint16 len)

#if (HAL_UART_DMA == 1)
if (port == HAL_UART_PORT_0)return HalUARTWriteDMA(buf, len);
#endif
#if (HAL_UART_DMA == 2)
if (port == HAL_UART_PORT_1)return HalUARTWriteDMA(buf, len);
#endif
#if (HAL_UART_ISR == 1)
if (port == HAL_UART_PORT_0)return HalUARTWriteISR(buf, len);
#endif
#if (HAL_UART_ISR == 2)
if (port == HAL_UART_PORT_1)return HalUARTWriteISR(buf, len);
#endif
 
#if HAL_UART_USB
HalUARTTx(buf, len);
return len;
#else
return 0;
#endif
}
```

# 三、程序设计

```c
void SerialApp_CallBack(uint8 port, uint8 event)   //接收数据会触发
{
    unsigned char buf={0};
    HalUARTRead(HAL_UART_PORT_0,buf,32);
    if(strcmp((char*)buf,"hello") == 0)
    {
      led_ctrl(LED0,LED_ON);
      led_ctrl(LED1,LED_ON);
    }
    else if(strcmp((char*)buf,"byebye") == 0)
    {
      led_ctrl(LED0,LED_OFF);
      led_ctrl(LED1,LED_OFF);
    }

}

static void InitUart(void)
{
        halUARTCfg_t   uartConfig;
        uartConfig.configured         = TRUE;
        uartConfig.baudRate             = HAL_UART_BR_9600; //设置波特率
        uartConfig.flowControl          = FALSE;
        uartConfig.flowControlThreshold = 64;
        uartConfig.rx.maxBufSize      = 128;
        uartConfig.tx.maxBufSize      = 128;
        uartConfig.idleTimeout          = 6;   
        uartConfig.intEnable            = TRUE;               
        uartConfig.callBackFunc         = SerialApp_CallBack;//设置回调函数
        HalUARTOpen (HAL_UART_PORT_0, &uartConfig);   
}

if ( events & GENERICAPP_MY_EVT1 )        //事件
{//事件要做的事
    P1_0 = !P1_0;
    P1_1 = !P1_1;
    unsigned char str={"hello,are you ok?\r\n"};
    HalUARTWrite(HAL_UART_PORT_0,str,strlen((char *)str));
    unsigned char temp;
    if(Start_DHT11() == 1)        //读取dht11数据
    {
      sprintf(temp,"temperature:%d,humidity:%d\r\n",temperature,humidity);
      HalUARTWrite(HAL_UART_PORT_0,temp,strlen((char *)temp));
    }
    else
    {
      HalUARTWrite(HAL_UART_PORT_0,"error\r\n",strlen("error\r\n"));
    }
    return (events ^ GENERICAPP_MY_EVT1);
}
```

yamika 发表于 2021-7-26 11:00

学习了,最近正好想了解下zigbee,nb等物联网用的协议
页: [1]
查看完整版本: zigbee串口通信