6163|5

53

帖子

0

TA的资源

纯净的硅(中级)

楼主
 

Hanker TI M4 开发板开发应用教程第三章第四节:串口通信 [复制链接]

第四章Hanker TM4C123 外设应用
4.4 TM4C123 的串口通信
4.41 原理分析:
学过51 的同学都会知道串口通信。串口是计算机上一种非常通用设备通信的协议。大多数计算机包含两个基于RS232 的串口。串口同时也是仪器仪表设备通用的通信协议;很多GPIB 兼容的设备也带有RS-232 口。同时,串口通信协议也可以用于获取远程采集设备的数据。串口通信的概念非常简单,串口按位(bit)发送和接收字节。尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。它很简单并且能够实现远距离通信。比如IEEE488 定义并行通行状态时,规定设备线总长不得超过20 米,并且任意两个设备间的长度不得超过2米;而对于串口而言,长度可达1200 米。典型地,串口用于ASCII 码字符的传输。通信使用3 根线完成:(1)地线,(2)发送,(3)接收。由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。其他线用于握手,但是不是必须的。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。

对于两个进行通信的端口,这些参数必须匹配:
a,波特率:这是一个衡量通信速度的参数。它表示每秒钟传送的bit 的个数。例如300 波特表示每秒钟发送300 个bit。当我们提到时钟周期时,我们就是指波特率例如如果协议需要4800 波特率,那么时钟是4800Hz。这意味着串口通信在数据线上的采样率为4800Hz。通常电话线的波特率为14400,28800 和36600。波特率可以远远大于这些值,但是波特率和距离成反比。高波特率常常用于放置的很近的仪器间的通信,波特率除数(baud-rate divisor)是一个22 位数,它由16 位整数和6 位小数组成。波特率发生器使用这两个值组成的数字来决定位周期。通过带有小数波特率的除法器,在足够高的系统时钟速率下,UART 可以产生所有标准的波特率,而误差很小。

波特率除数公式:
BRD = BRDI.BRDF = SystemClock/(16×BaudRate)

其中:
BRD 是22 位的波特率除数,由16 位整数和6 位小数组成
BRDI 是BRD 的整数部分
BRDF 是BRD 的小数部分
SystemClock 是系统时钟(UART 模块的时钟直接来自SystemClock)
BaudRate 是波特率(9600,38400,115200 等)

b,数据位:这是衡量通信中实际数据位的参数。当计算机发送一个信息包,实际的数据不会是8 位的,标准的值是5、7 和8 位。如何设置取决于你想传送的信息。比如,标准的ASCII 码是0~127(7 位)。扩展的ASCII 码是0~255(8 位)。如果数据使用简单的文本(标准ASCII 码),那么每个数据包使用7 位数据。每个包是指一个字节,包括开始/停止位,数据位和奇偶校验位。由于实际数据位取决于通信协议的选取,术语“包”指任何通信的情况。

c,停止位:用于表示单个包的最后一位。典型的值为1,1.5 和2 位。由于数据是在传输线上定时的,并且每一个设备有其自己的时钟,很可能在通信中两台设备间出现了小小的不同步。因此停止位不仅仅是表示传输的结束,并且提供计算机校正时钟同步的机会。适用于停止位的位数越多,不同时钟同步的容忍程度越大,但是数据传输率同时也越慢。

d,奇偶校验位:在串口通信中一种简单的检错方式。有四种检错方式:偶、奇、高和低。当然没有校验位也是可以的。对于偶和奇校验的情况,串口会设置校验位(数据位后面的一位),用一个值确保传输的数据有偶个或者奇个逻辑高位。例如,如果数据是011,那么对于偶校验,校验位为0,保证逻辑高的位数是偶数个。如果是奇校验,校验位为1,这样就有3 个逻辑高位。高位和低位不真正的检查数据,简单置位逻辑高或者逻辑低校验。

图1 为UART 的外设模块图,可以看出,串口模块提供uDAM 通道,并且有16*8 的接收和发送缓冲。需要了解的就是串口对应的寄存器,比如控制与状态寄存器,中断控制寄存器等。

