关于c51串口的驱动

发布者:知音学友最新更新时间:2016-11-21 来源: eefocus关键字:c51  串口  驱动 手机看文章 扫描二维码
随时随地手机看文章
1、C51串口的弊端。
C51的串口收发程序相信大家都很熟悉了,在hello.c里面有很简单的例程,不知 道大家有没有注意到hello.c里面有一句很不显眼的语句"TI = 1;" 当你在初始化串口的时候如果你不让TI = 1的话,相信你看到你的数据永远都发不出去,debug里运行stop会看到程序实际上是进行到了while(!TI);的语句处进入死循环了。

深 入一点的看,可以在keil/c51/lib下发现putchar函数的原文件,和许多软件串口驱动一样printf()都是反复调用putchar() 来实现的,所以putchar函数是我们进入死循环的症结。putchar函数很简单,在其中有一个最小实现方式,我就以这个简单的例子来解释。

char putchar(char c){        
    while(!TI);
    TI = 0;
    return(SBUF = c);
}

很 显然,C51中缺省的putchar函数是靠查询并等待TI这个标志位来实现串口发送的,也就是说,在putchar函数中确实发送了所有的数据,但是每 发送一个BYTE前都等待了一段时间。这就不难理解为什么在初始化串口的时候必须把TI置位了,无非是想让发第一个数据的时候让putchar函数能顺利 执行。

注意,这里有一个问题出现了,我们可以把UART理解为一个独立的外设,在一次数据装订后就应该交给UART自动完成数据收发,也 就是说宝贵的CPU时间应该不在这里浪费掉,所以我们可以做出这样一个结论C51的putchar函数其实是有弊端的,它在等待TI置位时大大占用了 CPU时间。

2、刨根问底
为什么C51这么别有用心的设计这样一个基础的函数来实现收发呢,为什么必须用TI来支持这个判断,我在写程序的时候发现了一点,其实就是51中UART的一点特性。
51 的UART可以理解为一个自动的串行输出外设,每对SBUF写一个数据就会触发UART的一次串行输出操作,即在定时器分频的基础上逐步移初所有数据位 (包括启始为和结束位等等),移出速度是靠定时器溢出时间来来度量的,所以对于MCU来说这个时间一般都比较长。因此如果在定时器还没有溢出的时候再对 SBUF写数据的话会重新引起这个新数据的发送。这样如果你写

while(1)
  SBUF = 'a';

其实是没有任何意义的,发出的肯定是乱码。
由于以上的原因我们就可以看出TI确实是上次发送的结束和下次发送的开始的结点。C51也是利用了这样一个特性来实现自己的函数。

3 改进的PUTCHAR函数
缓 冲区是连接告诉设备和低速设备的接口,我们的串口收发其实就是MCU的高速和UART的低速的协同工作,所以我们应该设计一个缓冲区作为数据的暂存位置, 当设备发送数据的时候如果UART正在忙于发上一个数据那么就应该把数据存在BUFF里面,而如果UART不忙了就应该把数据从BUFF里面顺序读出并发 送。

这个正好符合队列的概念,我就设计了一个循环队列来实现这个功能。而在
putchar函数就应该设计成
void putchar(char c)
{
    if(UART不忙)
        直接发送数据到SBUF
    else
        把数据写到BUFF里
}

