串口通信的优化

写了个串口发送程序,在STC单片机里运行正确,可把这程序烧到89C2051里面就不好使!
使用51单片机,用的是定时器1,晶振是7.3728M。
任务是每20ms通过串口发送一次两组80个的数,两组数中间间隔0.5ms。
在STC里面是正确的,可用到89C2051里面就有问题了,收到的全是FF。

悬赏分:100 | 2011-11-12 19:09  解决时间:2011-11-17 20:40:44

下面是程序:
===================================================
#include <reg51.h>

unsigned int ch[2][80] = {
   {0x01,0x03,0x05,0x07,0x09,0x01,0x03,0x05,0x07,0x09,
    0x01,0x03,0x05,0x07,0x09,0x01,0x03,0x05,0x07,0x09,
    ......
    0x01,0x03,0x05,0x07,0x09,0x01,0x03,0x05,0x07,0x09},
   {0x02,0x04,0x06,0x08,0x02,0x04,0x06,0x08,0x02,0x04,
    ......
    0x06,0x08,0x02,0x04,0x06,0x08,0x02,0x04,0x06,0x08}};

void init_serialcom( void ) //串口通信初始设定
{
    //PCON = 0x80 ; //SMOD=1; 波特率为320.4K
    PCON = 0x00 ;   //SMOD=0; 波特率为115.2K
    SCON = 0x98 ;   //UART为模式2,8位数据,允许接收
    TMOD = 0x10 ;   //定时器1为模式1
    TH1  = 0xD0 ;   //装载高位
    TL1  = 0x00 ;   //装载地位 
    IE   = 0x98 ;   //开总中断,串口中断,定时器中断
    TR1  = 1 ;      //启动定时器1              
}
其它略(做而论道注,有兴趣可到原题网址去看全文)
原题网址:http://zhidao.baidu.com/question/341613564.html?fr=im100008
=========
问题补充:

AT89C2051是12T模式的!
115.2K跟TH1没关系。
用的是串口模式2, SMOD=0;波特率 = f / 64 = 115200;
===================================================
最佳答案:

2051片内RAM空间,仅仅有128字节,但是楼主的数组就用了160字节。
要定义为CODE类型才行。

回答者: 做而论道 | 十五级采纳率:43% 名人
----------------------------------------
追问:

定时 t = 0.02s,晶振周期为 1 / 7372800;
所以 x = 0.02 * 7372800 / 12 = 12288;
定时初值为 65536 - 12288 = 53248 = D000。

老兄说可能是溢出,我觉得有道理,可是把数组改成很小的数试了也是收到FF!

2011-11-13 09:01
----------------------------------------
回答:

试试看:
;每20ms通过串口发送一次两组80个的数,
;两个数中间间隔0.5MS
;fosc = 7.3728MHz

    ORG  0000H
    JMP  START
START:
    MOV  PCON,  #80H ;SMOD = 1
    MOV  SCON,  #90H ;方式2, 9位数据, fosc/32=230400bps

    MOV  TMOD,  #01H
    SETB TR0  
LOOP:
    JNB  TF0,  $  ;等待20ms到来.
    CLR  TF0
    MOV  TH0,  #(65536 - 12288) / 256
    MOV  TL0,  #(65536 - 12288) MOD 256

    MOV  DPTR, #TAB1
    CALL SEND
    CALL DL_500
    CALL SEND
    SJMP LOOP
;---------------------------------------
SEND:
    MOV  R2, #80
S1: CLR  A 
    MOVC A, @A + DPTR
    MOV  C, P
    MOV  TB8, C
    MOV  SBUF, A
    JNB  TI, $
    CLR  TI
    INC  DPTR
    DJNZ R2, S1
    RET
;---------------------------------------
DL_500:
    MOV  R7, #160
    DJNZ R7, $
    RET