4.42 硬件设计:
几乎任何单片机或者是ARM 都有异步串口外设,学过51 单片机的通信都知道,一般串口都有两条线:RXD 和TXD。TM4C123 有八个UART 模块。大家可能觉得串口太多了吧,觉得没有用吧。其实不然,一工程师说到他的一个项目中,MUC 用到了九个串口,在一些特殊场合,这么多串口也是需要的。

Hanker-TM4C123 开发板抛弃了传统的串口输出,加入串口转USB,因为现在大家使用的笔记本已经无串行接口端。Silicon Laboratories 公司推出的USB 接口与RS232 接口转换器CP2102 是一款高度集成的USB-UART 桥接器,提供一个使用最小化元件和PCB 空间来实现RS232 转换USB 的简便解决方案。详细资料请参考相关datasheet.选择cp2102 之前,考虑过pl2303,但pl2303 不但外围器件多,在有干扰时很容易挂起出错,特别是提供的驱动程序在挂起后使电脑当机了,只有关掉电源,重新上电开机后才能恢复工作。而且CP2102 接口线路简单,电路如图2 所示:

硬件连接:PE4----------------U5RX
PE5----------------U5TX 串口多通道了,我们选择串口5,如何要选择其他
通道请去查找参考手册:14.2 Signal Description 内对管脚对应的串口有具体描述:

4.43 软件设计:.
那么首先我们建立工程项目如下图所示:

下面介绍下几个加入文件,其中lcd_320X240_ili932x.c 文件为液晶触摸屏的驱动文件,如果不使用液晶屏的话就可以不加入,要使用的时候还必须结合图形驱动库文件一起使用。

Main 函数就是我们用户编写的代码,由于我们使用了库函数编写,所以要加入外设驱动库封装.lib 文件,这里面封装了所有的外设驱动,下面我们在下面文件夹找到

ustdilb.c 文件是标准的串口输出函数库,这个是配合TI 的库专门写的。

Uartstdio.c 文件则是提供简单的串口控制功能,配合用户使用的。这两个文件都是串
口辅助文件。
driverlib/uart.C 查找下面几个要使用的函数:
1.UARTConfigSetExpClk( )功能:
UART 配置(要求提供明确的时钟速率)
原型
  1. void UARTConfigSetExpClk(unsigned long ulBase,
  2. unsigned long ulUARTClk,
  3. unsigned long ulBaud,
  4. unsigned long ulConfig)
复制代码
参数
ulBase:UART 端口的基址,取值UART0_BASE、UART1_BASE 或UART2_BASE
ulUARTClk:提供给UART 模块的时钟速率,即系统时钟频率
ulBaud:期望设定的波特率
ulConfig:UART 端口的数据格式,取下列各组数值之间的“或运算”组合形式:
数据字长度
  1. UART_CONFIG_WLEN_8 // 8 位数据
  2. UART_CONFIG_WLEN_7 // 7 位数据
  3. UART_CONFIG_WLEN_6 // 6 位数据
  4. UART_CONFIG_WLEN_5 // 5 位数据
复制代码
停止位
  1. UART_CONFIG_STOP_ONE // 1 个停止位
  2. UART_CONFIG_STOP_TWO // 2 个停止位(可降低误码率)
复制代码
校验位
  1. UART_CONFIG_PAR_NONE // 无校验
  2. UART_CONFIG_PAR_EVEN // 偶校验
  3. UART_CONFIG_PAR_ODD // 奇校验
  4. UART_CONFIG_PAR_ONE // 校验位恒为1
  5. UART_CONFIG_PAR_ZERO // 校验位恒为0
复制代码
2.UARTConfigSet( )
功能
UART 配置(自动获取时钟速率)
原型
  1. #define UARTConfigSet(a, b, c) UARTConfigSetExpClk(a, SysCtlClockGet( ), b, c)
复制代码
参数
详见上个函数描述
返回

