海思 HI35xx 平台串口配置方法

海思 HI35xx 平台串口配置方法 Winki 2024-01-05 10:33:11 929

一、前言

串行接口简称串口(通常指COM接口),是采用串行通信方式的扩展接口,其特点是通信线路简单,只要一对传输线就可以实现双向通信,从而大大降低了成本,但传送速度一般,数据传输率为115kbps~230kbps。异步串行UART(Universal Asynchronous Receiver/Transmitter),即通用异步接收/发送。UART是一款并行输入转换为串行输出的芯片(如MAX232、MAX485等),它们通常集成在主板上。UART芯片的另一功能是将TTL逻辑电平进行转换,属于硬件逻辑实现,不需要软件的干涉。UART常用的接口标准有RS-232、RS-485,其中RS-232的传送距离最大为约15米,最高速率为20kb/s;而RS-485的最大传输距离约为1219米,最大传输速率为10Mb/s。这两种接口标准的传输速率与传输速度差异这么大,主要是因对逻辑电平的规定以及信号传输抗干扰能力不一样导致的,在实际应用中根据传输距离及速度的不同需求选用即可。

二、海思UART

在海思芯片架构中,UART主要是将来自外围设备的数据进行串并转换后传入内部总线,以及将数据进行并串转换后输出到外围设备,从而实现两芯片之间的通信。Hi35XX提供了3个UART单元:

  • UART0:4线UART,可用于调试、报警和云台控制。
  • UART1:2线UART,可用于调试、报警。
  • UART3:2线UART,可用于调试、报警。

UART配置:

  • 支持数据位和停止位的位宽可编程。数据位可通过编程设定为5/6/7/8比特,停止位可通过过编程设定为1bit或2bit。
  • 支持奇、偶校验方式或无校验。
  • 支持速率可编程,支持9600bit/s、14400bit/s、19200bit/s、38400bit/s、57600bit/s、76800bit/s、115200bit/s、230400bit/s、460800bit/s多种波特率可选。

三、海思UART启用

海思默认只开启UART0单元作为调试功能使用,在实际应用中我们常常需要使用UART1、UART2来与外围设备对接,以实现串口通信。此时我们就需要配置启用UART1、UART2单元,这个过程分为3步:

  • 确保硬件IO口设计及时钟频率正常
  • 检查UART单元所使用的IO口复用关系
  • 配置内核,将UART映射为设备文件

硬件电路部分按要求布线连接,一般没什么问题,这里主要讲解IO口的复用关系配置及内核配置。

上表是海思芯片IO口复用关系表,由此可知大多数IO口的默认功能都不是作为UART单元来使用,故需要配置它们的复用关系,可以采用在系统启动脚本里添加如下命令来配置IO口的复用关系:

himm 0x120F00F8 0x1
himm 0x120F00FC 0x1
……

接下来是配置内核,以实现UART单元映射为linux下的设备文件,这里主要涉及就是海思的设备树更改,相对简单。进入SDK目录\osdrv\opensource\kernel\linux-3.18.y\arch\arm\boot\dts,找到以下设备树文件:

修改以下内容:

至此海思UART单元配置完成,重新编译内核,并将内核烧录运行。如果没有什么异常,在设备上的/dev/目录下会有以下3个设备文件出现,接下来软件对此设备文件进行编程操作即可。

/dev/ttyAMA0
/dev/ttyAMA1
/dev/ttyAMA2

四、海思UART软件操作

与其他的linux设备操作类似,通过open、fcntl、close来实现与UART单元进行操作。在串口设备中,比较特殊的就是串口的波特率、奇偶校验、数据位以及停止位的设置了,只有将它们正确设置了才能进行串口通讯。

*
*Function: HI_Serial_Open(int fd,char* ComDevice)  
*Param: fd:file descirbe handle     Serial Device: /dev/ttyAMA1 /dev/ttyAMA2
*Output: Ok or Fail
*/

int HI_Serial_Open(char* HiSerDevice)  
{  
    int fd;

    fd = open(HiSerDevice, O_RDWR|O_NOCTTY|O_NDELAY);  
    if (HI_FALSE == fd)  
    {  
        perror("HiSerial Can't Open Serial HiSerDevice");  
        return(HI_FALSE);  
    }  
    //恢复串口为阻塞状态                                 
    if(fcntl(fd, F_SETFL, 0) < 0)  
    {  
        debugpri("fcntl failed!\n");  
        return(HI_FALSE);  
    }       
    else  
    {  
        debugpri("fcntl=%d\n",fcntl(fd, F_SETFL,0));  
    }  
    //测试是否为终端设备      
    if(0 == isatty(STDIN_FILENO))  
    {  
        debugpri("standard input is not a terminal device\n");  
        return(HI_FALSE);  
    }  
    else  
    {  
        debugpri("isatty success!\n");  
    }                
    printf("fd->open=%d\n",fd);  
    return fd;  
}  

