TM4C123系列(四)————UART串口通信

一.实验简介

使用TM4C123的串口通信功能实现单片机与PC端通信。

二.UART介绍

TM4C123有八个串口,其中UART0已经与USB集成,UART0建议只用来和PC端通信,不要与外界通信。

除此之外,与STM32不同,TM4的每个串口还都有两个FIFO,一个用来接收,一个用来发送,所谓FIFO也就是数据缓存区,对于接收的FIFO就是PC端传输数据到FIFO中,FIFO再传给单片机处理;对于发送的FIFO就是单片机先将数据存放在FIFO,然后FIFO再将数据发送给PC端。

通过设置FIFO深度来触发中断,FIFO的数据深度有1/8,1/4,1/2,3/4,7/8五种,比如,设置接收FIFIO深度为1/8,那么就是FIFO中装入了16*1/8=2字节时触发中断,如果不用FIFO,那么每接收一个字节都要触发一次中断,导致频繁的进入中断,而使用FIFO以后,将先把一定量的数据存入FIFO中,到达设置的FIFO深度后再触发中断,然后将这些数据一起处理,减少了进入中断的次数,而且更加高效。

FIFO可以设置以下的模式:

//! - \b UART_INT_9BIT - 9-bit Address Match interrupt
//! - \b UART_INT_OE - Overrun Error interrupt
//! - \b UART_INT_BE - Break Error interrupt
//! - \b UART_INT_PE - Parity Error interrupt
//! - \b UART_INT_FE - Framing Error interrupt
//! - \b UART_INT_RT - Receive Timeout interrupt
//! - \b UART_INT_TX - Transmit interrupt
//! - \b UART_INT_RX - Receive interrupt
//! - \b UART_INT_DSR - DSR interrupt
//! - \b UART_INT_DCD - DCD interrupt
//! - \b UART_INT_CTS - CTS interrupt
//! - \b UART_INT_RI - RI interrupt

经常用的有发送,接收,接收超时这几种,发送和接收不用多说。对于接收超时中断来说,要是没有接收超时中断,接收的字节数如果没有到达设置的FIFO深度,那么中断将不会触发,这些数据将得不到有效处理,但是要是有超时中断,如果接收的字节数未到触发深度但是已经没有别的数据可以接受,那么在不超过三个数据的接收时间就会触发超时中断,数据将会照常处理。

三.原理图

 或者也可以在Tiva C Series PinMux中查看,链接在上一篇中有。(11条消息) TM4C123系列(三)————PWM输出_G.883的博客-CSDN博客

 四.相关函数

没有注明作用的函数请看我之前的文章有写

1.SysCtlClockSet(uint32_t ui32Config)

2.SysCtlPeripheralEnable(uint32_t ui32Peripheral)

3.GPIOPinConfigure(uint32_t ui32PinConfig)

4.GPIOPinTypeUART(uint32_t ui32Port, uint8_t ui8Pins)

5.UARTClockSourceSet(uint32_t ui32Base, uint32_t ui32Source)

参数:uint32_t ui32Base为串口基地址,uint32_t ui32Source为串口的波特时钟源一般为UART_CLOCK_PIOSC是16MHz

作用:为指定的UART设置波特时钟源

6.UARTStdioConfig(uint32_t ui32PortNum, uint32_t ui32Baud, uint32_t ui32SrcClock)

参数:uint32_t ui32PortNum为串口编号,即0,1,2····,uint32_t ui32Baud为波特率,uint32_t ui32SrcClock为UART的源时钟频率(launchpad上为16MHz,所以这个数为16000000)

7.UARTprintf(const char *pcString, ...)

参数:const char *pcString为要显示的字符串, ...为显示的变量。

作用:与printf的作用和使用格式一样,例如a=10,UARTprintf(“a=%d”, a)

8.UARTConfigSetExpClk(uint32_t ui32Base, uint32_t ui32UARTClk,uint32_t ui32Baud, uint32_t ui32Config)

参数:uint32_t ui32Base为串口基地址,uint32_t ui32UARTClk为提供给UART的时钟频率,通过SysCtlClockGet()函数可以得到,通过uint32_t ui32Config来配置串口的字长,校验位,停止位

作用:配置串口参数

9.UARTCharPut(uint32_t ui32Base, unsigned char ucData)

