UART串口通信

不管是单片机开发还是嵌入式Linux开发,串口都是最常用到的外设。可以通过串口将开发板与电脑相连,然后在电脑上通过串口调试助手来调试程序。还有很多模块,比如蓝牙、GPS、GPRS等都使用串口来与主控进行通讯的,在嵌入式Linux中一般使用串口作为控制台

1. UART简介

串口全称串行接口,是指数据一个一个的顺序传输,通信线路简单(两条线即可)。UART与外界相连最少只需要三根线:TXD(发送)、RXD(接收)、GND(地线)。其通讯格式如下图示:

  • 空闲位:数据线在空闲状态时为高电平
  • 起始位:将数据线拉低,表示开始数据传输
  • 数据位:实际要传输的数据
  • 奇偶校验位:对数据中1的位数进行奇偶校验用
  • 停止位:数据传输完成标志位
  • 波特率: 数据传输的速率,即每秒传输的数据位数

UART一般的接口电平有TTL和RS232,TTL用低电平表示逻辑0,高电平表示逻辑1;RS232采用差分线,-3 ~ -15V表示逻辑1, +3 ~ +15V表示逻辑0

IMX6U一共有8个UART,UART功能很多,这里只用到其最基本的串口功能。UART的时钟源由寄存器CCM_CSCDR1的UART_CLK_SEL位来选择,分频值由UART_CLK_PODF位来设置。下面介绍UART几个重要的寄存器:

  • UARTx_UCR1控制寄存器1
  • ADBR:自动波特率检测使能位
  • UARTEN:UART使能位
  • UARTx_UCR2控制寄存器2
  • IRTS:RTS引脚功能,为0时使用,为1时忽略
  • PREN:奇偶校验使能位
  • PROE:奇偶校验模式选择位
  • STOP:停止位数量,为0时1位停止位,为1时2位停止位
  • WS:数据位长度,为0时7位数据位,为1时8位数据位
  • TXEN:发送使能位,0关闭,1开启
  • RXEN:接收使能位,0关闭,1开启
  • SRST:软件复位
  • UARTx_UCR3控制寄存器3
  • RXDMUXSEL:始终置1
  • UARTx_USR2 状态寄存器2
  • TXDC:发送完成标志位,为1时表示发送缓冲区和移位寄存器为空(即发送完成)
  • RDR:数据接收标志位,为1时表示至少接收到一个数据
  • UARTx_UFCRUARTx_UBMRUARTx_UBIR这三个寄存器配合可得波特率

  • UARTx_URXD接收数据寄存器

  • UARTx_UTXD发送数据寄存器

综上所述,使用UART1来完成开发板与串口助手之间的通信,UART1的配置步骤如下:

  1. 设置UART1的时钟源
  2. 初始化UART1
  3. 使能UART1
  4. 编写UART1数据收发函数

2. 硬件介绍

本例程需要用到的硬件资源:

  • LED0
  • UART1


使用USB串口线将串口1和电脑连接后,利用串口调试助手与电脑进行通信

3. 程序编写

  • 新建uart文件夹,编写uart驱动文件bsp_uart.c和bsp_uart.h
