查看: 2972|回复: 2

SAM4N试用之UART的使用

[复制链接]
  • TA的每日心情
    奋斗
    2015-1-22 18:04
  • 签到天数: 189 天

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2013-10-27 19:20:26 | 显示全部楼层 |阅读模式
    分享到:
    本帖最后由 nongxiaoming 于 2013-10-27 19:22 编辑

    一、准备工作:
         将上一节搭建的工程复制一份,命名为“3.uart”。这一节主要讲如何使用SAM4NUART功能,实现串口的收发。
    二、程序编写:
    细心看数据手册的朋友也许已经发现了,SAM4N4UART,还有3USART哦,如果都配置成串口,那就足足有7个可用的串口了。也许很多人就疑惑了,UARTUSART有啥区别啊?其实细节上我也不太懂有多少区别,看了数据手册,大概就明白USART可用工作在SPI模式,可用使用硬件流控,可用设置不同数据位和停止位,功能比UART要强很多,UART不支持硬件流控,不支持SPI模式,不支持数据位和停止位编程。好了,下面咱就去试试UART是怎么用的吧。
    打开原理图,可用看到有如下电路:
    file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps_clip_image-23937.png 图片1.png
    是的,这里说明板子上的USB CDC虚拟串口设备连接在了SAM4N的PA10和PA9上,而这两个正是UART0的UTXD和URXD。
    file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps_clip_image-129.png 图片2.png
    通过上面这个表可用看出,UART0的URXD0是PA9的外设A功能,UTXD0是PA10的外设A功能。
    要使用UART0,首先需要对它进行初始化配置,代码如下:
    /**************************************************************************
    * 函数名:UART0_Init()
    * 参数  :uint32_t buadrate 波特率
    * 返回值:void
    * 描述  :UART0初始化函数,在使用UART0前先调用
    **************************************************************************/
    void UART0_Init(uint32_t baudrate)
    {

      uint32_t Fdiv =0;
            /*禁止外设管理控制寄存器(PMC)写保护*/
      PMC->PMC_WPMR = 0x504D4300;
      /*使能UART1PIOA时钟*/        
      PMC->PMC_PCER0 = ((1UL << ID_PIOA) |   
                        (1UL << ID_UART0) );  
            /*使能外设管理控制寄存器(PMC)写保护*/
      PMC->PMC_WPMR = 0x504D4301;  
      /*配置PA9UART0RXDPA10UART0TXD*/        
            PIOA->PIO_IDR=(PIO_PA9A_URXD0|PIO_PA10A_UTXD0);
            PIOA->PIO_PUDR=(PIO_PA9A_URXD0|PIO_PA10A_UTXD0);
            PIOA->PIO_ABCDSR[0]&=~(PIO_PA9A_URXD0|PIO_PA10A_UTXD0);
            PIOA->PIO_ABCDSR[1]&=~(PIO_PA9A_URXD0|PIO_PA10A_UTXD0);
            PIOA->PIO_PDR=(PIO_PA9A_URXD0|PIO_PA10A_UTXD0);
                    /* 复位并禁止UART的发送和接收*/
            UART0->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX
                            | UART_CR_RXDIS | UART_CR_TXDIS;
            /*配置UART0的波特率*/
            Fdiv = (SystemCoreClock/  baudrate) /UART_MCK_DIV ;
            if (Fdiv < UART_MCK_DIV_MIN_FACTOR || Fdiv > UART_MCK_DIV_MAX_FACTOR)
                    return ;
            UART0->UART_BRGR=Fdiv;
            /*定义数据位为8bit,停止位为1,校验位为NONE*/
            UART0->UART_MR = UART_MR_PAR_NO|UART_MR_CHMODE_NORMAL;
            /*禁止 DMA 通道 */
            UART0->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
            /*使能UART接收和发送*/
            UART0->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
            /*使能接收中断*/
            UART0->UART_IER=UART_IER_RXRDY;
       /*配置UART0的先占优先级为1,从优先级为1*/
       NVIC_SetPriority(UART0_IRQn, ((0x01<<3)|0x01));
            /*使能UART0的中断通道*/
        NVIC_EnableIRQ(UART0_IRQn);
    }
    第一步就是使能PIOAUART0的时钟,然后配置PIOA9PIOA10连接到外设A功能,也就是URXD0UTXD0功能,然后禁止PIOA9PIOA10GPIO功能,这样PIOA9PIOA10就配置成了URXD0UTXD0
    接下来配置UART,首先复位UART0并禁止接收和发送,接着计算波特率分频值,数据手册给出如下计算公式,按照这个计算就好。
    file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps_clip_image-5049.png 图片3.png
    接下来配置UART的模式,这里选择普通模式,校验位为NONE,然后禁止DMA功能,因为没有用DMA传输。
    最后使能UART的收发,使能中断,这样算是完成了UART的配置了。
    完成配置还不行,还需要一个接收和发送函数,代码如下:
    /**************************************************************************
    * 函数名:UART0_Handler()
    * 参数  :void
    * 返回值:void
    * 描述  :UART0中断服务函数
    **************************************************************************/
    void UART0_Handler(void)
    {
             uint8_t temp;
             if((UART0->UART_SR& UART_SR_RXRDY)==1)
             {                                            //接收数据中断
                              temp= UART0->UART_RHR&0xff;                         //接收一个字节
           UART0_SendByte(temp);                                                 //将接收的数据发回
       }
    }
      /*****************************************************************************
    * 函数名:UART0_SendByte()
    * 参数  :uint8_t c  要发送字符
    * 返回值:void
    * 描述  :UART0发送一个字符函数
    **************************************************************************/
    void UART0_SendByte(uint8_t c)
    {
       while((UART0->UART_SR & UART_SR_TXEMPTY) == 0);                //等待发送缓冲器为空
       UART0->UART_THR=c;                                                        //将发送字符写入发送保持寄存器
    }
    /******************************************************************************
    * 函数名:UART0_SendString()
    * 参数  :uint8_t *s  指向字符串的指针
    * 返回值:void
    * 描述  :UART0发送字符串函数
    **************************************************************************/
    void UART0_SendString(uint8_t *s)
    {
      while(*s)                                                                                                //判断是否到字符串末尾
      {
       UART0_SendByte(*s);                                                        //发送指针当前所指的字节
       s++;                                                                                                        //地址加1
      }

    }

    这里我们使用的中断接收方式,因为接收的数据只是用来实验是否有接收到,所有这里是收到后再发回去。接收时要读取UART状态寄存器UART_SR的值,看UART_SR_RXRDY位是否被置位,如果置位说明有数据接收。发送时要先检测UART的发送数据寄存器UART_THR是不是为空。
    好了,这样就完成UART0的驱动了,接下来按这样的方法去配置其他UART就都可以用了。
    接下来还需要去实现int fputc(int ch,FILE *f)这个函数,试printf的打印输出到UART0去,这样就可以在程序中使用printf()函数打印消息了,代码如下:
    int fputc(int ch,FILE *f)
    {
      UART0_SendByte((uint8_t)ch);                                                        //发送1个字节
      return ch;                                                                                                                                           //返回 ch
    }
    main.c中写个简单的测试程序,如下:
    int main(void)
    {
    systick_hw_init();
    led_hw_init();
    UART0_Init(115200);
    UART0_SendString("hello,this is demo for uart\r\n");
    while(1){
    printf("hello,I am SAM4N\r\n");
    led_hw_on();
    delay_ms(500);
    led_hw_off();
    delay_ms(500);
    }
    }
       下载程序,打开串口调试工具,就可以看到板子的串口输出了,如下图:
    file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps_clip_image-19097.png 图片5.png

    注意:使用printf需要把MicroLIB勾上,如下图:
    file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps_clip_image-25805.png
    图片6.png
    3.UART使用.pdf (158.63 KB, 下载次数: 4)
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2013-12-19 13:39
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2013-12-19 13:59:16 | 显示全部楼层
    谢谢楼主,辛苦了。
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2014-4-1 08:49
  • 签到天数: 13 天

    连续签到: 1 天

    [LV.3]偶尔看看II

    发表于 2014-3-7 09:17:26 | 显示全部楼层
    不错 正需要呢
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

    站长推荐上一条 /5 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-12-21 18:36 , Processed in 0.152653 second(s), 20 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.