s3c2440串口裸板驱动(使用fifo)

发布者:Yuexiang最新更新时间:2024-08-21 来源: cnblogs关键字:s3c2440吗  串口  裸板驱动  fifo 手机看文章 扫描二维码
随时随地手机看文章

 1:串口的数据发送的数据量较大时,使用fifo可以大大降低MCU的开销。(有点类似串入并出的cput处理模型,本质上还是串行收发)

 2:在某些特殊场合,例如制定较复杂的协议时,可以使用fifo特性来做协议简化,比如一包

数据包含8个字节,(并且fifo设置的长度为8),这样相当于把uart转换为类似CAN/以太网模型,

这样信息可扩展性得到了质的提高,当然,这里需要同步协调。


fifo分析拓展:

           1. 如果要用中断来处理接收到的数据,就是说,接收完数据然后产生中断,再于中断里处理接收的数据。如果要实现这个本意,要设置好触发点。

          至于超时中断之类,那是另外一回事了。

           2. 就UART的中断类型而言,还包括:RBR中断使能、THRE中断使能、RX线状态中断使能、自动波特率超时中断使能等。

           3. FIFO定义说了,先入先出缓冲区,在UART中有什么用呢。我们可以用它来批量发送 数据(而非FIFO模式,只能一字节一字节的发,而且发每个字节都需要等待缓冲区变空才能发送下一字节),这样能在一定程度上提高数据发送速度。还有就是 避免数据包的的丢失(这个问题,目前还没体会)。


需要了解的相关知识:

HCLK主要为S3C2440 AHB总线(Advanced High performance Bus)上挂接硬件提供工作频率,AHB总线主要挂接有内存,NAND,LCD控制器等硬件

FCLK主要为ARM920T内核提供工作频率;

PCLK主要为APB总线提供工作频率,APB总线主要挂接UART串口,Watchdog等硬件控制器。【所以在这里我们用PCLK作为UART的时钟源】

外接设备

起始地址

结束地址

存储控制器

0x48000000

0x48000030

USB Host控制器

0x49000000

0x49000058

中断控制器

0x4A000000

0x4A00001C

DMA

0x4B000000

0x4B0000E0

时钟和电源管理

0x4C000000

0x4C000014

LCD控制器

0x4D000000

0x4D000060

NAND FLASH控制器

0x4E000000

0x4E000014

摄像头接口

0x4F000000

0x4F0000A0

UART

0x50000000

0x50008028

脉宽调制计时器

0x51000000

0x51000040

USB设备

0x52000140

0x5200026F

WATCHDOG计时器

0x53000000

0x53000008

IIC控制器

0x54000000

0x5400000C

IIS控制器

0x55000000

0x55000012

I/O端口

0x56000000

0x560000B0

实时时钟RTC

0x57000040

0x5700008B

A/D转换器

0x58000000

0x58000010

SPI

0x59000000

0x59000034

SD接口

0x5A000000

0x5A000040

AC97音频编码接口

0x5B000000

0x5B00001C


  

在start.s中完成对看门狗,内存等进行初始化:      

GPBCON     EQU      0x56000010
GPBDAT             EQU      0x56000014
  AREA Init,CODE,READONLY             //声明一个只读性质的代码段Init.
ENTRY                                 //入口
start
close watchdog
    ldr r0,=0x53000000;               //将看门狗控制寄存器地址放入r0
    mov r1,#0                       
    str r1,[r0];                      //将r1的值0放到r0中,即设置看门/
    狗控制寄存器的值为0
    bl initmem;                       //跳转到initmem代码段,初始化内存
    
    IMPORT main;                      //引入main.c中的main函数
    ldr sp,=0x34000000;               //调用c程序前先初始化桟指针
    ldr lr,=loop;                     //设置main函数的返回地址
    ldr pc,=main;                     //跳转到c程序的main函数的入口处执行
loop
    b loop      ;                     //死循环
