Exynos4412裸机开发 —— UART

一、Exynos4412 UART 的特性

      Exynos4412 中UART,有4 个独立的通道,每个通道都可以工作于中断模式或DMA 模式,即 UART 可以发出中断或 DMA 请求以便在UART 、CPU 间传输数据。UART 由波特率发生器、发送器、接收器和控制逻辑组成。

    使用系统时钟时,Exynos4412 的 UART 波特率可以达到 4Mbps 。波特率可以通过编程进行 。

    Exynos4412 UART 的通道 0有 256 字节的发送 FIFO 和 256 字节的接收FIFO ;通道 1、4有 64 字节的发送 FIFO 和 64 字节的接收FIFO;通道 2、3有 16 字节的发送FIFO 和 16 字节 的接收 FIFO 。发送数据时, CPU 先将数据写入发送FIFO 中,然后 UART 会自动将FIFO 中的数据复制到“发送移位器” (Transmit Shifter )中,发送移位器将数据一位一位地发送到 TxDn 数据线上 (根据设定的格式,插入开始位 、较验和停止)。接收数据时,“移位器” (Receive Shifter )将 RxDn 数据线上的数据一位一位的接收进来,然后复制到FIFO 中, CPU即可从中读取数据。

     Exynos4412 UART的每个通道支持停止位有 1位、 2位,数据位有 5、6、7或 8位,支持校验功能,另外还有红外发送 /接收功能。

Exynos4412 UART结构图:



二、uart初始化步骤:

1、将所涉及的UART通道管脚设为UART功能

      比如 UART 通道 0中, GPA0_0 、GPA0_1 分别用作 RXD0 、TXD0,要使用 UART 通道 0时,先设置 GPA0CON 寄存器将 GPA0_0 、GPA0_1 引脚的功能设为 RXD0 、TXD0 。

2、 选择UART的时钟源

   

        Exynos4412 UART的时钟源有八种选择: XXTI 、XusbXTI 、SCLK_HDMI24M 、SCLK_USBPHY0 、 SCLK_HDMIPHY 、SCLKMPLL_USER_T 、SCLKEPLL 、SCLKVPLL ,由 CLK_SRC_PERIL0 寄存器控制。
选择好时钟源后,还可以通过 DIVUART0 ~4设置分频系数 设置分频系数 ,由 CLK_DIV_PERIL0 寄存器控制。 从分频器得到的时钟被称为SCLK UART 。

       SCLK UART 经过上图中的“ UCLK Generator”后,得到UCLK ,它的频率就是UART 的波特率。“ Generator UCLK Generator ”通过这 2个寄存器来设置: UBRDEVn 、UFRACVALn (在下面描述)。


3.、设置波特率:UBRDIVn寄存器(UART BAUD RATE DIVISOR)、UFRACVALn寄存器

      根据给定的波特率、所选择时钟源频率,可以通过以下公式计算 UBRDIVn 寄存器 (n 为 0~4,对应 5个 UART 通道 )的值。

      UBRDIVn = (int)( UART clock / ( buad rate x 16) ) – 1

     上式计算出来的 UBRDIVn 寄存器值不一定是整数, UBRDIVn 寄存器取其整数部分,小部分由 UFRACVALn 寄存器设置, UFRACVALn 寄存器的引入,使产生波特率更加精确。

例如,当UART clock为100MHz时,要求波特率为115200 bps,则:

100000000/(115200 x 16) – 1 = 54.25 – 1 = 53.25

UBRDIVn = 整数部分 = 53

UFRACVALn/16 = 小数部分 = 0.25

UFRACVALn = 4



4. 设置传输格式:ULCONn寄存器(UART LINE CONTROL)

ULCONn 寄存器 (n 为 0~4) 格式如下图所示:



5. 设置UART工作模式:UCONn寄存器(UART CONTROL)





6. UFCONn寄存器(UART FIFO CONTROL)、UFSTATn寄存器(UART FIFO STATUS)

        UFCON n寄存器用于设置是否使用FIFO,设置各 FIFO的触发阀值,即发送 FIFO中有多少个数据时产生中断、接收 FIFO 中有多少个数据时产生中断。并可以通过设置UFCON n寄存器来复位各个 FIFO 。

        读取 UFSTAT n寄存器可以知道各个 FIFO 是否已经满、其中有多少个数据。

不使用 FIFO 时,可以认为 FIFO 的深度为1,使用 FIFO 时 Exynos4412 的 FIFO 深度最高可达到256 。


7. UMCONn寄存器(UART MODEM CONTROL)、UMSTATn寄存器(UART MODEM STATUS)

       这两类寄存器用于流量控制,这里不介绍。


