Linux系统下通过9344芯片实现控灯示例
程序员文章站
2022-04-11 09:07:41
...
1、背景介绍
目前公司做的项目中使用了9344 USB转串口芯片,这样通过USB扩展四路串口,便于扩展。
项目中CPU通过串口与CPLD进行数据传输,实现点灯和读取机箱号、槽位号功能。
2、驱动加载
X86目前安装的linux操作系统,为了识别9344芯片,首先需要安装驱动,驱动源码下载地址:
https://download.csdn.net/download/jj12345jj198999/12244680
insmod 后就能在dev下看到四个串口设备
/dev/ttyWCHUSB0
/dev/ttyWCHUSB1
/dev/ttyWCHUSB2
/dev/ttyWCHUSB3
3、应用示例
这里使用了串口与CPLD通信,实现点灯和读机箱、槽位号功能,首先定义了传输规则,如下:
然后就可以编写应用程序了,代码如下:
/* TTY testing utility (using tty driver)
* Copyright (c) 2020
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License.
*
* Cross-compile with cross-gcc -I /path/to/cross-kernel/include
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/serial.h>
#include "uart.h"
int speed_arr[] = {
B115200,
B57600,
B38400,
B19200,
B9600,
B4800,
B2400,
B1200,
B300
};
int name_arr[] = {
115200,
57600,
38400,
19200,
9600,
4800,
2400,
1200,
300
};
/**
* libtty_setopt - config tty device
* @fd: device handle
* @speed: baud rate to set
* @databits: data bits to set
* @stopbits: stop bits to set
* @parity: parity set
*
* The function return 0 if success, or -1 if fail.
*/
int libtty_setopt(int fd, int speed, int databits, int stopbits, char parity)
{
struct termios newtio;
struct termios oldtio;
int i;
bzero(&newtio, sizeof(newtio));
bzero(&oldtio, sizeof(oldtio));
if (tcgetattr(fd, &oldtio) != 0) {
perror("tcgetattr");
return -1;
}
newtio.c_cflag |= CLOCAL | CREAD;
newtio.c_cflag &= ~CSIZE;
/* set tty speed */
for (i = 0; i < sizeof(speed_arr) / sizeof(int); i++) {
if (speed == name_arr[i]) {
cfsetispeed(&newtio, speed_arr[i]);
cfsetospeed(&newtio, speed_arr[i]);
}
}
/* set data bits */
switch (databits) {
case 5:
newtio.c_cflag |= CS5;
break;
case 6:
newtio.c_cflag |= CS6;
break;
case 7:
newtio.c_cflag |= CS7;
break;
case 8:
newtio.c_cflag |= CS8;
break;
default:
fprintf(stderr, "unsupported data size\n");
return -1;
}
/* set parity */
switch (parity) {
case 'n':
case 'N':
newtio.c_cflag &= ~PARENB; /* Clear parity enable */
newtio.c_iflag &= ~INPCK; /* Disable input parity check */
break;
case 'o':
case 'O':
newtio.c_cflag |= (PARODD | PARENB); /* Odd parity instead of even */
newtio.c_iflag |= INPCK; /* Enable input parity check */
break;
case 'e':
case 'E':
newtio.c_cflag |= PARENB; /* Enable parity */
newtio.c_cflag &= ~PARODD; /* Even parity instead of odd */
newtio.c_iflag |= INPCK; /* Enable input parity check */
break;
default:
fprintf(stderr, "unsupported parity\n");
return -1;
}
/* set stop bits */
switch (stopbits) {
case 1:
newtio.c_cflag &= ~CSTOPB;
break;
case 2:
newtio.c_cflag |= CSTOPB;
break;
default:
perror("unsupported stop bits\n");
return -1;
}
newtio.c_cc[VTIME] = 0; /* Time-out value (tenths of a second) [!ICANON]. */
newtio.c_cc[VMIN] = 0; /* Minimum number of bytes read at once [!ICANON]. */
tcflush(fd, TCIOFLUSH);
if (tcsetattr(fd, TCSANOW, &newtio) != 0)
{
perror("tcsetattr");
return -1;
}
return 0;
}
/**
* libtty_open - open tty device
* @devname: the device name to open
*
* In this demo device is opened blocked, you could modify it at will.
*/
int libtty_open(const char *devname)
{
int fd = open(devname, O_RDWR | O_NOCTTY | O_NDELAY);
int flags = 0;
if (fd == -1) {
perror("open device failed");
return -1;
}
flags = fcntl(fd, F_GETFL, 0);
flags &= ~O_NONBLOCK;
if (fcntl(fd, F_SETFL, flags) < 0) {
printf("fcntl failed.\n");
return -1;
}
if (isatty(fd) == 0)
{
printf("not tty device.\n");
return -1;
}
else
printf("tty device test ok.\n");
return fd;
}
/**
* libtty_close - close tty device
* @fd: the device handle
*
*/
int libtty_close(int fd)
{
return close(fd);
}
void tty_test(int fd)
{
int nwrite, nread;
char buf[10];
int i;
char hexarray[] = { 0xaa, 0x88, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x01, 0x55 };
memset(buf, 0x55, sizeof(buf));
while (1) {
nwrite = write(fd, hexarray, sizeof(hexarray));
printf("wrote %d bytes already.\n", nwrite);
sleep(1);
nread = read(fd, buf, sizeof(buf));
printf("read %d bytes already.\n", nread);
printf("*************************\n");
for (i = 0; i < nread; i++)
printf(" 0x%.2x", buf[i]);
printf("\n*************************\n");
sleep(1);
}
}
int libtty_set_rs485(int fd, int enable)
{
struct serial_rs485 rs485conf;
int ret;
if (enable)
rs485conf.flags |= SER_RS485_ENABLED;
else
rs485conf.flags &= ~SER_RS485_ENABLED;
ret = ioctl(fd, TIOCSRS485, &rs485conf);
if (ret < 0) {
printf("set rs485 fail.\n");
}
return ret;
}
#if 0
int main(int argc, char *argv[])
{
int fd;
int ret;
char ch;
fd = libtty_open("/dev/ttyWCHUSB3");
if (fd < 0) {
printf("libtty_open error.\n");
exit(0);
}
ret = libtty_setopt(fd, 9600, 8, 1, 'n');
if (ret != 0) {
printf("libtty_setopt error.\n");
exit(0);
}
// enable rs485
ret = libtty_set_rs485(fd, 1);
if (ret != 0) {
printf("libtty_set_rs485 error.\n");
exit(0);
}
tty_test(fd);
ret = libtty_close(fd);
if (ret != 0) {
printf("libtty_close error.\n");
exit(0);
}
}
#endif
int led_on(int number)
{
int fd;
int ret;
char ch;
int nwrite;
char hexarray1[] = { 0xaa, 0x88, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x01, 0x55 };
char hexarray2[] = { 0xaa, 0x88, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x01, 0x55 };
char hexarray3[] = { 0xaa, 0x88, 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x01, 0x55 };
char hexarray4[] = { 0xaa, 0x88, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x01, 0x55 };
char hexarray5[] = { 0xaa, 0x88, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x01, 0x55 };
char hexarray6[] = { 0xaa, 0x88, 0x00, 0x05, 0x80, 0x00, 0x00, 0x00, 0x01, 0x55 };
fd = libtty_open("/dev/ttyWCHUSB2");
if (fd < 0) {
printf("libtty_open error.\n");
return -1;
}
ret = libtty_setopt(fd, 9600, 8, 1, 'n');
if (ret != 0) {
printf("libtty_setopt error.\n");
return -1;
}
// enable rs485
ret = libtty_set_rs485(fd, 1);
if (ret != 0) {
printf("libtty_set_rs485 error.\n");
return -1;
}
switch(number){
case 0:
nwrite = write(fd, hexarray1, sizeof(hexarray1));
break;
case 1:
nwrite = write(fd, hexarray2, sizeof(hexarray2));
break;
case 2:
nwrite = write(fd, hexarray3, sizeof(hexarray3));
break;
case 3:
nwrite = write(fd, hexarray4, sizeof(hexarray4));
break;
case 4:
nwrite = write(fd, hexarray5, sizeof(hexarray5));
break;
case 5:
nwrite = write(fd, hexarray6, sizeof(hexarray6));
break;
default:
break;
}
ret = libtty_close(fd);
if (ret != 0) {
printf("libtty_close error.\n");
return -1;
}
return 0;
}
int led_off(int number)
{
int fd;
int ret;
char ch;
int nwrite;
char hexarray1[] = { 0xaa, 0x88, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x55 };
char hexarray2[] = { 0xaa, 0x88, 0x00, 0x01, 0x80, 0x00, 0x00, 0x00, 0x00, 0x55 };
char hexarray3[] = { 0xaa, 0x88, 0x00, 0x02, 0x80, 0x00, 0x00, 0x00, 0x00, 0x55 };
char hexarray4[] = { 0xaa, 0x88, 0x00, 0x03, 0x80, 0x00, 0x00, 0x00, 0x00, 0x55 };
char hexarray5[] = { 0xaa, 0x88, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x55 };
char hexarray6[] = { 0xaa, 0x88, 0x00, 0x05, 0x80, 0x00, 0x00, 0x00, 0x00, 0x55 };
fd = libtty_open("/dev/ttyWCHUSB2");
if (fd < 0) {
printf("libtty_open error.\n");
return -1;
}
ret = libtty_setopt(fd, 9600, 8, 1, 'n');
if (ret != 0) {
printf("libtty_setopt error.\n");
return -1;
}
// enable rs485
ret = libtty_set_rs485(fd, 1);
if (ret != 0) {
printf("libtty_set_rs485 error.\n");
return -1;
}
switch(number){
case 0:
nwrite = write(fd, hexarray1, sizeof(hexarray1));
break;
case 1:
nwrite = write(fd, hexarray2, sizeof(hexarray2));
break;
case 2:
nwrite = write(fd, hexarray3, sizeof(hexarray3));
break;
case 3:
nwrite = write(fd, hexarray4, sizeof(hexarray4));
break;
case 4:
nwrite = write(fd, hexarray5, sizeof(hexarray5));
break;
case 5:
nwrite = write(fd, hexarray6, sizeof(hexarray6));
break;
default:
break;
}
ret = libtty_close(fd);
if (ret != 0) {
printf("libtty_close error.\n");
return -1;
}
return 0;
}
int get_chasis()
{
int fd;
int ret;
char ch;
int nwrite, nread;
char buf[10];
char chasis_temp1,chasis_temp2;
int chasis=0;
int i;
char hexarray[] = { 0xaa, 0x88, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55 };
memset(buf, 0x55, sizeof(buf));
fd = libtty_open("/dev/ttyWCHUSB4");
if (fd < 0) {
printf("libtty_open error.\n");
return -1;
}
ret = libtty_setopt(fd, 9600, 8, 1, 'n');
if (ret != 0) {
printf("libtty_setopt error.\n");
return -1;
}
// enable rs485
ret = libtty_set_rs485(fd, 1);
if (ret != 0) {
printf("libtty_set_rs485 error.\n");
return -1;
}
nwrite = write(fd, hexarray, sizeof(hexarray));
sleep(1);
nread = read(fd, buf, sizeof(buf));
printf("read %d bytes already.\n", nread);
chasis_temp1=buf[7];
chasis_temp2=buf[8];
chasis=((chasis_temp1<<8)|chasis_temp2)&0x3f;
ret = libtty_close(fd);
if (ret != 0) {
printf("libtty_close error.\n");
return -1;
}
return chasis;
}
int get_slot()
{
int fd;
int ret;
char ch;
int nwrite, nread;
char buf[10];
char slot_temp1,slot_temp2;
int slot=0;
int i;
char hexarray[] = { 0xaa, 0x88, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55 };
memset(buf, 0x55, sizeof(buf));
fd = libtty_open("/dev/ttyWCHUSB3");
if (fd < 0) {
printf("libtty_open error.\n");
return -1;
}
ret = libtty_setopt(fd, 9600, 8, 1, 'n');
if (ret != 0) {
printf("libtty_setopt error.\n");
return -1;
}
// enable rs485
ret = libtty_set_rs485(fd, 1);
if (ret != 0) {
printf("libtty_set_rs485 error.\n");
return -1;
}
nwrite = write(fd, hexarray, sizeof(hexarray));
sleep(1);
nread = read(fd, buf, sizeof(buf));
printf("read %d bytes already.\n", nread);
slot_temp1=buf[7];
slot_temp2=buf[8];
slot=((slot_temp1<<8)|slot_temp2)&0x1f;
ret = libtty_close(fd);
if (ret != 0) {
printf("libtty_close error.\n");
return -1;
}
return slot;
}