1 硬件
先给出我使用的树莓派的核心板与核心板解出来的串口。
再给出底板的串口的原理图:
所以,结合这两个图,可以将核心板的TX接底板的RX,核心板的RX接底板的TX,能组成一个配对,在电脑上使用usb线,接到开发板上的usb转串口的接口上,就可以完成串口的debug口数据打印到电脑上。
这样,就完成调试串口的基本用法了。
2 增加串口功能
基于1的硬件的说明,可以在sys_config.fex中增加串口2。
[uart_para2]
uart_used = 1
uart_port = 2
uart_type = 2
uart_tx = port:PI18<3><1>
uart_rx = port:PI19<3><1>
;uart_rts = port:PI16<3><1>
;uart_cts = port:PI17<3><1>
由于这几根线并未在底板和核心板中引出来,所以,我们只需要做一个简单的实验去验证:
root@marsboard:~# echo "hello world" > /dev/ttyS0
hello world
root@marsboard:~#
root@marsboard:~# echo "hello world" > /dev/ttyS1
root@marsboard:~#
root@marsboard:~#
root@marsboard:~#
其中,ttyS0就是我们所看到的控制台,所以,直接echo能在串口上显示出来。
3 驱动武汉中显科技的Gpu35btp屏
基于以上说明,只需要在应用层控制Gpu35btp屏即可。
代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define UART_SPEED 115200
#define CHAR_ONE "CLS(0);DS16(0,0,'we need to send command to the uart',4);"
#define LCD_DEV "/dev/ttyS1"
static int fd = -1;
speed_t speed_arr[] = {B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300,
B115200, B57600, B38400, B19200, B9600, B4800, B2400, B1200, B300};
int name_arr[] = {115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 300,
115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200, 300};
static void set_speed(int fd, int speed)
{
int i = 0;
int status = 0;
struct termios opt = {0};
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 fd");
return;
}
tcflush(fd,TCIOFLUSH);
}
}
}
static int set_parity(int fd, int databits, int stopbits, char parity)
{
struct termios opt = {0};
if (tcgetattr(fd, &opt) != 0) {
perror("SetupSerial 1");
return -1;
}
opt.c_cflag &= ~CSIZE;
switch (databits) {
case 7:
opt.c_cflag |= CS7;
break;
case 8:
opt.c_cflag |= CS8;
break;
default:
printf("Unsupported data size");
return -1;
}
switch (parity) {
case 'n':
case 'N':
opt.c_cflag &= ~PARENB; //Clear parity enable
opt.c_iflag &= ~INPCK; //Enable parity checking
break;
case 'o':
case 'O':
opt.c_cflag |= (PARODD | PARENB);
opt.c_iflag |= INPCK; //Disnable parity checking
break;
case 'e':
case 'E':
opt.c_cflag |= PARENB; //Enable parity
opt.c_cflag &= ~PARODD;
opt.c_iflag |= INPCK; //Disnable parity checking
break;
case 'S':
case 's':
opt.c_cflag &= ~PARENB;
opt.c_cflag &= ~CSTOPB;break;
default:
printf("Unsupported parity");
return -1;
}
switch (stopbits) {
case 1:
opt.c_cflag &= ~CSTOPB;
break;
case 2:
opt.c_cflag |= CSTOPB;
break;
default:
printf("Unsupported stop bits\n");
return (-1);
}
if (parity != 'n') {
opt.c_iflag |= INPCK;
}
tcflush(fd,TCIFLUSH);
opt.c_cc[VTIME] = 150;
opt.c_cc[VMIN] = 0;
opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
opt.c_oflag &= ~OPOST;
if (tcsetattr(fd,TCSANOW,&opt)!= 0) {
printf("SetupSerial 3");
return -1;
}
return 0;
}
int main()
{
fd = open(LCD_DEV, O_RDWR);
if (fd < 0) {
printf("Error open %s\n\n", LCD_DEV);
return -1;
}
printf("[%d]Open %s Ok\n", fd, LCD_DEV);
set_speed(fd, UART_SPEED);
set_parity(fd, 8, 1, 'n');
write(fd,CHAR_ONE,sizeof(CHAR_ONE));
while(1) {
}
close(fd);
return 0;
}
运行程序:
root@marsboard:~# ./lcdTest
[3]Open /dev/ttyS1 Ok
^C
可以看到液晶显示内容如下:
4 速度测试
在树莓派A20上的main函数中执行如下内容:
unsigned int lcd_x = 0;
unsigned int pic_x = 0;
unsigned int index = 0;
unsigned int gap = 0;
unsigned int base_gap = 0;
unsigned int base_x = 0;
unsigned int p_value;
struct timeval tm_start;
struct timeval tm_end;
if ((fd = open(uart_inf.path, O_RDWR)) < 0) {
uart_error("Open %s Error, Return", uart_inf.path);
return -1;
}
set_speed(fd, UART_SPEED);
set_parity(fd, 8, 1, 'n');
memset(cmd, 0, UART_BUF_SIZE);
while(1){
usleep(1000);
//输入状态
gettimeofday(&tm_start,NULL);
write(fd,cmd,100);
gettimeofday(&tm_end,NULL);
printf("time eclapse:%ld ms\r\n",tm_end.tv_sec *1000 +
tm_end.tv_usec / 1000 - tm_start.tv_sec * 1000 - tm_start.tv_usec / 1000);
//while(1);
}
测试的时候,发现如下现象:
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:332 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:331 ms
也就是说,隔一段时间有300+ms的延迟。
按照计算来说,应该只有1ms+100*8/115200s的延迟,所以这个现象是不正常的。
而将程序移到linux上,发现的现象如下所示:
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:1 ms
time eclapse:0 ms
time eclapse:2 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:1 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:1 ms
time eclapse:0 ms
time eclapse:1 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:1 ms
time eclapse:6 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:18 ms
time eclapse:0 ms
time eclapse:19 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:17 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:17 ms
time eclapse:0 ms
time eclapse:19 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:19 ms
time eclapse:0 ms
time eclapse:19 ms
time eclapse:0 ms
time eclapse:0 ms
time eclapse:15 ms
time eclapse:0 ms
从这里来看,linux上跑起来的的也不算不正确。
note:
在linux上需要做如下操作:
$ dmesg
$ vi /etc/udev/rules.d/70-ttyusb.rules
在上面的.rules文件中,输入内容:“KERNEL=="ttyUSB[0-9]*",MODE="0666"。
最终经过一系列测试,发现有几个问题:
1.srand函数尽量不要放到while(1)中,因为这样产生的值有规律性,在液晶面板上看到的现象就是,一个短暂的时间内,值是不变的。这个原因还不得而知,因为没法知道其实现。
2.目前的A20板子的DCD没有使用,所以设置串口参数的时候,不能带O_NDELAY,否则write的时候会报错,尽管这会让液晶屏刷新速率提高,但是不提倡。