文章基于smart210开发板(主芯片为s5pv210),在linux系统移植完毕的基础上进行串口的收发调试。 为了测试方便,未将串口的相关的函数进行分离,建议使用时将此部分分开,在主函数内调用串口的函数。
其中涉及到的epoll的知识将不再介绍,请移步https://www.cnblogs.com/snailrun/p/5574611.html
准备步骤如下:
1.连接好测试要用的串口后,通过电脑的串口调试助 手,进行电脑和开发板(用超级终端显示)收发数据的测试,确定对 应的串口设备名;由于直接操作串口可以避免驱动的编写,而串口设备名不一会按照用户手册上的指定的来,所以需要进行该步骤,操作方法: 在超级终端上输入echo "hello" > /dev/ttySAC3,观察串口助手上是 否会接收到hello(串口助手上此时的波特率可以随机设置),如若接 收不到,将命令中串口设备名“ttySAC3”改为“ttySAC2”、“ttySAC1”,
2.根据上步的结果,确定好串口设备名后编写相应的串口发送程序,然后通过arm-linux-gcc命令完成编译,生成可执行文件,file一下可以 得到"...ELF 32-bit LSB executable, ARM..."这样的信息,表示生成 的可执行文件可用。
3.将生成的可执行文件通过根文件系统加入开发板文件系统中,用超级终端进行执行,如果串口助手方面接收到数据就表示测试成功。
测试步骤:
- 进行超级终端十六进制显示问题测试:
测试方法:使用printf+%x打印十六进制数据
测试代码:见附件text.c
#include <stdio.h>
char a = 0x11;
int main(void)
{
printf("%x\n", a);
return 0;
}
测试结果:成功打印数据11
2.进行超级终端十六进制数据发送:
测试方法:用串口编程的send函数发送一串十六进制数据
测试代码:见附件text_send.c
//串口相关的头文件
#include <stdio.h> /*标准输入输出定义*/
#include <stdlib.h> /*标准函数库定义*/
#include <unistd.h> /*Unix 标准函数定义*/
#include <linux/types.h>
#include <linux/stat.h>
#include <linux/fcntl.h> /*文件控制定义*/
#include <termios.h> /*PPSIX 终端控制定义*/
#include <linux/errno.h> /*错误号定义*/
#include <string.h>
//宏定义
#define FALSE -1
#define TRUE 0
/*******************************************************************
* 名称: UART0_Open
* 功能: 打开串口并返回串口设备文件描述
* 入口参数: fd :文件描述符 port :串口号(ttyS0,ttyS1,ttyS2)
* 出口参数: 正确返回为1,错误返回为0
*******************************************************************/
int UART0_Open(int fd,char* port)
{
fd = open( port, O_RDWR|O_NOCTTY|O_NDELAY);
if (FALSE == fd)
{
perror("Can't Open Serial Port");
return(FALSE);
}
//恢复串口为阻塞状态
if(fcntl(fd, F_SETFL, 0) < 0)
{
printf("fcntl failed!\n");
return(FALSE);
}
else
{
printf("fcntl=%d\n",fcntl(fd, F_SETFL,0));
}
//测试是否为终端设备
if(0 == isatty(STDIN_FILENO))
{
printf("standard input is not a terminal device\n");
return(FALSE);
}
else
{
printf("isatty success!\n");
}
printf("fd->open=%d\n",fd);
return fd;
}
/*******************************************************************
* 名称: UART0_Close
* 功能: 关闭串口并返回串口设备文件描述
* 入口参数: fd :文件描述符 port :串口号(ttyS0,ttyS1,ttyS2)
* 出口参数: void
*******************************************************************/
void UART0_Close(int fd)
{
close(fd);
}
/*******************************************************************
* 名称: UART0_Set
* 功能: 设置串口数据位,停止位和效验位
* 入口参数: fd 串口文件描述符
* speed 串口速度
* flow_ctrl 数据流控制
* databits 数据位 取值为 7 或者8
* stopbits 停止位 取值为 1 或者2
* parity 效验类型 取值为N,E,O,,S
*出口参数: 正确返回为1,错误返回为0
*******************************************************************/
int UART0_Set(int fd,int speed,int flow_ctrl,int databits,int stopbits,int parity)
{
int i;
int status;
int speed_arr[] = { B115200, B19200, B9600, B4800, B2400, B1200, B300};
int name_arr[] = {115200, 19200, 9600, 4800, 2400, 1200, 300};
struct termios options;
/*tcgetattr(fd,&options)得到与fd指向对象的相关参数,并将它们保存于options,该函数还可以测试配置是否正确,该串口是否可用等。若调用成功,函数返回值为0,若调用失败,函数返回值为1.
*/
if( tcgetattr( fd,&options) != 0)
{
perror("SetupSerial 1");
return(FALSE);
}
//设置串口输入波特率和输出波特率
for ( i= 0; i < sizeof(speed_arr) / sizeof(int); i++)
{
if (speed == name_arr[i])
{
cfsetispeed(&