/* 函数声明 */
void uart_init(void);
void uart_io_init(void);
void uart_disable(UART_Type *base);
void uart_enable(UART_Type *base);
void uart_softreset(UART_Type *base);
void putc(unsigned char c);
void puts(char *str);
unsigned char getc(void);
/* 初始化串口1,波特率为115200 */
void uart_init(void){uart_io_init();    //初始化串口IO/* 初始化UART1 */uart_disable(UART1); //先关闭UART1uart_softreset(UART1);    //软件复位UART1UART1->UCR1 = 0;     //先清除UCR1寄存器    /* 设置UART的UCR1寄存器,关闭自动波特率* bit14: 0 关闭自动波特率检测,我们自己设置波特率 */UART1->UCR1 &= ~(1<<14); /* 设置UART的UCR2寄存器,设置内容包括字长,停止位,校验模式,关闭RTS硬件流控* bit14: 1 忽略RTS引脚* bit8: 0 关闭奇偶校验* bit6: 0 1位停止位* bit5: 1 8位数据位* bit2: 1 打开发送* bit1: 1 打开接收 */UART1->UCR2 |= (1<<14) | (1<<5) | (1<<2) | (1<<1);/* UART1的UCR3寄存器* bit2: 1 必须设置为1!参考IMX6ULL参考手册3624页 */UART1->UCR3 |= 1<<2; /* 设置波特率* 波特率计算公式:Baud Rate = Ref Freq / (16 * (UBMR + 1)/(UBIR+1)) * 如果要设置波特率为115200,那么可以使用如下参数:* Ref Freq = 80M 也就是寄存器UFCR的bit9:7=101, 表示1分频* UBMR = 3124* UBIR =  71* 因此波特率= 80000000/(16 * (3124+1)/(71+1))=80000000/(16 * 3125/72) = (80000000*72) / (16*3125) = 115200 */UART1->UFCR = 5<<7; //ref freq等于ipg_clk/1=80MhzUART1->UBIR = 71;UART1->UBMR = 3124;/* 使能串口 */uart_enable(UART1);
}
/* 初始化串口1所使用的IO引脚 */
void uart_io_init(void){/* 1、初始化IO复用 * UART1_RXD -> UART1_TX_DATA* UART1_TXD -> UART1_RX_DATA */IOMUXC_SetPinMux(IOMUXC_UART1_TX_DATA_UART1_TX,0);    /* 复用为UART1_TX */IOMUXC_SetPinMux(IOMUXC_UART1_RX_DATA_UART1_RX,0); /* 复用为UART1_RX *//* 2、配置UART1_TX_DATA、UART1_RX_DATA的IO属性 *bit 16:0 HYS关闭*bit [15:14]: 00 默认100K下拉*bit [13]: 0 keeper功能*bit [12]: 1 pull/keeper使能*bit [11]: 0 关闭开路输出*bit [7:6]: 10 速度100Mhz*bit [5:3]: 110 驱动能力R0/6*bit [0]: 0 低转换率 */IOMUXC_SetPinConfig(IOMUXC_UART1_TX_DATA_UART1_TX,0x10B0);IOMUXC_SetPinConfig(IOMUXC_UART1_RX_DATA_UART1_RX,0x10B0);
}
/* @description : 关闭指定的UART* @param - base: 要关闭的UART* @return        : 无 */
void uart_disable(UART_Type *base){base->UCR1 &= ~(1<<0);
}
/* @description : 打开指定的UART* @param - base: 要打开的UART* @return        : 无 */
void uart_enable(UART_Type *base){base->UCR1 |= (1<<0);
}
/* @description : 复位指定的UART* @param - base: 要复位的UART* @return        : 无  */
void uart_softreset(UART_Type *base){base->UCR2 &= ~(1<<0);           /* UCR2的bit0为0,复位UART */while((base->UCR2 & 0x1) == 0); /* 等待复位完成             */
}
/* @description : 发送一个字符* @param - c  : 要发送的字符* @return      : 无 */
void putc(unsigned char c){while(((UART1->USR2 >> 3) &0X01) == 0);/* 等待上一次发送完成 */UART1->UTXD = c & 0XFF;                 /* 发送数据 */
}
/* @description : 发送一个字符串* @param - str   : 要发送的字符串* @return     : 无 */
void puts(char *str){char *p = str;while(*p)putc(*p++);
}
/* @description : 接收一个字符* @param      : 无* @return       : 接收到的字符 */
unsigned char getc(void){while((UART1->USR2 & 0x1) == 0);/* 等待接收完成 */return UART1->URXD;                /* 返回接收到的数据 */
}
  • 主程序main.c编写