/*
*Function: HI_Serial_Close(int fd) 
*Param: fd:file descirbe handle     
*Output: Null
*/

void HI_Serial_Close(int fd)  
{  
    if(fd > 0)
        close(fd); 
    return;    
}  

/*
*Function: HI_Serial_Set(int fd,int speed,int flow_ctrl,int databits,int stopbits,int parity) 
*Param1: fd: file descirbe handle     
*Param2: speed: select the Serial speed.115200,19200,9600...
*Param3: flow_ctrl: if use flow control
*Param4: databits: data bit select
*Param5: stopbits: stopbits select    
*Param5: parity: partiy select    
*Output: Ok or Fail
*/
int HI_Serial_Set(int fd,int speed,int flow_ctrl,int databits,int stopbits,int parity)  
{
    /*******
    ********
    ********/  
}

int HI_Serial_Usage(void)
{
    printf("Usage:\n");
    printf("\tmyhicom [-d] <HiSerialDevice> [-s] get netdeviece info [-rw] read or wite select\n");
    printf("\tmyhicom [-h] for more usage\n");
    printf("\tmyhicom [-v] the verson of the sofware\n");
    printf("\tExample:\n\tmyhicom -d /dev/ttyAMA1 -s 115200 -w HiSerial:HelloWorld\n");
}


/*
**Function: main()
**usage: read or write com
**parameter: help
*/
int main ( int argc, char *argv[] )
{
    int cmd;
    int len;
    //extern char *optarg;
    //extern int optind, opterr, optopt;
    char HiSerialDev[32]="/dev/ttyAMA1";
    char sendbuf[1024]={0};
    char recvbuf[1024]={0};
    int SerialSpeed = 115200;

    Hi_init_signals();
    if(argc == 1)
    {
        HI_Serial_Usage();        
        exit(0);
    }
    else
    {
        while ((cmd = getopt(argc, argv, ":d:s:rw:hv")) != -1)
        {
            switch (cmd)
            {
                case 'h':
                    HI_Serial_Usage();
                    break;
                case 'v':
                    printf("myHicom --Verson V1.0.0\n");
                    break;
                case 'd':
                    //printf("catch -d %s \n",optarg);
                    memset(HiSerialDev,0,sizeof(HiSerialDev));
                    sprintf(HiSerialDev,"%s",optarg);
                    printf("myHicom HiSerialDev %s\n",optarg);
                    break;
                case 's':
                    SerialSpeed = atoi(optarg);
                    printf("myHicom speed %d\n",SerialSpeed);
                    break;
                case 'r':                    
                     debugpri("myHicom read\n");
                     HiSerfd = HI_Serial_Open(HiSerialDev);
                     HI_Serial_Init(HiSerfd,SerialSpeed,0,8,1,'N');
                     while(1)
                     {
                        len = HI_Serial_Recv(HiSerfd, recvbuf,sizeof(recvbuf));  
                        if(len > 0)  
                        {  
                            recvbuf[len] = '\0';  
                            printf("Hiserial receive data: %s\n",recvbuf);  
                            memset(recvbuf,0,sizeof(recvbuf));
                            //break;  
                        }  
                        else  
                        {  
                            debugpri("Hiserial haven't data receive \n");  
                        }  
                        sleep(2);                          
                     };        
                     break;
                case 'w':
                     debugpri("myHicom write %s\n",optarg);
                     HiSerfd = HI_Serial_Open(HiSerialDev);
                     printf("fd = %d device = %s speed = %d\n",HiSerfd,HiSerialDev,SerialSpeed);
                     HI_Serial_Init(HiSerfd,SerialSpeed,0,8,1,'N');                     
                     sprintf(sendbuf,"%s\n",optarg);                     
                     HI_Serial_Send(HiSerfd, sendbuf, strlen(sendbuf)+1); 
                     if(HiSerfd > 0)
                         HI_Serial_Close(HiSerfd);                    
                     break;
                case ':':
                    printf ("option: -%c missing argument. -h for help.\n",(char)optopt);
                    break;
                case '?':
                    printf("Unknown option: -%c\n",(char)optopt);
                    break;
                default:
                    exit(0);
            }
        }    
    }    
    return 0;
}

五、总结

串口通信加强了主控芯片与外围设备之间的联系,通过RS485接口可以实现远距离通信。在海思平台开发中,可以实现球机平台远程控制、红外报警等智能监控应用。本文主要是总结海思UART单元的应用于配置及提供一个简单的串口通信样例实现。

样例运行效果图:

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
Winki
红包 2 1 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
Winki
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区