查看: 4132|回复: 0

USART的使用

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

    连续签到: 1 天

    [LV.7]常住居民III

    发表于 2013-10-27 20:53:05 | 显示全部楼层 |阅读模式
    分享到:
    一、准备工作:
         将上一节搭建的工程复制一份,命名为“4.usart”。这一节主要讲如何使用SAM4NUSART功能,实现串口的收发。
    二、程序编写:
    SAM4N除了4UART,还提供了3USART,这3USART可以配置成多种模式,支持SPI模式,流控模式,IrDA红外模式,IS07816模式,RS485模式等,真的很强大,足以满足用户连接各种Modem,射频卡等需求。
    file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps_clip_image-9224.png 图片15.png
    通过上面这段概述可以知道,USART比上一节的UART要多了不少功能。
    file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps_clip_image-19684.png 图片13.png
    由上面的表格可以看出PA5PA6分别为USART0RXDTXD,都是用的是外设功能A,和上一节讲的UART0很类似。
    file:///C:\Users\ADMINI~1\AppData\Local\Temp\ksohtml\wps_clip_image-13301.png 图片14.png
    从上面的描述可以看出,计算波特率的方式和UART有些不同。
    总体上来看,USARTUART有很多相似的地方,委员不同的是波特率的配置和模式配置,多了很多模式。
    下面开始编写USART0的初始化代码。
    /*************************************************************
    * 函数名:USART0_Init()
    * 参数  :uint32_t buadrate 波特率
    * 返回值:void
    * 描述  :USART0初始化函数,在使用USART0前先调用
    *************************************************************/
    void USART0_Init(uint32_t baudrate)
    {
            /*禁止外设管理控制寄存器(PMC)写保护*/
      PMC->PMC_WPMR = 0x504D4300;
      /*使能USART1PIOA时钟*/       
      PMC->PMC_PCER0 = ((1UL << ID_PIOA) |   
                        (1UL << ID_USART0) );  
            /*使能外设管理控制寄存器(PMC)写保护*/
      PMC->PMC_WPMR = 0x504D4301;  
      /*配置PA5USART0RXDPA6USART0TXD*/       
            PIOA->PIO_IDR=(PIO_PA5A_RXD0|PIO_PA6A_TXD0);
            PIOA->PIO_PUDR=(PIO_PA5A_RXD0|PIO_PA6A_TXD0);
            PIOA->PIO_ABCDSR[0]&=~(PIO_PA5A_RXD0|PIO_PA6A_TXD0);
            PIOA->PIO_ABCDSR[1]&=~(PIO_PA5A_RXD0|PIO_PA6A_TXD0);
            PIOA->PIO_PDR=(PIO_PA5A_RXD0|PIO_PA6A_TXD0);
                    /* 复位并禁止USART的发送和接收*/
            USART0->US_CR = US_CR_RSTRX | US_CR_RSTTX
                            | US_CR_RXDIS | US_CR_TXDIS;
            /*配置USART0的波特率*/
            USART0->US_BRGR=BAUD(baudrate);
            /*定义数据位为8bit,停止位为1,校验位为NONE*/
            USART0->US_MR = US_MR_USART_MODE_NORMAL|   //普通模式
                               US_MR_CHRL_8_BIT|          //数据位为8
                              US_MR_NBSTOP_1_BIT|        //停止位为1
                              US_MR_PAR_NO|              //校验位为NONE
                              US_MR_CHMODE_NORMAL;       //普通通道模式
            /*禁止 DMA 通道 */
            USART0->US_PTCR = US_PTCR_RXTDIS | US_PTCR_TXTDIS;
            /*使能USART接收和发送*/
            USART0->US_CR = US_CR_RXEN | US_CR_TXEN;
            /*使能接收中断*/
            USART0->US_IER=US_IER_RXRDY;
       /*配置USART0的先占优先级为1,从优先级为1*/
       NVIC_SetPriority(USART0_IRQn, ((0x01<<3)|0x01));
            /*使能USART0的中断通道*/
        NVIC_EnableIRQ(USART0_IRQn);
    }
    从代码上来看,和UART的配置一样,就是寄存器的名字变了一点,模式配置那里多了数据位,停止位的配置,其他基本就是一样的。
    下面是接收和发送代码:
    /*************************************************************
    * 函数名:USART0_Handler()
    * 参数  :void
    * 返回值:void
    * 描述  :USART0中断服务函数
    *************************************************************/
    void USART0_Handler(void)
    {
             uint8_t temp;
             if((USART0->US_CSR& US_CSR_RXRDY)==1)
             {    //接收数据中断
              temp= USART0->US_RHR&0xff;         //接收一个字节
           USART0_SendByte(temp);              //将接收的数据发回
       }
    }
      /***************************************************************
    * 函数名:USART0_SendByte()
    * 参数  :uint8_t c  要发送字符
    * 返回值:void
    * 描述  :USART0发送一个字符函数
    *************************************************************/
    void USART0_SendByte(uint8_t c)
    {   /*等待发送缓冲器为空*/
       while((USART0->US_CSR & US_CSR_TXEMPTY) == 0);     
       USART0->US_THR=c;        //将发送字符写入发送保持寄存器
    }
    /***************************************************************
    * 函数名:USART0_SendString()
    * 参数  :uint8_t *s  指向字符串的指针
    * 返回值:void
    * 描述  :USART0发送字符串函数
    *************************************************************/
    void USART0_SendString(uint8_t *s)
    {
      while(*s)                                                                                                //判断是否到字符串末尾
      {
       USART0_SendByte(*s);        //发送指针当前所指的字节
       s++;                                                                                                        //地址加1
      }
    }
    main.c中写个简单的测试程序,如下:
    int main(void)
    {
    systick_hw_init();
    led_hw_init();
    USART0_Init(115200);
    USART0_SendString("hello,this is a usart demo!\r\n");
    while(1){
    USART0_SendString("hello,I am SAM4N!\r\n");
    led_hw_on();
    delay_ms(500);
    led_hw_off();
    delay_ms(500);
    }
    }
       找一条串口线接到PA5PA6上就可以看到输出了,效果和上一节一样。注意串口线要用TTL电平的哦。
    4.usart.rar (171.9 KB, 下载次数: 5)
    回复

    使用道具 举报

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

    本版积分规则

    关闭

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

    手机版|小黑屋|与非网

    GMT+8, 2024-12-21 10:52 , Processed in 0.111026 second(s), 16 queries , MemCache On.

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

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.