4. M601 UART 的使用

1 UART 相关的数据结构和 API


本文介绍的数据结构和 API 可以参考 SDK 中 zyf_uart.h 文件。


1.1 概述


在 OpenCPU 中,串口包括物理串口和虚拟串口。物理串口可以连接外部设备,虚拟串口用于应用程序和底层操作系统之间进行通信。其中一个物理串口有硬件握手功能,其它的为三线接口。OpenCPU 支持两个虚拟串口用于 App 和 Core 之间的通信。这些串口设计根据物理串口的特点,具有 RI 和 DCD 信息。DCD 的电平可以指示虚拟串口处于数据模式还是 AT 命令模式。


1.2 用法


物理串口和虚拟串口的初始化和使用,可以通过以下步骤完成。
Step 1: 使用 ZYF_UartRegister 注册串口的回调函数。
Step 2: 使用 ZYF_UartOpen 来打开串口
Step 3: 使用 ZYF_UartWrite 往串口写数据。当实际发送的字节数小于要发送的字节数时,应用程序应停止发送数据,应用程序将会从回调函数收到EVENT_UART_READY_TO_WRITE 事件。接收事件后,应用程序可以继续发送数据,之前未发送的数据也一并发送。
Step 4: 在 回 调 函 数 中 , 处 理 串 口 的 通 知 。 如 果 通 知 类 型 为EVENT_UART_READY_TO_WRITE,开发者必须从 UART RX buffer 中读取全部数据;否则,当有新的数据进入 UART RX buffer 时,不会有这个消息通知应用程序。


1.3 UART 相关 API


1.3.1 ZYF_UartRegister 串口注册
 函数原型
int32_t ZYF_UartRegister(Enum_SerialPort port, PsFuncPtrcallback_uart)
 参数

port:
[输入] 串口名称。取值于 Enum_SerialPort
callback_uart:
[输入] 串口注册回调函数
 返回结果
ZYF_RET_OK 成功
其它值失败

1.3.2 ZYF_UartOpen 打开串口
 函数原型
int32_t ZYF_UartOpen(Enum_SerialPort port, uint32_t baudrate,Enum_FlowCtrl flowCtrl)
 参数
port:
[输入] 串口名称。取值于 Enum_SerialPort
baudrate:
[输入] 串口波特率
flowCtrl:
[输入] 流控,取值于 Enum_FlowCtrl
 返回结果
ZYF_RET_OK 成功
其它值失败

1.3.3 ZYF_UartWrite 串口发送数据
 函数原型
int32_t ZYF_UartWrite(Enum_SerialPort port, uint8_t* data, uint32_t writeLen )
 参数
port:
[输入] 串口名称。取值于 Enum_SerialPort
data:
[输入] 要发送的数据
writeLen:
[输入] 发送数据长度
 返回结果
If >= 0,发送成功,返回发送成功的数据长度
其它值失败
If <0,发送失败

1.3.4 ZYF_UartRead 串口读取数据
 函数原型
int32_t ZYF_UartRead(Enum_SerialPort port, uint8_t* data, uint32_t readLen)
 参数
port:
[输入] 串口名称。取值于 Enum_SerialPort
data:
[输出] 读取串口的数据
writeLen:
[输入] 读取数据的长度
 返回结果
If >= 0,读物成功,返回读取的数据长度
其它值失败
If <0,读取失败

1.3.5 ZYF_UartClose 关闭串口
 函数原型
int32_t ZYF_UartClose(Enum_SerialPort port)
 参数
port:
[输入] 串口名称。取值于 Enum_SerialPort
 返回结果
NONE
1.3.6 ZYF_UartOpenEx 配置串口属性并打开串口
 函数原型
int32_tZYF_UartOpenEx (Enum_SerialPort port, ST_UARTDCB *dcb)
 参数
port:
[输入] 串口名称。取值于 Enum_SerialPort
dcb:
[输入] 串口属性参数。取值于 ST_UARTDCB
 返回结果

ZYF_RET_OK 成功。其它值失败

1.3.7 ZYF_UartGetDCBConfig 获取串口属性
 函数原型
int32_t ZYF_UartGetDCBConfig(Enum_SerialPort port, ST_UARTDCB *dcb)
 参数
port:
[输入] 串口名称。取值于 Enum_SerialPort
dcb:
[输出] 串口属性参数
 返回结果
ZYF_RET_OK 成功。其它值失败
1.3.8 ZYF_UartSetDCBConfig 设置串口属性
 函数原型
int32_t ZYF_UartSetDCBConfig(Enum_SerialPort port, ST_UARTDCB *dcb)
 参数
port:[输入] 串口名称。取值于 Enum_SerialPort
dcb:[输入] 设置串口属性参数
 返回结果
ZYF_RET_OK 成功。其它值失败

1.3.9 ZYF_UartWriteCbRegister 注册回调函数
 函数原型
int32_t ZYF_UartWriteCbRegister(Enum_SerialPort port, PsFuncPtr
write_callback,void*Param)
 参数

port:[输入] 串口名称。取值于 Enum_SerialPort
write_callback:[输出] 指向串口写完成的回调函数
 返回结果
ZYF_RET_OK 成功。其它值失败

1.3.10 ZYF_UartWriteCallbackSwitch 串口写完成回调通知开关
 函数原型
int32_t ZYF_UartWriteCallbackSwitch(Enum_SerialPort port, uint8_t on_off)
 参数
port:[输入] 串口名称。取值于 Enum_SerialPort
on_off:[输入] 打开/关闭功能
 返回结果
