搜索
bottom↓
回复: 17

马老师,请问您书上的(354页)的595真值表和下面的驱动函数,我对他有很大的疑问,请批评指点

[复制链接]

出0入0汤圆

发表于 2010-10-29 21:23:20 | 显示全部楼层 |阅读模式
1、您书中595的真值表中有下降沿,但有的pdf中怎么没有呢?---见下图

2、不管是下面的函数还是我改过后,595驱动的结果都一样,不知为什么。
void Hc595_send_byte(unsigned char byte)
{
     unsigned char i;
     for(i=0;i<8;i++)
     {
          if(byte&0x80)
               Hc595_data=1;
          else
               Hc595_data=0;
          byte <<=1;
          Hc595_clk=1;//下降沿
          Hc595_clk=0;     
     }
     Hc595_stcp=1;//下降沿
     Hc595_stcp=0;
}
改过后的
void Hc595_send_byte(unsigned char byte)
{
     unsigned char i;
     for(i=0;i<8;i++)
     {
          if(byte&0x80)
               Hc595_data=1;
          else
               Hc595_data=0;
          byte <<=1;
          Hc595_clk=0;//上降沿
          Hc595_clk=1;     
     }
     Hc595_stcp=0;//上降沿
     Hc595_stcp=1;
}



(原文件名:33.jpg)


(原文件名:45.jpg)


(原文件名:儿童.jpg)


(原文件名:595(philip).jpg)

请马老师指点迷津啊,先谢谢了

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入0汤圆

发表于 2010-10-30 00:07:19 | 显示全部楼层
书上的表我做过整理的,为了更清楚一点。

对于595,不管是CLK,还是LATCH,都是上升沿起作用的,下降沿没有动作。

另外的考虑是CLK和LATCH的准备状态(起始/结束)的电平,由于595只是上升沿有动作,所以准备状态为高或低电平都可以。但我建议为低电平,这样第1次改变电平状态就意味这操作,操作完后,拉到低电平,保持。如果准备状态是高电平,那么是在第2次改变电平才操作。

