S3C2440串口驱动程序设计

串口作用:数据传输、充当控制台

串口通讯,分为同步通讯和异步通讯,我们通常使用的都是异步串口。通讯时,双方先约定好数据帧的格式,即波特率,数据位,停止位,奇偶校验位等。

波特率:这是一个衡量通信速度的参数。它表示每秒钟传送的bit的个数。常用的波特率有38400,115200。
起始位:当线路空闲时候,电平为高。一旦检测到一个下降沿,则视为一个起始位。然后接收方按照约定好的格式,接收这一帧数据。
数据位:一帧中实际有效数据的位数。
停止位:表示这帧数据的结束。
校验位:用于检测数据传输是否正确的位。

串口硬件连接
我们通常使用的RS232的9帧串口,其中最为重要的是2,3,5脚
2:RXD:接收数据
3:TXD:发送数据
5:GND:接地

S3C2440提供了三个独立的串口端口,它们都可以通过查询、中断、DMA方式传输数据


驱动程序设计

串口驱动程序设计:串口初始化、数据发送、数据接收
串口初始化步骤:
1.配置gpio引脚功能
2.1 设置数据模式
2.2 设置工作模式
3.设置波特率
其中设置gpio引脚功能、设置数据模式、设置工作模式可通过设置相应的寄存器的相应位来完成。
与设置波特率有关的寄存器为UBRDIVn,该寄存器的值应为:

这里写图片描述

使用的时钟为PCLK,波特率一般取115200
ps:2440设置波特率时,只考虑(UART clock/(buad rate*16))-1的整数部分,而S3C6410,S5pv210不仅考虑整数部分,还考虑小数部分。如210与设置波特率有关的寄存器有UBRDIVn,UDIVSLOTn两个。UBRDIVn存放整数部分,UDIVSLOTn存放与小数部分有关的数值。


数据发送

对于程序员来说,发送数据只需要将数据写入buffer register,硬件会自动将数据一位位地发送出去。但如果在写入buffer register前,该寄存器并不是空的,则意味着前一数据还在发送中,我们需要等待该数据发送完毕再开始新的发送。判断buffer register是否有数据可通过UTRSTATn寄存器得知

这里写图片描述

UTRSTATn[0]可用于判断是否有接收到数据,当该位为1时表明接收buffer寄存器有有效数据(数据手册上只说该位会自动置1,并没有说读取该数据后自动清零,但根据程序的功能可推断出该位会在数据被读取后自动清零,UTRSTATn[1],UTRSTATn[2]同理)。
发送数据的buffer register为UTXHn

这里写图片描述

数据接收

串口接收到的数据存放在URXHn里

这里写图片描述

最后还要强调几点关于非FIFO模式下UART中断的一些注意事项:

  1. 对于s3c2440来说,接收数据是被动的,发送数据是主动的,因此一般来说,接收数据用中断方式,发送数据用查询方式较好;
  2. 在中断方式下,当接收到数据时,尽管可能该数据无用,但也一定要读取它,否则下次再接收数据时,不会再引起中断,因为接收数据缓存器被上次接收到的数据所霸占,只要没有读取它,它就永远在那里;
  3. 由于UART中断涉及到SUBSRCPND寄存器,因此在中断处理程序中不仅要清SRCPND寄存器,还要清SUBSRCPND寄存器,它们的顺序一定是先清SUBSRCPND寄存器,再清SRCPND寄存器,否则就会引起一个中断两次响应的问题。因为是否中断由SRCPND寄存器决定,而SRCPND寄存器的相关状态位由SUBSRCPND寄存器决定,如果先清SRCPND寄存器,而还没有清SUBSRCPND寄存器的话,SRCPND寄存器的相关位还是会被置1,而一旦被置1,则一定还会引起中断。

代码:

#define GPHCON (*(volatile unsigned long*)0x56000070)
#define ULCON0 (*(volatile unsigned long*)0x50000000)
#define UCON0  (*(volatile unsigned long*)0x50000004)
#define UBRDIV0  (*(volatile unsigned long*)0x50000028)
#define UTRSTAT0 (*(volatile unsigned long*)0x50000010)
#define UTXH0 (*(volatile unsigned long*)0x50000020)
#define URXH0 (*(volatile unsigned long*)0x50000024)

#define PCLK 50000000
#define BAUD 115200

void uart_init()
{
    //1.配置引脚功能
    GPHCON &= ~(0xf<<4);
    GPHCON |= (0xa<<4);

    //2.1 设置数据格式
    ULCON0 = 0b11;

    //2.2 设置工作模式
    UCON0 = 0b0101; 

    //3. 设置波特率  
    UBRDIV0 =(int)(PCLK/(BAUD*16)-1);
}

void putc(unsigned char ch)
{
    while (!(UTRSTAT0 & (1<<2)));
    UTXH0 = ch;  
}

unsigned char getc(void)
{
    unsigned char ret;

    while (!(UTRSTAT0 & (1<<0)));
    // 取数据
    ret = URXH0;  

    if ( (ret == 0x0d) || (ret == 0x0a) )     /*回显功能,即接收到数据,会将该数据发送回去在pc端显示,0d是回车键,0a是换行键*/
    {
        putc(0x0d);
        putc(0x0a); 
    }       
    else
        putc(ret);

        return ret;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值