微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 上升沿问题

上升沿问题

时间:10-02 整理:3721RD 点击:
在这里上升沿为什么不是由0到1,而是由1到0,而且调试的时候前面的没有问题,后面的就会乱闪?求教!在这里上升沿为什么不是由0到1,而是由1到0,而且调试的时候前面的没有问题,后面的就会乱闪?求教!



表示没看懂你表达的意思

就是锁存的时候为什么先给高电平呢?像74595不是要上升沿么,我理解的意思是要先给低电平,再给高电平,就叫上升沿,但是很多都是先给低电平,再给高电平的,为什么呢?

上升沿肯定是由0到1啊!由0上升到1后就触发起作用了

'我理解的意思是要先给低电平,再给高电平,就叫上升沿,但是很多都是先给低电平,再给高电平的'
这句话前后的意思像是一样的吧?

74595的上升沿是用于‘触发’,不是‘锁存’;

你说的先高电平,后低电平锁存,多数出现在用于地址锁存的74373或74573这一类的‘透明D锁存器’,高电平时将数据输入D触发器,低电平时无论输入如何、保持输出D触发器的内容;

如果是你说的‘触发’的话输出只在上升沿或下降沿时改变;
而74373或74573只要EN端为高电平,其输出是跟随输入变化的,所以叫‘透明锁存器’;

你的问题实际是啥问题,好多内容都是猜的,希望对你有帮助;
提问的时候尽量将问题描述清楚,你看一下,一楼位置的提问能看出你用了74595吗?

脉冲是需要延时的,如果需要上升沿的话,应该先将电平拉低,延时一会(uS)再拉高。另外,小编给程序的时候一定要完整,否则谁也看不懂的

非常感谢前辈的细心回答,第一次发帖子,请见谅。不过我还是有点想不明白,所以把程序贴上来,请前辈们指教,不胜感激:这是一个16*16的点阵,通过两片74Hc595D级联来送位码和段码。第一个程序
#include<reg52.h>
#include <intrins.h>
unsigned char  segout[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //8列
unsigned char code tab[]={0x08,0x1C,0x3E,0x7F,0x1C,0x1C,0x1C,0x1C};
sbit LATCH = P1^0;
sbit SRCLK= P1^1;
sbit SER  = P1^2;
sbit LATCH_B = P2^2;
sbit SRCLK_B= P2^1;
sbit SER_B= P2^0;
void DelayUs2x(unsigned char t)        //延时
{   
while(--t);
}
void DelayMs(unsigned char t)       //延时
{
while(t--)
{
     DelayUs2x(245);
         DelayUs2x(245);
}
}
void SendByte(unsigned char dat)    //送段码
{   
  unsigned char i;
   for(i=0;i<8;i++)
        {
         SRCLK=0;
         SER=dat&0x80;
         dat<<=1;
         SRCLK=1;
         }
void Send2Byte(unsigned char dat1,unsigned char dat2)
{   
   SendByte(dat1);
   SendByte(dat2);      
}
void Out595(void)
{
        LATCH=1;
        _nop_();
        LATCH=0;
}
void SendSeg(unsigned char dat)              //  送位码
{   
unsigned char i;
   for(i=0;i<8;i++)             //发送字节
        {
         SRCLK_B=0;                                         //      这里是先0后1,上升沿。
         SER_B=dat&0x80;
         dat<<=1;
         SRCLK_B=1;
         }
      LATCH_B=1;           //锁存//    ?在这里为什么是先1而不是先0开始呢?74595                                                                      是上升沿锁存的。
      _nop_();
      LATCH_B=0;
  }
void main()
{
unsigned char i,j,k;
while(1)
{  
        for(i=0;i<8;i++) //8列显示
  {
         SendSeg(segout);
         Send2Byte(~tab,0xff);
         Out595();
         DelayMs(1);
         Send2Byte(0xff,0xff);
         Out595();
  }
}
}
第二个程序,这个不是16*16点阵的,但是是74595的,在串行输入移位的时候为什么又是先shcp1=1,后shcp1=0?不是上升沿才移位的吗?

#include<reg51.h>

#include <intrins.h>

#define uchar unsigned char

#define uint unsigned int

sbit stcp1=P2^2;  //STcp

sbit ds1=P2^1;   //DS

sbit shcp1=P2^0; //SHcp

sbit stcp2=P2^5;  //STcp

sbit ds2=P2^4;   //DS

sbit shcp2=P2^3; //SHcp

uchar codeDAT[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};//共阴数码管显示码

uchar codetab[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};

uchar codewei[9]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff};

void delay(uint ms)

{                           

  uint x,y;

  for(x=ms;x>0;x--)

     for(y=255;y>0;y--);

}

void QR0_5951(uchar num1)

{

    uchar j;

    for (j=0;j<8;j++)

    {

     num1=num1<<1 ;  

     ds1=CY;

     shcp1=1;//上升沿发生移位  

     shcp1=0;

     }        

}

void OUT_5951()//将移位寄存器内的数据锁存到输出寄存器并显示  

{

stcp1=0;      

stcp1=1;//上升沿将数据送到输出锁存器   

stcp1=0;

}  

void QR1_5952(uchar num2)

{

uchar j;

  for(j=0;j<8;j++)

  {

   num2=num2<<1 ;  

   ds2=CY;

   shcp2=1;//上升沿发生移位  

   shcp2=0;

}         

}                              

void OUT_5952()//将移位寄存器内的数据锁存到输出寄存器并显示  

{

stcp2=0;      

stcp2=1;//上升沿将数据送到输出锁存器   

stcp2=0;

}

void main()

{

uchar i;

while(1)

  {

   for(i=0;i<2;i++)

    {

      QR0_5951(DAT[0]);

      OUT_5951();

      QR1_5952(wei);

       OUT_5952();

       delay(1);         

    }

  }

}               再次感谢回复的每个人,谢谢你们指教哈!


非常感谢前辈的细心回答,第一次发帖子,请见谅。不过我还是有点想不明白,所以把程序贴上来,请前辈们指教,不胜感激:这是一个16*16的点阵,通过两片74Hc595D级联来送位码和段码。第一个程序
#include<reg52.h>
#include <intrins.h>
unsigned char  segout[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //8列
unsigned char code tab[]={0x08,0x1C,0x3E,0x7F,0x1C,0x1C,0x1C,0x1C};
sbit LATCH = P1^0;
sbit SRCLK= P1^1;
sbit SER  = P1^2;
sbit LATCH_B = P2^2;
sbit SRCLK_B= P2^1;
sbit SER_B= P2^0;
void DelayUs2x(unsigned char t)        //延时
{   
while(--t);
}
void DelayMs(unsigned char t)       //延时
{
while(t--)
{
     DelayUs2x(245);
         DelayUs2x(245);
}
}
void SendByte(unsigned char dat)    //送段码
{   
  unsigned char i;
   for(i=0;i<8;i++)
        {
         SRCLK=0;
         SER=dat&0x80;
         dat<<=1;
         SRCLK=1;
         }
void Send2Byte(unsigned char dat1,unsigned char dat2)
{   
   SendByte(dat1);
   SendByte(dat2);      
}
void Out595(void)
{
        LATCH=1;
        _nop_();
        LATCH=0;
}
void SendSeg(unsigned char dat)              //  送位码
{   
unsigned char i;
   for(i=0;i<8;i++)             //发送字节
        {
         SRCLK_B=0;                                         //      这里是先0后1,上升沿。
         SER_B=dat&0x80;
         dat<<=1;
         SRCLK_B=1;
         }
      LATCH_B=1;           //锁存//    ?在这里为什么是先1而不是先0开始呢?74595                                                                      是上升沿锁存的。
      _nop_();
      LATCH_B=0;
  }
void main()
{
unsigned char i,j,k;
while(1)
{  
        for(i=0;i<8;i++) //8列显示
  {
         SendSeg(segout);
         Send2Byte(~tab,0xff);
         Out595();
         DelayMs(1);
         Send2Byte(0xff,0xff);
         Out595();
  }
}
}
第二个程序,这个不是16*16点阵的,但是是74595的,在串行输入移位的时候为什么又是先shcp1=1,后shcp1=0?不是上升沿才移位的吗?

#include<reg51.h>

#include <intrins.h>

#define uchar unsigned char

#define uint unsigned int

sbit stcp1=P2^2;  //STcp

sbit ds1=P2^1;   //DS

sbit shcp1=P2^0; //SHcp

sbit stcp2=P2^5;  //STcp

sbit ds2=P2^4;   //DS

sbit shcp2=P2^3; //SHcp

uchar code DAT[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};//共阴数码管显示码

uchar code tab[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};

uchar code wei[9]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff};

void delay(uint ms)

{                           

   uint x,y;

   for(x=ms;x>0;x--)

     for(y=255;y>0;y--);

}

void QR0_5951(uchar num1)

{

     uchar j;

     for (j=0;j<8;j++)

     {

      num1=num1<<1 ;

      ds1=CY;

      shcp1=1;//上升沿发生移位

      shcp1=0;

     }        

}

void OUT_5951()//将移位寄存器内的数据锁存到输出寄存器并显示

{

  stcp1=0;     

  stcp1=1;//上升沿将数据送到输出锁存器   

  stcp1=0;

}

void QR1_5952(uchar num2)

{

  uchar j;

  for (j=0;j<8;j++)

  {

    num2=num2<<1 ;

    ds2=CY;

    shcp2=1;//上升沿发生移位

    shcp2=0;

  }        

}                             

void OUT_5952()//将移位寄存器内的数据锁存到输出寄存器并显示

{

  stcp2=0;     

  stcp2=1;//上升沿将数据送到输出锁存器   

  stcp2=0;

}

void main()

{

  uchar i;

  while(1)

  {

    for(i=0;i<2;i++)

    {

      QR0_5951(DAT[0]);

      OUT_5951();

      QR1_5952(wei);

       OUT_5952();

       delay(1);         

    }

  }

}               再次感谢回复的每个人,谢谢你们指教哈!


非常感谢前辈的细心回答,第一次发帖子,请见谅。不过我还是有点想不明白,所以把程序贴上来,请前辈们指教,不胜感激:这是一个16*16的点阵,通过两片74Hc595D级联来送位码和段码。第一个程序
#include<reg52.h>
#include <intrins.h>
unsigned char  segout[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //8列
unsigned char code tab[]={0x08,0x1C,0x3E,0x7F,0x1C,0x1C,0x1C,0x1C};
sbit LATCH = P1^0;
sbit SRCLK= P1^1;
sbit SER  = P1^2;
sbit LATCH_B = P2^2;
sbit SRCLK_B= P2^1;
sbit SER_B= P2^0;
void DelayUs2x(unsigned char t)        //延时
{   
while(--t);
}
void DelayMs(unsigned char t)       //延时
{
while(t--)
{
     DelayUs2x(245);
         DelayUs2x(245);
}
}
void SendByte(unsigned char dat)    //送段码
{   
  unsigned char i;
   for(i=0;i<8;i++)
        {
         SRCLK=0;
         SER=dat&0x80;
         dat<<=1;
         SRCLK=1;
         }
void Send2Byte(unsigned char dat1,unsigned char dat2)
{   
   SendByte(dat1);
   SendByte(dat2);      
}
void Out595(void)
{
        LATCH=1;
        _nop_();
        LATCH=0;
}
void SendSeg(unsigned char dat)              //  送位码
{   
unsigned char i;
   for(i=0;i<8;i++)             //发送字节
        {
         SRCLK_B=0;                                         //      这里是先0后1,上升沿。
         SER_B=dat&0x80;
         dat<<=1;
         SRCLK_B=1;
         }
      LATCH_B=1;           //锁存//    ?在这里为什么是先1而不是先0开始呢?74595                                                                      是上升沿锁存的。
      _nop_();
      LATCH_B=0;
  }
void main()
{
unsigned char i,j,k;
while(1)
{  
        for(i=0;i<8;i++) //8列显示
  {
         SendSeg(segout);
         Send2Byte(~tab,0xff);
         Out595();
         DelayMs(1);
         Send2Byte(0xff,0xff);
         Out595();
  }
}
}
第二个程序,这个不是16*16点阵的,但是是74595的,在串行输入移位的时候为什么又是先shcp1=1,后shcp1=0?不是上升沿才移位的吗?

#include<reg51.h>

#include <intrins.h>

#define uchar unsigned char

#define uint unsigned int

sbit stcp1=P2^2;  //STcp

sbit ds1=P2^1;   //DS

sbit shcp1=P2^0; //SHcp

sbit stcp2=P2^5;  //STcp

sbit ds2=P2^4;   //DS

sbit shcp2=P2^3; //SHcp

uchar code DAT[11]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};//共阴数码管显示码

uchar code tab[10]={0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};

uchar code wei[9]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f,0xff};

void delay(uint ms)

{                           

   uint x,y;

   for(x=ms;x>0;x--)

     for(y=255;y>0;y--);

}

void QR0_5951(uchar num1)

{

     uchar j;

     for (j=0;j<8;j++)

     {

      num1=num1<<1 ;

      ds1=CY;

      shcp1=1;//上升沿发生移位

      shcp1=0;

     }        

}

void OUT_5951()//将移位寄存器内的数据锁存到输出寄存器并显示

{

  stcp1=0;     

  stcp1=1;//上升沿将数据送到输出锁存器   

  stcp1=0;

}

void QR1_5952(uchar num2)

{

  uchar j;

  for (j=0;j<8;j++)

  {

    num2=num2<<1 ;

    ds2=CY;

    shcp2=1;//上升沿发生移位

    shcp2=0;

  }        

}                             

void OUT_5952()//将移位寄存器内的数据锁存到输出寄存器并显示

{

  stcp2=0;     

  stcp2=1;//上升沿将数据送到输出锁存器   

  stcp2=0;

}

void main()

{

  uchar i;

  while(1)

  {

    for(i=0;i<2;i++)

    {

      QR0_5951(DAT[0]);

      OUT_5951();

      QR1_5952(wei);

       OUT_5952();

       delay(1);         

    }

  }

}               再次感谢回复的每个人,谢谢你们指教哈!


好利害的样子啊!

唉,你先看一下595的数据手册吧

小编程序自己写的,还是别人的?别人的程序不一定是对的。还得自己亲身去试验过才知道。
上升沿触发肯定是先电平再变高电平。发我的程序给你参考一下。要想知道你的驱动程序正不正确发送一个字节测试一下595的输出管脚正不正确就知道了。

  1. /*******************************************************************************
  2. * 函数名称       : HC595SendData
  3. * 函数功能                 : 595驱动函数,向SPI总线发送数据
  4. * 输入           : 传送数值
  5. * 输出                  : 无
  6. *******************************************************************************/
  7. void HC595SendData(unsigned char dat)
  8. {  
  9.         unsigned char i;
  10.                
  11.           for(i=0;i<8;i++)
  12.            {
  13.                 SER=dat>>7;
  14.                 dat<<=1;
  15.                 SCLK = 0;                    //产生上升沿,移位
  16.                 _nop_();                //产生方形波
  17.                 _nop_();
  18.                 SCLK = 1;       
  19.            }
  20.    
  21.         RCLK = 0;              //产生上升沿,锁存
  22.           _nop_();               //产生方形波
  23.           _nop_();
  24.           RCLK = 1;              

  25. }

复制代码

嗯,十分感谢你的回答,你的建议很好。我就是因为试过不行所以才抓狂的。我再试试吧,谢谢哈。

我试的时候别人的行,我改过成先低电平再高电平就不行了

我大概猜到是怎么回事了。小编是不是参照第二个程序写的?第二个程序是有问题的,不过他运行正常是看不出来的。

  1. void QR1_5952(uchar num2)
  2. {
  3.   uchar j;
  4.   for (j=0;j<8;j++)
  5.   {
  6.     num2=num2<<1 ;
  7.     ds2=CY;
  8.     shcp2=1;//上升沿发生移位
  9.     shcp2=0;
  10.   }        
  11. }   

复制代码


刚开始运行这个程序的时候,因为52管脚初始是高电平,第一次shcp2=1;是不产生上升沿的。但是以后再次运行到这来的时候shcp2的状态都是低电压,因此shcp2=1;就会产生上升沿。因此这个程序刚开始的时候是不正常的,以后每次都能正常。

  1. void OUT_5951()//将移位寄存器内的数据锁存到输出寄存器并显示
  2. {
  3.   stcp1=0;     
  4.   stcp1=1;//上升沿将数据送到输出锁存器   
  5.   stcp1=0;
  6. }

复制代码


他的锁存是有上升沿的。而你的却有问题。
你可以用我上次发给你的那个函数。将Out595();放在SendByte和SendSeg里面,那程序就不用再次调用Out595()了。
程序我就不帮你改了,希望可以帮到你,
有问题再上来问。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top