0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

【飞凌RZ/G2L开发板试用体验】5. 迪文串口屏事件分析

开发板试用精选 来源:开发板试用 作者:电子发烧友论坛 2022-10-24 16:58 次阅读

本文来源电子发烧友社区,作者:voidpbq, 帖子地址:https://bbs.elecfans.com/jishu_2303725_1_1.html


一、前言

本章介绍下OKG2L的uart引脚、测试方法以及如何处理迪文串口的uart信息

二、硬件

2.1 电路图

OKG2L支持三个uart口,其中

image.png

GPIO33、35分别为rx,tx

image.png

image.png

在底板的P23,从下往上数左侧第9个为uart的rx(接收端),可以查看uart图标找到对应位置。

35是开发板的TX,33是开发板的RX。

使用电脑的串口工具时,连接usb ttl小板,开发板TX接小板RX。

2.2 连接图

连接迪文串口屏,开发板tx连接串口屏rx

连接如下图

image.png

三、代码

3.1 fltest_uarttest——官方实现uart基础测试

串口代码路径:drivers/tty/serial/sh-sci.c

开发板中路径:/dev/ttySX

外接的uart时ttySC1

官方提供的cmd:fltest_uarttest

image.png

fltest_uarttest工具代码路径:OKG2L-linux-sdk10appsrcforlinx-cmduarttest

我的代码也是基于这个增加了串口件通信
PS:注意,这里是一位一位获取数据的,经我测试,一次读取最多8位,所以需要增加新的机制判断一组数据是否获取完毕。
详见如下问题一节。

3.2 实现迪文串口间通信

此代码为我基于官方实现添加了迪文串口屏的事件判定,开源,禁止商用,谢谢。

uart_example.c



#include "dwin.h"

#include           /*��׼�����������*/
#include          /*��׼�����ⶨ��*/
#include          /*Unix��׼��������*/
#include       /**/
#include        /**/
#include           /*�ļ����ƶ���*/
#include         /*PPSIX�ն˿��ƶ���*/
#include           /*����Ŷ���*/
#include	 
#include     
#include     
#include    "stdbool.h"

#define uint8_t u_int8_t
#define bool _Bool

extern void u8_to_char(uint8_t * , char ** );
extern int judge_dwin_cmd(uint8_t ** );
extern int get_len(uint8_t *cmd_u8);
extern dwin_event_flag uart_judge_dwin_event(i_dwin_cmd * cmd);
extern i_dwin_cmd temp_cmd_recv;
extern dwin_event_key event_key_list[EVENT_KEY_NUM_MAX];
extern dwin_event_key_spec event_key_spec[EVENT_KEY_SPEC_NUM_MAX];

extern c_dwin_cmd cmd_recv_char; // from dwin
extern c_dwin_cmd cmd_send_char; // send to dwin
extern dwin_event_flag c_judge_dwin_event(c_dwin_cmd * cmd);
extern void c_dwin_cmd_analysis(char * in,c_dwin_cmd *cmd);
extern void c_print_cmd(c_dwin_cmd *cmd);

#define UART_ID                 0

#define UART_RECV_LEN           1024
#define BUF_RX_MAX 512
#define LEN_CHAR_TEMP 17

c_dwin_cmd cmd_char;

int search_str_end(uint8_t *str_z, int count)
{
int temp_zero = 1;
int temp_count = count -1;  // 有效字符11个,12个是0x00
printf("init count = %d, temp_count = %dn",count,temp_count);
uint8_t *str_temp1 = str_z;

while(1)
{
printf("str = [%02X], temp_zero = [%d], temp_count = [%d]n",*str_temp1,temp_zero,temp_count);
// if find 10 zero, will return count
if(*str_temp1 != 0x00)
{
printf("value = %02X, %ldn",*str_temp1,str_temp1-str_z);
temp_count += temp_zero;
str_temp1++;
temp_zero = 1;
}
else
{
temp_zero++;
printf("value = %02X, %ldn",*str_temp1,str_temp1-str_z);
}

if(temp_zero > 10)
break;

}
printf("init count = %d, temp_count = %dn",count,temp_count);
return temp_count;

}

