Linux裸机开发|UART串口通信
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_UFCR、UARTx_UBMR、UARTx_UBIR这三个寄存器配合可得波特率
UARTx_URXD接收数据寄存器
UARTx_UTXD发送数据寄存器
综上所述,使用UART1来完成开发板与串口助手之间的通信,UART1的配置步骤如下:
- 设置UART1的时钟源
- 初始化UART1
- 使能UART1
- 编写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串口通信相关推荐
- linux与开发板串口通信
研究了一天的linux串口,结果改了树莓派的系统配置文件config.txt给改了导致系统崩溃....其实我感觉网上的大多数方法都是不符合新版本树莓派的,网上的方法是通过修改系统配置文件后安装mini ...
- linux编译运行uart,嵌入式Linux裸机开发(七)——UART串口通信
嵌入式Linux裸机开发(七)--UART串口通信 一.UART串口通信简介 通用异步收发器简称UART,即UNIVERSAL ASYNCHRONOUS RECEIVER AND TRANSMITTE ...
- 【正点原子MP157连载】 第十六章 UART串口通信实验-摘自【正点原子】STM32MP1嵌入式Linux驱动开发指南V1.7
1)实验平台:正点原子STM32MP157开发板 2)购买链接:https://item.taobao.com/item.htm?&id=629270721801 3)全套实验源码+手册+视频 ...
- NXP(I.MX6uLL) UART串口通信原理————这个未复习
参考:Linux NXP (I.MX6uLL) UART串口通信原理 作者:一只青木呀 发布时间: 2020-09-20 16:48:33 网址:https://blog.csdn.net/weixi ...
- 嵌入式linux启动过程分析,嵌入式Linux裸机开发(二)——S5PV210启动过程分析
嵌入式Linux裸机开发(二)--S5PV210启动过程分析 一.iROM启动方式简介 友善之臂Smart210开发板的SoC为三星S5PV210,S5PV210采用iROM启动方式进行启动,通过查阅 ...
- 嵌入式linux s5pv210,嵌入式Linux裸机开发(二)——S5PV210启动过程分析
嵌入式Linux裸机开发(二)--S5PV210启动过程分析 一.iROM启动方式简介友善之臂Smart210开发板的SoC为三星S5PV210,S5PV210采用iROM启动方式进行启动,通过查阅三 ...
- (四)裸机s5pv210之串口通信详解
裸机s5pv210之串口通信详解 文章目录 裸机s5pv210之串口通信详解 前言 一.电子通信概念 1.同步通信和异步通信 2.电平信号和差分信号 3.并行接口和串行接口 二.串口通信的基本概念 1 ...
- 串口 单片机 文件_STM32物联网实战项目 HAL裸机开发09 串口打印
就喜欢你关注我- HAL裸机开发09 - 串口打印 综合信息1.获取开发工具 微信公众号后台发送消息 - 工具2.获取开发板 淘宝搜索店铺 - 硬件家园3.快速了解平台 ...
- Linux uart寄存器读写,Linux下读写UART串口的代码
Linux下读写UART串口的代码,从IBM Developer network上拿来的东西,操作比較的复杂,就直接跳过了,好在代码能用,记录一下- 两个实用的函数- /** *@brief 设置串口 ...
最新文章
- 好货不能错过!一款在GitHub上22k+star的人力资源管理系统
- centos6 安装 mantisbt-1.2.8 —— (1) VMware Workstation 12 Pro 虚拟机安装步骤详解(window 10 系统)
- ASP.NET之Request和Response对象
- jquery 导航栏目
- 空调自控系统基础知识及应用
- 03-Arm SiP Services
- jvm_垃圾收集算法讲解(一)
- jquery通过ajax向后台发送(checkbox)数组,并在后台接收,(发送的数据是checkedbox)...
- 利用SMW01分析BDOC错误
- vue 公众号扫描_vue编写微信公众号打开相机功能
- 教师节,老师们最大的愿望竟然是。。 | 今日最佳
- [渝粤教育] 西南科技大学 高等数学1 在线考试复习资料
- python os读取文件名_Python3基础 os.path.splitext 处理文件名,得到文件名+扩展名
- Receiver type ‘X’ for instance message is a forward declaration
- USACO 简易题解(蒟蒻的题解)
- java 一次CPU占用过高问题的排查及解决,java基础面试笔试题
- easyui treegrid 获取新添加行inserted_IDEA 2020.2 稳定版发布,带来了不少新功能...
- 两千万像素分辨率是多少_一亿像素究竟有无意义?荣耀红米为它“打”的火热...
- Nginx转发Tcp、Udp详细教程(简单粗暴)
- 嵌入式工程师待遇北京地区最高