最简单的一个UART通信实例

1、What’s UART?

UART全称为Universal Asynchronous Receiver/Transmitter,即通用异步收发器,是串行通信一种通信技术,常用于单片机和电脑之间以及单片机和单片机之间的板级通信。下面是串口通信硬件连接图:

最简单的一个UART通信实例_第1张图片

 

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、运行结果:(这里打印的是读取数据的结果)

最简单的一个UART通信实例_第2张图片

代码参考地址:

https://github.com/gunder1129/android-tool/tree/master/UARTsample

你可能感兴趣的:(Linux,C/C++)