第4课:UART串口编程

发布者:创意火花最新更新时间:2016-08-06 来源: eefocus关键字:UART  串口编程 手机看文章 扫描二维码
随时随地手机看文章
首先明确一点:我们学习的串口是异步串口。在传输时,他们各自有各自的时钟。就是我们说的波特率。

我们学习的RS232与UART的区别是,UART使用标准的TTL/COMS电平 进过一个芯片使它的高低电平从TTL中0与3.3V 变成了 低电平5v到15v

高电平-3v到-12v。

首先说一下串口的数据帧格式。它由一个开始位,数据位,校验位和停止位组成。

平时数据处于1状态。

当要开始发送时,从UART改变TxD数据变成0状态1个位的时间,在接受端到0之后的1.5位的时间,接收端开始接受数据。

数据位分为5,6,7,8。四种类型的数据位。之后就是校验位站1位,可以设置也可以不设置。最后的是停止位。可以是1位,1.5位,2位。这个是高电平1。

第4课:UART串口编程 - zcwell@126 - 《ARM嵌入式系统开发-软件设计与优化》

 

UART可以用中断或DMA来工作。它有3个单独的通道。它由4部分组成,发送器,接收器,波特率发生器,控制逻辑组成。

这些部分的设置都是通过寄存器来实现的。

发送的过程是这样的,UART只能通过shifter一位一位的来发数据。它先把要发的数据放到它的缓存FIFO里,当然缓存也可以取消。然后放入shifter里面来发出去。接受也是一样的。通过缓存来接受,然后再通过接受的shifter来接。

具体继电器的设置主要由以下几个:

ULCON  逻辑数据桢格式控制器

UCON  串口的控制继电器

UFCON FIFO控制寄存器

UMCON 串口MODEN控制器 (可以控制AFC 自动流控制)

以下是状态寄存器,用来确定状态的,比如说shifter发送器的状态,接收器的状态。

UTRSTAT 接受发送控制器

UERSTAT 错误状态寄存器

UFSTAT FIFO状态寄存器

最后一个单独的设置寄存器,它用来设置波特率

UBRDIV  波特率发生器

 

以下来写个简单的串口例子。

它不使用FIFO 中断 而直接用shifter收发,采用轮询的方式来检测数据是否发送或被接受。然后通过minicom向开发板发送1表示亮灯,发送2表示熄灯。

文件总共是7个 一个crt0.s main.c addr.h uart.h uart.c uart.lds makefile

crt0.s 是关闭watchdog 并跳转到mian 之后用个deadloop。

.text
.globl _start
_start:
 ldr r0, =0x53000000     @ WATCHDOG close
 mov r1, #0x0
 str r1, [r0]           
 ldr     sp, =1024*4         @set stack,but the capitcy of cache is only 4k

        bl      main      
halt_loop:
            b       halt_loop

第2个是addr.h用来写寄存器的宏定义。

#ifndef ADDR_H
#define ADDR_H
#define GPECON (*(volatile unsigned int *)0x56000040)
#define GPEDAT (*(volatile unsigned int *)0x56000044)

#define GPE12_out (1<<(12*2))
#define GPE13_out (1<<(13*2))

#define GPHCON (*(volatile unsigned int *)0x56000070)
#define GPHUP (*(volatile unsigned int *)0x56000074)
#define ULCON0 (*(volatile unsigned int *)0x50000000)
#define UCON0 (*(volatile unsigned int *)0x50000004)
#define UFCON0 (*(volatile unsigned int *)0x50000008)
#define UMCON0 (*(volatile unsigned int *)0x5000000C)
#define UTRSTAT0 (*(volatile unsigned int *)0x50000010)
#define UFSTAT0 (*(volatile unsigned int *)0x50000018)
#define UTXH0 (*(volatile unsigned int *)0x50000020)
#define URXH0 (*(volatile unsigned int *)0x50000024)
#define UBRDIV0 (*(volatile unsigned int *)0x50000028)

#endif

第3个文件来写uart.h,这是个我们的功能

#ifndef UART_H
#define UART_H
void uart_init();                         //初始化继电器

void uart_write(char *a);           //串口写一行

void uart_read(char *a,int n);   //串口读n个字

void uart_read_line(char *a);   //读一行

void led_on();                          //开灯

void led_off();                          //关灯
#endif

第4个文件具体来写uart.C

