7589|9

531

帖子

0

TA的资源

一粒金砂(高级)

楼主
 

LM3S811开发板使用心得(1)——UART [复制链接]

               

ARM新人,请多多指导

首先感谢eeworld能给我机会发布这次心得!

其次有问题的地方欢迎大家批评指正!

计划采用LM3S811开发板制作一个倒车雷达,硬件都已经准备完毕,最近太忙没有太多时间来实现。先做个简单的时钟模块的实验吧(uart+I2C)第一步来个uart!

即以此篇心得与同为ARM新人的坛友们分享,做一个工程离不开3个要素,编译器,代码方式,使用手册。下面的心得将从这3个方面做介绍。

ARM的编译器有很多种,大家如果有兴趣可以到百度上去搜索下。TI给的代码使用Keil编译器使用的,以前接触过51单片机的同学使用起来会感到很轻松,我本身是做FPGA的比较多,所有使用起来感觉很不习惯。因此特意为有和我一样问题的坛友找了一段关于编译器的视频,视频详细的讲解了mdk上每个选项的意思及用法,适合初学mdk的童鞋们

视频地址http://v.youku.com/v_show/id_XMjQwMDA5MDI0.html

代码方式,主要采用TI例程的源代码。标准的C语言代码,函数很多,暂时还没有发现结构体。和单片机比较起来真的是差距太大了,LM3S811提供的driverlib库有点像是TI DSP C6000提供的CSL库,应用的方式都是一样的。在这里告诉初学者不要贪心哦,想要弄明白每个函数是不可能的事情,个人认为最好的方式是一面看例程的程序流程,一面对应着Stellaris® Peripheral Driver Library  USERS GUIDE.PDF 文档来看,前期指导函数的作用就可以了。

不得不说TI提供的手册真的是太多了,看的云里雾里的,首先是扫了一遍LM3S811芯片的数据手册,对于这个手册的使用我有点想法,希望大家明白为什么叫手册,如果你都把手册背下来了还用手册干什么?最近发现实验室新来的师弟师妹们居然有想法把手册都给记下来,我当时被雷倒了。手册是什么啊?放在手边的小册子啊(其实他是最大的啦)。只要大家指导里面有什么东西就可以了,就拿例程里面的uart例程来说,你根本不需要把所有有关的寄存器都被下来,只要你指导你使用的时候要做什么就好了。我的想法是3pdf文档需要关注,1、手册(具体设置时候使用),2、驱动说明(函数调用),3、硬件原理图。驱动库给的函数真的是太好用了。

下面以UART例程为例,给eeworld打个招呼!(貌似很多例程都是hello的)

1、打开uart-echo 工程,在工程窗口看到调用的drivelib库文件,这个文件不用手动的添加,在主函数所在的文件中调用这个函数就可以了,编译的时候编译器自动加载到工程中。

如下截图所示:

[ 本帖最后由 ming1005 于 2011-5-16 19:09 编辑 ]

RAUT初始化配置.doc

1.49 MB, 下载次数: 159

最新回复

https://bbs.eeworld.com.cn/viewthread.php?tid=231790&highlight= 这个。。。让我情何以堪啊,百度文库。。。。。。  详情 回复 发表于 2011-5-16 21:53
 
点赞 关注

回复
举报

531

帖子

0

TA的资源

一粒金砂(高级)

沙发
 

2、在百度文库看到有关uart写的很好的文章,传上来给大家分享。

我们可以看到UART模块的寄存器主要包括五部分:
1)控制/状态寄存器
2)数据寄存器
3)波特率寄存器
4)中断控制寄存器
5)标识寄存器(Identification Registers)

1、控制/状态寄存器
控制状态寄存器主要功能是控制UART工作模式,跟踪UART的工作状态,定义UART的数据格式以及使能禁能UART。
2、数据寄存器
发送和接收数据,有两个16字节的FIFO,发送FIFO和接收FIFO。当FIFO使能时写数据寄存器操作会将数据放入发送FIFO尾,读数据寄存器操作会将数据从接收FIFO中读取出来。如果没有使能FIFO,可以认为FIFO深度为1字节。
3、波特率寄存器
用来设置UART波特率。
4、中断控制寄存器
用来配置UART中断。
5、标识寄存器
只读,用于标识器件。

使用UART的操作基本步骤有四步:
1)使能UART模块,使能与UART相关的GPIO模块,将相应的TX和RX引脚设置为UART模式;
2)配置和使能UART,主要包括设置UART的波特率,是否使用FIFO,数据帧格式;
3)配置UART中断(可选);
4)读写数据;


UART使用中最常用到的API:
1、UARTConfigSetExpClk(unsigned long ulBase, unsigned long ulUARTClk,unsigned long ulBaud, unsigned long ulConfig)
带时钟参数的UART配置函数,参数分别是UART模块基地址,系统主频,波特率,数据帧格式配置。
这个函数功能非常强大,可以说一句话就完成了第二步工作。
这个函数的执行结果是:设置波特率为ulBaud,将数据帧格式设置为ulConfig,使能FIFO,使能UART。
数据帧格式配置参数ulConfig是由三个参数进行或运算得来的,这三个参数是数据字长(WordLENgth),奇偶校验(PARity),停止位长度(STOP)。

2、UARTEnable(unsigned long ulBase),UARTDisable(unsigned long ulBase)
使能和禁能UART

3、UARTFIFOEnable(unsigned long ulBase),UARTFIFODisable(unsigned long ulBase)
使能和禁能FIFO

4、void UARTCharPut(unsigned long ulBase, unsigned char ucData),tBoolean UARTCharPutNonBlocking(unsigned long ulBase, unsigned char ucData)
发送一个字符,区别是:
使用UARTCharPut函数如果发送FIFO满,函数会等待发送FIFO变成非满状态再将要发送字符放入发送FIFO。
使用UARTCharPutNonBlocking函数如果发送FIFO满,函数会放弃发送字符并返回false。

5、void UARTCharGet(unsigned long ulBase),tBoolean UARTCharGetNonBlocking(unsigned long ulBase)
接收一个字符,区别是:
使用UARTCharGet函数如果接收FIFO空,函数会等待接收FIFO变成非空再获取字符。
使用UARTCharGetNonBlocking函数如果接收FIFO空,函数会放弃接收并返回false。

6、tBoolean UARTCharsAvail(unsigned long ulBase),tBoolean UARTSpaceAvail(unsigned long ulBase)
查看接收FIFO是否有数据,查看发送寄存器是否满。

 
 

回复

531

帖子

0

TA的资源

一粒金砂(高级)

板凳
 

下面是一个非常简单的程序,演示UART的基本使用。

#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/uart.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "drivers/rit128x96x4.h"

int main()
{
    char cLoop = 0;
    //各种初始化工作.......
    SysCtlClockSet(SYSCTL_OSC_MAIN|SYSCTL_XTAL_8MHZ|SYSCTL_USE_OSC|SYSCTL_SYSDIV_1);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    GPIOPinTypeUART(GPIO_PORTA_BASE,GPIO_PIN_0|GPIO_PIN_1);

    RIT128x96x4Init(1000000);
    RIT128x96x4StringDraw("UART0test...",20,12,15);
    RIT128x96x4StringDraw("Baudrate:    9600",10,24,15);    
    RIT128x96x4StringDraw("WordLength:  8",10,36,15);
    RIT128x96x4StringDraw("Parity       None",10,48,15);
    RIT128x96x4StringDraw("Stop         One",10,60,15);
    
    //UART初始化,设置波特率为9600,数据字长8bit,无校验,1位停止位,使能FIFO,使能UART。
    UARTConfigSetExpClk(UART0_BASE,SysCtlClockGet(),9600,UART_CONFIG_WLEN_8|UART_CONFIG_PAR_NONE|UART_CONFIG_STOP_ONE);

    while(1)
    {
        //打印‘a’到‘z’;
        for(cLoop = 'a';cLoop<='z';cLoop++)
        {
            UARTCharPut(UART0_BASE,cLoop);
        }
        //换行
        UARTCharPut(UART0_BASE,13);
        UARTCharPut(UART0_BASE,10);
        //如果接收FIFO不为空,则打印字符到Oled
        while(UARTCharsAvail(UART0_BASE))
        {
            cLoop = UARTCharGet(UART0_BASE);
            RIT128x96x4StringDraw(&cLoop,60,72,15);
        }
        SysCtlDelay(SysCtlClockGet()/3);//延时1s
    }
}

需要注意的是在调用UARTConfigSetExpClk这个函数时会使能FIFO和UART,FIFO是很有用的东西,它可以显著减少UART产生的CPU中断,提高程序运行效率,所以FIFO一般不必Disable。
如果只想配置UART而不想使能UART,那就需要在UARTConfigSetExpClk函数后紧接着UARTDisable了。

 
 
 

回复

531

帖子

0

TA的资源

一粒金砂(高级)

4
 

UART中断
UART一共有如下几种中断


溢出错误(Overrun error):接收FIFO满时有新的数据到来,导致数据丢失产生溢出错误;
帧错误(Frame error):接收数据停止位为‘0’;
奇偶校验错误(parity error):就是奇偶校验错误.....;
中止错误(break error):RX在一个帧周期内一直为低电平。

当发送FIFO和接收FIFO中数据数量超过一定限度时可以产生Transmit或Receive中断,这个限度可以通过
UARTFIFOLevelSet(unsigned long ulBase, unsigned long ulTxLevel,unsigned long ulRxLevel)
函数设置。这个限度可以是FIFO深度的1/8,2/8,4/8,6/8,7/8

