Linux系统下通过9344芯片实现控灯示例

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;
}
发布了1769 篇原创文章 · 获赞 388 · 访问量 279万+

猜你喜欢

转载自blog.csdn.net/jj12345jj198999/article/details/104825612