int main(void){unsigned char a = 0;unsigned char state = OFF;int_init();               /* 初始化中断(一定要最先调用!) */imx6u_clkinit();            /* 初始化系统时钟          */delay_init();             /* 初始化延时               */clk_enable();              /* 使能所有的时钟          */led_init();                   /* 初始化led           */beep_init();              /* 初始化beep          */uart_init();              /* 初始化串口,波特率115200 */while(1){   puts("请输入1个字符:");a = getc();putc(a);  //回显功能puts("您输入的字符为:");putc(a);puts("\r\n\r\n");state = !state;led_switch(LED0, state);}return 0;
}

4. 下载验证

  • 修改Makefile文件:修改TARGET为uart,追加“bsp/uart”文件夹,还需修改如下代码
$(SOBJS) : obj/%.o : %.S$(CC) -Wall -nostdlib -fno-builtin -c -O2 $(INCLUDE) -o $@ $<
$(SOBJS) : obj/%.o : %.c$(CC) -Wall -nostdlib -fno-builtin -c -O2 $(INCLUDE) -o $@ $<
#加入了“-fno-builtin”选项,表示不使用内建函数,使用自已实现的函数
#如果不加该选项,编译的时候回提示“putc”“puts”这两个函数与内建函数冲突
  • 使用imxdownload软件将bin文件下载到SD卡中
  • 烧写成功后,插入SD卡,使用串口工具连接开发板,复位后提示输入字符,输入字符后会回显出来

Linux裸机开发|UART串口通信相关推荐

  1. linux与开发板串口通信

    研究了一天的linux串口,结果改了树莓派的系统配置文件config.txt给改了导致系统崩溃....其实我感觉网上的大多数方法都是不符合新版本树莓派的,网上的方法是通过修改系统配置文件后安装mini ...

  2. linux编译运行uart,嵌入式Linux裸机开发(七)——UART串口通信

    嵌入式Linux裸机开发(七)--UART串口通信 一.UART串口通信简介 通用异步收发器简称UART,即UNIVERSAL ASYNCHRONOUS RECEIVER AND TRANSMITTE ...

  3. 【正点原子MP157连载】 第十六章 UART串口通信实验-摘自【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7

    1)实验平台:正点原子STM32MP157开发板 2)购买链接:https://item.taobao.com/item.htm?&id=629270721801 3)全套实验源码+手册+视频 ...

  4. NXP(I.MX6uLL) UART串口通信原理————这个未复习

    参考:Linux NXP (I.MX6uLL) UART串口通信原理 作者:一只青木呀 发布时间: 2020-09-20 16:48:33 网址:https://blog.csdn.net/weixi ...

  5. 嵌入式linux启动过程分析,嵌入式Linux裸机开发(二)——S5PV210启动过程分析

    嵌入式Linux裸机开发(二)--S5PV210启动过程分析 一.iROM启动方式简介 友善之臂Smart210开发板的SoC为三星S5PV210,S5PV210采用iROM启动方式进行启动,通过查阅 ...

  6. 嵌入式linux s5pv210,嵌入式Linux裸机开发(二)——S5PV210启动过程分析

    嵌入式Linux裸机开发(二)--S5PV210启动过程分析 一.iROM启动方式简介友善之臂Smart210开发板的SoC为三星S5PV210,S5PV210采用iROM启动方式进行启动,通过查阅三 ...

  7. (四)裸机s5pv210之串口通信详解

    裸机s5pv210之串口通信详解 文章目录 裸机s5pv210之串口通信详解 前言 一.电子通信概念 1.同步通信和异步通信 2.电平信号和差分信号 3.并行接口和串行接口 二.串口通信的基本概念 1 ...

  8. 串口 单片机 文件_STM32物联网实战项目 HAL裸机开发09 串口打印

    就喜欢你关注我- HAL裸机开发09 - 串口打印 综合信息1.获取开发工具    微信公众号后台发送消息  -  工具2.获取开发板       淘宝搜索店铺  -  硬件家园3.快速了解平台    ...

  9. Linux uart寄存器读写,Linux下读写UART串口的代码

    Linux下读写UART串口的代码,从IBM Developer network上拿来的东西,操作比較的复杂,就直接跳过了,好在代码能用,记录一下- 两个实用的函数- /** *@brief 设置串口 ...

最新文章

  1. 好货不能错过!一款在GitHub上22k+star的人力资源管理系统
  2. centos6 安装 mantisbt-1.2.8 —— (1) VMware Workstation 12 Pro 虚拟机安装步骤详解(window 10 系统)
  3. ASP.NET之Request和Response对象
  4. jquery 导航栏目
  5. 空调自控系统基础知识及应用
  6. 03-Arm SiP Services
  7. jvm_垃圾收集算法讲解(一)
  8. jquery通过ajax向后台发送(checkbox)数组,并在后台接收,(发送的数据是checkedbox)...
  9. 利用SMW01分析BDOC错误
  10. vue 公众号扫描_vue编写微信公众号打开相机功能
  11. 教师节,老师们最大的愿望竟然是。。 | 今日最佳
  12. [渝粤教育] 西南科技大学 高等数学1 在线考试复习资料
  13. python os读取文件名_Python3基础 os.path.splitext 处理文件名,得到文件名+扩展名
  14. Receiver type ‘X’ for instance message is a forward declaration
  15. USACO 简易题解(蒟蒻的题解)
  16. java 一次CPU占用过高问题的排查及解决,java基础面试笔试题
  17. easyui treegrid 获取新添加行inserted_IDEA 2020.2 稳定版发布,带来了不少新功能...
  18. 两千万像素分辨率是多少_一亿像素究竟有无意义?荣耀红米为它“打”的火热...
  19. Nginx转发Tcp、Udp详细教程(简单粗暴)
  20. 嵌入式工程师待遇北京地区最高

热门文章

  1. Pranav Mistry第六感装置
  2. 怎样把主键盘区的减号(-)改成下划线(_)
  3. oracle 透明网关 MSSQL(oracle database gateway)
  4. Java接入支付宝支付(alipay)
  5. 上门私教上门瑜伽上门推拿等为什么是好项目?上门小程序APP源码系统开发
  6. GAT: 图注意力模型介绍及PyTorch代码分析
  7. 《Qt 6.x从入门到精通》简介
  8. kali部署配置巡风安全扫描器
  9. 高智商男性对伴侣更忠诚
  10. 数据结构入门----集合的交、并、差