initmen                               //内存初始化
    ldr r0,=0x48000000;               //加载内存相关寄存器首地址r0
    ldr r1,=0x48000034;               //加载内存相关寄存器尾地址到r1
    adr r2,memdata;                   //将寄存器配置数据地址段首地址加载到r2
 initmemloop
    ldr r3,[r2],#4;                   //循环设置存寄存器
    str r3,[r0],#4
    teq r0,r1
    bne initmemloop;                  //循环到最后一个寄存器时退出函数
    mov pc,lr
 memdata                              // 存放内存控制器设置数据
           DCD 0x22000000                 ;BWSCON

           DCD 0x00000700                 ;BANKCON0    

           DCD 0x00000700                 ;BANKCON1    

           DCD 0x00000700                 ;BANKCON2    

           DCD 0x00000700                 ;BANKCON3             

           DCD 0x00000700                 ;BANKCON4    

           DCD 0x00000700                 ;BANKCON5    

           DCD 0x00018005                 ;BANKCON6    

           DCD 0x00018005                 ;BANKCON7    

           DCD 0x008e07a3                 ;REFRESH        

           DCD 0x000000b1                 ;BANKSIZE      

           DCD 0x00000030                 ;MRSRB6

           DCD 0x00000030                 ;MRSRB7

           END

在uart.c中: 

#define GPHCON  (*(volitile unsigned long *)0X56000070)
#define GPHDAT  (*(volitile unsigned long *)0X56000074)
#define GPHUP   (*(volitile unsigned long *)0X56000078)
#define UFCON0  (*(volitile unsigned long *)0x50000008)
#define UMCON0  (*(volitile unsigned long *)0X5000000C)
#define UCON0   (*(volitile unsigned long *)0X50000004)
#define ULCON0  (*(volitile unsigned long *)0X50000000)
#define UART_CLK            PCKL               //UART0的时钟源为PCLK
#define UART_BAUD_DATE      115200             //波特率
#define UART_BRD           ((UART_CLK/(UART_BAUD_DATE*16))-1)
void uart_init(void)
{
                   
    UFCON0=0xbf;                               //使用fifo(发送fifo和接收fifo的触发深度都为32字节)【在中断模式下的fifo要设置触发方式(超时触发或字节触发)】
    UMCON0=0x00;                               //不使用流控
    UBRDIV0=UART_BRD;                          //波特率为115200
    GPHCON  |=0xa0;                            //GPH2,GPH3用作TXD0,RXD0
    GPHUP=0x0c;                                //GPH2,GPH3内部上拉
    UCON0=0X05                                 //时钟源为PCKL
    ULCON0 &=0X03;                             //正常模式,数据格式:8个数据位,没有流控,1个数据位
}
当发送缓冲区里有数据需要传送时,我们就需要中断,来完成发送数据的任务。这个中断的产生,是由 s3c24xx_serial_start_tx()函数来完成的,具体来说,是它所调用的一个是中断使能的函数 enable_irq(TX_IRQ(port))来完成的。而此中断一旦使能,就会调用该中断的服务函数 s3c24xx_serial_tx_chars()去做后续的工作。

[1] [2]
关键字:s3c2440吗  串口  裸板驱动  fifo 引用地址:s3c2440串口裸板驱动(使用fifo)

上一篇:S3C2440 IIS操作 uda134x录放音
下一篇:ARM Linux字符设备驱动程序

推荐阅读最新更新时间:2026-03-25 13:05

