一、准备工作:

     将上一节搭建的工程复制一份,命名为“3.uart”。这一节主要讲如何使用SAM4N的UART功能,实现串口的收发。

二、程序编写:

细心看数据手册的朋友也许已经发现了,SAM4N有4个UART,还有3个USART哦,如果都配置成串口,那就足足有7个可用的串口了。也许很多人就疑惑了,UART和USART有啥区别啊?其实细节上我也不太懂有多少区别,看了数据手册,大概就明白USART可用工作在SPI模式,可用使用硬件流控,可用设置不同数据位和停止位,功能比UART要强很多,UART不支持硬件流控,不支持SPI模式,不支持数据位和停止位编程。好了,下面咱就去试试UART是怎么用的吧。

打开原理图,可用看到有如下电路:

是的,这里说明板子上的USB CDC虚拟串口设备连接在了SAM4N的PA10和PA9上,而这两个正是UART0的UTXD和URXD。

通过上面这个表可用看出,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;

  /*使能UART1和PIOA时钟*/

  PMC->PMC_PCER0 = ((1UL << ID_PIOA) |  

                    (1UL << ID_UART0) ); 

/*使能外设管理控制寄存器(PMC)写保护*/

  PMC->PMC_WPMR = 0x504D4301; 

  /*配置PA9为UART0的RXD,PA10为UART0的TXD*/

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);

}

第一步就是使能PIOA和UART0的时钟,然后配置PIOA9和PIOA10连接到外设A功能,也就是URXD0和UTXD0功能,然后禁止PIOA9和PIOA10的GPIO功能,这样PIOA9和PIOA10就配置成了URXD0和UTXD0。

接下来配置UART,首先复位UART0并禁止接收和发送,接着计算波特率分频值,数据手册给出如下计算公式,按照这个计算就好。

接下来配置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);

}

}

   下载程序,打开串口调试工具,就可以看到板子的串口输出了,如下图:

注意:使用printf需要把MicroLIB勾上,如下图:

[SAM4N学习笔记]UART的使用的更多相关文章

  1. [SAM4N学习笔记]按键程序(中断方式)

    一.准备工作:      将上一节搭建的工程复制一份,命名为"6.key interrupt".这一节主要讲如何使用SAM4N的GPIO中断功能,实现按键的中断输入. 二.程序编写 ...

  2. [SAM4N学习笔记]按键程序(查询方式)

    一.准备工作:      将上一节搭建的工程复制一份,命名为"5.key scanf".这一节主要讲如何使用SAM4N的GPIO输入功能,实现按键的输入. 二.程序编写:      ...

  3. [SAM4N学习笔记]LED点灯程序

    一.准备工作:      将上一节搭建的工程模板复制一份,命名为"1.blink",这作为我们开发的第一个程序. 二.程序编写:      板子上只有一个可控制的LED,就是LED ...

  4. [SAM4N学习笔记]SAM4N工程模板搭建

    一.需要安装的软件: 因为笔者是使用MDK-ARM开发的版本是4.72,所以需要安装这个工具,具体在哪里下载自行放狗或问度娘.除了这个重要工具以为,还需要安装Atmel官方的Atmel Studio, ...

  5. 【原创】ZYNQ学习笔记(一) HelloWorld实现

    拿过ZYNQ开发板,里面给了很多部件,果断从网上下载了手册,N多手册和原理图. 要比Spartan-6复杂多了,耐心地看了看,知道ZYNQ系列分为PS(系统)以及PL(逻辑)部分. 之前,自己一直在做 ...

  6. LM3S之boot loader学习笔记-1

    LM3S之boot loader学习笔记-1 彭会锋 (首先声明,此系列文章编写参考了很多资料,其中一些内容是原版内容的引用和整理,并加入了一些自己的见解,我已经尽量标明引用部分,如有未全部标注部分, ...

  7. 嵌入式学习笔记(综合提高篇 第一章) -- 利用串口点亮/关闭LED灯

    1      前言 从踏入嵌入式行业到现在已经过去了4年多,参与开发过的产品不少,有交换机.光端机以及光纤收发器,停车场出入缴费系统,二维码扫码枪,智能指纹锁以及数字IC芯片开发等; 涉及产品中中既有 ...

  8. FPFA学习笔记的系列

    1.Zynq 学习裸跑系列 学会Zynq(1)搭建Zynq-7000 AP SoC处理器 作者:FPGADesigner 学会Zynq(2)Zynq-7000处理器的配置详解 作者:FPGADesig ...

  9. 嵌入式Linux学习笔记之第一阶段---基础篇

    嵌入式Linux学习分五个阶段 第一阶段: 01嵌入式环境搭建初期 02C语言语法概述 03C语言内存操作 04c语言函数 05linux基础 06gun基础 第二阶段: 01-linux之io系统编 ...

随机推荐

  1. 互联网HTTP连接等出错代码大全

    100 - Continue  101 - Switching Protocols Success Codes  200 - OK  201 - Created  202 - Accepted  20 ...

  2. 表格td、th强制换行

    表格td.th强制换行 <table style="table-layout:fixed" width="100%"> <tr>< ...

  3. 查看Oracle表空间使用情况与增大表空间

    1,查看表空间使用情况 SELECT D.TABLESPACE_NAME, SPACE || 'M' "SUM_SPACE(M)", BLOCKS "SUM_BLOCKS ...

  4. bzoj4038: 医疗援助

    Description 一只带着先进设备和药物的医疗团队来到了埃博拉病毒疫区的某个非洲国家.这个国家有n个村庄,均坐落在该国唯一的一条公路旁,n个村庄依次标号为1,2,…n.第i个村庄有a_i个埃博拉 ...

  5. iOS开发 - NSBundle, NSDevice, NSLocale

    iOS的APP的应用开发的过程中,有时为了bug跟踪或者获取用反馈的需要自动收集用户设备.系统信息.应用信息等等,这些信息方便开发者诊断问题,当然这些信息是用户的非隐私信息,是通过开发api可以获取到 ...

  6. Ubuntu 安装 JDK 7 / JDK8 的两种方式

    ubuntu 安装jdk 的两种方式: 1:通过ppa(源) 方式安装. 2:通过官网下载安装包安装. 这里推荐第1种,因为可以通过 apt-get upgrade 方式方便获得jdk的升级 使用pp ...

  7. 个人笔记--Servlet之过滤器实现权限拦截

    一.编写一个Java类实现javax.servlet.Filter接口 package cn.edu.sxu.filter; import java.io.IOException; import ja ...

  8. bzoj 3597: [Scoi2014]方伯伯运椰子 0/1分数规划

    3597: [Scoi2014]方伯伯运椰子 Time Limit: 30 Sec  Memory Limit: 64 MBSubmit: 144  Solved: 78[Submit][Status ...

  9. WINDOWS下,中文JSON格式读取报错处理:ValueError: No JSON object could be decoded

    File "C:\Python27\lib\json\__init__.py", line 290, in load **kw) File "C:\Python27\li ...

  10. struts2文件下载出现Can not find a java.io.InputStream with the name的错误

    今天在用struts2就行文件下载时出现如下错误: Servlet.service() for servlet default threw exception java.lang.IllegalArg ...