接收中断(Receive):当接收FIFO中数据超过设置限度时产生中断。
发送中断(Receive):当发送FIFO中数据超过设置限度时产生中断。

由于只有当接收FIFO数据达到设置限度时才会产生接收中断,这有可能导致FIFO中有少量数据却由于没有产生中断而长时间没有被处理,所以设这一个接收超时中断。
接收超时(Receive Timeout):当接收FIFO中有数据且在32bit周期内没有接收到其他数据,则产生接收超时中断

下面这个程序简单演示了RX中断,RT中断,Break中断。
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "driverlib/uart.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/interrupt.h"
#include "inc/hw_ints.h"
void UART0IntHandler(void);
int main()
{
    //各种初始化。。。。。。
    SysCtlClockSet(SYSCTL_OSC_MAIN|SYSCTL_XTAL_8MHZ|SYSCTL_USE_OSC|SYSCTL_SYSDIV_1);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
    GPIOPinTypeUART(GPIO_PORTA_BASE,GPIO_PIN_0|GPIO_PIN_1);

    RIT128x96x4Init(1000000);
    RIT128x96x4StringDraw("UART0Inttest...",20,12,15);

    //初始化UART0
    UARTConfigSetExpClk(UART0_BASE,SysCtlClockGet(),9600,UART_CONFIG_WLEN_8|UART_CONFIG_PAR_NONE|UART_CONFIG_STOP_ONE);
    //设置FIFO中断条件,当TX或RX6/8满时产生TX或RX中断
    UARTFIFOLevelSet(UART0_BASE,UART_FIFO_TX6_8,UART_FIFO_RX6_8);
    UARTIntEnable(UART0_BASE,UART_INT_RX|UART_INT_BE|UART_INT_RT);//使能RX,BE,RT中断

    IntEnable(INT_UART0);//使能UART0中断
    IntMasterEnable();//使能全局中断

    while(1);
}

//各种中断进行逻辑或后传给中断控制器,在中断服务程序中应该先判断中断源
void UART0IntHandler(void)
{
    unsigned long ulStatus;
    IntMasterDisable();
    ulStatus = UARTIntStatus(UART0_BASE,true);//保存屏蔽后中断状态
    UARTIntClear(UART0_BASE,UART_INT_RX|UART_INT_RT|UART_INT_BE);//清除中断标志

    //根据不同的中断标志执行不同的中断服务
    if(ulStatus&UART_INT_RX)
    {
        RIT128x96x4StringDraw("UART0_RX_INT",4,24,15);
        RIT128x96x4UnsignedLongBinaryDraw(ulStatus,12,4,36,15);
        while(UARTCharGetNonBlocking(UART0_BASE));//将接收FIFO中字符读出
    }
    if(ulStatus&UART_INT_RT)
    {
        RIT128x96x4StringDraw("UART0_RT_INT",4,24,15);
        RIT128x96x4UnsignedLongBinaryDraw(ulStatus,12,4,36,15);
    }    
    if(ulStatus&UART_INT_BE)
    {
        RIT128x96x4StringDraw("UART0_BE_INT",4,24,15);
        RIT128x96x4UnsignedLongBinaryDraw(ulStatus,12,4,36,15);
    }
    IntMasterEnable();
}

通过串口调试工具发送一个字符可以产生RT中断,发送一个字符串(大于12个)可以产生RX中断,将RX端口接地可以产生BE中断

[ 本帖最后由 ming1005 于 2011-5-16 19:10 编辑 ]
 
 
 

回复

531

帖子

0

TA的资源

一粒金砂(高级)

5
 

3、调试结果

[ 本帖最后由 ming1005 于 2011-5-16 19:12 编辑 ]
 
 
 

回复

531

帖子

0

TA的资源

一粒金砂(高级)

6
 
接下来打算做个时钟模块,先跑下IIC端口,有兴趣的坛友可以一起讨论,更希望大侠们的指点。
 
 
 

回复

2万

帖子

71

TA的资源

管理员

7
 
楼主 请将图片以附件形式上传 呵呵 现在图片都在你本地 我们这里看不到啊
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
个人签名

加油!在电子行业默默贡献自己的力量!:)

 
 

回复

531

帖子

0

TA的资源

一粒金砂(高级)

8
 
好的,谢谢提醒啊
 
 
 

回复

63

帖子

0

TA的资源

一粒金砂(中级)

9
 
https://bbs.eeworld.com.cn/viewthread.php?tid=231790&highlight=
这个。。。让我情何以堪啊,百度文库。。。。。。
 
 
 

回复

531

帖子

0

TA的资源

一粒金砂(高级)

10
 

回复 9楼 blackwc2006 的帖子

2楼已经说了啊,这个写的真的挺好的,可以参考函数库是一样的
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

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

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