打印

单片机疑难问题,(宇宙级难题)

[复制链接]
7990|49
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
taijing33|  楼主 | 2011-10-28 15:54 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
  我的目的:主机一个,从机数目小于8个,从机地址在1-250之间不重复。从机采集AD值发给主机显示。主机上电一开始发送1-255地址码给从机,从机接收到和自己相符的地址码后发回主机,主机保存在数组里。然后从机轮流向主机发送数据。
我的问题:开始焊了8个从机,一个主机能很好的工作。主机采用stc12C5A08AD从机用的是stc12C5604AD。晶振都是 11.0592.12pf电容。但是后来焊接的几个从机出现了很多问题,
问题一:主机的串口是和485芯片前的光耦相连的,这时不能通过串口给单片机下载程序。串口必须断开光耦才能下载程序。(这个问题在第一次焊接的板子上不存在)。
问题二:接着问题一,下载程序后,如果不断开串口和光耦额定连线,程序运行到一个子函数后就一直运行该子函数,该子函数功能是发送地址1-250到从机(具体程序看下面)。但是有时候也可能只运行该子函数一次(我的要求就是一次)。
我用过的办法。
1.以为12pf电容太小,结果换了30pf的也不行。
2.把没有问题的板子上的单片机和有问题的板子的单片机互换。结果有问题的还是照旧,。没问题的还是没问题。就是排除了单片机问题。
3.测量电源正常,光耦换了N个。还不行。我直接把光耦去掉,用串口直接485芯片还是不行。貌似必须串口悬空才能下载程序。只有悬空才能不循环执行那个子函数。
下面是函数:
void get_num(void)
   {
      uchar temp=16;
   uint N=0;
   uchar k=0;   
    UartInit();
    Delay1ms(200);
       TB8=1;RED=1;   
     for(N=1;N<251;N++)
    {
     //if(N==253)
     // {break;}
     Delay1ms(200);
     EN=0;         //使能发送
     Delay1ms(10);
     SBUF=N;
     while(TI==0);
     TI=0;
     Delay1ms(100);
           EN=1;  //使能接受
     Delay1ms(10);
       if(RI==1)
       {
      RI=0;
         temp=SBUF;
      pot_address[k]=temp;   //从机发来的地址保存数组里
     
      k++;
    }
   
        }
     RED=0;
   }
  