#include"uart.h"
#include"addr.h"
#define UART_CLK 50000000                                                                        //我们用的是PCLK 50MHz
#define UART_BAUD_RATE 115200                                                              //比特率是115200
#define UART_BRD (int)(UART_CLK/(UART_BAUD_RATE *16))-1                //计算公式的宏
void uart_init()
{
 GPHCON |=0xa0;                                                                                            //这个是TXD0与RXD0的设置,他们用的是GPH2和3复用的特殊
 GPHUP = 0x0c;                                                                                               //功能,所以还要在这设置上拉电阻,以区别高低电平的。
 ULCON0 = 0x3;                                                                                               //桢格式的设置8个数据位,无校验
 UCON0 = 0x5;                                                                                                 //选择的是中断与轮询模式
 UFCON0 = 0;                                                                                                  //不设FIFO
 UMCON0 = 0;                                                                                                 //不设AFC
 UBRDIV0 = UART_BRD;                                                                                 //设置波特率
}

void uart_write(char *a)
{
 do{
   while(!(UTRSTAT0&2));                                                                            //UTRSTAT0的第2位是1的话表示发送数据的shifter内的数据已经被发送了,现在数据为空。如果里面的数据没有空的话!(U&2)会一直是1,造成一直循环,知道出现UTRSTAT0第2位为1的情况。

 UTXH0 = *(a++);                                                                                         //发送寄存器只能一次最多发8位
}
 while(*a!='\0');
}

void uart_read(char *a,int n)
{
 do{

  while(!(UTRSTAT0&1));                                                                            //第1位为1表示shifter内的数据已经有了,可以读了,如果为0的话将一直循环,知道有数据可读。
  *(a++) = (char)URXH0;
  n--;
 }
 while(n>0);
}

void uart_read_line(char *a)
{
 do{

  while(!(UTRSTAT0&1));
  *(a++) = URXH0;
 }
 while(*a!='\0');
}

void led_on()
{
        GPEDAT = 0;
}

void led_off()
{
 GPEDAT = (3<<12);
}

第5个文件main.c文件

#include"addr.h"
#include"uart.h"

int main()
{
 char *t = "Welcome to bootloader...\r\n";             //这里只能用指针来传递,指针指向常量字符串的首地址传入。  
 char *t1 = "press 1 to light loop on\r\n";
 char *t2 ="press 2 to light loop off\r\n";
 char *t3 ="please input your choice\r\n";
 char r[10] ;                                                         //这里指针务必用数组来分配,一个没有malloc函数。
 GPECON = GPE12_out|GPE13_out;
 
 uart_init();
 uart_write(t);
 uart_write(t1);
 uart_write(t2);
 uart_write(t3);
 while(1){
  uart_read(r,1);
  UTXH0 = *r;                                                        //这里是为了回显 
  switch(*r){
   case '1':led_on();break;
   case '2':led_off();break;
  }
 }
 return 0;
}

 

第6个连接文件

SECTIONS {
 . = 0x00;
   .text          :   { *(.text) }
 .rodata ALIGN(4) : {*(.rodata)} 
   .data ALIGN(4) : { *(.data) }
   .bss ALIGN(4)  : { *(.bss)  *(COMMON) }
}
最后介绍下makefile比较好的写法。

SRC := $(wildcard *.c)                                                      //设定直接变量SRC,$(wildcard )表示使用通配符
OBJC := $(patsubst %.c,%.o,$(SRC))                              //表示把SRC里的值是.c结尾的换成.o结尾的结果保存到OBJC中

uart.bin:uart.elf
 arm-linux-objcopy -O binary -S $^ $@                            //表示 $@目标文件 $^所有依赖
 arm-linux-objdump -D -m arm $^ > uart.dis
uart.elf:crt0.o $(OBJC)
 arm-linux-ld -T uart.lds $^ -o $@                                   
%.o:%.c                                                                           //任意.o的依赖为.c 
 arm-linux-gcc  -c $^ -o $@
%.o:%.s    
 arm-linux-gcc  -c $^ -o $@

clean:
 rm -f uart.bin uart.dis uart.elf uart.o crt0.o main.o

然后用jtag烧入0x0内部SRAM的4k容量内,并在minicom里输入数据来控制led

关键字:UART  串口编程 引用地址:第4课:UART串口编程

上一篇:第3课: 点亮开发板led灯
下一篇:第5课:ARM的中断

推荐阅读最新更新时间:2024-03-16 15:03