8. UTRSTATn寄存器(UART TX/RX STATUS)

       UTRSTAT n寄存器用来表明数据是否已经发送完毕、是否已经接收到数据,格式如下表所示,下面说的“缓冲区”,其实就是下图中的 FIFO ,不使用 FIFO 功能时可以认为其深度为 1。



9. UERSTATn寄存器(UART ERROR STATUS)

      用来表示各种错误是否发生,位 [0] 至位 [3] 为 1时分别表示溢出错误、校验错误、帧错误、检测到“ break ”信号。读取这个寄存器时,它会自动清 0。

      需要注意的是,接收数据时如果使用 FIFO ,则 UART 内部会使用一个“错误 FIFO ”来表明接收 FIFO 中哪个数据在接收过程发生了错误。 CPU 只有在读出这个错误的数据时,才会觉察到发生了错误 。要想清除“FIFO ”,则必须读出错误的数据,并读出UERSTATn 寄存器。


10. UTXHn寄存器(UART TRANSMIT BUFFER REGISTER)

       CPU 将数据写入这个寄存器, UART即会将它保存到缓冲区中,并自动发送出去。


11. URXHn寄存器(UART RECEIVE BUFFER REGISTER)

      当 UART 接收到数据时,读取这个寄存器,即可获得数据。


三、示例程序编写

         下面是一个小demo,实现在终端上的回显功能,并通过在终端上输入“beep_on”、"beep_off"实现蜂鸣器的开启和停止:

头文件定义:

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. /*****************************************    UART  * *************************************/  
  2. /* UART0*/  
  3. typedef struct {  
  4.                 unsigned int ULCON0;  
  5.                 unsigned int UCON0;  
  6.                 unsigned int UFCON0;  
  7.                 unsigned int UMCON0;  
  8.                 unsigned int UTRSTAT0;  
  9.                 unsigned int UERSTAT0;  
  10.                 unsigned int UFSTAT0;  
  11.                 unsigned int UMSTAT0;  
  12.                 unsigned int UTXH0;  
  13.                 unsigned int URXH0;  
  14.                 unsigned int UBRDIV0;  
  15.                 unsigned int UFRACVAL0;  
  16.                 unsigned int UINTP0;  
  17.                 unsigned int UINTSP0;  
  18.                 unsigned int UINTM0;  
  19. }uart0;  
  20. #define UART0 ( * (volatile uart0 *)0x13800000 )  
UART.c

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. #include "exynos_4412.h"  
  2. #include "pwm.h"  
  3.   
  4. void mydelay_ms(int time)  
  5. {  
  6.     int i, j;  
  7.     while(time--)  
  8.     {  
  9.         for (i = 0; i < 5; i++)  
  10.             for (j = 0; j < 514; j++);  
  11.     }  
  12. }  
  13.   
  14. int strcmp(const char *src, const char *des)  
  15. {  
  16.     while(*src || *des)  
  17.     {  
  18.         if(*src > *des)  
  19.             return 1;  
  20.         else if(*src < *des)  
  21.             return -1;  
  22.         else  
  23.         {  
  24.             src++;  
  25.             des++;  
  26.         }  
  27.     }  
  28.     return 0;  
  29. }  
  30.   
  31. void uart0_init()  
  32. {  
  33.   
  34.     /*UART0 initialize*/  
  35.     GPA0.CON = (GPA0.CON & ~0xFF ) | (0x22); //GPA1_0:RX;GPA1_1:TX  
  36.   
  37.     UART0.ULCON0 = 0x3; //Normal mode, No parity,One stop bit,8 data bits  
  38.     UART0.UCON0 = 0x5;  //Interrupt request or polling mode  
  39.     //Baud-rate : src_clock:100Mhz  
  40.     UART0.UBRDIV0 = 53;  
  41.     UART0.UFRACVAL0 = 0x4;  
  42. }  
  43.   
  44. void putc0(const char data)  
  45. {  
  46.     while(!(UART0.UTRSTAT0 & 0X2));  
  47.     UART0.UTXH0 = data;  
  48.     if (data == '\n')  
  49.             putc0('\r');  
  50. }  
  51. char getc0(void)  
  52. {  
  53.     char data;  
  54.     while(!(UART0.UTRSTAT0 & 0x1));  
  55.     data = UART0.URXH0;  
  56.     if ((data == '\n') || (data == '\r'))  
  57.     {  
  58.         putc0('\n');  
  59.         putc0('\r');  
  60.     }  
  61.     else  
  62.         putc0(data);  
  63.   
  64.     return data;  
  65. }  
  66. void puts0(const  char  *pstr)  
  67. {  
  68.     while(*pstr != '\0')  
  69.         putc0(*pstr++);  
  70. }  
  71.   
  72. void gets0(char *p)  
  73. {  
  74.     char data;  
  75.     while((data = getc0())!= '\r')  
  76.         *p++ = data;  
  77.     if(data == '\r')  
  78.         *p++ = '\r';  
  79.     *p = '\0';  
  80. }  
  81.   
  82.   
  83. /* 
  84.  *  裸机代码,不同于LINUX 应用层, 一定加循环控制 
  85.  */  
  86. int main (void)  
  87. {  
  88.     char ch[20];  
  89.     pwm_init();  
  90.     uart0_init();  
  91.     char *q = "hello UART!";  
  92.     puts0(q);  
  93.     while(1)  
  94.     {  
  95.         gets0(ch);  
  96.         puts0(ch);  
  97.         if(!strcmp(ch, "beep_on\n"))  
  98.             beep_on();  
  99.         if(!strcmp(ch, "beep_off\n"))  
  100.             beep_off();  
  101.   
  102.     //  putc0(getc0());  
  103.     }  
  104.    return 0;  
  105. }  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/402044.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Exynos4412裸机开发 —— 看门狗定时器

