3639|2

84

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

UART深入学习续~通过寄存器赋值实现功能 [复制链接]

 

先贴库函数操作的程序~

void delay(long i)

{

 

for(i=0;i<10000;i++)

{

}

}

 

//这个函数的作用是向串口发送一个字符串

void

UARTSend(const unsigned char *pucBuffer, unsigned long ulCount)

{

    //循环发送字符

    while(ulCount--)

    {

        //UART写下一个字符

        UARTCharPutNonBlocking(UART0_BASE, *pucBuffer++);

    }

}

 

int

main(void)

{

    //这个函数设置时钟从晶体输出

    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |

                   SYSCTL_XTAL_8MHZ);

//打开两个外设,GPIOA端口,遗迹UART0端口

    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

 

    //打孔石进程中断

    IntMasterEnable();

 

    //设置GPIOA0,A1UART引脚

    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

 

    //配置UART参数 波特率11520 0数据长度8 1个停止位 无奇偶校验 FIFO禁能无中断

    UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200,

                        (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |

                         UART_CONFIG_PAR_NONE));

    //打开UART中断

    IntEnable(INT_UART0);

    UARTIntEnable(UART0_BASE, UART_INT_RX | UART_INT_RT);

 

    //文字提示输入

    UARTSend((unsigned char *)" ", 12);

 

    //无限循环等待中断

    while(1)

    {

    }

}

在详细研究了一下DS后,我将下面两条语句实现的功能用寄存器赋值的方法实现了:

 

1

SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |

                   SYSCTL_XTAL_8MHZ);

替换成:

SYSCTL_RCC_R=(SYSCTL_RCC_BYPASS|SYSCTL_RCC_XTAL_8MHZ|SYSCTL_RCC_OSCSRC_MAIN|SYSCTL_RCC_USESYSDIV|SYSCTL_RCC_SYSDIV_M);

       SYSCTL_RCC_R&=(~SYSCTL_RCC_BYPASS);

 

详细分析如下:

PLL的配置可通过直接对RCC/RCC2 寄存器执行写操作来实现。如果 RCC2寄存器正在使用,则USERCC2位必须置位,适当的 RCC2/域被使用。 成功改变基于PLL的系统时钟所需的步骤如下:

 