你的两段代码都能正确的操作595,区别在2点:
void Hc595_send_byte(unsigned char byte)
{
     unsigned char i;
     for(i=0;i<8;i++)
     {
          if(byte&0x80)
               Hc595_data=1;
          else  
               Hc595_data=0;
          byte <<=1;
          Hc595_clk=1;   //下降沿(这个解释不对!)===》 产生上升沿,打入数据
          Hc595_clk=0;   //                        ===》 产生下降沿,回到准备状态,停留在低电平   
     }
     Hc595_STCp=1;       //下降沿XX                ===》 产生上升沿,锁存数据  
     Hc595_STCp=0;       //                        ===》 产生下降沿,回到准备状态,停留在低电平

void Hc595_send_byte(unsigned char byte)
{
     unsigned char i;
     for(i=0;i<8;i++)
     {
          if(byte&0x80)
               Hc595_data=1;
          else  
               Hc595_data=0;
          byte <<=1;
          Hc595_clk=0;   //xx上降沿            //产生下降沿,无用
          Hc595_clk=1;                         //产生上升沿,打入数据,同时也是返回准备状态,停留在高电平
     }
     Hc595_STCp=0;       //xx上降沿            //产生下降沿,无用
     Hc595_STCp=1;                             //产生上升沿,打入数据,同时也是返回准备状态,停留在高电平
}

对于串行通信,CLK的准备状态是什么,上升沿/下降沿做什么,都是非常重要的,思路要非常清晰。595属于比较简单的,只有上升沿有作用。而SPI就复杂了,上升沿/下降沿都有动作,而且还跟准备状态有关。如果不清楚,就非常容易出错。

出0入12汤圆

发表于 2010-10-30 08:27:45 | 显示全部楼层
对头,我以前也是这样,对  准备状态 这个理解不足

出0入0汤圆

发表于 2010-10-30 19:01:28 | 显示全部楼层
明白了,马老师说的很清楚~o(∩_∩)o...

出0入0汤圆

发表于 2010-10-30 19:07:25 | 显示全部楼层
mark

出0入0汤圆

 楼主| 发表于 2010-10-30 19:48:14 | 显示全部楼层
回复【1楼】machao
-----------------------------------------------------------------------

马老师这么晚了还在回帖,您太辛苦了。经过您的讲解,我终于明白了,再次感谢一下!!!

再请教一个问题:

您书上写的是
void Hc595_send_byte(unsigned char byte)  
{  
     unsigned char i;  
     for(i=0;i<=7;i++)  
     {   
          Hc595_data=byte&1<<i;   
          Hc595_clk=1;   
          Hc595_clk=0;      
     }
}
其中:Hc595_data=byte&1<<i;  Hc595_data的值应该为0或1,但我在ICCavr6.31a中这样写,结果是错的, 即用函数Hc595_send_byte(unsigned char byte);发送的字符时发出的编码不正确,我改成
if(byte&0x80)  
       Hc595_data=1;  
else   
       Hc595_data=0;  
就对了。

例如:Hc595_data=0x40&0x50,Hc595_data=1;呢还是Hc595_data=0x40呢,假如Hc595_data=0x40的话,那结果就错了

请马老师指点

出0入0汤圆

 楼主| 发表于 2010-10-30 20:43:53 | 显示全部楼层
回复【1楼】machao
-----------------------------------------------------------------------

马老师,我还有一个疑问:
初始化时:

Hc595_clk=1;
Hc595_STCp=1;  

执行下面的函数后,在第一个for循环中并没有上升沿产生,所以byte的最高位没有被送入锁存器里,所以一位数据已经丢失了
我这样理解对吗???

我按这样的写法把程序下进去后刚上电时总是有led不亮,而等会儿就正常了

void Hc595_send_byte(unsigned char byte)  
{  
     unsigned char i;  
     for(i=0;i<8;i++)  
     {  
          if(byte&0x80)  
               Hc595_data=1;  
          else   
               Hc595_data=0;  
          byte <<=1;  
          Hc595_clk=1;   //xx上降沿            //产生下降沿,无用
          Hc595_clk=0;                         //产生上升沿,打入数据,同时也是返回准备状态,停留在高电平
     }  
     Hc595_STCp=1;       //xx上降沿            //产生下降沿,无用
     Hc595_STCp=0;                             //产生上升沿,打入数据,同时也是返回准备状态,停留在高电平
}

出0入0汤圆

发表于 2010-10-30 20:54:28 | 显示全部楼层
1楼的回答我也有点不懂得地方,希望马老师帮忙解答,谢谢。
  Hc595_clk=1;   //下降沿(这个解释不对!)===》 产生上升沿,打入数据  
  Hc595_clk=0;   //                        ===》 产生下降沿,回到准备状态,停留在低电平
  
这个默认就是认为准备状态的电平是0(Hc595_clk=0)这样才能产生上升沿。Hc595_clk=0;是如何得来? 假设接的是51单片机IO端口,默认的话 Hc595_clk=1 啊? 不是很明白,这个内容是十二章的,没看见有初始化。望解答。

Hc595_clk=0;   //xx上降沿            //产生下降沿,无用
Hc595_clk=1;                         //产生上升沿,打入数据,同时也是返回准备状态,停留在高电平

这个默认就是认为准备状态电平是1(Hc595_clk=1)这样才能产生下降升沿,无用。Hc595_clk=1;是如何得来得?
是不是51单片机或avr初始化得到的呢?

出0入0汤圆

发表于 2010-10-30 20:56:44 | 显示全部楼层
mark

出0入0汤圆

发表于 2010-10-30 21:07:42 | 显示全部楼层
回复【1楼】machao
-----------------------------------------------------------------------

我在7楼的疑问 和 6楼的 差不多。

出0入0汤圆

发表于 2010-11-1 00:35:54 | 显示全部楼层
回复【6楼】guxingganyue ,【7楼】 scort

请仔细、全面、踏实的学习。代码只是参考,不同的环境下需要做修改的。

我用的是CVAVR,这个C支持位(bit)变量的。代码中的Hc595_clk、Hc595_data都是位变量。ICC不支持位变量,你这样写有问题的。


在初始化时,当然应该把CLK和stcp设置在准备状态。

下面是六楼有问题的代码(不知道6楼是否仔细看了我在1楼的代码解释,6楼的解释怎么还是反的!)

Hc595_clk=1;   
Hc595_STCp=1;   
// 以上是初始化,把2个信号的准备状态定在高电平

void Hc595_send_byte(unsigned char byte)   
{   
     unsigned char i;   
     for(i=0;i<8;i++)   
     {   
          if(byte&0x80)   
               Hc595_data=1;   
          else   
               Hc595_data=0;   
          byte <<=1;   
          Hc595_clk=1;   //xx上降沿            //产生下降沿,无用 ???
          Hc595_clk=0;                         //产生上升沿,打入数据,同时也是返回准备状态,停留在高电平???  
     }   
     Hc595_STCp=1;       //xx上降沿            //产生下降沿,无用  ???
     Hc595_STCp=0;                             //产生上升沿,打入数据,同时也是返回准备状态,停留在高电平 ???
}   

     //那么在第一次循环中没有产生上升沿,只有一个下降沿。这意味者第1位根本没有打入!

出0入0汤圆

 楼主| 发表于 2010-11-1 15:52:47 | 显示全部楼层
回复【10楼】machao
-----------------------------------------------------------------------

马老师,我的意思是那样第一次循环后,byte <<=1;  是左移了一位(但这一位并没有移入移位寄存器啊,丢失了),第二次循环时送入移位寄存器的位是byte的第二位(次高位),那么byte的最高位不就没有送入移位寄存器吗???这样就导致了一位数据的丢失

出0入0汤圆

发表于 2010-11-1 18:38:36 | 显示全部楼层
laotan

出0入0汤圆

 楼主| 发表于 2010-11-1 19:43:22 | 显示全部楼层
回复【10楼】machao
-----------------------------------------------------------------------
马老师,我认为这样写也不是什么错误,只能说明我的595程序写的不够健壮,初始化函数应该不要求唯一的写法

Hc595_clk=1;     
Hc595_STCp=1;   
// 以上是初始化,把2个信号的准备状态定在高电平

void Hc595_send_byte(unsigned char byte)   
{   
     unsigned char i;   
     for(i=0;i<8;i++)   
     {   
          if(byte&0x80)   
               Hc595_data=1;   
          else     
               Hc595_data=0;   
          byte <<=1;   
          Hc595_clk=1;   //xx上降沿            //产生下降沿,无用 ???  
          Hc595_clk=0;                         //产生上升沿,打入数据,同时也是返回准备状态,停留在高电平???   
     }   
     Hc595_STCp=1;       //xx上降沿            //产生下降沿,无用  ???
     Hc595_STCp=0;                             //产生上升沿,打入数据,同时也是返回准备状态,停留在高电平 ???
}   



可以改为

Hc595_clk=1;     
Hc595_STCp=1;   
// 以上是初始化,把2个信号的准备状态定在高电平

void Hc595_send_byte(unsigned char byte)   
{   
     unsigned char i;   
     for(i=0;i<8;i++)   
     {   
          if(byte&0x80)   
               Hc595_data=1;   
          else     
               Hc595_data=0;   
          byte <<=1;
          Hc595_clk=0;    //写成这样的话无论怎么初始化都应该没问题的
          Hc595_clk=1;  
          Hc595_clk=0;                        
     }  
     Hc595_STCp=0;    //写成这样的话无论怎么初始化都应该没问题的
     Hc595_STCp=1;               
     Hc595_STCp=0;         
}

出0入0汤圆

发表于 2011-10-7 22:31:54 | 显示全部楼层
good,我用PIC验证13楼的程序没问题。

出0入0汤圆

发表于 2011-10-7 23:10:48 | 显示全部楼层
this is what I typically do:


void Hc595_send_byte(unsigned char byte)     
{     
     unsigned char i;     
     for(i=0;i<8;i++)     
     {     
          Hc595_clk=0;    //写成这样的话无论怎么初始化都应该没问题的
          if(byte&0x80)     
               Hc595_data=1;     
          else      
               Hc595_data=0;     
          Hc595_clk=1;   
          //Hc595_clk=0;                        
          byte <<=1;  
     }   
     //Hc595_STCp=0;    //写成这样的话无论怎么初始化都应该没问题的
     //Hc595_STCp=1;               
     //Hc595_STCp=0;         
}     

it has the advantage of 1) requires no initialization; and 2) produces near 50% dc on clk, and 3) you can handle STCp separately - useful for multi-byte writes and can be easily replaced with a hardware spi routine.

出0入0汤圆

发表于 2011-10-7 23:25:49 | 显示全部楼层
顶m&m.

出0入0汤圆

发表于 2011-11-15 13:12:02 | 显示全部楼层
do mark
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 02:52

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表