一、看门狗定时器概述 看门狗&#xff08;WatchDog Timer) 定时器和PWM的定时功能目的不一样。它的特点是&#xff0c;需要不同的接收信号&#xff08;一些外置看门狗芯片&#xff09;或重新设置计数器&#xff0c;保持计数值不为0。一旦一些时间接收不到信号&#xff0c;或计数…

Exynos4412裸机开发 —— RTC 实时时钟单元

RTC(Real-Time Clock) 实时时钟。RTC是集成电路&#xff0c;通常称为时钟芯片。在一个嵌入式系统中&#xff0c;通常采用RTC来提供可靠的系统时间&#xff0c;包括时分秒和年月日等&#xff0c;而且要求在系统处于关机状态下它也能正常工作&#xff08;通常采用后备电池供电&am…

Exynos4412裸机开发——中断处理

以KEY2控制LED3亮灭为例&#xff1a; 一、轮询方式 【0】检测按键k2&#xff0c;按键k2按下一次&#xff0c;灯LED2闪一次。 【1】查看原理图&#xff0c;连接引脚和控制逻辑 &#xff08;1&#xff09;按键k2 连接在GPX1_1引脚 &#xff08;2&#xff09;控制逻辑 k2 按…

远程WEB控制MP3播放器设计(基于mini2440)

网上有很多 基于mini2440的MP3播放器设计的资料&#xff0c;多是按键控制&#xff0c;这里博主做了些轻微改动&#xff0c;利用远程WEB来控制MP3播放&#xff0c;具体怎么实现&#xff0c;下面会给出&#xff0c;大家先看看效果&#xff1a; WEB界面&#xff1a; 后台运行&…

嵌入式数据库 SQLite 浅析

SQLite是一个非常轻量级自包含(lightweight and self-contained)的DBMS&#xff0c;它可移植性好&#xff0c;很容易使用&#xff0c;很小&#xff0c;高效而且可靠。SQLite嵌入到使用它的应用程序中&#xff0c;它们共用相同的进程空间&#xff0c;而不是单独的一个进程。从外…

socket 请求Web服务器过程

HTTP协议只是一个应用层协议&#xff0c;它底层是通过TCP进行传输数据的。因此&#xff0c;浏览器访问Web服务器的过程必须先有“连接建立”的发生。 而有人或许会问&#xff1a;众所周知&#xff0c;HTTP协议有两大特性&#xff0c;一个是“无连接”性&#xff0c;一个是“无状…

有些事情现在不做一辈子就都不会做了

这句话最近一直印在我的脑海里。这句话最早是在Casperkid的百度空间里面看见的&#xff0c;那时他生日。作为师傅的刺&#xff08;道哥&#xff09;送了他自己写的一本《白帽子讲WEB安全》给他&#xff0c;并在扉页上写着这句话。那时一看到这句话&#xff0c;仿佛有种触电的感…

HTTP 数据包头解析

一、连接至Web服务器 一个客户端应用&#xff08;如Web浏览器&#xff09;打开到Web服务器的HTTP端口的一个套接字&#xff08;缺省为80&#xff09;。 例如&#xff1a;http://www.myweb.com:8080/index.html 在Java中&#xff0c;这将等同于代码&#xff1a; [java] view pla…

Shell 脚本中如何使用make命令

