为得到更高的带宽,需要使用更高的波特率。UART波特率的计算已经介绍过了,现在就尝试下调整外设的时钟频率。可以有多种方法调整外设时钟(MCK)的频率,这里先介绍先主要时钟(MAINCK)的设置,其中包括外部晶振的使用。

外设的时钟(MCK)可以在慢时钟(SLCK)、主要时钟(MAINCK)和MAINCK经锁相环升频后的时钟PLLACK三者中选择,并可以对选择的时钟进行分频。重置时,MCK使用的时钟为MAINCK,且不分频。

MAINCK可以选择使用一个嵌入的快速RC振荡器,或是一个晶体振荡器产生时钟。快速RC振荡器启动时间较短,但不是太精确;而晶体振荡器则相反。同时,RC振荡器可以选择输出时钟的频率(4/8/12 MHz)。重置时,MAINCK使用RC振荡器,频率为4 MHz。

一、 使用芯片嵌入的快速RC振荡器

在PMC时钟产生器主要振荡器寄存器(CKGR_MOR)中,可以对MAINCK进行一系列的设置。注意,在修改该寄存器的值时,需要同时往其KEY字段写入一个魔数:0x37,否则写入不生效。

  1. 使能快速RC振荡器。在设置RC振荡器的频率之前,需要先使能它,并且要等到它运行稳定(即不能同时使能RC振荡器和设置它的频率):

    /* 使能RC震荡器 */
    PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD /* 密码 */
    | (PMC->CKGR_MOR| CKGR_MOR_MOSCRCEN)
    ;
    /* 等待时钟稳定 */
    while(!(PMC->PMC_SR & PMC_SR_MOSCRCS))
    ;
  2. 设置RC振荡器频率为12 Mhz。设置后同样需要等待它运行稳定。

    /* 设置快速RC振荡器频率为12 MHz */
    PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD
    | (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCF_Msk)
    | CKGR_MOR_MOSCRCF_12_MHz
    ;
    /* 等待稳定 */
    while(!(PMC->PMC_SR & PMC_SR_MOSCRCS))
    ;
  3. 为MAINCK选择快速RC振荡器。

    /* 切换至RC振荡器 */
    PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD
    | (PMC->CKGR_MOR & ~CKGR_MOR_MOSCSEL)
    ;
    /* 等待切换完成 */
    while (!(PMC->PMC_SR & PMC_SR_MOSCSELS))
    ;
  4. 设置UART。此时,若将UART_BRGR中CD字段的值设为13,则理论的波特率值为 12M/(16 * 13) = 57692 Hz,若PC端选择使用57600 Hz的波特率,则误差约为0.16%。

    UART0->UART_BRGR = UART_BRGR_CD(13 );

接下来,将PC端串口的波特率设置为57600 Hz,尝试下通信是否正常。

若在PC端接收到的是乱码,可能就是RC振荡器不够精确引起的。其产生的时钟频率受工作温度和电压等因素的影响,所以需要校准。可以通过PMC振荡器校准寄存器(PMC_OCR)来进行校准,但在这里不做讨论。

二、 使用外部晶振

可以使用一个外部的晶振以提供更为精确的频率。使用的晶振是由开发板携带的,在芯片手册中,对其的介绍为“3~20 MHz晶振”,即表示具体的频率是由开发板的生产厂家决定的。晶振的一个缺点是需要一定的启动时间,而且由于芯片无法了解使用的芯片的具体信息,所以用户必须手动指定这个启动时间。

SAM4E_EK所携带的晶振的频率为12 MHz,启动时间为15625 us。具体可以查阅开发板的电路图:

或者也可以参考头文件“sam4e_ek.h”中相关的定义:

/** Board oscillator settings(晶振频率) */
#define BOARD_FREQ_MAINCK_XTAL (12000000U)
/** board main clock xtal statup time (主要时钟晶振启动时间)*/
#define BOARD_OSC_STARTUP_US 15625