而中断函数则应该写为
ISR(){
    ……

    if(TI){
        TI = 0;
    if(BUFF里面还有数据)
        取下一个数据并发送;
}

新的问题又出现了,什么是UART忙,他与TI的关系如何,是不是TI = 0就是UART忙?

前两个问题先不说,最后一个问题的答案很显然是“no!”,从最极端的角度来看,上电后UART就是空闲,TI也应该等于0!

上面的几个问题从另一个角度也可以得到答案,这里有一点点哲理的问题,一个物品一般只能完成一件事情,既然TI已经作为上次发送的结束和下次发送的开始的结点那么它应该不是作为UART忙的标致。

4、最后的设计概要
从OS的角度来看UART是一种资源,对于我们的程序我们把SBUF看做它的载体,所以对于高速和低速设备的同步问题我们应该引入互斥量来实现对这个资源占用情况的标志。所以我设计的串口驱动里写了一个mutex_sbuf来实现这个功能。
后面的事情就简单了

void putchar(char c)
{
    if(mutex_sbuf == 0){
        EA = 0
        mutex_sbuf = 1;
        SBUF = c;
        EA = 1
    }
    else
        把数据写到SBUF里面
}

ISR()
{
    ……

    if(TI){
        TI = 0;
        mutex_sbuf = 0;
        if(BUFF里面还有数据){
                mutex_sbuf = 1;
                取下一个数据并送;
        }
    }
}

写到这里说的差不多了,没兴致了:( 以后我把程序贴上来供大家参考
希望大家能把我的程序优化一下,我现在的这个版本的driver是用纯C写的,对ROM的占用太大了。以后我会用ASM来改写部分代码。

而且还有一个问题就是C51对于指针的使用很麻烦,程序很容易跑飞,我的代码还不是足够的清晰,因为就是指针的乱跑,所以我在必要的函数里面加了指针类型限定,但是我发现如果都加限定的话反而也会飞。

过两天我会放上来希望大家能一起把这个写好。

写得不错,但我不倾向采用中断发送。因为如果采 用中断发送的话,需要一个发送缓冲区,缓冲区设多大?只设一个字节的话,那么调用putchar的时候是不是先得判断缓冲区非空,如果不空则printf 一类的函数仍然需要等待。缓冲区设很大的话,有两个问题,一是51本来内存就小,二仍然是需要判断缓冲区空不空。考虑再三,还是用的查询发送。到底采用查 询或中断发送,可能要根据自己的需求来选择。

另外,KeilC写的不见得就比asm写的占空间大;c指针跑飞的原因,大部分是指针越界,比如申请了5字节内存,使用了第6个,把别的变量冲掉了等等,不在于你是否加cast,也就是说与强制类型转换无关,要加强对查表等索引指针的检查,确保指针不越界。

确实是这样的,根据项目需要吧,我现在只是想写一个模块出来给大家参考:)
代码量大是因为我用了循环队列,对于buff的操作几乎是透明的,所以几乎不用考虑,还有一点因为我用的是RD2的芯片,所以有ERAM,我对内存的考虑就稍微少了一些。

如果不用中断的话就要写一个scheduler来实现,我想以后要写一个调度器的实现方式,不过我现在不知道怎么模拟串口收数据,好象这个问题比较麻烦,斑竹有没有什么好的想法?
于这个问题我想还是有必要讨论一下的,你可能认为我对buff的校验不到位,所以产生了越界,但是我想问为什么有了casting以后就可以不越界了呢

我对C51不是很熟悉,但是我觉得症结可能在于函数嵌套过多,虽然结构明晰了,但是堆栈不够用了。

另外一个需要注意的是为什么总是跑到IDATA里面,这个我也不解:)
我所有的buff都是在XDATA中的,而且我用了MALLOC函数,但我又用的是compact mode


关键字:c51  串口  驱动 引用地址:关于c51串口的驱动

上一篇:浅谈1602显示汉字
下一篇:C51中断及寄存器使用的总结

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