ZYF_RET_OK 成功。其它值失败

2 UART 例程介绍


本章节主要介绍如何在 SDK 中使用 app_uart.c 单独测试 UART 功能。
编译方法:.\examples\build\对应的.bat 文件双击执行或打开就可以编译。
生成文件:.\out\对应目录\hex\M601_example_**.pac


1、通过 ZYF_UartRegister()注册串口和接收数据 read 回调函数。
2、通过 ZYF_UartWriteCbRegister()注册串口的发送数据 write 回调函数。
3、使用 ZYF_UartOpen()配置波特率和流控,并打开串口。
4、接收数据在 UartReadCallBack()中处理。
5、发送数据的结果在 UartWriteCallBack()中处理。


#include <string.h>
#include <stdlib.h>

#include "zyf_trace.h"
#include "zyf_uart.h"
#include "zyf_error.h"
#include "zyf_thread.h"
#include "zyf_timer.h"
#include "zyf_app.h"

static Uart_Param_t g_uart1param;
static Uart_Param_t g_uart2param;
static Uart_Param_t g_uart3param;



void UartWriteCallBack(void* Param) // general com
{
    Uart_Param_t *uartparam = (Uart_Param_t *)Param; 
    if(Param == NULL)
    {
        return;
    }    

    ZYF_UartWrite(uartparam->port,(uint8_t *)"UartWrite succeed\r\n",strlen("UartWrite succeed\r\n"));
    ZYF_UartWriteCallbackSwitch(uartparam->port,false);

}

void UartReadCallBack(void* Param) // 
{
    uint32_t recvlen = 0;
    Uart_Param_t *uartparam = (Uart_Param_t *)Param; 

    /*
    UART_PORT1 = 0,
    UART_PORT2 = 1,
    UART_PORT3 = 2,
    */
    ZYF_LOG("Uart%d recv",uartparam->port);

    while(ZYF_UartRead(uartparam->port, &(uartparam->uartbuf[recvlen]), 1))
    {
        ZYF_LOG("recv :%02x",uartparam->uartbuf[recvlen]);
        recvlen++;
    }
    ZYF_UartWrite(uartparam->port,uartparam->uartbuf,recvlen);
    ZYF_UartWriteCallbackSwitch(uartparam->port,true);
}


static void _AppUart1Init(void)
{
    int32_t ret;
    g_uart1param.port = UART_PORT1;
    ZYF_UartRegister(g_uart1param.port, UartReadCallBack,&g_uart1param);
    ZYF_UartWriteCbRegister(g_uart1param.port,UartWriteCallBack,&g_uart1param);
    ZYF_UartOpen(g_uart1param.port, 115200, ZYF_FC_NONE);
//    ST_UARTDCB uartDcb = {0};
//    uartDcb.baudrate = 115200;
//    uartDcb.dataBits = DB_8BIT;
//    uartDcb.flowCtrl = ZYF_FC_NONE;
//    uartDcb.parity = PB_NONE;
//    uartDcb.stopBits = SB_ONE;
    
//    ret = ZYF_UartOpenEx(g_uart1param.port,&uartDcb);

    ZYF_LOG("_AppUart1Init");
    return;
}


static void _AppUart2Init(void)
{  
    g_uart2param.port = UART_PORT2;
    ZYF_UartRegister(UART_PORT2, UartReadCallBack,&g_uart2param);
    ZYF_UartWriteCbRegister(UART_PORT2,UartWriteCallBack,&g_uart2param);
    ZYF_UartOpen(UART_PORT2, 115200, ZYF_FC_NONE);
    ZYF_LOG("_AppUart2Init");

    return;
}


static void _AppUart3Init(void)
{   
    g_uart3param.port = UART_PORT3;
    ZYF_UartRegister(UART_PORT3, UartReadCallBack,&g_uart3param);
    ZYF_UartWriteCbRegister(UART_PORT3,UartWriteCallBack,&g_uart3param);
    ZYF_UartOpen(UART_PORT3, 115200, ZYF_FC_NONE);
    ZYF_LOG("_AppUart3Init");

    return;
}



void ZYF_AppUartInit(void)
{
    _AppUart1Init();
    _AppUart2Init();
    _AppUart3Init();
}

void UartThread_Example(void * Param)
{
    ZYF_MsgQ_t *ptMsg;
    ZYF_AppMsg_t tMsg;
    int iRet = -1;
    ptMsg = ZYF_MsgQCreate(10, sizeof(ZYF_AppMsg_t));
    ZYF_LOG("thread enter!");
    
    while (1) {
        ZYF_LOG("in while.");
        iRet = ZYF_MsgQGet(ptMsg, (void *)&tMsg);
        if (iRet < 0) {
            ZYF_LOG("Failed to get msg");
            ZYF_ThreadSleep(1000);
        }
    }

}

static void prvInvokeGlobalCtors(void)
{
    extern void (*__init_array_start[])();
    extern void (*__init_array_end[])();

    size_t count = __init_array_end - __init_array_start;
    for (size_t i = 0; i < count; ++i)
        __init_array_start[i]();
}


int appimg_enter(void *param)
{
    ZYF_AppUartInit();
    ZYF_LOG("application image enter, param 0x%x", param);

    prvInvokeGlobalCtors();

    ZYF_ThreadCreate("UartThread_Example", UartThread_Example, NULL, ZYF_PRIORITY_HIGH, 10*1024);
    return 0;
}

void appimg_exit(void)
{
    OSI_LOGI(0, "application image exit");
}


猜你喜欢

转载自blog.csdn.net/w_hizyf_m/article/details/107083189