7、TM4单片机学习之串口功能
文章目录
- 一、初始化过程
- 1、使能相应外设端口
- 2、配置引脚的复用功能
- 3、配置引脚类型
- 4、时钟源设置
- 5、串口帧格式配置
- 二、使用方法
- 1、简单使用
- 2、使用中断
- 3、printf 函数
- 四、测试例程
- 1、循环打印字符串"Hello"
- 2、中断方式获取命令控制LED灯
一、初始化过程
1、使能相应外设端口
TM4C123GH6PM一共有8个串口,UART0~UART7。以串口0为例,串口0在硬件上用的是PA0和PA1。
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOA));
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UART0));
2、配置引脚的复用功能
表示将PA0和PA1分别作为串口0的接收端和发送端。
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
3、配置引脚类型
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
这里讲一下,这个函数其实是官网库二次封装的一个函数,可以看下其定义:
void
GPIOPinTypeUART(uint32_t ui32Port, uint8_t ui8Pins)
{//// Check the arguments.//ASSERT(_GPIOBaseValid(ui32Port));//// Make the pin(s) be peripheral controlled.//GPIODirModeSet(ui32Port, ui8Pins, GPIO_DIR_MODE_HW);//// Set the pad(s) for standard push-pull operation.//GPIOPadConfigSet(ui32Port, ui8Pins, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD);
}
即:设置引脚为GPIO_DIR_MODE_HW
,电流为GPIO_STRENGTH_2MA
,类型为GPIO_PIN_TYPE_STD
所以也可以用这两行代码进行替换:
GPIODirModeSet(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW);
GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD);
4、时钟源设置
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);//Clock 16MHz
串口的时钟源有两个,一个是用系统时钟,另一个使用内部振荡器,这里用了内部振荡器,16MHz。
也可以使用系统时钟,则代码为:
UARTClockSourceSet(UART0_BASE, UART_CLOCK_SYSTEM);
时钟树如图:
5、串口帧格式配置
UARTConfigSetExpClk(UART0_BASE, 16000000, 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));
第一个参数UART0_BASE
:为串口0基址。
第二个参数16000000
:表示时钟频率16MHz。若之前配置的时钟源为系统时钟,那么这个要改为SysCtlClockGet()
。
第三个参数为帧格式
:UART_CONFIG_WLEN_8
表示八个数据位,UART_CONFIG_STOP_ONE
表示一个停止位,UART_CONFIG_PAR_NONE
表示无校验位,将它们以或运算的形式填进去即可。
二、使用方法
1、简单使用
可以用UARTCharPut
函数打印字符,如:
UARTCharPut(UART0_BASE, 'A');
用UARTCharGet
获得字符,如:
char c;
c = UARTCharGet(UART0_BASE);
2、使用中断
初始化配置:
void UART3_Init(uint32_t Baud)
{SysCtlPeripheralEnable(SYSCTL_PERIPH_UART3);while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UART3));SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOC));GPIOPinConfigure(GPIO_PC6_U3RX);GPIOPinConfigure(GPIO_PC7_U3TX);GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_6 | GPIO_PIN_7);UARTConfigSetExpClk(UART3_BASE, SysCtlClockGet(), Baud, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));UARTIntRegister(UART3_BASE, IntHandler_UART3);UARTIntEnable(UART3_BASE, UART_INT_RX | UART_INT_RT);IntEnable(INT_UART3);
}
中断响应函数:
void IntHandler_UART3(void)
{UARTIntClear(UART3_BASE, UARTIntStatus(UART3_BASE, true));char c = 0;while(UARTCharsAvail(UART3_BASE)){c = UARTCharGetNonBlocking(UART3_BASE);}
}
3、printf 函数
首先需要在Keil设置里面勾选使用MicroLib,步骤如图所示:
包含一下头文件#include <stdio.h>
重写fputc
函数:
// 重写fputc函数以支持printf功能
int fputc(int ch, FILE *f)
{UARTCharPut(UART0_BASE,(unsigned char)ch); //这里填写的基址(UART0_BASE)不同,则printf用的串口不同return ch;
}
便可以直接使用printf
功能了,用法和C语言一样。
四、测试例程
1、循环打印字符串"Hello"
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_gpio.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "inc/hw_memmap.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include <stdio.h>void delay_ms(int n)
{for(int i = 0; i < n; i++)SysCtlDelay(SysCtlClockGet()/3000);
}//重写fputc函数以支持printf
int fputc(int ch, FILE *f)
{UARTCharPut(UART0_BASE,(unsigned char)ch);//如果用其他串口,只需修改基址(UART0_BASE)即可。return ch;
}int main()
{ SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UART0));SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOA));//配置引脚复用PIOPinConfigure(GPIO_PA0_U0RX);GPIOPinConfigure(GPIO_PA1_U0TX);//配置引脚类型GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); //GPIODirModeSet(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_DIR_MODE_HW);//GPIOPadConfigSet(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1, GPIO_STRENGTH_2MA, GPIO_PIN_TYPE_STD); //时钟源选择UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);//帧格式配置UARTConfigSetExpClk(UART0_BASE, 16000000, 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE)); while(1){printf("Hello\n");//打印字符串测试delay_ms(100);}
}
2、中断方式获取命令控制LED灯
// include ...void UART3_Init(uint32_t Baud);
void IntHandler_UART3(void);int main()
{ SysCtlClockSet(SYSCTL_SYSDIV_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);// 灯光IO口初始化SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1);GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0);GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);// 串口3初始化UART3_Init(115200);while(1){}
}
void IntHandler_UART3(void)
{UARTIntClear(UART3_BASE, UARTIntStatus(UART3_BASE, true));char c = 0;while(UARTCharsAvail(UART3_BASE)){c = UARTCharGetNonBlocking(UART3_BASE);if(c == 'r'){GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, GPIO_PIN_1);GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);}else if(c == 'g'){GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1, 0);GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);}else{}}
}void UART3_Init(uint32_t Baud)
{SysCtlPeripheralEnable(SYSCTL_PERIPH_UART3);while(!SysCtlPeripheralReady(SYSCTL_PERIPH_UART3));SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOC));GPIOPinConfigure(GPIO_PC6_U3RX);GPIOPinConfigure(GPIO_PC7_U3TX);GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_6 | GPIO_PIN_7);UARTConfigSetExpClk(UART3_BASE, SysCtlClockGet(), Baud, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));UARTIntRegister(UART3_BASE, IntHandler_UART3);UARTIntEnable(UART3_BASE, UART_INT_RX | UART_INT_RT);IntEnable(INT_UART3);
}
7、TM4单片机学习之串口功能相关推荐
- PIC单片机学习—USART串口
PIC单片机学习-USART串口 最近做了几个项目都用到了PIC单片机,在这几个项目之前我只用到了51单片机和STM32来做控制类的项目,用PIC单片机的时候发现使用的时候和51单片机还是有所区别,有 ...
- 单片机学习笔记 —— 串口通信原理
一.串口通信电路 电路图: 说明:当RXD TXD为低电平时,对应的led灯会亮起 二.串口通信控制寄存器 下图为80C51串行口的结构: SCON(serial Control Register): ...
- 51单片机学习之-串口中断
串口中断 SM2:多机通信控制位, (0:数据直接进入SBUF,并同时使R1致1) T1:发送中断标志位,(发送数据自动由硬件置1,并且同时执行中断程序,也必须在中断程序中写0) RI:接收中断标志位 ...
- 【串口发送中断】基于赛元单片机使用三合一串口的UART功能
文章目录 前言 中断的方式发送数据 代码示例 准备工作 宏定义及全局变量 初始化 中断服务函数 ==发送逻辑函数== 启动发送函数 总结 前言 关于赛元单片机触摸的那篇文章确实帮助到过一些网友,后来有 ...
- STM8学习笔记----普通IO口模拟串口功能
串口在产品应用中很常见,但是单片机的默认带的串口往往比较少,有时候就会出现串口不够用,所以就想着能不能用普通IO口模拟串口来实现串口的功能. 要模拟串口首先要清楚串口数据传输过程中的原理. 常用的串口 ...
- 【蓝桥杯】单片机学习(7)——UART串口通信
UART串口通信 一.基础知识介绍 1.通信方式的分类 2.RS232通信接口 3.UART模块介绍 (1)串口控制寄存器SCON(可位寻址) (2)电源控制寄存器PCON(不可位寻址) (3)辅助寄 ...
- 51单片机学习笔记(清翔版)(19)——串口通信
学好了中断再学串口通信 今天这课内容是关于数据传输的,在工业控制和商业控制是很重要的.数据传输包含串口.并行通信. 这里说的计算机都可以理解为单片机,因为工作方式是一样的. 单片机通信是指单片机之间, ...
- 【STC单片机学习】第十三课:串口通信和RS485
[朱老师课程总结 侵删] 第一部分.章节目录 1.13.1.通信有关的常见概念 1.13.2.什么是串行通信 1.13.3.51单片机的串行通信 1.13.4.STC51的串行通信相关寄存器1 1.1 ...
- 51单片机学习--定时器--中断--串口通信
51单片机学习–定时器–中断–串口通信 定时器–中断–串口通信 中断分类 定时器中断 外部中断 串口中断 基本概念 对于单片机来讲, 中断是指 CPU 在处理某一事件 A 时, 发生了另一事件 B, ...
最新文章
- 018 Android加固之实现dex加载器
- linux学习心得(一)
- 剑指offer之链表续
- 微信小程序页面跳转与返回并回传数据
- EXCEL数据导入dataset
- java 取dataset_Java LineDataSet.getYVals方法代码示例
- go 链路追踪_Go技术日报(20200911)
- jquery序列化serialize()方法空格变为+问题解决参考方法
- 数据库版本自带的mysql replication双机主从备份安装配置
- 关于视频监控线缆的常识
- 签到界面加图片java_签到功能实现,没有你想的那么复杂(二)
- 中缀表达式转后缀表达式
- oracle数据库sqlloader,Oracle SQL Loader(sqlldr)
- 抖音源码为什么会成为短视频源码中的翘楚
- 运行Android项目时,报Installation failed due to invalid APK file!错误的解决办法
- 这些年我踩过的`Mybatis`代码生成的坑
- Kubernetes:开源 K8s 管理工具 Rancher 认知
- 新闻资讯系统(论文)
- 阅文集团以人民币10.8亿元出售懒人听书股权给腾讯音乐
- Mac中pycharm安装低版本tensorflow1.8的方法