找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1590|回复: 10
收起左侧

单片机74HC595程序有些地方看不懂

[复制链接]
ID:890956 发表于 2021-10-13 19:34 | 显示全部楼层 |阅读模式
新手小白,正在学习74HC595,找了一串代码,有些地方看不懂,各位大佬帮忙解释一下。
1.dat可以帮忙解释一下吗,没有定义为什么没有报错?
2._nop_();为什么要连用两次,可以用一次吗,用一次和用两次有什么区别?
3.P0=0x7f;在这里是控制第一列的吧(这个不太确定),可以不加吗?

单片机源程序如下:
  1. #include "reg51.h"                        
  2. #include<intrins.h>


  3. typedef unsigned int u16;         
  4. typedef unsigned char u8;


  5. sbit SRCLK=P3^6;
  6. sbit RCLK=P3^5;
  7. sbit SER=P3^4;


  8. u8 ledduan[]={0x38,0x44,0x42,0x21,0x42,0x44,0x38,0x00};
  9. u8 ledwei[]={0x7f
  10. ,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};

  11. void delay(u16 i)
  12. {
  13.         while(i--);        
  14. }
  15. void Hc595SendByte(u8 dat)
  16. {
  17.         u8 a;
  18.         SRCLK=0;
  19.         RCLK=0;
  20.         for(a=0;a<8;a++)
  21.         {
  22.                 SER=dat>>7;
  23.                 dat<<=1;


  24.                 SRCLK=1;
  25.                 _nop_();
  26.                 _nop_();
  27.                 SRCLK=0;        
  28.         }


  29.         RCLK=1;
  30.         _nop_();
  31.         _nop_();
  32.         RCLK=0;
  33. }

  34. void main()
  35. {                        
  36.         u8 i;
  37.         while(1)
  38.         {
  39.                 P0=0x7f;
  40.                 for(i=0;i<8;i++)
  41.                 {
  42.                         P0=ledwei[i];                  
  43.                         Hc595SendByte(ledduan[i]);
  44.                         delay(100);                  
  45.                         Hc595SendByte(0x00);  
  46.                 }        
  47.         }               
  48. }
复制代码

回复

使用道具 举报

ID:624769 发表于 2021-10-13 20:42 | 显示全部楼层
用一次就是等一拍,用两次就是等两拍,只用一个,就是等的时间少了,根据你实际需求决定。

其实HC595频率可以高达27MHz, 如果你单片机的速度没有比他高,完全可以不用 NOP。反正我写HC595代码时从来不用NOP。
回复

使用道具 举报

ID:57657 发表于 2021-10-13 22:02 | 显示全部楼层
188610329 发表于 2021-10-13 20:42
用一次就是等一拍,用两次就是等两拍,只用一个,就是等的时间少了,根据你实际需求决定。

其实HC595频 ...

你还没用过硬件SPI驱动,速度更快,完全没有问题。
回复

使用道具 举报

ID:366464 发表于 2021-10-13 22:18 来自手机 | 显示全部楼层
百度就知道!不懂先问度妹!
Screenshot_20211013_221740_com.android.browser.jpg
回复

使用道具 举报

ID:839438 发表于 2021-10-14 08:05 | 显示全部楼层
你这个是驱动数码管的,最近也是在研究595 ,有的程序就没有nop ,这个是延时手册上有,dat 这个传参,我给你一个控制24个led 可以参考一下,我这个是最近抄的,多个可以这样一直下去
H595Sendbyte(0xff,0xff,0xff);
#include "74HC595.h"
sbit SRCLK=P3^2;//移位寄存器时钟(上升沿有效)
sbit RCLK=P3^3;//存储寄存器时钟(上升沿有效)
sbit sid=P4^3; //液晶LCD的sid与74hc595的ds工用
        /**
* @brief  595驱动函数
* @param  无
* @retval * 3个联级74HC595的工作过程:
* 每个74HC595内部都有一个8位的寄存器,两个联级起来就有两个寄存器。ST引脚就相当于一个刷新
* 信号引脚,当ST引脚产生一个上升沿信号时,就会把寄存器的数值输出到74HC595的输出引脚并且锁存起来,
* sid是数据引脚,SH是把新数据送入寄存器的时钟信号。也就是说,srclk引脚负责把数据送入到寄存器里,rclk引脚
* 负责把寄存器的数据更新输出到74HC595的输出引脚上并且锁存起来。
**/
void  H595Sendbyte(u8 dat1,u8 dat2,u8 dat3) //595输出函数,         dat1 第一个595, dat2 第二个 dat3 第三个
{
        unsigned char i;
        for(i = 0; i < 8; i ++)
        {
                if(dat3 >= 0x80)
                {
                        sid = 1;
                }
                else
                {
                        sid = 0;
                }
                SRCLK = 0;        /*引脚的上升沿把数据送入寄存器*/
                  _nop_();
      _nop_();
                SRCLK = 1;                       
                dat3 = dat3 <<1;
        }
        for(i = 0; i < 8; i ++)
        {
                if(dat2 >= 0x80)
                {
                        sid = 1;
                }
                else
                {
                        sid = 0;
                }
                SRCLK = 0;        /*Srck引脚的上升沿把数据送入寄存器*/
                  _nop_();
      _nop_();
                SRCLK = 1;                       
                dat2 = dat2 <<1;
        }
        //temp = dat1;        /*再先送低8位*/
        for(i = 0; i < 8; i ++)
        {
                if(dat1 >= 0x80)
                {
                        sid = 1;
                }
                else
                {
                        sid = 0;
                }
                 SRCLK = 0;        /*SH引脚的上升沿把数据送入寄存器*/
                  _nop_();
      _nop_();
                 SRCLK = 1;
                 dat1 = dat1 <<1;
        }
       
            RCLK = 0;        /*rclk引脚把3个寄存器的数据更新输出到74HC595的输出引脚上并且锁存起来*/
            _nop_();
      _nop_();
            RCLK = 1;

}
回复