int my_strlen(uint8_t *str)
{
printf("enter my_strlen");
uint8_t *str_temp = str;
// assert(str);
int count = 0;

// while (*str != '') // this will ignore 0x00
while (*str_temp != '')
{
printf("value = %02X, %ldn",*str_temp,str_temp-str);
count++;
str_temp++;
}
// has found 0x00, str end. but uart data may contents 0x00 .. 0x00
// so, need to judge next value
count = search_str_end(str_temp-1,count);

return count;

}

int judge_char(uint8_t * str)
{
if (str != NULL){
// not empty
printf("enter judge_char");
if (my_strlen(str) != 0) {
// not ''
return 1;
}
else
return 0;
}
else
return -1;
}

void func_uart_write(uint8_t * str, int fd)
{
printf("enter func_uart_write");
unsigned int ret;

// plus 3 due to dwin has head1/2/len
ret = write(fd, str, *(str+2));
if (ret <0)
{
printf("%s, %d: LzUartInit(%d) failed!n", __FILE__, __LINE__, ret);
return;
}

}

void uint8_2_char(uint8_t * in,char * out, int cp_len)
{
printf("raw uint8_t data[");
int cmd_len=*(in+2)+3;
char tmp[3];
memset(tmp,0x00,3);
for(int i =0;i< cp_len;i++)
{
printf("%02X",*(in+i));
sprintf(tmp,"%02X",*(in+i));
strcat(out,tmp);

memset(tmp,0x00,3);
}
printf("]n");

}

void main(void)
{
int fd;
int nread;
char buf_rx[BUF_RX_MAX+1];
int n=0,i=0;
char dev[]  = "/dev/ttySC1";
struct termios oldtio,newtio;
speed_t speed = B115200;
int next_option,havearg = 0,flow = 0;


/*  打开串口 */
fd = open(dev, O_RDWR | O_NONBLOCK| O_NOCTTY | O_NDELAY);
if (fd < 0)	{
printf("Can't Open Serial Port!n");
exit(0);	
}

printf("Welcome to uart buf_txn");

//save to oldtio
tcgetattr(fd,&oldtio);
bzero(&newtio,sizeof(newtio));
newtio.c_cflag = speed|CS8|CLOCAL|CREAD;
newtio.c_cflag &= ~CSTOPB;
newtio.c_cflag &= ~PARENB;
newtio.c_iflag = IGNPAR;
newtio.c_oflag = 0;
// newtio.c_cc[VTIME]=10;
tcflush(fd,TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);
tcgetattr(fd,&oldtio);

memset(buf_rx,0,BUF_RX_MAX+1);

char buf_tx[100]="forlinx_uart_test.1234567890...";

printf("Send buf_tx data:n[%s] [%ld]n",buf_tx,strlen(buf_tx));
write(fd, buf_tx, strlen(buf_tx));
fd_set rd;

int flag_rx=0;
bool flag_rx1= false;
bool flag_rx2 = false;

bool flag_print=true;
int cmd_len=0;

uint8_t str_send[UART_RECV_LEN] = "HelloWorld!n";
char str_send_char[513] = "";
uint8_t recv_int8[UART_RECV_LEN];
char recv_char[UART_RECV_LEN];
uint8_t recv_int8_t[9];
char recv_char_t[LEN_CHAR_TEMP];

char *recv_char_p=NULL;

bool status_uart_send = false;

init_dwin_status();

// ------------------- test uint8 to char -------------------
uint8_t xxx[]={0X5A,0XA5,0X05,0X82,0X10,0X00,0X00,0X01};
// u8_2_char(xxx);
char *yyy=(char *)malloc(get_len(recv_int8));
u8_to_char(xxx,&yyy);
// yyy = (char *)u8_to_char(xxx);
printf("yyy = %sn",yyy);
// ------------------- test uint8 to char -------------------

printf("enter whilen");

while (1)
{
// ----------------- uart read -----------------
memset(recv_int8_t,0x00,UART_RECV_LEN);
int nread = read(fd, recv_int8_t, UART_RECV_LEN);
if (nread >  0)
{
if(*recv_int8_t==0x5a && *(recv_int8_t+1)==0xa5)
{
cmd_len=*(recv_int8_t+2)+3;
cmd_len=2*cmd_len ;
printf("ncmd len = %dn",cmd_len);

}

memset(recv_char_t,0x00,LEN_CHAR_TEMP);
uint8_2_char(recv_int8_t,recv_char_t, nread);

strcat(recv_char,recv_char_t);

flag_rx1=true;
flag_rx2=true;


}
else if(nread < 0 )
{
printf("%s, %d: LzUartInit(%d) failed!n", __FILE__, __LINE__, nread);
return;
}
if(nread == 0)
{
// 判断传输停止
if(flag_rx1==true&&flag_rx2==true)
{
flag_rx2=false;
}
else if(flag_rx1==true&&flag_rx2==false)
{
flag_rx1=false;

if(strlen(recv_int8)>0)
{
if(strlen(recv_char)==cmd_len)
{
printf(">>>recv_cmd_char = [%s]n",recv_char);
c_dwin_cmd_analysis(recv_char,&cmd_recv_char);
memset(recv_char,0x00,UART_RECV_LEN);
tcflush(fd, TCIOFLUSH);
}

}


}


}

}
close(fd);

return;
}

