首页 > 技术知识 > 正文

环境:Ubuntu 12.04-64bit 硬件平台:Hi3520D_V100 内核版本:linux-3.0.y Qt版本:qt4.8.6 编译器:arm-hisiv100nptl-linux-gcc 作者:MacianYuan 原文链接:https://www.ebaina.com/articles/140000004247 摘要: 485通讯 与 TTL通讯区别:RE使能 485通讯初始化处理 第一节:485通讯 与 TTL通讯区别:RE使能 一、QT中的GPIO操作

485 TTL 串口 232 422 的理论知识这里就不做介绍了,网上可以找到很多相关介绍。 较其他485特殊的地方是:因为普遍使用485 是半双工的方式。而485芯片都有收发使能,即不能同时收发,所以通过RE对收发状态进行控制。

RE使能主要从3个寄存器控制引脚的状态:

项目中硬件工程师设计的485电路,RE连接到UART1_RTSN(GPIO5_0)引脚,首先找到复用寄存器偏移地址配置复用禁用,当做普通GPIO使用,然后控制GPIO为输出,再向GPIO写入数据。参考芯片手册文档《Hi3520D/Hi3515A/Hi3515C H.264编解码处理器用户指南.pdf》 a)复用控制寄存器

复用的基地址 0x200F0000】 复用偏移地址 【0x04c】 【0】: GPIO5_0; 【1】: UART1_RTSN 复用控制地址 【0x200F004C】 即向【0x200F004C】 写入 【0】 【海思HI3520之QT开发】-串口通讯实战(四):串口通讯之485通讯

b)方向控制寄存器

GPIO_DIR 为 GPIO 方向控制寄存器。用来配置 GPIO 管脚方向。 GPIO_DIR = GPIO5_BASE + OFFSET(0x400) 【0】:输入 【1】:输出 即向 【0x201A0400】 写入 【1】 根据下图手册截取的部分 :GPIO5_BASE 【0x201A0000】 【海思HI3520之QT开发】-串口通讯实战(四):串口通讯之485通讯1 根据下图手册截取的部分 :GPIO_DIR Offset Address 【0x400】 【海思HI3520之QT开发】-串口通讯实战(四):串口通讯之485通讯2

c)数据控制寄存器

GPIO_DATA 为 GPIO 数据寄存器。用来对输入或输出数据进行缓存。当配置 GPIO_DIR 中对应位为输出时,写入 GPIO_DATA 寄存器的值将会输出到相应的管脚(注意需要配置正确的管脚复用);如果配置为输入时,将会读取相应输入管脚的值。

当 GPIO_DIR 相应的bit配置为输入时,有效读取的结果将返回管脚的值;当配置为 输出的时候,有效读取的结果将返回写入的值。GPIO_DATA 寄存器利用 PADDR[9:2]实现了读写寄存器比特的屏蔽操作。该寄存器对应 256 个地址空间。 PADDR[9:2]分别对应 GPIO_DATA[7:0], 当相应的 bit 为高时,则可以对相应的位进行读写操作;反之,若对应 bit 为低则不能进行操作。

例如:

若地址为 0x3FC( 0b11_1111_1100),则对 GPIO_DATA[7:0]这 8bit 操作全部有效。

若地址为 0x200( 0b10_0000_0000),则仅对 GPIO_DATA[7]的操作有效

对于GPIO5_0

GPIO_DATA = GPIO5_BASE + OFFSET(0x004)

GPIO_DATA[0] DATA寄存器地址 【0b00_0000_0100】 = 【0x004】

即向【0x201A0004】 写入 【1】/【0】 【海思HI3520之QT开发】-串口通讯实战(四):串口通讯之485通讯3

二、QT调用API对上述寄存器进行操作

1、在海思给的SDK中方法比较多,这里使用最简单的一种,调用一个API就可以实现: 对于访问物理地址的Api,可以使用这个函数来访问内存地址或寄存器地址

HI_S32 HI_MPI_SYS_SetReg(HI_U32 u32Addr, HI_U32 u32Value)

2、使用这个API 只需包含头文件、并在工程中增加lib库即可

#include “mpi_sys.h” LIBS += lmpi 第二节 485通讯初始化处理 一、 qt配置485 发送接收命令 485RE 引脚拉低 读 设置为接收模式 HI_MPI_SYS_SetReg(0x200F004C,0); HI_MPI_SYS_SetReg(0x201A0400,1); HI_MPI_SYS_SetReg(0x201A0004,0); 485RE 引脚拉高 写 设置为发送模式 HI_MPI_SYS_SetReg(0x200F004C,0); HI_MPI_SYS_SetReg(0x201A0400,1); HI_MPI_SYS_SetReg(0x201A0004,1); 485初始化函数 SensorAnalysis::SensorAnalysis(QObject *parent) : QObject(parent) { //485RE 引脚拉低 可读 HI_MPI_SYS_SetReg(0x200F004C,0); HI_MPI_SYS_SetReg(0x201A0400,1); HI_MPI_SYS_SetReg(0x201A0004,0); //普通串口初始化 Device_public::sensor_port = new QextSerialPort(“/dev/ttyAMA3”,QextSerialPort::EventDriven); //注意:得要先打开串口,然后再设置串口的参数,不然设置无效!!! int m_fd = Device_public::sensor_port->open(QIODevice::ReadWrite); //定义串口对象,并传递参数,在构造函数里对其进行初始化 if(m_fd){ //Device_public::sensor_port->setDtr(true); //Device_public::sensor_port->setRts(false); //设置波特率 Device_public::sensor_port->setBaudRate(BAUD9600); //设置数据位 Device_public::sensor_port->setDataBits(DATA_8); //设置奇偶校验 Device_public::sensor_port->setParity(PAR_NONE); //设置停止位 Device_public::sensor_port->setStopBits(STOP_1); //设置数据流控制,我们使用无数据流的默认设置 Device_public::sensor_port->setFlowControl(FLOW_OFF); //设置延时 –Modify 改小点 Device_public::sensor_port->setTimeout(10); qDebug() <<“Device_public::sensor_port /dev/ttyAMA3 success!”; }else{ qDebug () << tr(“open serial failed”); } //定时接收100ms的数据 使接收数据包完整 timer = new QTimer(this); timer->setInterval(100); //在有数据到达时开启计时 connect(timer, SIGNAL(timeout()), this,SLOT(on_timeout())); //定时获取传感器状态,5S采集一次 timer2 = new QTimer(this); timer2->setInterval(5000); timer2->start(); connect(timer2, SIGNAL(timeout()), this,SLOT(on_timeout2())); //有数据读取到,进入数据分析槽函数,分析出数据 connect(Device_public::sensor_port, SIGNAL(readyRead()), this,SLOT(ReadCom())); }
<

猜你喜欢