写了个串口发送程序,在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语言解决吗?
==================================================