void main()
{ uchar i,j,n,temp,addr1,k;
   uint m;
   P2=0xff;
   UartInit();
   Tim0_init();
   S119=1;
  RED=0;
  get_num();       //我用串口连接电脑,查看运行情况
                        //程序执行到子函数,就一直循环执行这个子函数。
  for(i=0;i<8;i++)
  {
    if(pot_address==0)
    {
      bbb=i+1;
   break;
    }
    else
    bbb=9;
  }
++++++++++++++下面还有程序,我只贴出这些。
我认为应该是硬件的问题。但是我极其认真的比较了有问题的板子和没问题的板子实在找不出差别。

相关帖子

沙发
taijing33|  楼主 | 2011-10-28 15:57 | 只看该作者
串口RXD加上拉电阻,我也试过不行

使用特权

评论回复
板凳
taijing33|  楼主 | 2011-10-28 16:00 | 只看该作者
这个问题说的明白点就是:单片机串口连接的外围电路会影响单片机程序的执行??

使用特权

评论回复
地板
taijing33|  楼主 | 2011-10-28 16:03 | 只看该作者
void UartInit(void)                //4800bps@11.0592MHz
{

        PCON &= 0x7f;                //波特率不倍速
        SCON = 0xD0;                //8位数据,可变波特率
        BRT = 0xB8;                    //设定独立波特率发生器重装值
        AUXR |= 0x04;                //独立波特率发生器时钟为Fosc,即1T
        AUXR |= 0x01;                //串口1选择独立波特率发生器为波特率发生器
        AUXR |= 0x10;                //启动独立波特率发生器
        ES=0;
        EA=1;
}
这是串口初始化程序,我今天通宵等待问题答案。有解决问题者,悬赏,可以现金交易

使用特权

评论回复
5
aihe| | 2011-10-28 17:50 | 只看该作者
宇宙级难题让宇宙人来解决吧!
自己慢慢想,硬件软件都有问题

使用特权

评论回复
6
NE5532| | 2011-10-28 21:20 | 只看该作者
说几个结论:

1.这电路里光耦是费力不讨好,等于没加。
2.发现带着光耦下不了程序,应该用示波器来看串口上的信号而不是瞎猜。而且提示你,光耦次级在这个时候是不是有输出?会不会跟程序下载的串口波形打架。
3.程序是最简单的东西,只有自己写错得份,不安静下来不要想找到问题。
4.楼主不会调试软硬件,建议在本版搜索我的精华帖看下。

使用特权

评论回复
7
sw008| | 2011-10-28 22:02 | 只看该作者
我以前遇到过光耦的问题,光耦输出到74HC164,结果传输时总有问题,费了些时间,最后发现原来是光耦的速度不够快,导致光耦输出信号的上升沿不够陡,不得已又加了整形电路后解决的。
后来想起来,应该直接使用高速光耦更合适。
楼主是不是也是这问题?

使用特权

评论回复
8
zq1987731| | 2011-10-29 01:12 | 只看该作者
N年没在这边回帖了......上来就被“宇宙级难题”吸引...一看...似曾相识
首先LZ这光耦加得...和三极管有什么区别?GND和VCC两侧都用一样的:L
而且这机制明显就不怎么好,3年前我做的485总线,就32个设备...没主从机概念,管他谁谁同时往总线上发数据都无所谓(没写错...就是允许多主同一时刻疯狂发数据互相打架而不出错),任意时刻拿个镊子拼命短路总线,疯狂热插拔,总线绝不崩溃......支持组播...点对点...广播通讯方式...
当然了,整个程序还外挂了5ms刷新频率的动态数码管显示,LCD多级菜单,支持双击/长按/长短击的键盘,通过接收485时间广播自动同步时间的RTC(当然没有用RTC芯片)...
全程没有任何一处使用超过1个_nop_();的“死机式延时”...就状态机+定时器,而且用到的MCU可低级多了——STC89C52RC...

使用特权

评论回复
9
taijing33|  楼主 | 2011-10-29 07:51 | 只看该作者
首先LZ这光耦加得...和三极管有什么区别?GND和VCC两侧都用一样的
————————————————————————
这个问题我认识到错了,但是板子已经成型。没法再改了。

谢谢大家的答复。问题是我把光耦去掉直接485芯片也不行。
我最 不明白的就是为什么串口接上后面的485芯片部分,程序就在那个子函数里一直运行?
下面是我的pcb

使用特权

评论回复
10
NE5532| | 2011-10-29 09:05 | 只看该作者
首先LZ这光耦加得...和三极管有什么区别?GND和VCC两侧都用一样的
————————————————————————
这个问题我认识到错了,但是板子已经成型。没法再改了。

谢谢大家的答复。问题是我把光耦去掉 ...
taijing33 发表于 2011-10-29 07:51


2个输出不能接在同一个输入上,楼主你再对这句话视而不见,我保证你1年都做不出来!

使用特权

评论回复
11
taijing33|  楼主 | 2011-10-29 09:16 | 只看该作者
我知道把485和串口断开可以写程序,但是我写进程序后。我把电脑那边的串口线拔掉了,也不行哦。还是一直运行那个子函数

使用特权

评论回复
12
NE5532| | 2011-10-29 09:20 | 只看该作者
我知道把485和串口断开可以写程序,但是我写进程序后。我把电脑那边的串口线拔掉了,也不行哦。还是一直运行那个子函数
taijing33 发表于 2011-10-29 09:16


楼主啊,我不知道你搞研发时候到底看没看过芯片资料,485芯片在输入断开的情况下,RXD是输出高电平的。这个问题拿脑袋想都想得通——如果一个485设备,在不插电缆的时候,RXD输出为低或者有信号,单片机不是要疯了啊~~~~~~!

使用特权

评论回复
13
NE5532| | 2011-10-29 09:22 | 只看该作者
运行某个你不希望的函数,是软件上的问题,不要去找借口说这个单片机可以对,那个不能对,芯片出问题的概率小于你买彩票中奖的概率,你现在应该静下心来找,这个函数为什么被运行了,也许在硬件和软件设计上有你根本没有考虑到的漏洞或者边界情况!没有经过这样历练出来的工程师,始终只是一个模仿者而不是开发者!

使用特权

评论回复
14
ShakaLeo| | 2011-10-29 09:28 | 只看该作者
楼主你的485的AB线上的电平不对,在不发送的时候是小于0.2V的电压,这可能导致7576的R端电平不确定,主机就会收到误码。估计你的接收缓冲pot_address[]可能比较小,在收到误码后可能越界了,破坏了内存数据导致复位,你看到的现象就是一直在运行某个函数。把那个120欧姆电阻改成4.7K以上试试。120欧是用来做阻抗匹配的,如果不是高波特率或长传输线是没必要的,而且如果用120欧电阻做匹配,相应的上拉和下拉电阻也应该使用较小的阻值。
还有,发送完了之后,为什么要延时100mS之后再使能接收呢?

使用特权

评论回复
15
taijing33|  楼主 | 2011-10-29 09:29 | 只看该作者
NE5532 你好你还在么?我把TXD和RXD通过一个 1K电阻和光耦连接可以下载程序了,而且程序也不一直执行那个子函数了,真是很感谢你。把你帐号发过来,。我给你报酬

使用特权

评论回复
16
taijing33|  楼主 | 2011-10-29 09:31 | 只看该作者
我经验太少了。以前没做过通信,都是单机小产品。这次真是见笑了。

使用特权

评论回复
17
NE5532| | 2011-10-29 09:40 | 只看该作者
呵呵,谢谢楼主的热情,不过这里是互助论坛,要卖技术的时候我会标价的。

你的1K电阻也有问题,单片机输入端和PCB走线上有寄生电容,串1K电阻将导致波形边沿变得圆滑,对高波特的信号会产生影响。我的建议是你取消电阻,单片机通过485直接下程序(反正STC那个下程序说穿了就是个串口通讯),或者是用个跳针来解决问题,总之就是这个原则:不要为了只用1次的下载程序动作,去降低了每天都在使用的串口通讯(485)的可靠性,要抓住产品的主要矛盾,东西才可靠。


至于程序调试,建议你看我的精华帖,楼主离一个合格的Engineer确实还有一定距离,不过楼主加油!

使用特权

评论回复
18
taijing33|  楼主 | 2011-10-29 09:56 | 只看该作者
郁闷。我串了1K电阻后,程序倒是能下载了,可是问题是不拔掉和电脑连接的串口线后那个子函数程序能执行一次,但是不往下执行,拔掉串口线时那个子函数一直执行。我彻底郁闷了。还是买个弄个示波器看看吧。谢谢你

使用特权

评论回复
19
刘前辈| | 2011-10-29 10:11 | 只看该作者

485总线阻抗标准,必须大于50欧姆!

本帖最后由 刘前辈 于 2011-10-29 10:12 编辑

LZ能否告诉我你的485总线的电阻值是多少?万用表量一下即可。

          标准是大于50欧姆,按照你的(错误)电路,如果接入8个从站,总线电阻值为120/8 = 15 欧姆!从站越多,阻值越小;485还怎么传输?

  所以,当你接入2个从站时,总线阻值为60欧姆,一切正常;接多了,总线阻抗不正常了。工作异常。



、、

使用特权

评论回复
20
taijing33|  楼主 | 2011-10-29 10:14 | 只看该作者
我接了三个从机。485线都是半米左右。离的很近

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

163

主题

365

帖子

3

粉丝