s3c2440的UART用法
SPI、IIC和UART是最常用的三种串行总线,这三种总线在s3c2440中都被集成了。在这里我们主要介绍UART,另两个总线在后面的文章中给出。 UART(Universal Asynchronous Receiver/Transmitter,通用异步接收/发送装置)用于异步通信,可以实现全双工发送和接收。它不仅可以实现不同嵌入式系统之间的通信,还可以实现与PC之间的通信。 s3c2440提供了三个UART端口,它们都可以通过查询、中断和DMA方式传输数据,而且每个UART都分别有一个64个字节的接收FIFO和一个64个字节的发送FIFO。在这里,我们只给出非FIFO模式,即传输数据不利用FIFO缓存,一
[单片机]
51单片机的调试经验分享
简介:一个全双工UART(通用异步接收发送器)的串行I/O口,用于实现单片机之间或单片机与微机之间的串行通信; 片内振荡器和时钟产生电路,石英晶体和微调电容需要外接。最高振荡频率取决于单片机型号及性能。 一.单片机的组成: CPU:由运算和控制逻辑组成,同时还包括中断系统和部分外部特殊功能寄存器; RAM:用以存放可以读写的数据,如运算的中间结果、最终结果以及欲显示的数据; ROM:用以存放程序、一些原始数据和表格; I/O口:四个8位并行I/O口,既可用作输入,也可用作输出; T/C:两个定时/记数器,既可以工作在定时模式,也可以工作在记数模式; 五个中断源的中断控制系统; 一个全双工UART(通
[单片机]
单片机UART串口通信(代码亲自调试成功)
1.实现代码 代码如下(示例): #include reg52.h #include stdio.h //printf头文件 #define uc unsigned char #define uint unsigned int uc flag,i,flag_t,s = ,j=0,flag_n=0; uc code table = 单片机接收了: ; void init() { TMOD=0x20; //定时器工作方式,选择了定时器1,工作方式2 八位初值自动重装的8位定时器。 TH1=0xf3; //定时器1初值 ,设置波特率为2400 晶振11.955Mhz
[单片机]
单片机<font color='red'>UART</font>串口通信(代码亲自调试成功)
51单片机 UART串口通信
使用半双工通信 /************************************ 使用硬件UART模块和串口中断 ************************************/ #include reg52.h typedef unsigned int uint; void configUART(uint baud); void main() { EA = 1; configUART(9600); while (1) ; } void configUART(uint baud) { SCON = 0x50;
[单片机]
STM32 --UART串口通信
UART串口时序 UART串口协议参考下面文章: http://blog.csdn.net/gogomusic/article/details/54767502 UART串口配置 1)串口时钟使能。串口作为 STM32 的一个外设,其时钟由外设时钟使能寄存器控制,这里我们使用的串口1是APB2ENR寄存器的第14位。(除了串口 1 的时钟使能在 APB2ENR 寄存器,其他串口的时钟使能位都在 APB1ENR 寄存器,而 APB2(72M)的频率一般是 APB1(36M)的一倍。) 2)串口复位。当外设出现异常的时候可以通过复位寄存器里面的对应位设置,实现该外设的复位,然后重新配置这个外设达到让其重新工作的目
[单片机]
STM32 --<font color='red'>UART</font>串口通信
第011课 Jz2400串口(UART)的使用
第001节硬件知识_UART硬件介绍 1.串口的硬件介绍 UART的全称是Universal Asynchronous Receiver and Transmitter,即异步发送和接收。 串口在嵌入式中用途非常的广泛,主要的用途有: 打印调试信息; 外接各种模块:GPS、蓝牙; 串口因为结构简单、稳定可靠,广受欢迎。 通过三根线即可,发送、接收、地线。 通过TxD- RxD把ARM开发板要发送的信息发送给PC机。 通过RxD- TxD线把PC机要发送的信息发送给ARM开发板。 最下面的地线统一参考地。 2.串口的参数 波特率:一般选波特率都会有9600,19200,115200等选项。其实意思就是每
[单片机]
第011课 Jz2400串口(<font color='red'>UART</font>)的使用
S3C2440 UART串口驱动
1.1 UART串口 通用异步接收器和发送器(Universal Asynchronous Receiver and Transmitter) 简称UART。通常是嵌入式设备中默认都会配置的通信接口。这是因为,很多嵌入式设备没有显示屏,无法获得嵌入式设备实时数据信息,通过UART串口和超级终端相连,打印嵌入式设备输出信息。并且在对嵌入式系统进行跟踪和调试时,UART串口了是必要的通信手段。比如:网络路由器,交换机等都要通过串口来进行配置。UART串口还是许多硬件数据输出的主要接口,如GPS接收器就是通过UART串口输出GPS接收数据的。 1.1.1 异步通信和同步通信 图2-56同步信号与异步信号 同步通信技术 在发送
[单片机]
S3C2440 <font color='red'>UART</font>串口驱动
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved