• HI3521D串口使用 转载自www.acodelife.cn


    概述

    因项目需要,需要使用的HI3521D的串口1和串口2,并把串口2作为485使用。

    海思UART启用

    因为海思默认启用uart0 ,作为调试串口。所以我们需要说明的是uart1和uart2。

    uart1:

    我们进入/dev目录下,发现有uart1存在,编写代码的时候,open /dev/ttyARM1,发现报错No such device or address。我猜,肯定是内核问题,所以内核需要配置,这个稍后再讲。 使用uart1 ,我们需要做些什么? 查看电路图:

    连接uart1的引脚,有两个功能,所以,我们先要复用引脚。
    在Hi3521DV100_PINOUT_CN.xlsx文件中,找到GPIO6_5和GPIO6_7,如图

    我们可以在启动文件中,通过如下方式复用GPIO6_5和GPIO6_7使为uart1引脚使用。

    himm 0x120F00F8 0x1
    himm 0x120F00FC 0x1
    

    第二步:就是我们将的配置内核了。以实现UART单元映射为linux下的设备文件,这里主要涉及就是海思的设备树更改。
    在osdrv/opensource/kernel/linux-3.18y/arch/arm/boot/dts目录下,找到如下文件

    打开hi3521d.dtsi文件,修改文件。

    aliases {
            fmc = &fmc;
            serial0 = &uart0;
            serial1 = &uart1;
            spi0 = &spi_bus0;
        };
    
    
    uart1: uart@121090000 {
                    compatible = "arm,pl011", "arm,primecell";
                    reg = <0x12090000 0x1000>;
                    interrupts = <0 7 4>;
                    clocks = <&clock HI3521D_UART1_CLK>;
                    clock-names = "apb_pclk";
                    status = "okay";
                };
    

    保存,然后编译内核,烧写内核,就ok啦。

    uart2

    对呀uart2,完全就是按照uart1的方式操作,略过。

    串口编程

    uart1

    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <sys/ioctl.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <math.h>
    #include <time.h>
    #include <unistd.h>
    #include <termios.h>
    
    
    
    int serial_fd = 0 ;
    #define RECE_BUFF_LEN 3000
    char serialBuff[RECE_BUFF_LEN] ;
    
    int open_port(int fd,int comport)
    {
        long  vdisable;
    
        fd = open("/dev/ttyAMA2", O_RDWR|O_NOCTTY|O_NDELAY);
        if (-1 == fd)
        {
            perror("Can't Open Serial Port");
            return(-1);
        }else
        {
            printf("%d
    " , fd) ;
        }
    
         return fd;
    }
    
    
    int set_speed(int fd , int speed)
    {
        int birdrate_arr[] = {B115200, B38400, B19200, B9600, B4800,
        B2400, B1200, B300, B38400, B19200, B9600, B4800, B2400, B1200, B300};
        int name_arr[] = {115200, 38400, 19200, 9600, 4800, 2400 ,
        1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300};
    
        struct termios oldtio;
        if  (tcgetattr( fd,&oldtio)  !=  0) {
          perror("SetupSerial 1");
          return -1;
         }
        int i = -1 ;
        for(i = 0 ; i < sizeof(name_arr)/sizeof(name_arr[0]) ; i++)
        {
            if(speed == name_arr[i])
                break ;
        }
    
        tcflush(fd,TCIFLUSH);
        cfsetispeed(&oldtio, birdrate_arr[i]);
        cfsetospeed(&oldtio, birdrate_arr[i]);
        if((tcsetattr(fd,TCSANOW,&oldtio))!=0)
        {
            perror("com set error");
            return -1;
        }
        tcflush(fd,TCIFLUSH);
    
        return 0 ;
    
    }
    
    
    int set_Parity(int fd, int databits, int stopbits, int parity)
    {
        struct termios oldtio;
        if  (tcgetattr( fd,&oldtio)  !=  0)
        {
          perror("SetupSerial 1");
          return -1;
        }
        oldtio.c_cflag |= (CLOCAL | CREAD) ;
        switch(databits) //ÉèÖÃÊýŸÝλ
        {
            case 7:
                oldtio.c_cflag &= ~CSIZE ;
                oldtio.c_cflag |= CS7 ;
                break ;
            case 8:
                oldtio.c_cflag &= ~CSIZE ;
                oldtio.c_cflag |= CS8 ;
                break ;
            default:
                perror("Unsupported data size.");
                return -1 ;
        }
        switch(parity)
        {
            case 'n':
            case 'N':
                oldtio.c_cflag &= ~PARENB ;
                oldtio.c_iflag &= ~INPCK ;
                break ;
            case 'o':
            case 'O':
                oldtio.c_cflag |= PARENB ;
                oldtio.c_cflag |= PARODD ;
                oldtio.c_iflag |= INPCK ;
                break ;
            case 's':
            case 'S':
                oldtio.c_cflag &= ~PARENB ;
                oldtio.c_cflag &= ~CSTOPB ;
                oldtio.c_iflag |= INPCK ;
                break ;
            case 'e':
            case 'E':
                oldtio.c_cflag |= PARENB;
                oldtio.c_cflag &= ~ PARODD ;
                oldtio.c_iflag |= INPCK ;
                break ;
            default :
                perror("Unsupported parity.");
                return -1 ;
        }
    
        switch(stopbits)
        {
            case 1:
                oldtio.c_cflag &= ~CSTOPB ;
                break ;
            case 2:
                oldtio.c_cflag |= CSTOPB ;
                break ;
            default :
                perror("Unsupported stopbits.");
                return -1 ;
        }
    
        oldtio.c_cflag |= (CLOCAL|CREAD) ;
        oldtio.c_iflag &= ~(ICANON|ECHO|ECHOE|ISIG) ;
    
        oldtio.c_oflag &= ~OPOST ;
        oldtio.c_oflag &= ~(ONLCR|OCRNL) ;
    
        oldtio.c_iflag &= (ICRNL | INLCR) ;
        oldtio.c_iflag &= ~(IXON|IXOFF|IXANY) ;
    
    
        tcflush(fd,TCIFLUSH);
        oldtio.c_cc[VTIME] = 0 ;
        oldtio.c_cc[VTIME] = 0 ;
    
        /*raw model*/
        oldtio.c_lflag  &= ~(ICANON | ECHO | ECHOE | ISIG);
        oldtio.c_oflag  &= ~OPOST;
    
        oldtio.c_iflag &= ~(INLCR|IGNCR|ICRNL);
        oldtio.c_iflag &= ~(ONLCR|OCRNL);
    
        oldtio.c_oflag &= ~(INLCR|IGNCR|ICRNL);
        oldtio.c_oflag &= ~(ONLCR|OCRNL);
        if((tcsetattr(fd,TCSANOW,&oldtio))!=0)
        {
            perror("com set error");
            return -1;
        }
        return 0 ;
    
    
    }
    
    
    int init_serial_port()
    {
        int serial_fd ;
        if((serial_fd=open_port(serial_fd,1))<0){//Žò¿ªŽ®¿Ú
            perror("open_port error");
            return 0;
        }
    
        int speed = 9600; //115200 ;
        if(set_speed(serial_fd,speed) < 0)
        {
            perror("set speed error");
            return 0 ;
        }
        int databits = 8 ;
        int stopBits = 1 ;
        if(set_Parity(serial_fd,databits , stopBits , 'N') < 0)
        {
            perror("set_Parity error");
            return 0 ;
        }
    
        return serial_fd ;
    }
    
    
    void serial_port_pthread()
    {
    
        while(1)
        {
            usleep(400) ;
            if(serial_fd <= 0)
            {
                printf("get_serial_fd() <= 0
    ") ;
    
                continue ;
            }
    
            {
                char buff[RECE_BUFF_LEN] ;
    
    
                int ret = read(serial_fd , buff , RECE_BUFF_LEN) ;
                if(ret <= 0)
                {
                    //printf("serial read error!
    ") ;
                    continue ;
                }else
                {
                    int i = 0 ;
                    for( i = 0 ; i < ret ; i++)
                       printf("%x,", buff[i]) ;
                       printf(" end!
    ") ;
    
                }
    
            }
        }
    }
    
    
    int main(void)
    {
        printf("Hello World!
    ");
    
    
        if((serial_fd = init_serial_port()) ==-1)
               printf("init_serial_port error!
    ") ;
    
        serial_port_pthread();
    
        return 0;
    }
    
    

    uart2串口编程

    对于uart2,我们是用来作为RS485的,所以,需要有一个使能信号。如图:

    RE脚连接到海思是GPIO0_7引脚,图就不截了。

    所以,我们需要设置GPIO0_7为IO输出,配置步骤如下:
    通用输入输出
    每个管脚可以配置为输入或者输出,具体步骤如下:
    步骤 1. 参考“管脚复用控制寄存器”配置管脚的相应位,使能需要使用的GPIO 管脚功能。
    步骤 2. 配置寄存器GPIO_DIR,选择GPIO 是作为输入还是输出。
    步骤 3. 当配置成输入管脚时,读取GPIO_DATA 寄存器可查看输入信号值;当配置成输出管
    脚时,通过向GPIO_DATA 寄存器写入输出值可控制GPIO管脚输出电平。

    配置GPIO_DIR

    GPIO0基地址(0x1215_0000)+GPIO_DIR偏移地址(0x400),设置为何值?

    从图可以看出,我们设置的是GPIO0_7的DIR,所以第8位设置为1,即himm 0x12150400 0x80

    配置GPIO_DATA ,因为DATA的配置跟DIR差不多,所以不详细的说。GPIO_DATA 地址:0x121503FC

    所以,uart2的编程跟uart1编程区别就在,需要发送数据的时候,DATA拉高,读取数据的时候DATA拉低。

    system("himm  0x121503fc 0xff");
    usleep(250);
    write(serial_fd , buff , ret) ;
    system("himm  0x121503fc 0x7f");
    

    以上是我的小见解,如有错误,多多指教

  • 相关阅读:
    茶香账簿小程序开发进度(3)
    软件需求十步走阅读笔记(一)
    茶香账簿小程序开发进度(2)
    茶香账簿小程序开发进度(1)
    软件工程概论总结及对老师的意见
    人月神话阅读笔记03
    第二阶段第七次站立会议
    第二阶段第六次站立会议
    第二阶段第五次站立会议
    第二阶段第四次站立会议
  • 原文地址:https://www.cnblogs.com/new-ass/p/11309619.html
Copyright © 2020-2023  润新知