1、What’s UART?
UART全称为Universal Asynchronous Receiver/Transmitter,即通用异步收发器,是串行通信一种通信技术,常用于单片机和电脑之间以及单片机和单片机之间的板级通信。下面是串口通信硬件连接图:
2、使用的的系统函数
int tcgetattr(int fd, struct termios *termios_p); //用于获取与终端相关的参数
int tcsetattr(int fd, int optional_actions, struct termios *termios_p); //用于设置终端参数
int tcflush(int fd, int queue_selector); //刷清(扔掉)输入缓存
int cfsetispeed(struct termios *termios_p, speed_t speed); //设置输入速度
int cfsetospeed(struct termios *termios_p, speed_t speed) //设置输出速度
int open(const char *pathname,int flags);//打开或创建文件
ssize_t read(int fd,void*buf,size_t count)//从fd指向的文件中读取count字节到buf中
ssize_t write(int fd,void*buf,size_t count)//将从buf数据中写入count字节到fd指向的文件中
3、简单实现:
/**********************************************************************
Description: uart communications
Author: Gunder
**********************************************************************/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MCUUARTPORT "/dev/ttyLP3"
int main()
{
int fd;
printf("main start--->\n");
printf(" init dev start\n");
//打开设备/dev/ttyMT1
fd= open(MCUUARTPORT, O_RDWR | O_NDELAY | O_NOCTTY|O_NONBLOCK);
if (-1 == fd)
{
printf("open serial port %s fail %d\n", MCUUARTPORT, fd);
return fd;
}
fcntl(fd, F_SETFL, 0);//设置文件状态标志值为0,阻塞模式
printf("set baudrate\n");
//设置波特率
struct termios options;
memset(&options, 0x00, sizeof(options));
if (0 != tcgetattr(fd, &options))//获得串口属性
{
printf("%s error\n", __FUNCTION__);
return -1;
}
tcflush(fd, TCIOFLUSH);//刷新输入输出缓冲区
cfsetispeed(&options, B115200);//设置输入速度为115200
cfsetospeed(&options, B115200);//设置输出速度为115200
if (0 != tcsetattr(fd, TCSANOW, &options))//设置串口属性,TCSANOW:不等数据传输完毕就立即改变属性
{
printf("---- tc setattr error\n");
return -1;
}
tcflush(fd, TCIOFLUSH);//刷新输入输出缓冲区
//串口属性配置
printf("set properties\n");
memset(&options, 0x00, sizeof(options));
if (0 != tcgetattr(fd, &options))//获得串口属性
{
printf("tcgetattr failed-->1\n");
return -1;
}
options.c_cflag |= (CLOCAL | CREAD);
options.c_cflag &= ~CSIZE;
options.c_cflag |= CS8;
options.c_cflag &= ~CSTOPB;
options.c_cflag &= ~PARENB;
options.c_cflag &= ~CRTSCTS;
options.c_iflag &= ~(IXON | IXOFF | IXANY);
options.c_iflag &= IGNCR;
options.c_oflag &= ~OPOST;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 0;
tcflush(fd, TCIFLUSH);//刷新输入缓冲区
if (0 != tcsetattr(fd, TCSANOW, &options))//设置串口属性
{
printf("tcgetattr failed-->2\n");
return -1;
}
#if 0
//向串口写数据
int len;
printf("mcu_reboot start\n");
unsigned char write_data[] = { 1, 4, 2, 2, 1, 3, 133, 232, 0 };
len = write(fd, &write_data[0], 9);//执行后mcu会重启,不同的平台可能对应的协议不一样,写入的值就不一样
printf("mcu_open_lcd start\n");
unsigned char write_data[] = { 7, 8, 9, 2, 2, 82, 231, 0 };
len = write(fd, &write_data[0], 8);//执行后会打开lcd,不同的平台可能对应的协议不一样,写入的值就不一样
if (len > 0)
{
printf("len = %d, mcu will reboot or lcd\n", len);
}
else
{
printf("write failed\n");
tcflush(fd, TCOFLUSH);
}
#endif
#if 1
//向串口读数据
printf("read start-->\n");
FILE* fp;
fp = fopen("/data/gan.log", "a+");
if (fp == NULL)
{
printf("fopen failed\n");
}
//freopen("/data/gunder.txt", "a", stdout); setbuf(stdout, NULL);//将标准输出重定向到/data/gunder.txt
//freopen("/data/gunder.txt", "a", stderr); setbuf(stderr, NULL);//将标准出错重定向到/data/gunder.txt
int j = 1;
while(1){//由于不是每次都能读取到数据,所以要在循环中不断去读取
static uint8_t recv_buf[512];
int readLen = read(fd, recv_buf, 512);
if (readLen < 0)
{
printf("read failed\n");
return -1;
}
if(readLen == -1 || readLen == 0)
{
continue;//读取不到数据,就结束本次循环,进入下一次循环进行重新读取
}
printf("readLen = %d\n", readLen);
for(int i =0; i 10)break;//读取完10条数据就跳出while循环
}
#endif
close(fd);
printf("main end\n");
return 0;
}
4、源码编译中需要的Android.mk文件
# Copyright (C) 2012 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := mcu_main.cpp
LOCAL_LDLIBS := -llog
LOCAL_MODULE := mcu_update
LOCAL_CFLAGS += -Wall
LOCAL_MODULE_TAGS := eng
include $(BUILD_EXECUTABLE)
5、运行结果:(这里打印的是读取数据的结果)
代码参考地址:
https://github.com/gunder1129/android-tool/tree/master/UARTsample