;---------------------------------------
TAB1:
    DB  0x01,0x03,0x05,0x07,0x09,0x01,0x03,0x05
    DB  0x07,0x09,0x01,0x03,0x05,0x07,0x09,0x01
    DB  0x03,0x05,0x07,0x09,0x01,0x03,0x05,0x07
    DB  0x09,0x01,0x03,0x05,0x07,0x09,0x01,0x03
    DB  0x05,0x07,0x09,0x01,0x03,0x05,0x07,0x09
    DB  0x01,0x03,0x05,0x07,0x09,0x01,0x03,0x05
    DB  0x07,0x09,0x01,0x03,0x05,0x07,0x09,0x01
    DB  0x03,0x05,0x07,0x09,0x01,0x03,0x05,0x07
    DB  0x09,0x01,0x03,0x05,0x07,0x09,0x01,0x03
    DB  0x05,0x07,0x09,0x01,0x03,0x05,0x07,0x09

    DB  0x02,0x04,0x06,0x08,0x02,0x04,0x06,0x08
    DB  0x02,0x04,0x06,0x08,0x02,0x04,0x06,0x08
    DB  0x02,0x04,0x06,0x08,0x02,0x04,0x06,0x08
    DB  0x02,0x04,0x06,0x08,0x02,0x04,0x06,0x08
    DB  0x02,0x04,0x06,0x08,0x02,0x04,0x06,0x08
    DB  0x02,0x04,0x06,0x08,0x02,0x04,0x06,0x08
    DB  0x02,0x04,0x06,0x08,0x02,0x04,0x06,0x08
    DB  0x02,0x04,0x06,0x08,0x02,0x04,0x06,0x08
    DB  0x02,0x04,0x06,0x08,0x02,0x04,0x06,0x08
    DB  0x02,0x04,0x06,0x08,0x02,0x04,0x06,0x08
;---------------------------------------
END
===================================================
追问:

大侠!你那CODE类型很有用!我把数据类型改成了unsigned char code,结果想要的数据出来了,一个都不错!

但新的问题出来了。

通过示波器根本看不到20MS周期的样子,然后就把周期改为80ms,结果周期是出来了,才发现,我每发完80个数花了16多ms,不应该啊,而且中间的间隔不是我想要的0.5ms,而是3ms左右。每个字节花去的时间是200us,都不正常。然而每位的跳变为8.5us左右,这个应该是正确的。
您上面的程序,我明天上午再试试
==================================================
回答:

祝贺。
你以前没有用CODE型,显然是要占用RAM空间,而RAM空间显然是不够的。
现在你的时间问题,也不难理解。
你的串口发送,是在定时中断里面进行的,直到发送完了160字节之后,才继续定时20ms。
试试我的汇编程序吧,定时和串口发送,是并行的,互相不耽误。   
===================================================
追问:

您汇编程序在115.2 bps 是好使的!
可是我最后要在10ms内发160个数据,必须在10ms内,按理论算应该是能发完的!
可实际就发不完160个数。

我用示波器看了一下数据是这样的,每一位持续4us多点

0100111000111111
0010111000111111
0110111001111111
0001111000111111

就感觉问题出在停止位后面的1持续的时间太长了。
==================================================
回答:

哦,发送完九位数后,停止位、空闲位,太多了。竟然有5~6位之多!
也就是说,下面几行,应该优化一下:
    MOV  SBUF, A
    JNB  TI, $
    CLR  TI
呵呵,这个工作,只能用汇编来进行,等我想想看。
==============
===想想想想想=====
====================
发送程序优化如下,空闲位,不会超过一个。  呵呵,绝对自豪!
;---------------------------------------
SEND:
    MOV  R2, #80
    CLR  A 
    MOVC A, @A + DPTR
    INC  DPTR
    MOV  C, P
    MOV  TB8, C
S0: MOV  SBUF, A
    DJNZ R2, S1
    JNB  TI, $
    CLR  TI
    RET
;-------------------------
S1: CLR  A 
    MOVC A, @A + DPTR
    INC  DPTR
    MOV  C, P
    MOV  TB8, C
    JNB  TI, $   ;等待发送结束
    CLR  TI
    SJMP S0
;---------------------------------------   
==================================================
提问者对于答案的评价:

谢谢大侠了!加完你后面的程序,就一点问题都没有了!空闲位基本没了!可帮我大忙了!
;-------------------------
大家能猜出来是怎样优化的吗?
呵呵,有谁能用C语言解决吗?
==================================================

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值