接下来就可以进行具体的设置了。

  1. 使用新的头文件。现在需要了解开发板相关的信息,所以需要使用新的头文件:

    //#include <sam.h>
    #include <sam4e_ek.h>

    但是在新的头文件中,修改CKGR_MOR密码的宏没有定义,所以需要自己定义:

    #define CKGR_MOR_KEY_PASSWD CKGR_MOR_KEY(0x37)
  2. 禁用PB8和PB9引脚的输出。这一步是可选的。PB8和PB9的系统功能分别是XOUT和XIN,即是使用晶振时要用到的引脚。由于PIO控制器中的配置对引脚的输入没有影响,所以无需配置引脚的复用,只需禁用输出即可。

    /* 禁用PB8和PB9引脚的输出 */
    Pio* xtal_pio = PIOB;
    const uint32_t pio_mask = PIO_PB8 | PIO_PB9;
    xtal_pio->PIO_PER = pio_mask;
    xtal_pio->PIO_ODR = pio_mask;
  3. 计算晶振启动时间参数。需要制定一个16位的值(MOSCXTST)来表明晶振启动的时间,具体计算方法为:启动时间 = MOSCXTST * 8 * SLCK周期。

    uint32_t slowck_freq = CHIP_FREQ_SLCK_RC;
    volatile uint32_t xt_start =
    (BOARD_OSC_STARTUP_US * slowck_freq / 8 / 1000000);
    if (xt_start > 0xFF)
    xt_start = 0xFF;
  4. 使能晶振,并等待其运行稳定。使能晶振时,必须同时使用旁路模式。

    PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD
    | (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTBY)
    | CKGR_MOR_MOSCXTEN
    | CKGR_MOR_MOSCXTST(xt_start)
    ;
    /* 等待晶振运行稳定 */
    while (!(PMC->PMC_SR & PMC_SR_MOSCXTS))
    ;
  5. 让MAINCK切换为晶振时钟源,并等其运行稳定。

    /* 切换至晶振 */
    PMC->CKGR_MOR |= CKGR_MOR_KEY_PASSWD
    | CKGR_MOR_MOSCSEL ;
    /* 等待切换完成 */
    while (!(PMC->PMC_SR & PMC_SR_MOSCSELS))
    ;

由于MCK的时钟并未改变,均是12 MHz,所以不用修改UART的设置,就可以正常通信了。

SAM4E单片机之旅——9、UART与MCK之MAINCK的更多相关文章

  1. SAM4E单片机之旅——11、UART之PDC收发

    使用PDC进行数据的收发能减少CPU的开销.这次就使用PDC进行UART数据的接收与发送,同时,也利用TC也实现了PDC的接收超时. PDC是针对外设的DMA控制器.对比DMA控制器,它更为简便,与相 ...

  2. SAM4E单片机之旅——10、UART与MCK之PLL

    为使用更更高的波特率,则需要更更高的外设时钟的频率.这个时候就需要用到锁相环(PLL)了.锁相环可以对输入的时钟进行分频.升频后进行输出.MCK可以使用的锁相环为PLLA,而PLLA的输入时钟为MAI ...

  3. SAM4E单片机之旅——8、UART初步

    通信还是比让LED灯闪烁实用得多的. 这次试试使用UART,实现开发版和PC间的通信.功能比较简单,就是把PC发向开发版的内容发送回去.这次主要介绍一下UART的配置,至于通信,则使用较为简单的不断查 ...

  4. SAM4E单片机之旅——17、通过UART进行标准IO

    交互还是很有必要的,而且使用键盘和显示器的交互效率还是很高的.当然,可以直接使用UART进行字符的输入和输出.但是又何必浪费了C的标准输入输出的格式控制之类的功能呢? 这次内容就是使用scanf() ...

  5. SAM4E单片机之旅——18、通过AFEC(ADC)获取输入的电压

    很多时候,一个电压不仅仅需要定性(高电平或者低电平),而且要定量(了解具体电压的数值).这个时候就可以用到模数转换器(ADC)了.这次的内容是测量开发板搭载的滑动变阻器(VR1)的电压,然后把ADC转 ...

  6. SAM4E单片机之旅——19、CAN间通信

    CAN协议具有良好的可靠性,在工业中应用广泛.这次就先熟悉CAN的基本功能. 开发板有两个CAN,每个CAN有8个信箱.这次内容是从CAN0的信箱0发送数据到CAN1的信箱0. 除本次使用的功能外,C ...

  7. SAM4E单片机之旅——13、LCD之ASF初步

    在Atmel Studio 6中,集成了Atmel Software Framework(ASF框架).通过它提供的库,可以很快速地完成新的项目. 这次的最终目标使用ASF在LCD上显示出文字“Hel ...

  8. SAM4E单片机之旅——12、USART

    清楚了UART的用法之后,现在来研究一下USART的用法.和上一次差不多,这次也通过USART的串口来实现和PC的通信.和上一次不同的是,USART本身就有接收超时的功能,所以这次就不用TC了. US ...

  9. SAM4E单片机之旅——24、使用DSP库求向量数量积

    DSP(Digital Signal Processing,数字信号处理)中会使用大量的数学运算.Cortex-M4中,配置了一些强大的部件,以提高DSP能力.同时CMSIS提供了一个DSP库,提供了 ...