1.通过置位RCC寄存器的BYPASS位,清零寄存器的USESYS位来旁路PLL和系统时钟分频器。 该操作将系统配置为选择原始的(raw时钟源(使用主振荡器或内部振荡器),并在系统时钟切换为PLL之前允许新的PLL配置生效。

2.SYSCTL_RCC_R=SYSCTL_RCC_BYPASS

 

3.选择晶体值(XTAL)和振荡器源(OSCSRC),并清零<P2><I5>RCC</I5>PWRDN 位和OEN</P2><P6>RCC/RCC2<I7>PWRDN</I7><P6> XTAL域的设置操作将自动获得所选晶体的有效的PLL配置数据,清零PWRDN位将给PLL及其输出供电并将它们使能。

 

SYSCTL_RCC_R= SYSCTL_RCC_XTAL_8MHZ|SYSCTL_RCC_OSCSRC_MAIN

 

4.RCC/RCC2 中选择所需的系统分频器(SYSDIV),置位RCCUSESYS位。 SYSDIV域决定了微控制器的系统频率.

 

SYSCTL_RCC_R=SYSCTL_RCC_USESYSDIV|SYSCTL_RCC_SYSDIV_M

 

4. 通过查询原始中断状态(RIS)寄存器的 PLLLRIS位来等待PLL锁定。

5. 通过清零RCC/RCC2中的 BYPASS位来使能PLL的使用。

SYSCTL_RCC_R&=(~SYSCTL_RCC_BYPASS);

 

lm3s8962.h文件中定义如下:

#define SYSCTL_RCC_BYPASS       0x00000800  // PLL Bypass.

#define SYSCTL_RCC_XTAL_8MHZ    0x00000380  // 8 MHz

#define SYSCTL_RCC_OSCSRC_MAIN  0x00000000  // Main oscillator (default)

#define SYSCTL_RCC_USESYSDIV    0x00400000  // Enable System Clock Divider.

#define SYSCTL_RCC_SYSDIV_M     0x07800000  // System Clock Divisor.

 

(2)

SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

 

替换成:

 

SYSCTL_RCGC1_R=SYSCTL_RCGC1_UART0;

  delay(100);

  UART0_CTL_R&=(~UART_CTL_UARTEN);

// 在对任一控制寄存器编程之前,必须将     UART禁能,这可以通过将UARTCTL寄存器的UARTEN位清零来实现。

  UART0_IBRD_R=10;

  UART0_FBRD_R=54;

  UART0_LCRH_R=UART_LCRH_WLEN_8;

  UART0_CTL_R|=UART_CTL_UARTEN;

 

要使用UART,必须使能外设时钟,这可以通过将RCGC1寄存器中的 UART0位或 UART1位置位来实现。

SYSCTL_RCGC1_R=SYSCTL_RCGC1_UART0;

 

本小节讨论了使用UART模块所需的步骤。例如,假定系统时钟为20MHz,且所需的UART配置为:

波特率115200

数据长度8

■ 1个停止位

无奇偶校验

■ FIFO禁能

无中断

因为对UARTIBRDUARTFBRD寄存器的写操作必须先于UARTLCRH寄存器,所以在对UART

行编程时,首先要考虑的是波特率除数(BRD)。而BRD可以通过““波特率的产生 284中描述

的等式计算得到:

BRD = 20,000,000 / (16 * 115,200) = 10.8507

UARTIBRD 寄存器( 295) DIVINT位域应该设为10。加载到UARTFBRD 寄存器( 296)

 

的值是通过以下等式算出来的:

UARTFBRD[DIVFRAC] = integer(0.8507 * 64 + 0.5) = 54

 

如此便得到了BRD的值,接着要按照以下顺序将UART配置写入模块:

1.       UARTCTL寄存器中的UARTEN位清零,以便将UART禁能。

UART0_CTL_R&=(~UART_CTL_UARTEN);

 

2.       BRD的整数部分写入UARTIBRD寄存器。

UART0_IBRD_R=10;

3.       BRD的小数部分写入UARTFBRD寄存器。

 UART0_FBRD_R=54;

 

4. 将所需的串行参数写入UARTLCRH寄存器(这种情况下为0x0000.0060)。

UART0_LCRH_R=UART_LCRH_WLEN_8;

 

4.       UARTCTL寄存器中的UARTEN位置位,以便将UART使能。

UART0_CTL_R|=UART_CTL_UARTEN;

 

 

3  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

 

替换成:

SYSCTL_RCGC2_R=SYSCTL_RCGC2_GPIOA;

        delay(100);  

//这条delay语句一定要加,因为使能端口后需要延时一段时间,否则功能就实现不了!

  GPIO_PORTA_DEN_R|=0x00000003H;

  GPIO_PORTA_AFSEL_R|=0x00000003H;

  GPIO_PORTA_ODR_R&=(~0x00000003H);  

 

为了使用GPIO,必须通过置位RCGC2寄存器中相应的GPIO端口位字段(GPIOn)将外设时钟使能。

SYSCTL_RCGC2_R=SYSCTL_RCGC2_GPIOA;

 

复位时,所有GPIO 管脚(除了5 JTAG 管脚外)都配置为非驱动(三态):GPIOAFSEL=0,

GPIODEN=0, GPIOPDR=0 GPIOPUR=0。表 9-1 DS156 列出了GPIO端口的所有可能的配置以及为实现这些配置所要求的控制寄存器的设置。表 9-2 DS 157 给出了为GPIO端口的管脚2配置上升沿中断的方法。

配置GPIO 寄存器位的值a

                   AFSEL  DIR  ODR  DEN  PUR  PDR  DR2R DR4R DR8R SLR

数字输入/输出 (SSI)    1     X      0    1      ?    ?    ?     ?      ?   ?

数字输入/输出 (UART)  1     X      0    1      ?    ?    ?     ?       ?   ?

模拟输入(比较器)    0     0       0    0      0    0   X    X       X   X

数字输出(比较器)   1     X        0    1     ?    ?    ?    ?        ?    ?

从表中可以看出,UART需要配置的寄存器是AFSEL  ODR  DEN。分别配置成1  0  1

最新回复

谢谢分享,楼主把串口写得比较透彻了,就差收发状态寄存器的使用了  详情 回复 发表于 2010-11-8 22:47
 
点赞 关注

回复
举报

84

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
学习完UART就要开始我的SD卡和文件系统学习了~Fighting!
 
 

回复

2641

帖子

0

TA的资源

五彩晶圆(中级)

板凳
 
谢谢分享,楼主把串口写得比较透彻了,就差收发状态寄存器的使用了
 
 
 

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

随便看看
查找数据手册?

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
快速回复 返回顶部 返回列表