说明
本宏函数常用来代替函数UARTConfigSetExpClk( ),在调用之前应当先调用SysCtlClockSet( )函数设置系统时钟(不要使用误差很大的内部振荡器IOSC、
IOSC/4、INT30 等)
示例
// 配置UART0:波特率9600,8 个数据位,1 个停止位,无校验
UARTConfigSet(UART0_BASE, 9600, UART_CONFIG_WLEN_8
|UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE);
// 配置UART1:波特率最大,5 个数据位,1 个停止位,无校验
UARTConfigSet(UART1_BASE,SysCtlClockGet( )/ 16,UART_CONFIG_WLEN_5
|UART_CONFIG_STOP_ONE |UART_CONFIG_PAR_NONE);

3.UARTEnable( )
功能
使能指定UART 端口的发送和接收操作
原型
  1. void UARTEnable(unsigned long ulBase)
复制代码
参数
ulBase:UART 端口的基址,取值UART0_BASE、UART1_BASE 或UART2_BASE

4.UARTCharPut( )
功能
发送1 个字符到指定的UART 端口(等待)
原型
  1. void UARTCharPut(unsigned long ulBase, unsigned char ucData)
复制代码
参数
ulBase:UART 端口的基址,取值UART0_BASE、UART1_BASE 或UART2_BASE
ulData:要发送的字符
返回
无(在未发送完毕前不会返回)
5.UARTCharGet( )
功能
从指定的UART 端口接收1 个字符(等待)
原型
  1. long UARTCharGet(unsigned long ulBase)
复制代码
参数
ulBase:UART 端口的基址,取值UART0_BASE、UART1_BASE 或UART2_BASE
返回
读取到的字符,并自动转换为long 型(在未收到字符之前会一直等待)
6.UARTCharPutNonBlocking( )
功能
发送1 个字符到指定的UART 端口(不等待)
原型
  1. tBoolean UARTCharPutNonBlocking(unsigned long ulBase, unsigned char ucData)