JZ2440 串口裸机编程
ARM裸机1期加强版视频课程配套WiKi第11课_串口(UART)的使用, 共2节:第001节_辅线1_硬件知识_UART硬件介绍和第002节_S3C2440_UART编程,讲的是JZ2440 UART裸机编程。 文字不能完全替代视频,所以如果你看了这些文章感觉不错却不太懂,建议购买视频进一步学习。 第001节_辅线1_硬件知识_UART硬件介绍 1. 串口的硬件介绍 UART的全称是Universal Asynchronous Receiver andTransmitter,即异步发送和接收。串口在嵌入式中用途非常广泛: 打印调试信息 外接各种模块:GPS、蓝牙 串口因为结构简单、稳定可靠,广受欢迎。通过三根线即
[单片机]
JZ2440 <font color='red'>串口</font>裸机编程
在EM78Pxx上模拟8(COM)*8(SEG)LCD驱动
;/*============================================================================= ; 在EM78Pxx上模拟8(COM)*8(SEG) LCD 驱动 | ; | ; | ;一. LCD扫描原理: | ;正向扫描: COM on=V CC ,COM off=1/2VCC,对应SEG=1则输出VSS,为0 则
[单片机]
脉宽调制(PWM)电机驱动器电源分析
  1 概述   三相交流电机工作可靠、高效、费效比高,需要少量维修或根本不需要维修,一直是工业领域的主力。此外,交流电机(如感应电机和磁阻电机)无需与转子的电气连接,因此很容易实现阻燃,适用于矿山等危险环境等应用场合。   采用脉宽调制( PWM )的三相电机驱动电路工作原理框图如图1所示,为电机提供三相供电电源,电压和频率可以变化。 PWM 交流电机 驱动器 可以高效提供从零速到全速的全转矩,并且通过改变驱动电源的供电相位相序,可以很容易实现电机双向运转。   2 脉宽调制电机 驱动器 原理   三相交流输入供电电源经过整流和滤波后,产生直流总线,为 驱动器 的逆变器部分提供电源。逆变器由3 对半导体开关(MOSF
[电源管理]
脉宽调制(PWM)电机<font color='red'>驱动</font>器电源分析
如何正确选择的LED照明驱动IC
在LED照明领域,为体现出LED灯节能和长寿命的特点,正确选择LED驱动IC至关重要。没有好的驱动IC的匹配,LED照明的优势无法体现出来。那么在选用LED驱动IC时,应该注意哪些性能指标和使用方法吗? LED照明灯具在近期得到飞跃的发展,LED作为绿色环保的清洁光源得到广泛的认可。LED光源使用寿命长、节能省电、应用简单方便、使用成本低,因而在家庭照明都将得到海量的应用,欧司朗光学 半导体 公司2008年调查统计,全球每年家庭照明灯座出货量约为500亿个。 LED光源的技术日趋成熟,每瓦发光流明迅速增长,促使其逐年递减降价。以1W LED光源为例,2008年春的价格已是2006年春的价格三分之一,2009年春将降至2006年的四
[电源管理]
如何正确选择的LED照明<font color='red'>驱动</font>IC
技术文章—如何最大限度提高Σ-Δ ADC驱动器性能
简介 您有没有检查过网络上有多少条关于“ADC缓冲器设计”的内容?答案是超过400万条,在如此多的参考文献中很难找到我们需要的内容。对于大多数模拟和混合信号数据采集系统设计工程师来说,这可能不是很意外,因为设计无缓冲模数转换器(ADC)的外部前端需要有耐心和大量建议。它常常被视为一种艺术形式,是经过多年摸索掌握其窍门的古怪大师的保留地。对于没有经验的人来说,这是一个令人沮丧的反复尝试过程。大多数时候,由于相互关联的规格要求很多,迫使设计人员不得不进行很多权衡(和评估)才能达到最佳效果。 挑战 放大器级的设计由两个彼此相关的不同级组成,因此问题变得难以在数学上建模,特别是因为有非线性因素与这两级相关。第一步是选择用来缓
[电源管理]
技术文章—如何最大限度提高Σ-Δ ADC<font color='red'>驱动</font>器性能
点阵式液晶显示器的动态驱动
液晶的显示是由于在显示像素上施加了电场,这个电场是显示像素前后两电极上的电位信号的合成。由于直流电场容易使液晶的寿命降低,因此,一般都只建立直流成分非常小的交流电场。直流分量通常小于50mV.液晶显示器的驱动通过调整施加在液晶显示器电极上的电位信号的相位、峰值、频率等建立驱动电场以实现显示。 动态驱动法 当液晶显示器显示的像素众多时,如点阵型,为了节省庞大的硬件驱动电路,液晶显示器电极的制作与排列做了加工,实施了矩阵式结构:即把水平一组显示像素的背电极都连在一起引出,称之为行电极;把纵向显示像素的段电极都连在一起引出,称之为列电极。显示器上每个像素都由其所在行列位唯一确定。液晶显示器的动态驱动法就是循环地给行电极施加选择脉冲,同时
[电源管理]
点阵式液晶显示器的动态<font color='red'>驱动</font>法
基于ADSP-21160的液晶驱动电路设计及系统软件实现
薄膜晶体管液晶显示器(TFT-LCD)具有重量轻、平板化、低功耗、无辐射、显示品质优良等特点,其应用领域正在逐步扩大,已经从音像制品、笔记本电脑等显示器发展到台式计算机、工程工作站(EWS)用监视器。对液晶显示器的要求也正在向高分辨率、高彩色化发展。 由于CRT显示器和液晶屏具有不同的显示特性,两者的显示信号参数也不同,因此在计算机(或MCU)和液晶屏之间设计液晶显示器的驱动电路是必需的,其主要功能是通过调制输出到LCD电极上的电位信号、峰值、频率等参数来建立交流驱动电场。 本文实现了将VGA接口信号转换到模拟液晶屏上显示的驱动电路,采用ADI公司的高性能DSP芯片ADSP-21160来实现驱动电路的主要功能。 硬件电
[嵌入式]
基于LED驱动器的新型调光方案详解
在许多照明应用中,人们都采用了能够产生已调大电流脉冲的功率驱动器,从DLP 投影机中的大电流 led到高功率激光二极管等等。例如:在高端视频投影机中,高功率 LED 用于产生彩色照明。这些投影机中的RGB LED 需要精准的调光控制以实现准确的彩色混合 ── 在该场合中,除了简单的 PWM 调光以外,还能够提供更多的控制功能。通常,为了实现彩色混合中所要求的宽动态范围,LED 驱动器必须要能够在两种完全不同的已调峰值电流状态之间快速切换,并叠加 PWM 调光而不造成任何损坏。LT3743 能够满足这些苛刻的准确度和速度要求。   LT3743 是一款同步降压型 DC/DC 控制器,它运用固定频率、平均电流模式控制,以通过一个
[电源管理]
基于LED<font color='red'>驱动</font>器的新型调光方案详解
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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