最近开发的项目中需要编写Shell脚本对整个工程进行自动化编译&#xff0c;即在Shell脚本中使用make命令来进行编译&#xff0c;下面回顾一下Shell脚本中如何使用make命令&#xff09; 在开发一个系统时&#xff0c;一般是将一个系统分成几个模块&#xff0c;这样做提高了系统的…

Shell 脚本知识回顾 (六) —— Shell 函数

一、Shell函数&#xff1a;Shell函数返回值、删除函数、在终端调用函数 函数可以让我们将一个复杂功能划分成若干模块&#xff0c;让程序结构更加清晰&#xff0c;代码重复利用率更高。像其他编程语言一样&#xff0c;Shell 也支持函数。Shell 函数必须先定义后使用。 Shell 函…

Shell 脚本知识回顾 (五) —— Shell 循环

一、Shell for循环 与其他编程语言类似&#xff0c;Shell支持for循环。 for循环一般格式为&#xff1a;for 变量 in 列表 docommand1command2...commandN done 列表是一组值&#xff08;数字、字符串等&#xff09;组成的序列&#xff0c;每个值通过空格分隔。每循环一次&…

Shell 脚本知识回顾 (四) —— Shell 命令及Shell 相关语句

一、Shell echo命令 echo是Shell的一个内部指令&#xff0c;用于在屏幕上打印出指定的字符串。命令格式&#xff1a;echo arg您可以使用echo实现更复杂的输出格式控制。 显示转义字符 echo "\"It is a test\""结果将是&#xff1a;"It is a test"…

Shell 脚本知识回顾 (三) —— 替换、运算符、字符串、数组

一、Shell替换&#xff1a;Shell变量替换&#xff0c;命令替换&#xff0c;转义字符 如果表达式中包含特殊字符&#xff0c;Shell 将会进行替换。例如&#xff0c;在双引号中使用变量就是一种替换&#xff0c;转义字符也是一种替换。 举个例子&#xff1a; [cpp] view plaincop…

Shell 脚本知识回顾 (二) —— Shell变量

一、Shell变量&#xff1a;Shell变量的定义、删除变量、只读变量、变量类型 Shell支持自定义变量。定义变量 定义变量时&#xff0c;变量名不加美元符号&#xff08;$&#xff09;&#xff0c;如&#xff1a; [cpp] view plaincopy variableName"value" 注意&…

Shell 脚本知识回顾 (一) —— 基础篇

一、Shell简介&#xff1a;什么是Shell&#xff0c;Shell命令的两种执行方式 Shell本身是一个用C语言编写的程序&#xff0c;它是用户使用Unix/Linux的桥梁&#xff0c;用户的大部分工作都是通过Shell完成的。Shell既是一种命令语言&#xff0c;又是一种程序设计语言。作为命令…

红帽集群RHCS

1、简介&#xff1a;RHCS是RedHatClusterSuite的缩写&#xff0c;也就是红帽子集群套件&#xff0c;RHCS是一个能够提供高可用性、高可靠性、负载均衡、存储共享且经济廉价的集群工具集合&#xff0c;它将集群系统中三大集群架构融合一体&#xff0c;可以给web应用、数据库应用…

Java 基础——数组解析

数组对于每一门编辑应语言来说都是重要的数据结构之一&#xff0c;当然不同语言对数组的实现及处理也不尽相同。 Java语言中提供的数组是用来存储固定大小的同类型元素。 可以声明一个数组变量&#xff0c;如numbers[100]来代替直接声明100个独立变量number0&#xff0c;number…

《在你身边,为你设计》-哪位知道下载、在线阅读地址啊?

《在你身边&#xff0c;为你设计》-前端UI必读出自腾讯CDChttp://cdc.tencent.com/?p6761今天听同事说这本书写的非常好&#xff0c;改变了他关于前端UI的许多看法&#xff0c;可谓&#xff1a;醍醐灌顶。可惜我网上找了下都需要Money买&#xff0c;哪位有在线阅读、PDF下载地…

一、OpenStack架构

DashBoardHorizon提供WEB界面ComputerNova计算也就是虚拟机NetworkingNeutron提供给nova网络支持Object StorageSwift提供对象存储Block StorageCinder提供云硬盘给nova&#xff0c;同时备份到SwiftIdentity SserviceKeystone提供所有组件的认证Image ServiceGlance提供给nova镜…

Java 三大特性 —— 多态

Java中多态性的实现 一、什么是多态 1.面向对象的三大特性&#xff1a;封装、继承、多态。从一定角度来看&#xff0c;封装和继承几乎都是为多态而准备的。这是我们最后一个概念&#xff0c;也是最重要的知识点。 2.多态的定义&#xff1a;指允许不同类的对象对同一消息做出响应…