使用道具 举报

ID:839438 发表于 2021-10-14 08:23 | 显示全部楼层
1.dat 没有定义,就没办法传参数,
2._nop_();有的程序都没有这句,只是延时的时间稍微长一点
我最近也在研究595,给你一个595驱动24个led 参考一下 如果是n个可以这么一直写下去
void  H595Sendbyte(u8 dat1,u8 dat2,u8 dat3) //595输出函数,         dat1 第一个595, dat2 第二个 dat3 第三个
{
        unsigned char i;
//        temp=dat3;
        for(i = 0; i < 8; i ++)
        {
                if(dat3 >= 0x80)
                {
                        sid = 1;
                }
                else
                {
                        sid = 0;
                }
                SRCLK = 0;        /*引脚的上升沿把数据送入寄存器*/
                  _nop_();
      _nop_();
                SRCLK = 1;                       
                dat3 = dat3 <<1;
        }
        for(i = 0; i < 8; i ++)
        {
                if(dat2 >= 0x80)
                {
                        sid = 1;
                }
                else
                {
                        sid = 0;
                }
                SRCLK = 0;        /*Srck引脚的上升沿把数据送入寄存器*/
                  _nop_();
      _nop_();
                SRCLK = 1;                       
                dat2 = dat2 <<1;
        }
        //temp = dat1;        /*再先送低8位*/
        for(i = 0; i < 8; i ++)
        {
                if(dat1 >= 0x80)
                {
                        sid = 1;
                }
                else
                {
                        sid = 0;
                }
                 SRCLK = 0;        /*SH引脚的上升沿把数据送入寄存器*/
                  _nop_();
      _nop_();
                 SRCLK = 1;
                 dat1 = dat1 <<1;
        }
       
            RCLK = 0;        /*rclk引脚把3个寄存器的数据更新输出到74HC595的输出引脚上并且锁存起来*/
            _nop_();
      _nop_();
            RCLK = 1;

}
回复

使用道具 举报

ID:332444 发表于 2021-10-14 09:12 | 显示全部楼层
回复

使用道具 举报

ID:123289 发表于 2021-10-14 09:31 | 显示全部楼层
单片机执行每一条指令都是需要时间的,
RCLK=1之后需要保持一段时间,就用NOP来耗时间,其实用其它指令也同样能达成目的。
用多少个,与需要延时量决定,你需要查看595的手册,了解这个时间量!
关键:是你对595的了解不够!
P0=0x7问题,需要你结合原理图,看P0口的接线。同样也需要你对595的了解透彻。
回复

使用道具 举报

ID:624769 发表于 2021-10-14 20:44 | 显示全部楼层
npn 发表于 2021-10-13 22:02
你还没用过硬件SPI驱动,速度更快,完全没有问题。

HC595严格来讲,属于移位寄存器,虽然,也可以用硬件SPI来传输,但是自由度不如软件控制来的高。

说来也奇怪,DS1302, 用硬件SPI传输会很爽,但是却没有人研究,还一个个的都说不是SPI,其实只是双线SPI用的少而已。反而HC595这种,本不是SPI,却特别热衷SPI传输。
回复

使用道具 举报

ID:57657 发表于 2021-10-18 10:06 | 显示全部楼层
188610329 发表于 2021-10-14 20:44
HC595严格来讲,属于移位寄存器,虽然,也可以用硬件SPI来传输,但是自由度不如软件控制来的高。

说来 ...

硬件SPI 通常用于与内存卡、物联网、USB模块、摄像头等高速传输数据,建议控制等长走线。
回复

使用道具 举报

ID:624769 发表于 2021-10-18 20:48 | 显示全部楼层
npn 发表于 2021-10-18 10:06
硬件SPI 通常用于与内存卡、物联网、USB模块、摄像头等高速传输数据,建议控制等长走线。

硬件SPI通常用于,完整字节的传输, HC595根据应用的需要,有时候,只是移位用,此时用硬件SPI反而不方便。所以,不能一概而论。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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