dwin.h



#include "stddef.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "stdbool.h"
#include "stdint.h"

#define TRUE 1
#define FALSE 0
#define uint8_t u_int8_t
#define bool _Bool

typedef enum{
EVENT_FLAG_OK = 0X0,
EVENT_FLAG_AUDIO_RECORD = 0x3,
EVENT_FLAG_AUDIO_PLAY = 0x4,
EVENT_FLAG_CAM_SCAN = 0x5,
EVENT_FLAG_NFC_SCAN = 0x6,
EVENT_FLAG_BOOK_SEARCH = 0x10,
EVENT_FLAG_BOOK_INPUT = 0x11,
EVENT_FLAG_UNKOWN = -1,
}dwin_event_flag;

typedef enum{
// EVENT_FLAG_STATUS_START = 0x0,
EVENT_FLAG_STATUS_ING = TRUE,
EVENT_FLAG_STATUS_STOP = FALSE,
EVENT_FLAG_STATUS_ERROR = -1,
}dwin_event_flag_status;

typedef enum{
EVENT_TYPE_DWIN_SEND = 0x0,  // uart read
EVENT_FLAG_DWIN_RECV = 0x1,  // uart write
}dwin_event_type;

#define DWIN_CMD_LEN_U8_MAX 259

typedef struct
{
uint8_t head[2];
uint8_t len;
uint8_t wr;
uint8_t addr[2];
uint8_t * value;
// uint8_t cmd_u8[DWIN_CMD_LEN_U8_MAX];
uint8_t * cmd_u8;
char * cmd_char;
}i_dwin_cmd;

void uart_recv_value_cut(uint8_t * recv_all);
// dwin_event_flag uart_judge_dwin_event(char *str);
dwin_event_flag uart_judge_dwin_event(i_dwin_cmd * cmd);

void print_dwin_cmd(i_dwin_cmd cmd);

char * dwin_cmd_uint8_t2char(i_dwin_cmd cmd);

char * uint8_t2char(uint8_t value);

char * uint8_t2char_list(uint8_t * p_dwin_u8_value,int len);

void change_dwin_status(dwin_event_flag event_flag);

// UART recv/send judge dwin_event
#define EVENT_KEY_NUM_MAX 10
// #define EVENT_KEY_MAX -1

// function
void func_open_record();
void func_close_record();
void func_open_cam();
void func_close_cam();
void func_open_nfc();
void func_close_nfc();

#define EVENT_NAME_MAX 11
#define EVENT_FLAG_NAME_MAX 30
#define EVENT_KEY_VALUE_MAX 11   //"3000 0001"  is 8

typedef struct
{
dwin_event_flag flag;
char event_name[EVENT_NAME_MAX];
dwin_event_flag_status status;
char key[EVENT_KEY_VALUE_MAX];   // key[0,3] addr key[4,7] value
char flag_name[EVENT_FLAG_NAME_MAX];
void (*open)();
void (*close)();
}dwin_event_key;

