新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > Linux下的串口總線驅動(四)

        Linux下的串口總線驅動(四)

        作者: 時間:2016-11-22 來源:網絡 收藏
        六.串口測試代碼

        我們已經配置了mini2440的串口配置,然后根據mini2440開發板的硬件電路知道S3C2440本身總共有3個串口:UART0、1、2,其中UART0,1可組合為一個全功能的串口,在大部分的應用中,我們只用到3個簡單的串口功能(本開發板提供的Linux和WinCE驅動也是這樣設置的),即通常所說的發送(TXD)和接收(RXD),它們分別對應板上的CON1、CON2、CON3,這3個接口都是從CPU直接引出的,是TTL電平。為了方便用戶使用,其中UART0做了RS232電平轉換,它們對應于COM0,可以通過附帶的直連線與PC機互相通訊。我們這個實驗選用CON1作為測試串口的端口。用導線將CON1的1號(TXD1)和2號(RXD1)引腳相連,實現自發自收。

        本文引用地址:http://www.104case.com/article/201611/319915.htm

        實驗環境:內核linux2.6.32.2,arm-linux-gcc交叉編譯器,mini2440開發板

        內核配置:選中s3c2440.o samsung.o serial_core.o tty_io.o n_tty.o tty_ioctl.o tty_ldisc.o tty_buffer.o tty_port.o。

        測試代碼如下:

        #include

        #include

        #include

        #include

        #include

        #include

        #include

        #include

        #include

        #include

        #define FALSE 1

        #define TRUE 0

        char *recchr="We received:"";

        int speed_arr[] = {

        B921600, B460800, B230400, B115200, B57600, B38400, B19200,

        B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600,

        B4800, B2400, B1200, B300,

        };

        int name_arr[] = {

        921600, 460800, 230400, 115200, 57600, 38400, 19200,

        9600, 4800, 2400, 1200, 300, 38400, 19200, 9600,

        4800, 2400, 1200, 300,

        };

        void set_speed(int fd, int speed)

        {

        int i;

        int status;

        struct termios Opt;

        tcgetattr(fd, &Opt); //獲取線路設置

        for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++) {

        if (speed == name_arr[i]) {

        tcflush(fd, TCIOFLUSH); //刷新輸入輸出隊列

        cfsetispeed(&Opt, speed_arr[i]); //設置輸入波特率

        cfsetospeed(&Opt, speed_arr[i]); //設置輸出波特率

        status = tcsetattr(fd, TCSANOW, &Opt); //設置線路設置

        if (status != 0)

        perror("tcsetattr fd1");

        return;

        }

        tcflush(fd,TCIOFLUSH); //刷新輸入輸出隊列

        }

        }

        int set_Parity(int fd,int databits,int stopbits,int parity, int flowctrl)

        {

        struct termios options;

        if ( tcgetattr( fd,&options) != 0) { //獲取線路設置

        perror("SetupSerial 1");

        return(FALSE);

        }

        options.c_cflag &= ~CSIZE ; //利用CSIZE掩碼把正確位從cflag中分離并清零,其他位不變

        switch (databits) {

        case 7:

        options.c_cflag |= CS7;

        break;

        case 8:

        options.c_cflag |= CS8;

        break;

        default:

        fprintf(stderr,"Unsupported data sizen");

        return (FALSE);

        }

        switch (parity) {

        case n:

        case N:

        options.c_cflag &= ~PARENB;

        options.c_iflag &= ~INPCK;

        break;

        case o:

        case O:

        options.c_cflag |= (PARODD | PARENB);

        options.c_iflag |= INPCK;

        break;

        case e:

        case E:

        options.c_cflag |= PARENB;

        options.c_cflag &= ~PARODD;

        options.c_iflag |= INPCK;

        break;

        case S:

        case s:

        options.c_cflag &= ~PARENB;

        options.c_cflag &= ~CSTOPB;

        break;

        default:

        fprintf(stderr,"Unsupported parityn");

        return (FALSE);

        }

        switch (stopbits) {

        case 1:

        options.c_cflag &= ~CSTOPB; //相應位置0

        break;

        case 2:

        options.c_cflag |= CSTOPB;

        break;

        default:

        fprintf(stderr,"Unsupported stop bitsn");

        return (FALSE);

        }

        if (flowctrl)

        options.c_cflag |= CRTSCTS;

        else

        options.c_cflag &= ~CRTSCTS;

        if (parity != n)

        options.c_iflag |= INPCK;

        // VTIME設定字節輸入時間計時器

        options.c_cc[VTIME] = 150; // 15 seconds

        //VMIN設定滿足讀取功能的最低字節個數

        options.c_cc[VMIN] = 0;

        options.c_lflag &= ~(ECHO | ICANON);

        tcflush(fd,TCIFLUSH); //刷新輸入隊列

        if (tcsetattr(fd,TCSANOW,&options) != 0) { //設置線路設置

        perror("SetupSerial 3");

        return (FALSE);

        }

        return (TRUE);

        }

        int OpenDev(char *Dev) //打開串口

        {

        int fd = open( Dev, O_RDWR ); //| O_NOCTTY | O_NDELAY

        if (-1 == fd) {

        perror("Cant Open Serial Port");

        return -1;

        } else

        return fd;

        }

        int main(int argc, char *argv[])

        {

        int fd, next_option, havearg = 0;

        char *device = "/dev/ttySAC1";

        int speed = 115200;

        int flowctrl = 0;

        int nread;

        char buff[512];

        pid_t pid;

        char *xmit = "com test by ptr 2012";

        sleep(1);

        fd = OpenDev(device);

        if (fd > 0) {

        set_speed(fd,speed);

        } else {

        fprintf(stderr, "Error opening %s: %sn", device, strerror(errno));

        exit(1);

        }

        if (set_Parity(fd,8,1,N,flowctrl)== FALSE) {

        fprintf(stderr, "Set Parity Errorn");

        close(fd);

        exit(1);

        }

        pid = fork();

        if (pid < 0) {

        fprintf(stderr, "Error in fork!n");

        } else if (pid == 0){

        while(1) {

        printf("SEND: %sn",xmit);

        write(fd, xmit, strlen(xmit));

        sleep(1);

        }

        exit(0);

        } else {

        while(1) {

        if (nread > 0) {

        buff[nread] =

        主站蜘蛛池模板: 乡宁县| 湖北省| 准格尔旗| 富民县| 宁强县| 左贡县| 绥滨县| 靖西县| 察雅县| 朝阳区| 阳新县| 平潭县| 建宁县| 沅陵县| 洪江市| 南昌县| 绍兴县| 南汇区| 额敏县| 蒙自县| 宁津县| 禹城市| 和林格尔县| 荔浦县| 赤城县| 永州市| 平陆县| 桂东县| 伊宁县| 巢湖市| 开远市| 肃北| 宁国市| 来凤县| 永平县| 铜山县| 来安县| 宜兴市| 永修县| 新巴尔虎左旗| 资溪县|