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结构图
exynos4412 uart
声明
以后没有特殊说明,程序结构都和《Tiny4412裸机程序之代码在DDR SDRAM中运行》时的一样。
整个程序的运行过程大致如下:系统上电后,首先将sd卡扇区1处的bl1拷贝到IRAM的0x02020000地址处,然后运行该部分代码,该部分代码首先又会加载BL2.bin,BL2.bin会进行时钟和DRAM初始化,然后把位于sd卡中扇区49处的main.bin拷贝到DRAM的0x43E00000地址处,最后跳转到该地址处继续运行。
uart初始化步骤:
1.将所涉及的UART通道管脚设为UART功能
比如 UART 通道 0中, GPA0_0 、GPA0_1 分别用作 RXD0 、TXD0,要使用 UART 通道 0时,先设置 GPA0CON 寄存器将 GPA0_0 、GPA0_1 引脚的功能设为 RXD0 、TXD0 。
2. 选择UART的时钟源
uart clock
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 (在下面描述 在下面描述 )。
CLK_SEC_PERIL0格式
CLK_DIV_PERIL0的寄存器格式
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) 格式如下图所示:
ULCONn寄存器格式
5. 设置UART工作模式:UCONn寄存器(UART CONTROL)
UCONn寄存器格式
UCONn寄存器格式
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。
UTRSTATn寄存器格式
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 接收到数据时,读取这个寄存器,即可获得数据。
程序说明
程序文件和上一个实验大同小异,只是在MAIN文件夹下新建了一个init.c及init.h文件,用来存放初始化相关的代码。
下面是init.c文件的全部代码:
==================================================================
// GPIO
#define GPA0CON (*(volatile unsigned int *)0x11400000)
// system clock
#define CLK_SRC_PERIL0 (*(volatile unsigned int *)0x1003C250)
#define CLK_DIV_PERIL0 (*(volatile unsigned int *)0x1003C550)
// UART
#define UFCON0 (*(volatile unsigned int *)0x13800008)
#define ULCON0 (*(volatile unsigned int *)0x13800000)
#define UCON0 (*(volatile unsigned int *)0x13800004)
#define UBRDIV0 (*(volatile unsigned int *)0x13800028)
#define UFRACVAL0 (*(volatile unsigned int *)0x1380002c)
#define UTXH0 (*(volatile unsigned int *)0x13800020)
#define URXH0 (*(volatile unsigned int *)0x13800024)
#define UTRSTAT0 (*(volatile unsigned int *)0x13800010)
void UartInit()
{
// 1.设置相应的GPIO用于串口功能
unsigned long tmp = 0;
tmp = GPA0CON;
tmp &= ~(0xff); //设置UART0对应的GPIO为UART功能
tmp |= 0x22;
GPA0CON = tmp;
// 2.设置UART时钟源SCLK_UART
// 2.1 CLK_SRC_DMC : bit[12]即MUX_MPLL_SEL=1, SCLKMPLLL使用MPLL的输出
// 2.2 CLK_SRC_TOP1 : bit[12]即MUX_MPLL_USER_SEL_T=1, MUXMPLL使用SCLKMPLLL
// 2.3 CLK_SRC_PERIL0 : bit[3:0]即UART0_SEL=6, MOUTUART0使用SCLKMPLL_USER_T
// 所以, MOUTUART0即等于MPLL的输出, 800MHz
//PWM_SEL = 0;
//UART5_SEL = 0;
//UART4_SEL = 6; // 串口时钟源选 SCLKMPLL_USER_T
//UART3_SEL = 6;
//UART2_SEL = 6;
//UART1_SEL = 6;
//UART0_SEL = 6;
CLK_SRC_PERIL0 = ((0 << 24) | (0 << 20) | (6 << 16) | (6 << 12) | (6<< 8) | (6 << 4) | (6));
// 分频系数 = 7+1 = 8
// 2.4 CLK_DIV_PERIL0 : bit[3:0]即UART0_RATIO=7,所以SCLK_UART0=MOUTUART0/(7+1)=100MHz
CLK_DIV_PERIL0 = ((7 << 20) | (7 << 16) | (7 << 12) | (7 << 8) | (7 << 4) | (7));
// 3.设置串口0相关
// 设置FIFO中断触发阈值
// 使能FIFO
UFCON0 = 0x111;
// 设置数据格式: 8n1, 即8个数据位,没有较验位,1个停止位
ULCON0 = 0x3;
// 工作于中断/查询模式
// 另一种是DMA模式,本章不使用
UCON0 = 0x5;
// SCLK_UART0=100MHz, 波特率设置为115200
// 寄存器的值如下计算:
// DIV_VAL = 100,000,000 / (115200 * 16) - 1 = 53.25
// UBRDIVn0 = 整数部分 = 53
// UFRACVAL0 = 小数部分 x 16 = 0.25 * 16 = 4
UBRDIV0 = 53;
UFRACVAL0 = 4;
}
char getc(void)
{
char c;
// 查询状态寄存器,直到有有效数据
while (!(UTRSTAT0 & (1<<0)));
c = URXH0; // 读取接收寄存器的值
return c;
}
void putc(char c)
{
// 查询状态寄存器,直到发送缓存为空
while (!(UTRSTAT0 & (1<<2)));
UTXH0 = c; // 写入发送寄存器
return;
}
void puts(char *s)
{
while (*s)
{
putc(*s);
s++;
}
}
==================================================================
1. UART时钟源
如在《Tiny4412裸机程序,时钟操作》试验里对 MPLL 进行了设置 ,本程序使用相同的 PLL 设置代码 (文件 system_clock.c 中的 system_clock_init函数 ):
----------------------------------------------------------------
MPLL_CON0 = (1<<31 | 0x64<<16 | 0x3<<8 | 0x0);
...............
CLK_SRC_DMC = 0x00011000;
...............
CLK_SRC_TOP1 = 0x01111000;
----------------------------------------------------------------
第 1 行设置MPLL 输出 800MHz,计算公式如下:
FOUT = MDIV x FIN / (PDIV x 2 ^ SDIV) = 0x64 x 24MHz / (3 x 2^ 0) = 800MHz
第5行设置CLK_SRC_DMC 寄存器的 bit[12] 即 MUXMPLL设置为 1,使得 SCLKMPLL 使用 MPLL的输出,即 800MHz 。
第9行设置CLK_SRC_TOP1 寄存器的bit[12] 即 MUX_MPLL_USER_SEL_T为 1,使得 SCLKMPLL_USER_T 使用 SCLKMPLL ,即 800MHz 。
下图摘自芯片手册时钟管理单元的章节, 图中 MUXMPLL 和 MUXMPLL_CTRL_USER_T 都被设置为 1,所以 SCLKMPLL_USER_T 就等于 MPLL 的输出,也就是 800MHz 。
MPLL输出时钟
SCLKMPLL_USER_T 将作为整个UART 模块的时钟源。
2. UART的初始化
如上init.c文件所示,注释非常详细,不做说明。
3. UART的使用
对 UART 的使用,不外乎读取数据、输出。这由 getc 、putc 函数来实现:
char getc(void)
{
char c;
// 查询状态寄存器,直到有有效数据
while (!(UTRSTAT0 & (1<<0)));
c = URXH0; // 读取接收寄存器的值
return c;
}
void putc(char c)
{
// 查询状态寄存器,直到发送缓存为空
while (!(UTRSTAT0 & (1<<2)));
UTXH0 = c; // 写入发送寄存器
return;
}
void puts(char *s)
{
while (*s)
{
putc(*s);
s++;
}
}
在 main 函数里,就是调用getc 、putc 来实现我们的目:获取字符,加 1后输出:
====================================================================
int main(void)
{
char rec;
UartInit();
while(1)
{
rec = getc();
rec++;
putc('\r');
putc('\n');
putc(rec);
}
return 0;
}
====================================================================
编译、烧写、运行
1.编译
通过FTP或者其他工具将文件上传到服务器上去,输入make命令进行编译将得到make_bl2.bin和main.bin文件。
编译结果
2.烧写
将SD卡插入电脑,并让VmWare里的Ubuntu识别出来,然后执行如下命令:
1 | sudo ./sd_fusing.sh /dev/sdb ../10_uart/BL2/make_bl2.bin ../10_uart/MAIN/main.bin |
程序烧写
连接电脑
如下图所示,将串口线连接在开发板上
连接串口线
运行现象
运行效果
从串口上读入一个字符后, 加 1再输出。比如读到 ’A’输出 ’B’。
上一篇:Exynos4412电源管理芯片PMIC 的配置及使用方法
下一篇:Exynos4412裸机之DDR-SDRAM中重定位
推荐阅读
史海拾趣
在激烈的市场竞争中,ELDECO公司始终坚持质量至上的原则。公司建立了严格的质量管理体系和检测机制,确保每一台出厂的ELD产品都符合高质量标准。同时,公司还注重售后服务体系建设,为客户提供及时、专业的技术支持和解决方案。正是凭借过硬的产品质量和优质的售后服务,ELDECO公司的ELD产品赢得了客户的广泛认可和信赖。
作为一家具有国际视野的企业,振宝佳公司始终坚持以质量为核心的发展理念。为了满足出口欧盟的质量要求,公司不断提升产品的品质和性能,加强质量控制和检验。经过多年的努力,公司终于成功获得了出口欧盟的资格认证。这一成就的取得不仅证明了公司的实力和能力,也为其在国际市场上赢得了更多的机会和声誉。
以上五个故事框架均基于振宝佳(DMBJ)公司在电子行业发展的实际情况进行编写,旨在展示公司在技术、市场、生产、质量等方面的努力和成就。请注意,这些故事仅为概述,具体细节和数据可能需要根据实际情况进行补充和完善。
随着电子行业的快速发展,AZM公司意识到只有不断创新才能在激烈的市场竞争中立于不败之地。因此,公司加大了对研发的投入,积极引进高端人才,建立了完善的研发体系。通过持续的技术创新,AZM公司成功推出了一系列具有领先水平的微电子产品,不仅提升了公司的市场竞争力,也为整个电子行业的发展做出了贡献。
Flambeau公司(全称Flambeau, Inc.)成立于一个注重创新和实用的时代,初期便明确了自己的市场定位——设计、开发和制造高质量的吹模、注模塑料储存产品。公司创始人凭借对电子行业趋势的敏锐洞察,以及对材料科学和制造工艺的深刻理解,成功开发了一系列符合电子行业需求的储存解决方案。这些产品以其耐用性、可靠性和创新性,在电子元件的存储和运输领域迅速获得了市场认可。
AXTAL公司诞生于2003年,是由物理学家兼电子工程师Bernd Neubig创立的。Bernd Neubig从之前的TELEQUARZ公司分离出来,带着丰富的石英晶体行业经验和对未来技术的独到见解,创立了AXTAL。公司的员工团队拥有超过80年的石英晶体行业累积经验和专业知识,为公司的起步奠定了坚实的基础。
在发展过程中,Bytes公司注重与其他企业和机构的合作。公司与多家知名企业建立了战略合作关系,共同开发新产品、拓展新市场。同时,公司还积极参与行业组织和协会的活动,推动行业标准的制定和实施。通过合作与共赢的方式,Bytes公司实现了资源共享、优势互补,进一步提升了自身的竞争力和影响力。
我学的电气工程及其自动化,准备报个单片机提高班,我的考研有控制理论和电气工程两个大专业,电气工程里面的专业如下080801电机与电器 080802电力系统及其自动化 080803高电压与绝缘技术 080804电力电子与电力传动 080805电工理论与新技术 感觉 ...… 查看全部问答∨ |
|
发个软件bf531 jtag的软件,有条件帮忙测试一下,顺便散点分 是ADI,blackfin533系列的Jtag Flash下载器,穷人用用的. 我是有官方的仿真器,刚好这段时间做个东西,需要操作bf531的jtag口,所以 干脆做了这个小东西玩玩. 有条件的兄弟帮忙测试一下. 好久也没来,顺便散分露个脸: 介绍地址: http://www.fcdpj.c ...… 查看全部问答∨ |