dwin_event_key event_key_list[EVENT_KEY_NUM_MAX];
// {
//     // {
//     //     event_flag, event_name,
//     //     event_status,
//     //     event_addr, event_flag_name,
//     //     event_ops1, enent_ops1
//     // },

//     {
//         EVENT_FLAG_AUDIO_RECORD, "record",
//         EVENT_FLAG_STATUS_STOP,
//         "1503", "EVENT_FLAG_AUDIO_RECORD",
//         func_open_record,   func_close_record
//     },

//     {
//         EVENT_FLAG_CAM_SCAN,    "cam",
//         EVENT_FLAG_STATUS_STOP,
//         "1504", "EVENT_FLAG_CAM_SCAN",
//         func_open_cam,      func_close_cam
//     },

//     {
//         EVENT_FLAG_NFC_SCAN,    "nfc",
//         EVENT_FLAG_STATUS_STOP,
//         "1505", "EVENT_FLAG_NFC_SCAN",
//         func_open_nfc,      func_close_nfc
//     },

//     {
//         EVENT_FLAG_UNKOWN,  "unknow",
//         EVENT_FLAG_STATUS_STOP,
//         "0000" , "EVENT_FLAG_UNKOWN"
//     }
// };

typedef struct
{
char key[EVENT_KEY_VALUE_MAX];   // key[0,3] addr key[4,7] value
char event_name[EVENT_FLAG_NAME_MAX];
void (*func)();
}dwin_event_key_spec;

void func_search();
void func_spec_end();

void searc_spec_event();

#define EVENT_KEY_SPEC_VALUE "over"
#define EVENT_KEY_SPEC_NUM_MAX 20
dwin_event_key_spec event_key_spec[EVENT_KEY_SPEC_NUM_MAX];
// {
//     // special event, just one ops
//     // {
//     //     event_key, event_name,
//     //     event_ops
//     // },

//     {
//         "1502010012",  "search",
//         func_search
//     },
//     // ...

//     {EVENT_KEY_SPEC_VALUE,  "end",
//         func_spec_end
//     }
// };

void change_dwin_status_key(dwin_event_key *in_key);

void change_cmd_send_status(dwin_event_flag temp_event_flag);

// -------------------- basic func  --------------------

void copy_u8_2_u8(uint8_t * u8_raw);

void u8_to_char(uint8_t * in_u8, char ** out);

uint8_t * u8_to_u8(uint8_t * in_u8);

// -------------------- dwin func --------------------
void dwin_cmd_init_send();
void init_dwin_status();
void i_dwin_cmd_clear(i_dwin_cmd * cmd);

// get u8 from example
void uart_dwin_cmd_analysis(uint8_t *str);

void copy_u8_to_cmdu8(i_dwin_cmd *cmd, uint8_t * u8);

//int my_strlen(uint8_t *str);

// int search_str_end(uint8_t *str_z, int count);
// int my_strlen(uint8_t *str);
// int judge_char(uint8_t * str);

#define DWIN_CMD_CHAR_ADDR_VALUE 8
#define DWIN_CMD_CHAR_VALUE_VALUE 12
#define DWIN_CMD_CHAR_MAX 513
#define DWIN_CMD_U8_MAX 256

// add for char
#define C_CMD_POINT_HEAD 0
#define C_CMD_POINT_LEN 4
#define C_CMD_POINT_WR 6
#define C_CMD_POINT_ADDR 8
#define C_CMD_POINT_VALUE 12

typedef struct
{
char head[5];
char len[3];
char wr[3];
char addr[5];
char * value;
char * cmd_char;
}c_dwin_cmd;


四、测试结果

image.png

这是检索事件

image.png

录音及停止事件

image.png

扫码及停止

image.png

nfc检索及停止

PS:电子发烧友的代码显示有异常,有兴趣的话去我的csdn查看,后续会更新出来。
https://blog.csdn.net/qq_38091632

六、编译

命令:$CC uart_example.c dwin.c -o dwin_test

五、问题

5.1 字符串地址传递

void u8_to_char(uint8_t * , char ** );

子函数内如果使用malloc分配空间,建议使用char **进行地址传递。