随机推荐

  1. CodeForces 618D Hamiltonian Spanning Tree

    题意:要把所有的节点都访问一次,并且不能重复访问,有两种方式访问,一种是根据树上的路径 走和当前节点连接的下一个节点cost x, 或者可以不走树上边,直接跳到不与当前节点连接的节点,cost y 分 ...

  2. [LeetCode] Edit Distance 字符串变换为另一字符串动态规划

    Given two words word1 and word2, find the minimum number of steps required to convert word1 to word2 ...

  3. 标准C程序设计七---57

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...

  4. linux 时间模块 三

    LINUX的时钟中断中涉及至二个全局变量一个是xtime,另一个则是jiffies.有一个与时间有关的时钟:实时时钟(RTC),这是一个硬件时钟,用来持久存放系统时间,系统关闭后靠主板上的微型电池保持 ...

  5. 计算机图形——OpenGL

    荒废了太久,趁着"寒假"死磕了两周,验证了不少想法,解开了不少疑惑,代码质量当然是没有的,一切只为看到结果. 有空了再写每一项的细节. 源码地址 2019/5/12 更新 延迟渲染 ...

  6. express之中间件bodyParser的理解

    bodyParser用于解析客户端请求的body中的内容,内部使用JSON编码处理,url编码处理以及对于文件的上传处理.另外bodyParse也可以接受客户端ajax提交的json数据,以及url的 ...

  7. Win32 绘制RGB三原色图案

    以前看到三原色的图案,一直很好奇是如何画出来.后来终于搞清楚了,其实很简单,实际上就是RGB三个分量的"位与"运算. 下面给出Win32绘制三原色图案的例子,特此记录在此: #in ...

  8. TextReader 和StreamReader

    TextReader 和StreamReader 目录: 为什么要介绍 TextReader? TextReader的常用属性和方法 TextReader 示例 从StreamReader想到多态 简 ...

  9. WEB学习-CSS行高、字体,链接的美化以及背景

    行高和字号 CSS中,所有的行,都有行高.盒模型的padding,绝对不是直接作用在文字上的,而是作用在“行”上的. 单行文本垂直居中 文本在行里面是居中 其中,行高:盒子高; 需要注意的是,这个小技 ...

  10. python 操作系统和进程

    一. 操作系统介绍 多道程序系统 多道程序设计技术       所谓多道程序设计技术,就是指允许多个程序同时进入内存并运行.即同时把多个程序放入内存,并允许它们交替在CPU中运行,它们共享系统中的各种 ...