欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-04-11 09:07:41
...

1、背景介绍

目前公司做的项目中使用了9344 USB转串口芯片,这样通过USB扩展四路串口,便于扩展。

 

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

项目中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通信,实现点灯和读机箱、槽位号功能,首先定义了传输规则,如下:

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

然后就可以编写应用程序了,代码如下:

/* 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;
}

 

相关标签: Felven在职场