复制代码
参数
ulBase:UART 端口的基址,取值UART0_BASE、UART1_BASE 或UART2_BASE
ulData:要发送的字符
返回
如果发送FIFO 里有可用空间,则将数据放入发送FIFO,并立即返回true
如果发送FIFO 里没有可用空间,则立即返回false(发送失败)
对于调用库函数编写串口程序一般可以归纳为如下步骤:
1. 使能串口外设所用到的GPIO 管脚
2. 使能串口外设
3. 配置管脚的复用功能
4. 配置串口时钟,串口波特率,等待位等
完成上面四个步骤,就可以用库函数配置为一个可用串口。
通常,在调用本函数之前应当先调用UARTSpaceAvail( )确认发送FIFO 里有可用空间
现在来实现PC 一个发送一个数据,串口接收,然后返回PC 的试验。程序如下:
这里面需要详细介绍下:
  1. 01. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. 02. //-----------------------------------------------------------------------------
  3. 03. // 文件名: uart.c
  4. 04. // 作者: 青风
  5. 05. // ARM 内核: Cortex-M4
  6. 06. // 使用芯片: LM4F232H5QD/TM4C
  7. 07. // 开发环境: KEIL
  8. 08. // 版本记录: V1.00 2011-12-26 14:30
  9. 09. // 功能说明:
  10. 10. //-----------------------------------------------------------------------------
  11. 11.
  12. 12.
  13. 13. #include "inc/hw_types.h" //定义常用的宏
  14. 14. #include "inc/hw_memmap.h" //定义功能存储映射
  15. 15. #include "grlib/grlib.h" //
  16. 16. #include "drivers/lcd_320x240_ili932x.h"
  17. 17. #include "driverlib/sysctl.h" //
  18. 18. #include "driverlib/gpio.h" //
  19. 19. #include "driverlib/sysctl.h"
  20. 20. #include "driverlib/uart.h"
  21. 21. #include "driverlib/pin_map.h" //
  22. 22. #include "driverlib/fpu.h" //
  23. 23. #include "inc/hw_ints.h" //定义中断分配数
  24. 24. #include "driverlib/interrupt.h" //
  25. 25. #include "utils/ustdlib.h"
  26. 26. #include "utils/uartstdio.h"
  27. 27.
  28. 28.
  29. 29. //-----------------------------------------------------------------------------
  30. 30. // 子函数功能说明: 串口功能设置
  31. 31. //-----------------------------------------------------------------------------
  32. 32. void
  33. 33. InitConsole(void)
  34. 34. {
  35. 35. SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); // 使能GPIO 外设
  36. 36. GPIOPinConfigure(GPIO_PE4_U5RX); // 配置串口接收管脚
  37. 37. GPIOPinConfigure(GPIO_PE5_U5TX); // 配置串口发送管脚
  38. 38. GPIOPinTypeUART(GPIO_PORTE_BASE, GPIO_PIN_4 | GPIO_PIN_5);//把GPIO 功能复用为
  39. 串口
  40. 39. UARTStdioInit(5); //设置串口属性
  41. 40. }
  42. 41. //-----------------------------------------------------------------------------
  43. 42. // 主函数
  44. 43. //-----------------------------------------------------------------------------
  45. 44. int main(void)
  46. 45. { tContext sContext;
  47. 46. tRectangle sRect;
  48. 47. char cThisChar;
  49. 48. // char cText[10];
  50. 49. int x=10;
  51. 50. int y=10;
  52. 51. FPUEnable(); //FPU 使能
  53. 52. FPULazyStackingEnable(); //使能FPU 堆栈
  54. 53. SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
  55. 54. SYSCTL_XTAL_16MHZ); //系统时钟设置
  56. 55. InitConsole();
  57. 56. lcd_ili932x_init();
  58. 57. // GLCD_Test(); //初始化LCD 驱动
  59. 58. GrContextInit(&sContext, &g_sLcdDisplay);//初始化图形库
  60. 59. lcd_backlight_on();
  61. 60. lcd_ili932x_flush(&sContext);
  62. 61. sRect.sXMin = 0;
  63. 62. sRect.sYMin = 0;
  64. 63. sRect.sXMax = GrContextDpyWidthGet(&sContext) - 1;
  65. 64. sRect.sYMax = 23;
  66. 65. GrContextForegroundSet(&sContext, ClrDarkBlue);
  67. 66. GrRectFill(&sContext, &sRect); // 填充蓝色方块
  68. 67. GrContextForegroundSet(&sContext, ClrWhite);
  69. 68. GrRectDraw(&sContext, &sRect); // 加白色框框
  70. 69. GrContextFontSet(&sContext, &g_sFontCm20);
  71. 70. GrStringDrawCentered(&sContext, "UART", -1,
  72. 71. GrContextDpyWidthGet(&sContext) / 2, 10, 0); // 显示串口实验标志
  73. 72. UARTprintf("start"); // 串口显示
  74. 73. GrContextFontSet(&sContext, &g_sFontCm20); //
  75. 74. GrStringDraw(&sContext, "start", -1, 50, 50, 1);// TFT 显示
  76. 75. while((x+y)<320) //
  77. 76. { y=y+x;
  78. 77. cThisChar = UARTCharGet(UART5_BASE); //
  79. 78. UARTCharPut(UART5_BASE, cThisChar); //
  80. 79. GrContextFontSet(&sContext, &g_sFontCm20);//
  81. 80. GrStringDraw(&sContext, &cThisChar, -1, y, 80, 1); //打印信息
  82. 81. }
  83. 82. return(0);
  84. 83. }
  85. 84.
复制代码
下载成功后出现下面现象:

打开串口调制助手,设置如下:

下载成功后:串口输入一句:QFV5.taobao.com.发送后回环接收。

最新回复

求iic通信的教程,楼主  详情 回复 发表于 2014-8-10 11:08
 
点赞 关注(1)

回复
举报

73

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
真是太给力了
 
 

回复

45

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
一如既往的赞
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(中级)

4
 
请问有关于I2C通信方面的内容吗
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(中级)

5
 
给力。。。。。
 
 
 

回复

9

帖子

1

TA的资源

一粒金砂(中级)

6
 
求iic通信的教程,楼主
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表