作者deo2000 (800IM)
看板ASM
标题Re: [问题] PC 收 51 传的0~255,有时会收到奇怪数字
时间Sat Jan 12 15:38:40 2013
现在51改传HEX给PC,PC端再解码为DEC,
所以就不是"000"~"255",现在是"00"~"FF"。
PC端的软体是VB6写的,收到讯号後画出波形 (用特殊Timer可达1000Hz)
PC送出字串"Q"给51时,会计算读到的HEX并送回给PC
所以每当PC送出"Q", MSC.Input 应该就要收到 "DE""F4"等字串
但是当扫描速度快(500Hz)时,有很高机会收到"DEDD""F4F5"等连续传两次的字串
请问这个问题该如何解决?
我每次收完 MSC.Input, 都有用 MSC.InBufferCount = 0 清除
却还是不能避免
#include "AT89X51.h"
/*
P2 读取ADC
P1,3,0 预留输出控制
*/
unsigned char ucADC0804;
char code HEX[16]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39
,0x41,0x42,0x43,0x44,0x45,0x46};
main()
{
IE=0x90; /* (中断Enable)EA=1,(串列中断)ES=1*/
P2=0xFF; /* P2为读取Port */
SCON=0x70; /*Serial Port mode1*/
TMOD=0x20; /*Timer mode1(Auto Load)*/
TH1=0xFD; /*
[email protected]*/
TR1=1; /*Timer1 启动!*/
TI=1; /*发射中断启动!*/
while(1)
{
ucADC0804=P2;
}
}
void serial_INT(void) interrupt 4
{
unsigned char swap;
ES=0; //暂时阻挡串列中断
if(RI&&'Q'==SBUF)// 如果收到请求,才发射ADC Value
{
swap=(ucADC0804>>4);//&0x0F; //取高4bit
SBUF=HEX[swap]; //发射高4bit之ASCII
while(!TI); //等待发射完毕
TI=0; //这个如果没加,几乎都送0出去
swap=ucADC0804&0x0F; //取低4bit
SBUF=HEX[swap]; //发射低4bit之ASCII
while(!TI);
TI=0; //清除发射中断旗标
}
RI=0;
ES=1; //恢复串列中断
}
※ 编辑: deo2000 来自: 140.122.165.222 (01/12 19:19)
1F:→ ksmrt0123:500Hz周期是2mS, 9600bps传2bytes需要2.08mS 01/13 00:47
那请问Rx收到的字串'Q'要不要算进去呢?
三个字=30bits,9600/30=上限320Hz
实际上是超过30Hz就会经常收到空字串,空字串出现机率,随频率增加而增加,
到500Hz就会很快发生溢位,PC当掉
※ 编辑: deo2000 来自: 140.122.136.12 (01/13 01:50)
Baud rate改19200之後改善很多,不过收到空字串机率还是太大,都要PC端用软体过滤
这是目前未经PC端软体滤波的讯号图
http://imgur.com/XSyNG
有出现正确讯号的轮廓,但常常会收到0(空字串)杂讯
※ 编辑: deo2000 来自: 140.122.136.12 (01/13 04:45)
2F:→ ksmrt0123:我猜是pc端的问题. pc是多工的环境, timing不准 01/13 14:20
3F:→ ksmrt0123:30Hz的话 33.3mS要做一次, 这个timing对pc应该有困难 01/13 14:21
timing不准没关系,当初就是有考虑到OS资源分配问题,所以才想用PC送出"Q",
等OS有空才请MCU送资料到SBUF,PC再去抓回来这样。
4F:→ ksmrt0123:btw, if(RI&&'Q'==SBUF) 是不好的写法最好别用 01/13 14:22
我知道SBUF的东西看过可能就不见了,在这里只用一次,并没有要存下这个字串,
而且也能少宣告一个buf变数、少一次传值动作。
※ 编辑: deo2000 来自: 140.122.165.222 (01/13 14:30)
5F:→ ksmrt0123:我是说把条件写成两个if比较好 01/13 14:40
6F:→ ksmrt0123:逻辑比较清楚, 也不怕compiler optimization造成错误 01/13 14:41
7F:→ ksmrt0123:pc端的问题需要再研究, 你是用timer产生event去读吗? 01/13 14:45
我用winmm.dll提供的timeGetTime(1)函式
8F:→ ksmrt0123:有示波器的话可量量看pc送'Q'出来的间隔准不准 01/13 14:49
PC送"Q"的间隔不准没差,我在意的只有,为什麽经常收到空字串?导致杂讯相当多
每一次要收字串前,都会让PC送"Q"出去,不应该会收到空字串才对
※ 编辑: deo2000 来自: 140.122.165.222 (01/13 15:03)
9F:推 cwl751005:直接以SBUF的资料判断太危险了('Q'=SBUF) 01/13 21:34
10F:→ cwl751005:试着先把SBUF的资料先丢出来再判断,中断部分做资料搬移 01/13 21:35
11F:→ cwl751005:在主程式里判断'Q',然後发送,看会不会好点 01/13 21:36