打印

三线(STB,CLK,DATA)主机只发,我只收,咋就这么难,想死的心都有了

[复制链接]
6679|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
主机:STB=0选通,CLK =0,串入数据,CLK=1,时钟上升沿串入数据到DATA上,发一个字节,时钟高低20US(脉宽20US,占空1/2),高
位先串入,数据有更新才发;

从机:只是收数据,主机数据有更新才发的,我是这么做的,24M晶体:
1,STB接51外中断,优先最高,STB下降沿触发外中断,进入中断先关中断,收完退出前再开
2,读数据
    while(MPG_CLK==1) ;   //确定CLK为低准备收                              
     for(mpg_temp = 0,MPG_RCV_data=0;mpg_temp < 8;mpg_temp++)  
     {   

       while(MPG_CLK == 0) //反复读取数据直到CLK=1
      {                                                         
             Cdate = MPG_DATA;
               if(Cdate)
               {
                    MPG_RCV_data |= 0x01 ;
               }
               
               NOP;NOP;NOP;NOP;  //CLK变高前得到有效的数据
               while(MPG_CLK==0);  
        }   
            MPG_RCV_data <<= 1;

    }
          gMPG_RcvComd = MPG_RCV_data;  //把数据缓存起来
3,收到的数据要末全为1,要末全为0,有时是错误的数据,发过来的是秒钟变化0~59
4,应该何时读DATA 上的数据呢?怎么读?痛苦中,再做不好要走人了,快帮我~~

11.jpg (70.56 KB )

11.jpg

相关帖子

沙发
win2000_li| | 2009-8-12 08:46 | 只看该作者
哈哈,,,,,,,,,,,,,,,,,,,

虽然我帮不上你,但是一定要**。并且不要急噪,对解决问题不利。。。。。。。。。。。。。。。。。。

使用特权

评论回复
板凳
sz_kd| | 2009-8-12 09:11 | 只看该作者
把你的时钟信号调慢点,不要那么快

使用特权

评论回复
地板
aolin| | 2009-8-12 09:13 | 只看该作者
DVD和MCU的3线通讯,有2种方法:
1,选用普通的MCU,用通用IO口来通讯。以这种方法来通讯的话,MCU的选择就没有什么限制,但就要改进通讯协议,使用通讯速度能自适应的通讯协议,通常可以参考Philips的DSA协议来做,这也是做车载DVD用得比较多的方法。
2,如果没有办法让DVD那边修改通讯协议,**使用VFD的通讯协议,则这种方法对MCU有比较高的要求,最好选用带SPI接口的MCU,利用SPI接口去接收DVD发送过来的数据,你就轻松很多了。

使用特权

评论回复
5
冷漠| | 2009-8-12 09:26 | 只看该作者
这段程序怎么可能接收到任何数据?

编译通过了么?把头文件及完整C代码写出来看看好吧。(然后送你段接收程序。)

使用特权

评论回复
6
古道热肠| | 2009-8-12 10:29 | 只看该作者
看您这波形图,似乎是主机在CLK为低时改变数据,在CLK为高时,数据有效.这个一定要搞清晰,因为这关系到采样的位置.
注意采样在有效值的中部较可靠

使用特权

评论回复
7
古道热肠| | 2009-8-12 10:31 | 只看该作者
先用Keil软件仿真调通,再与Host联调,怀疑是速度不够,上STC的11F系列单周期单片机测试,可基本排除是MCU速度不够出的BUG

使用特权

评论回复
8
泰山特曲123| | 2009-8-12 12:32 | 只看该作者
你应该等到CLK产生一个上升沿后,才读数据;就是
while(MPG_CLK == 1) ;
while(MPG_CLK == 0) ;
{读数据和处理}
你的程序看这样修改后行不行:
while(MPG_CLK==1) ;   //确定CLK为低准备收                              
     for(mpg_temp = 0,MPG_RCV_data=0;mpg_temp < 8;mpg_temp++)  
     {   

       while(MPG_CLK ==0); //等待为高电平,产生上升沿                                                         
             Cdate = MPG_DATA;
               if(Cdate)
               {
                    MPG_RCV_data |= 0x01 ;
                     MPG_RCV_data <<= 1;

               }
               
               NOP;NOP;NOP;NOP;  //CLK变高前得到有效的数据                        
               while(MPG_CLK ==1);等待为低电平

    }
          gMPG_RcvComd = MPG_RCV_data;  //把数据缓存起来

使用特权

评论回复
9
mcufan001|  楼主 | 2009-8-15 00:09 | 只看该作者
非常感谢大家的热心!还没成功,为此还特意做了一个时钟,把接收数据屏蔽掉,验证下驱动的1623数码管显示是否正确,现在可以肯定其他函数是没问题的,就是接收的数据不正确,秒钟显示位变化不正确,有乱的数据,还以为解码发过来的数据顺序不对,把接收的字节高低位颠倒也试过了:
还是不对!!!!
void serviceINT1(void) interrupt 2 using 3  //外部中断1的中断函数。用于MCU/DVD通讯读数。
{               
           BYTE   Timer;
           BYTE   mpg_temp;
           BYTE   Cdata = 0;
           WORD  MPG_RCV_data = 0;

          
           EX1=0;         //关中断
     
     while(MPG_CLK == 1);    //等待时钟变低
                                    
     for(mpg_temp = 0;mpg_temp < 11;mpg_temp++)  
     {        
               MPG_RCV_data <<= 1;             
        while(MPG_CLK == 0);   //直到CLK=1      
                  Cdata = MPG_DATA;
                  if(Cdata)
                  {
                MPG_RCV_data |=  0x01;
           }  
        Timer = 100;     
        while((MPG_CLK == 1) && (--Timer))   // 收完一位,如果还在高电平,死等下一个时钟
        {
                NOP;
//                NOP;   //24M
        }                  
     }
   // gMPG_RcvComd = (BYTE)(MPG_RCV_data >> 8);  //把高8位数据缓存起来   
   // gMPG_RcvData = (BYTE)(MPG_RCV_data);         //把低8位数据缓存起来       
     
         
     gMPG_RcvComd = (BYTE)MPG_RCV_data & 0x03;         //把高8位数据缓存起来   
     gMPG_RcvData = (BYTE)(MPG_RCV_data >> 3);         //把低8位数据缓存起来       
     //解码发送数据A0 A1 A2 A3 A4 A5 A6 A7 -----A7 A6 A5 A4 A3A 2A A1 A0//以下为8bit倒序
//     gMPG_RcvData = ((gMPG_RcvData & 0x55) << 1) | ((gMPG_RcvData & 0xaa) >> 1);  
//     gMPG_RcvData = ((gMPG_RcvData & 0x33) << 2) | ((gMPG_RcvData & 0xcc) >> 2);  
//     gMPG_RcvData = ((gMPG_RcvData & 0x0f) << 4) | ((gMPG_RcvData & 0xf0) >> 4);

     switch( gMPG_RcvComd)
     {
                   case 0x00:          
                  TIME_sec  = (gMPG_RcvData & 0x3f); break;  //低5bit有效
            case 0x01:          
                  TIME_min  = (gMPG_RcvData & 0x3f); break;  //低5bit
            case 0x02:          
                  TIME_hour = (gMPG_RcvData & 0x0f); break;  //低4bit               
     }
     //gMPG_RcvComd = 0xff;//初始
     //gMPG_RcvData = 0x00;
     EX1 =1;                                    //EA X ET2 ES ET1 EX1 ET0 EX0                
}

使用特权

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

本版积分规则

5

主题

33

帖子

2

粉丝