也可以在main函数中先分配,再传指针进子函数。

5.2 uart数据

串口传输可以选择hex还是字符串,我们在使用串口工具测试时选择hex,模拟实际迪文屏数据传输。

此外注意传入的数据为uint_8,需要转换为字符串进行分析。

原数据:0x5AA5
字符串:"5AA5"

传出时再进行字符串转为uint_8

5.3 一次接收8位

使用read函数对ttySC1进行读取,一次只能读8位。

由于迪文屏的串口数据结构,其中的第三个字节传输的是后续数据的长度。

比如0x5AA5 06 82 1000 01 1234

其中的06就是后续的82 1000 01 1234长度,所以先计算出一组数据长度为06+3,3是前面的5AA5加上len。

代码中先判断head为5AA5,然后存入len,当接收到的字符串长度为len*2,一组接收完毕。

乘以2是因为uint_8转换为两位char。

六、小结

串口通信较为简单,实现了基础的读写功能后再结合串口屏的传输协议进行数据处理。

此功能应该适用于其他linux开发板,后续可以在其他平台上试试。

目前上述代码只是实现了基本的事件判断架构,后续各种判断条件可以自行添加,只需要定义匹配的字符串以及执行的函数即可。

最后,感谢飞凌提供的试用机会。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 飞凌
    +关注

    关注

    0

    文章

    134

    浏览量

    16095
  • 开发板试用
    +关注

    关注

    3

    文章

    301

    浏览量

    2039