参数:uint32_t ui32Base为串口基地址,unsigned char ucData为单个字符

作用:打印输出单个字符

####注意配置串口时,要将5,6,7搭配使用;8,9搭配使用;5,6,7和8,9都可以用来配置一个串口,但是不能同时配置同一个串口,也就是不能混用。并且注意5,6,7搭配使用只能用于串口0到串口2,而8,9搭配使用时可以用于所有串口。

10.UARTFIFOEnable(uint32_t ui32Base)

参数:ui32Base为串口基地址

作用:使能FIFO

11.UARTFIFOLevelSet(uint32_t ui32Base, uint32_t ui32TxLevel,uint32_t ui32RxLevel)

参数:ui32Base为串口基地址,ui32TxLevel发送FIFO的深度,ui32RxLevel为接收FIFO的深度

作用:配置接收与发送的FIFO

12.UARTIntEnable(uint32_t ui32Base, uint32_t ui32IntFlags)

参数:ui32Base为串口基地址,ui32IntFlags为中断模式

作用:设置对应串口中断模式

13.UARTIntRegister(uint32_t ui32Base, void (*pfnHandler)(void))

14.IntPrioritySet(uint32_t ui32Interrupt, uint8_t ui8Priority)

参数:ui32Interrupt为中断外设,ui8Priority为中断优先级从0x0到0xE0,0x0优先级最高

15.IntEnable(uint32_t ui32Interrupt)

16.IntMasterEnable()

这两个不懂什么去别的可以去看我之前的文章

17.UARTIntStatus(uint32_t ui32Base, bool bMasked)

18.UARTIntClear(uint32_t ui32Base, uint32_t ui32IntFlags)

19.UARTCharsAvail(uint32_t ui32Base)

参数:ui32Base为串口基地址

作用:判断缓存区是否有字符存在,如果有的话为true,没有直接返回false

20.UARTCharGetNonBlocking(uint32_t ui32Base)

参数:ui32Base为串口基地址

作用:从指定的串口FIFO接收一个字符,NonBlocking指如果没有字符不等待直接返回-1

21.UARTCharPutNonBlocking(uint32_t ui32Base, unsigned char ucData)

参数:ui32Base为串口基地址,ucData为发送的单个字符

作用:从指定的串口FIFO发送一个字符,如果没有字符发送不等待直接返回-1

对应20与21还有一对函数,UARTCharPut与UARTCharGet,与20和21的区别就是这两个函数如果FIFO中没有数据,他会等待有数据在接收,而NonBlocking不等待

22.UARTEnable(uint32_t ui32Base)

参数:ui32Base为串口基地址

作用:使能串口

五.代码

