Tiny4412之串口(Uart)驱动编写

一:tiny4412串口驱动编写

  1、串口通信简介

  串口通信指串口按位(bit)发送和接收字节,串口通信的概念非常简单,串口按位(bit)发送和接收字节。尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线 接收数据。它很简单并且能够实现远距离通信。比如IEEE488定义并行通行状态时,规定设备线总长不得超过20米,并且任意两个设备间的长度不得超过2 米;而对于串口而言,长度可达1200米。

  串口通信所采用的通信协议为RS-232,RS-232通信方式允许简单连接三线:Tx、Rx和地线。但是对于数据传输,双方必须对数据定时采用使用相同的波特率。RS-232(ANSI/EIA-232标准)是IBM-PC及其兼容机上的串行连接标准。可用于许多用途,比如连接鼠标、打印机或者Modem,同时也 可以接工业仪器仪表。用于驱动和连线的改进,实际应用中RS-232的传输长度或者速度常常超过标准的值。RS-232只限于PC串口和设备间点对点的通信。

  2、串口的通信基本模型如下图所示:

TXD:发送数据

RXD:接收数据

GND:地线

串口驱动跟其他外设的驱动配置流程差不多,大概分为如下几步:

(1)查看电路图,配置相应的gpio功能引脚

(2)配置串口控制器的相应寄存器

(3)测试串口接收、发送

今天用的是第一个串口com0,下面是电路图:

找到相应的gpio功能引脚

下面是串口工作的整个模式图:

下面是串口控制器相应的寄存器:

今天我们实验用到的几个主要的寄存器是:

ULCON0:数据格式控制寄存器(配置数据位,停止位,校验位等);

UCON0:串口控制开关

UTXH0:发送数据

URXH0:接收数据

UTRSTAT0:数据收发状态寄存器

UBRDIV0,UFRACVAL0:配置波特率的

下面是uart所需要的工作得时钟频率,以及比特率计算公式:

经过计算uart所采用的SCLK_UART为100M

UBRDIV0=(100000000)/(115200 x16) - 1 = 53.3=53=0x35;

UFRACVAL0= 4;

下面具体测试代码:

 1 #ifndef __REGS_H
 2 #define __REGS_H
 3
 4 #define gpa0base  0x11400000
 5 #define GPA0CON      (*(volatile unsigned long *)(gpa0base + 0x0000))
 6
 7 #define uart0base  0x13800000
 8 #define ULCON0    (*(volatile unsigned long *)(uart0base + 0x0000))
 9 #define UCON0     (*(volatile unsigned long *)(uart0base + 0x0004))
10 #define UFCON0    (*(volatile unsigned long *)(uart0base + 0x0008))
11 #define UMCON0    (*(volatile unsigned long *)(uart0base + 0x000C))
12 #define UTRSTAT0  (*(volatile unsigned long *)(uart0base + 0x0010))
13 #define UERSTAT0  (*(volatile unsigned long *)(uart0base + 0x0014))
14 #define UFSTAT0   (*(volatile unsigned long *)(uart0base + 0x0018))
15 #define UMSTAT0   (*(volatile unsigned long *)(uart0base + 0x001C))
16 #define UTXH0     (*(volatile unsigned char *)(uart0base + 0x0020))
17 #define URXH0     (*(volatile unsigned char *)(uart0base + 0x0024))
18 #define UBRDIV0   (*(volatile unsigned long *)(uart0base + 0x0028))
19 #define UFRACVAL0 (*(volatile unsigned long *)(uart0base + 0x002C))
20 #define UINTP0    (*(volatile unsigned long *)(uart0base + 0x0030))
21 #define UINTSP0   (*(volatile unsigned long *)(uart0base + 0x0034))
22 #define UINTM0    (*(volatile unsigned long *)(uart0base + 0x0038))
23
24 #define uart3base  0x13830000
25 #define ULCON3    (*(volatile unsigned long *)(uart3base + 0x0000))
26 #define UCON3     (*(volatile unsigned long *)(uart3base + 0x0004))
27 #define UFCON3    (*(volatile unsigned long *)(uart3base + 0x0008))
28 #define UMCON3    (*(volatile unsigned long *)(uart3base + 0x000C))
29 #define UTRSTAT3  (*(volatile unsigned long *)(uart3base + 0x0010))
30 #define UERSTAT3  (*(volatile unsigned long *)(uart3base + 0x0014))
31 #define UFSTAT3   (*(volatile unsigned long *)(uart3base + 0x0018))
32 #define UMSTAT3   (*(volatile unsigned long *)(uart3base + 0x001C))
33 #define UTXH3     (*(volatile unsigned char *)(uart3base + 0x0020))
34 #define URXH3     (*(volatile unsigned char *)(uart3base + 0x0024))
35 #define UBRDIV3   (*(volatile unsigned long *)(uart3base + 0x0028))
36 #define UFRACVAL3 (*(volatile unsigned long *)(uart3base + 0x002C))
37 #define UINTP3    (*(volatile unsigned long *)(uart3base + 0x0030))
38 #define UINTSP3   (*(volatile unsigned long *)(uart3base + 0x0034))
39 #define UINTM3    (*(volatile unsigned long *)(uart3base + 0x0038))
40
41 #endif //__REGS_H
 1 #ifndef __UART_H
 2 #define __UART_H
 3
 4 void uart_init();
 5 void set_gpio();
 6 void show_serial();
 7 void myputc(unsigned char c);
 8 unsigned char mygetc(void);
 9 void myputs(unsigned char *str);
10 void mygets(unsigned char *str);
11
12 #endif //__UART_H
 1 #include "regs.h"
 2 #include "uart.h"
 3
 4 int main()
 5 {
 6     set_gpio();
 7     uart_init();
 8     show_serial();
 9     return 0;
10 }
11
12 void show_serial()
13 {
14     /*循环进行数据收发*/
15     unsigned char cmd[512];
16     while(1) {
17         myputs("[[email protected]]#");
18         mygets(cmd);
19         myputs(cmd);
20         myputs("\n");
21     }
22
23 }
24
25 void myputc(unsigned char c)
26 {
27     while(!(UTRSTAT0 & (1 << 1)));//等待buffer为空,再发送字符
28     UTXH0 = c;
29 }
30 unsigned char mygetc(void)
31 {
32     unsigned char ch;
33     while(!(UTRSTAT0 & 1));//等待buffer不为空
34     ch = URXH0;
35
36     return ch;
37 }
38
39 void myputs(unsigned char *str)
40 {
41     while(*str) {
42         myputc(*str);
43         if(*str == ‘\n‘)
44             myputc(‘\r‘);
45         str++;
46     }
47 }
48
49 void mygets(unsigned char *str)
50 {
51     unsigned char ch;
52     while(1) {
53         ch = mygetc();//获取字符
54         myputc(ch);
55         if(ch == ‘\r‘) {
56             myputc(‘\n‘);
57             break;
58         }
59         *str = ch;
60         str++;
61     }
62     *str = 0;
63 }
64
65 void set_gpio()
66 {
67      /*0x2 = UART_0_RXD
68        *0x2 = UART_0_TXD*/
69     GPA0CON &= ~0xff;
70     GPA0CON |= 0x22;
71 }
72
73 void uart_init()
74 {
75     /*step 1:数据格式控制*/
76     ULCON0 = 3; /*8bit data 1bit stop no parity*/
77     /*step 2: uart 开关*/
78     UCON0 = 1 | (1 << 2);
79     /*step 3: set Baud-rate*/
80     UBRDIV0 = 0x35;
81     UFRACVAL0 = 0x4;
82     /*step 4: 数据收发缓存*/
83     //UTXH0
84     //URXH0
85     /*step 5:数据收发状态寄存器*/
86     //UTRSTAT0
87 }
时间: 2024-11-03 01:27:09

Tiny4412之串口(Uart)驱动编写的相关文章

第三十三天:Tiny4412驱动开发之LED驱动和按键驱动编写

从今天开始进入驱动开发的课程的学习,共完成四件事情.一:u-boot的简单移植,二:uboot中编写helloword程序 三:开发板中led灯的驱动编写,包括led点亮,闪烁,跑马,流水.四:开发板中按键的驱动编写,按下按键后在屏幕中显示字符. 一:u-boot的简单移植 1.进入开发板提供的源码文件包,解压uboot源码包. cd /home/bunfly/source_code/ tar xf uboot_tiny4412-20130729.tgz 2.进入uboot文件夹,更改uboot

ARM-Linux S5PV210 UART驱动(转)

ARM-Linux S5PV210 UART驱动(3)----串口核心层.关键结构体.接口关系 尽管一个特定的UART设备驱动完全可以按照tty驱动的设计方法来设计,即定义tty_driver并实现tty_operations其中的成员函数,但是Linux已经在文件serial_core.c中实现了UART设备的通用tty驱动层,称为串口核心层,这样,UART驱动的主要任务变成了实现serial_core.c中定义的一组uart_xxx接口而非tty_xxx接口. uart设备是继tty_dri

第011课_串口(UART)的使用

from: 第011课_串口(UART)的使用 第001节_辅线1_硬件知识_UART硬件介绍 1. 串口的硬件介绍 UART的全称是 Universal Asynchronous Receiver and Transmiter ,即异步发送和接收. 串口在嵌入式中用途非常广泛,主要的用途有: 1. 打印调试信息: 2. 外接各种模块:GPS.蓝牙等: 串口因为结构简单.稳定可靠,广受欢迎.通过三根线即可,发送.接收.地线. 通过TxD -> RxD 把ARM开发板要发送的信息发送给PC机.通过

linux最简单的驱动编写及测试流程

本文采用nfs挂载网络文件系统的方式,手动创建设备节点, 动态加载驱动模块,对理解驱动编写流程有很大好处! 一.初级驱动执行流程: 1.写好Makefile文件,里面包含将应用程序编译成app文件,将驱动程序编译成mydrv.ko文件的脚本 2.在ubuntu里执行sudo make 3.确保mydrv.ko和app被拷贝到nfs挂载的根文件系统的/modules目录 4.在模块中创建设备节点(在串口软件显示的开发板文件系统里执行) mknod /dev/dcx-drv c 250 0 4.1.

UART驱动分析

在linux用户层上要操作底层串口需要对/dev/ttySxxx操作,这里的ttySx指实际的终端串口. 以下以全志A64为实例,分析UART驱动以及浅谈TTY架构. linux-3.10/drivers/tty/serial/sunxi-uart.c: 1 static const struct of_device_id sunxi_uart_match[] = { 2 { .compatible = "allwinner,sun8i-uart", }, 3 { .compatibl

[arm驱动]input system 子系统的驱动编写

更多可参考 Linux输入子系统分析 input 子系统架构总结 1.定义一个static struct input_dev结构体 static struct input_dev *mybutton_dev; 2.初始化时分配input_dev结构体 mybutton_dev = input_allocate_device();//分配 input_dev /*能产生的事件类型 1. #define EV_SYN 0x00 /*表示设备支持所有的事件*/ 2. #define EV_KEY 0x

SPI驱动编写要点

题外话:面对成功和失败,一个人有没有“冠军之心”,直接影响他的表现. 几周前剖析了Linux SPI 驱动框架,算是明白个所以然,对于这么一个庞大的框架,并不是每一行代码都要自己去敲,因为前人已经把这个框架搭建好了,作为驱动开发者的我们只需要搞清楚哪一部分是需要自己修改或重新编写就OK了. 结合Linux内核面向对象的设计思想,SPI总的设计思路大概是这样的: 第①处:内核中抽象了SPI控制器,让spi_master成为他的象征,他的实例化对象就是与硬生生的SPI控制器对应的,在Linux内核中

AM335x(TQ335x)学习笔记——触摸屏驱动编写

前面几篇文章已经通过配置DTS的方式完成了多个驱动的移植,接下来我们解决TQ335x的触摸驱动问题.由于种种原因,TQ335x的触摸屏驱动是以模块方式提供的,且Linux官方内核中也没有带该触摸屏的驱动源码,单纯的配置DTS是无法完成TQ335x的触摸驱动移植工作的,因此,本文参考内核中原有的pixcir_i2c_ts驱动编写TQ335x的触摸屏(TN92)驱动. 在之前移植TQ210时,我已经编写过TQ210的触摸屏驱动,我的TQ335x还是使用的TQ210的屏,因此,难度不是很大.这里需要说

Linux I2C驱动编写要点

继续上一篇博文没讲完的内容“针对 RepStart 型i2c设备的驱动模型”,其中涉及的内容有:i2c_client 的注册.i2c_driver 的注册.驱动程序的编写. 一.i2c 设备的注册分析:在新版本内核的i2c驱动模型中,支持多种方式来注册 i2c 设备,在Documentation/i2c/instantiating-devices文件中有讲到,在内核中对应的抽象数据结构就是 struct i2c_client. (1)Declare the I2C devices by bus