收藏 人收藏

    评论

    相关推荐

    RZ/G2L高速虚拟串口方案 基于瑞萨RZ/G2L SMARC开发板的虚拟(Virtual UART)实现方案

    RZ/G2L具有丰富的外设,比如千兆以太网,CANFD以及丰富的UART接口,可以满足工业数据收集处理相关的应用。本文主要介绍基于瑞萨RZ/G2L SMARC
    发表于 11-20 14:41 178次阅读
    <b class='flag-5'>RZ</b>/<b class='flag-5'>G2L</b>高速虚拟<b class='flag-5'>串口</b>方案 基于瑞萨<b class='flag-5'>RZ</b>/<b class='flag-5'>G2L</b> SMARC<b class='flag-5'>开发板</b>的虚拟(Virtual UART)实现方案

    RZ/G2L串口SCI的使用(下)

    RZ/G2L串口SCI的使用
    的头像 发表于 08-03 08:06 465次阅读
    <b class='flag-5'>RZ</b>/<b class='flag-5'>G2L</b><b class='flag-5'>串口</b>SCI的使用(下)

    串口如何与电脑连接

    串口是一种广泛应用于工业自动化领域的显示设备,它可以通过串口与电脑进行通信,实现数据的传输和控制。 一、
    的头像 发表于 08-01 15:10 883次阅读

    RZ/G2L串口SCI的使用(上)

    RZ/G2L串口SCI的使用
    的头像 发表于 07-25 08:06 478次阅读
    <b class='flag-5'>RZ</b>/<b class='flag-5'>G2L</b><b class='flag-5'>串口</b>SCI的使用(上)

    串口ModBus开发流程

    这里接前一章节,继续开发,前章主要讲解基础开发流程,此章节开始讲解
    的头像 发表于 07-19 08:21 428次阅读
    <b class='flag-5'>迪</b><b class='flag-5'>文</b><b class='flag-5'>串口</b><b class='flag-5'>屏</b>ModBus<b class='flag-5'>开发</b>流程

    RZ/G2L Demo调试经验流程分享(1)

    r01us0553ej0107-rz-g(Release Note).pdf,r01us0556ej0102-rz-g(Board_StartUp_Guide_smarcEVK).pdf,对SMARC EVK of RZ/
    的头像 发表于 05-06 14:25 602次阅读
    <b class='flag-5'>RZ</b>/<b class='flag-5'>G2L</b> Demo调试经验流程分享(1)

    RZ/G2LRZ/G2LC和RZ/G2UL的SMARC EVK启动指南Rev.1.01

    电子发烧友网站提供《RZ/G2LRZ/G2LC和RZ/G2UL的SMARC EVK启动指南Re
    发表于 02-02 09:45 1次下载
    <b class='flag-5'>RZ</b>/<b class='flag-5'>G2L</b>、<b class='flag-5'>RZ</b>/<b class='flag-5'>G2</b>LC和<b class='flag-5'>RZ</b>/<b class='flag-5'>G2</b>UL的SMARC EVK启动指南Rev.1.01

    米尔RZ/G2L开发板瑞米派双核A55Remi Pi学习兼容树莓派扩展模块

    RemiPi瑞萨第一款MPU生态板卡兼容树莓派扩展模块瑞萨RZ/G2L工业级处理器,便于企业客户产品开发;RemiPi兼容树莓派所有配件,方便产品原型搭建和创新应用;更多的工业接口,兼顾开发
    发表于 01-29 17:05 4次下载

    瑞萨RZ/G2L串口SCI的使用(下)

    RZ/G2L的SCIFA异步通讯模式下支持的最高波特率可以达到12.5Mbps,如果异步基础时钟选择16倍波特率,同时关闭波特率发生器的倍频模式下依然可以达到3.125Mbps。如果异步基础时钟选择8倍波特率或者波特率发生器开启倍频模式,最大波特率可以达到6.25Mbps
    的头像 发表于 01-17 12:20 1183次阅读
    瑞萨<b class='flag-5'>RZ</b>/<b class='flag-5'>G2L</b><b class='flag-5'>串口</b>SCI的使用(下)

    瑞萨RZ/G2L串口SCI的使用(上)

    瑞萨RZ/G2L串口简称SCI,全称Serial Communication Interface。
    的头像 发表于 01-17 12:19 1426次阅读
    瑞萨<b class='flag-5'>RZ</b>/<b class='flag-5'>G2L</b><b class='flag-5'>串口</b>SCI的使用(上)

    RZ/G2L RZ/G2LC RZ/G2UL用灵活的软件包设置GPIO

    电子发烧友网站提供《RZ/G2L RZ/G2LC RZ/G2UL用灵活的软件包设置GPIO.pd
    发表于 01-14 10:53 0次下载
    <b class='flag-5'>RZ</b>/<b class='flag-5'>G2L</b> <b class='flag-5'>RZ</b>/<b class='flag-5'>G2</b>LC <b class='flag-5'>RZ</b>/<b class='flag-5'>G2</b>UL用灵活的软件包设置GPIO

    RZ/G2L RZ/G2LC RZ/G2UL RZ/G3S灵活软件包应用说明

    电子发烧友网站提供《RZ/G2L RZ/G2LC RZ/G2UL
    发表于 01-14 10:46 1次下载
    <b class='flag-5'>RZ</b>/<b class='flag-5'>G2L</b> <b class='flag-5'>RZ</b>/<b class='flag-5'>G2</b>LC <b class='flag-5'>RZ</b>/<b class='flag-5'>G2</b>UL <b class='flag-5'>RZ</b>/<b class='flag-5'>G</b>3S灵活软件包应用说明

    RZ/G2L Linux系统如何添加新的内核模块

    RZ/G2L Linux系统的镜像基于yocto构建,本篇介绍如何添加新的内核模块。
    的头像 发表于 01-04 12:19 1693次阅读
    <b class='flag-5'>RZ</b>/<b class='flag-5'>G2L</b> Linux系统如何添加新的内核模块

    OK113i-S开发板试用】开机测评--硬件篇

    OK113i-S开发板试用】开机测评--硬件篇 一,开箱见图 包装精致 注意:上面红黄的先是本人接上的 配了电源线和一根usb线一根天线 OK113i-S
    发表于 12-24 20:51

    浏览器网页与T5L串口深度扩展(Node-RED技术)

    ——来自开发者论坛本期为大家推送一个很有创意的开发者论坛获奖开源案例——浏览器网页与T
    的头像 发表于 12-09 08:13 824次阅读
    浏览器网页与T<b class='flag-5'>5L</b><b class='flag-5'>迪</b><b class='flag-5'>文</b><b class='flag-5'>屏</b><b class='flag-5'>串口</b>深度扩展(Node-RED技术)