usart.c
#include "uart.h"
#include "gpio.h"
#include "usart.h"
#include "hw_memmap.h"
#include "pin_map.h"
#include "uartstdio.h"
#include "sysctl.h"
#include "hw_ints.h"
void USART0_IRQHandler(void);
void USART_Config(void)
{
    //使能外设
    SysCtlPeripheralEnable( SYSCTL_PERIPH_GPIOA);
	SysCtlPeripheralEnable( SYSCTL_PERIPH_UART0);
    //使能复用
	GPIOPinConfigure( GPIO_PA0_U0RX);
	GPIOPinConfigure( GPIO_PA1_U0TX);
    //分配信号
	GPIOPinTypeUART( GPIO_PORTA_BASE,  GPIO_PIN_0);
	GPIOPinTypeUART( GPIO_PORTA_BASE,  GPIO_PIN_1);
    /*搭配UARTprintf使用*/
    //设置串口0的时钟为UART_CLOCK_PIOSC
//	UARTClockSourceSet( UART0_BASE,  UART_CLOCK_PIOSC);
    //设置串口0波特率与波特时钟
//	UARTStdioConfig( 0,  115200,
//                             16000000);
    /*与UARTCharPut,UARTCharPutNonBlocking等搭配使用*/
    //配置串口0波特率与校验位,停止位,字长等
	UARTConfigSetExpClk( UART0_BASE,  SysCtlClockGet(),
                                 115200,  UART_CONFIG_WLEN_8|UART_CONFIG_STOP_ONE|UART_CONFIG_PAR_NONE);
    //使能FIFO
	UARTFIFOEnable( UART0_BASE);
    //接收发送的FIFO都为1/4,也就是16*1/4=4个字节
	UARTFIFOLevelSet( UART0_BASE,  UART_FIFO_TX2_8,
                              UART_FIFO_RX2_8);
    //使能串口的接收与接收超时中断
	UARTIntEnable( UART0_BASE,  UART_INT_RX|UART_INT_RT);
    //注册中断函数
	UARTIntRegister( UART0_BASE, USART0_IRQHandler);
    //设置中断优先级
	IntPrioritySet( INT_UART0,  0);
    //开启中断
	IntEnable( INT_UART0);
	IntMasterEnable();
    //使能串口
    UARTEnable( UART0_BASE);
}
void USART0_IRQHandler(void)
{
	uint32_t re_buf;
    //读取中断状态
    uint32_t status=UARTIntStatus( UART0_BASE,  true);
    //清除中断标志位
	UARTIntClear( UART0_BASE,  status);
    //判断UART0有没有字符未读取
	while(UARTCharsAvail( UART0_BASE))
	{
        //如果有字符为读取就取出,使用UARTCharGetNonBlocking防止等待
	    re_buf=UARTCharGetNonBlocking( UART0_BASE);
        //将读取出的字符再发送
		UARTCharPutNonBlocking( UART0_BASE, re_buf);
	}
}
usart.h
#ifndef __USART_H
#define __USART_H
void USART_Config(void);
void USART0_IRQHandler(void);
#endif
main.c
#include "tm4c123gh6pm.h"
#include <stdint.h>
#include <stdbool.h>
#include "inc/hw_sysctl.h"
#include "inc/hw_gpio.h"
#include "inc/hw_memmap.h"
#include "driverlib/gpio.h"
#include "driverlib/sysctl.h"
#include "uartstdio.h"
void main(void)
{
	SysCtlClockSet( SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
	USART_Config();
	while(1)
	{
	    
	}
}

注意:在此代码中我设置的是接收和接收超时中断两个UARTIntEnable( UART0_BASE,  UART_INT_RX|UART_INT_RT),并且深度都为4个字节,对于英文正好一个英文是一个字节,因为我设置了接收超时中断,所以不管我怎么样发送,都可以正常接收。

 但是如果我关闭了接收超时中断

 

 可以发现接收的时候少发送了一个g,那是因为前面十二个字符四个四个一组触发中断,最后单着一个g在FIFO中无法触发中断,所以发不回来。

 可以看到如果我再发送aaaa,加上之前的FIFO缓存区的g够了四个就触发中断,之前的g可以发回来,这就是超时中断的作用。

  • 12
    点赞
  • 64
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
TM4C123G是德州仪器(Texas Instruments)推出的一款高性能的微控制器,它具有丰富的外设和高性能的处理能力。串口通信是一种常见的通信方式,可以使TM4C123G与其他设备进行数据传输和通信。 TM4C123G具有多个UART(通用异步收发器)外设,可以通过这些UART口进行串口通信。每个UART口包括收发数据线、时钟线等接口,可通过配置寄存器设置通信速率、数据位数、校验位、停止位等参数。 首先,需要初始化串口通信,设置串口的工作模式和参数。可以通过编程的方式设置相应的寄存器来配置UART口。比如,需要设置通信速率为115200,数据位为8位,无校验位,1个停止位。设置完毕后,可以通过读写相应的寄存器来进行数据的发送和接收。 发送数据时,将要发送的数据写入到发送寄存器中,串口会根据配置的参数将数据发送出去,可通过查询或中断的方式判断数据是否发送成功。接收数据时,通过读取接收寄存器可以获取到接收到的数据,同样可以通过查询或中断的方式来判断是否接收到数据。 在通信过程中,还需要考虑到数据的传输准确性和稳定性。可以通过使用校验位来验证数据的正确性,以保证数据的完整性。另外,需要注意串口通信的时序问题,比如发送方和接收方的时钟频率要一致,并且发送和接收的时机要正确。 总之,TM4C123G可以通过配置UART口来进行串口通信,通过设置相应的寄存器来配置通信参数,通过读写寄存器来进行数据的发送和接收。在实际应用中,可以根据具体需求进行接口的配置和数据的处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值