第4课: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。
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:
ldrr0, =0x53000000 @ WATCHDOG close
movr1, #0x0
strr1, [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_
UART串口编 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)