S5PV210驱动:启动
以往2440和6410的启动方式,只要我们把裸板代码烧写到NAND FLASH的开始位置,当开发板上点启动时,处理器会自动从NAND FLASH上拷贝前面一段的代码到内部的RAM中执行。按照以前的方法,我写了一段汇编代码,如下: 1_ARM/1_start/start.S 1 #define WTCON 0xE2700000 2 3 .text 4 .align 2 5 .global _start 6 7 _start: 8 //close the watchdog 9 ldr r1, =WTCON 10 mov r0, #0 11 str r0, 12 13 loop: 14 b loop 代码没做什么具体的操作,大
[单片机]
S5PV210<font color='red'>裸</font><font color='red'>板</font><font color='red'>驱动</font>:启动
如何使用带FIFO串口来减少接收中断次数
本文介绍如何使用带FIFO的串口来减少接收中断次数,通过一种自定义通讯协议格式,给出帧打包方法;之后介绍一种特殊的串口数据发送方法,可在避免使用串口发送中断的情况下,提高系统的响应速度。 1、概述 在此之前,先来列举一下传统串口数据收发的不足之处: 每接收一个字节数据,产生一次接收中断。不能有效的利用串口硬件FIFO,减少中断次数。 应答数据采用等待发送的方法。由于串行数据传输的时间远远跟不上CPU的处理时间,等待串口发送完当前字节再发送下一字节会造成CPU资源浪费,不利于系统整体响应(在1200bps下,发送一字节大约需要10ms,如果一次发送几十个字节数据,CPU会长时间处于等待状态)。 应答数据采用中断发送。增加
[单片机]
如何使用带<font color='red'>FIFO</font>的<font color='red'>串口</font>来减少接收中断次数
min2440 uart中断模式(非fifo模式)
Makefile uart_interrupt.bin : start.s function.c arm-linux-gcc -g -c -o start.o start.s arm-linux-gcc -g -c -o function.o function.c arm-linux-ld -Ttext 0x30000000 -g start.o function.o -o uart_interrupt.elf arm-linux-objcopy -O binary -S uart_interrupt.elf uart_interrupt.bin arm-linux-objdump -D -m a
[单片机]
对UART的FIFO的理解
FIFO的必要性。在进行UART通信时,中断方式比轮询方式要简便且效率高。但是,如果没有收发FIFO,则每传输一个数据(5~8位)都要中断处理一次,效率仍然不高。如果有了收发FIFO,则可以在连续收发若干个数据(可多至14个)后才产生一次中断,然后一起处理。这就大大提高了收发效率。   接收超时问题。如果没有接收超时功能,则在对方已经发送完毕而接收FIFO未填满时并不会触发中断(FIFO满才会触发中断),结果造成最后接收的有效数据得不到处理的问题。有了接收超时功能后,如果接收FIFO未填满而对方发送已经停,则在不超过3个数据的接收时间内就会触发超时中断,因此数据会照常得到处理。   发送时,只要发送FIFO不满
[单片机]
51单片机的FIFO(先入先出)循环队列实现
////////////////////////////////////////////////////////// // 文件:config.h ////////////////////////////////////////////////////////// #ifndef __CONFIG_H #define __CONFIG_H //这一段无需改动 //This segment should not be modified #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif typedef unsigned char
[单片机]
labview的软件计数器和FIFO BUFFER
PLC编程中有大量的定时器和计数器可用,做工业自动化控制的朋友在LABVIEW编程时经常因为找不到类似熟悉的功能而烦恼,其实LABVIEW本身提供的逻辑功能非常强大,远远超过PLC. 看看加计数器的说明: 它有两个控制端 initialize--是计数器复位端,相当于PLC计数器的reset activate----计数控制端,当ACTIVATE=TRUE时,每调用一次,计数器内部计数加1. 两个输出端: Counter---输出计数器当前计数,U32数据类型,最大计数范围0XFFFFFFFF Overflow---溢出,当超过计数器最大计数,为真,计数器自动复位,重新从1开始计数. 应用举例:
[测试测量]
labview的软件计数器和<font color='red'>FIFO</font> BUFFER
FIFO程序设计解析(队列指针)
typedef struct { QUEUE_DATA_TYPE *Out; QUEUE_DATA_TYPE *In; QUEUE_DATA_TYPE *End; u16 NData; u16 MaxData; u8 (* ReadEmpty)(); u8 (* WriteFull)(); QUEUE_DATA
[单片机]
MAX1220多通道ADC/DAC,带有FIFO、温度传感器和GPIO端口
 MAX1220/MAX1257/MAX1258将一个12位、多路模数转换器(ADC)和一个12位、八路数模转换器(DAC)集成在单片IC上。这些器件还包含了温度传感器、可配置的通用I/O端口(GPIO)和一个25MHz的SPI™/QSPI™/MICROWIRE™兼容串行接口。该系列ADC具有8和16输入通道的产品。八路DAC输出在2.0µs内稳定,ADC转换速率为225ksps。   所有器件中都包括了为ADC和DAC提供的内部基准(2.5V或4.096V)。可编程的基准模式允许选择内部基准、外部基准或两者的组合。内部包括:±1°C的精密温度传感器、FIFO、扫描模式、可编程内部或外部时钟模式、数据平均与AutoShutdow
[模拟电子]
MAX1220多通道ADC/DAC,带有<font color='red'>FIFO</font>、温度传感器和GPIO端口
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved