找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3194|回复: 6
收起左侧

关于三个hc595级联的单片机程序,朋友们能帮我看下对么?

[复制链接]
ID:897033 发表于 2021-4-20 10:43 | 显示全部楼层 |阅读模式
* 函 数 名         : Hc595Send3Byte(u8 dat1,u8 dat2,u8 dat3,)
* 函数功能                   : 通过595发送三个字节的数据
* 输    入         : dat1:第3个595输出数值
*                  * dat2: 第2个595输出数值
*                  * dat3:第1个595输出数值
** 输    出        : 无
*******************************************************************************/
void  lcd_hc_595_drive(unsigned char dat1,unsigned char dat2,unsigned char dat3)
{
   unsigned char i;
   unsigned char temp;
   temp=dat1;
           for(i=0;i<8;i++)         
   {
      // 第一步准备数据放到数据io端
     if(temp>=0x80)
            {
           HC595_DS1=1;
         }
         else
          {
         HC595_DS1=0;
         }
          HC595_SH_CP1=0;        //给一个上升沿,数据移进去了移位寄存器
          HC595_SH_CP1=1;
         temp<<=1;
   }
temp=dat2;
           for(i=0;i<8;i++)         
  {
  //        第一步准备数据放到数据io端
     if(temp>=0x80)
            {
          HC595_DS1=1;
         }
         else
        {
          HC595_DS1=0;
         }
         HC595_SH_CP1=0;        //给一个上升沿,数据移进去了移位寄存器
        HC595_SH_CP1=1;
         temp<<=1;
   }
   temp=dat3;
           for(i=0;i<8;i++)         
   {
  //        第一步准备数据放到数据io端
     if(temp>=0x80)
            {
          HC595_DS1=1;
         }
         else
         {
          HC595_DS1=0;
          }
          HC595_SH_CP1=0;        //给一个上升沿,数据移进去了移位寄存器
          HC595_SH_CP1=1;
          temp<<=1;
   }
          HC595_ST_CP1=0;        //给一个上升沿,数据移进去了存储寄存器    HC595_ST_CP1=1;
          HC595_ST_CP1=1;
        HC595_SH_CP1=0;//拉低,提高抗干扰能力
        HC595_ST_CP1=0;
        HC595_DS1=0;

}
回复

使用道具 举报

ID:824490 发表于 2021-4-20 16:03 | 显示全部楼层
你这个的有点烦琐了。。
只要定义一个8位的发送函数:HC_595_SEND_BYTE(u8 data)
然后调用3次
HC_595_SEND_BYTE(dat1);
HC_595_SEND_BYTE(dat2);
HC_595_SEND_BYTE(dat3);
最后再统一锁存、输出,就OK了

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:824490 发表于 2021-4-20 16:46 | 显示全部楼层
//595送出串行数据
void send_595(char dat)        //595发送1字节数据
{
    char count1;               //位计数器,单字节为8位
        for (count1=8;count1>0;count1--)
          {       
                hc595_sda=dat & 0x01;  //取最低位数据做为串行数据位,低位先发,若高位先发,则dat & 0x80
                hc595_sck=0;           //置SCK为低
                Delay10us();           //延时
                hc595_sck=1;               //置SCK为高
                Delay10us();               //延时,输出一个位的数据
                dat>>=1;               //数据右移,下一个位的数据,若高位先发则dat<<=1
          }
}



while(1)
{
            send_595(dat1);
            send_595(dat2);
            send_595(dat3);
            hc595_rck=0;
            hc595_rck=1;     //数据已发完,锁存595的数据
            hc595_oe=0;      //数据已锁存,使能595的输出

     }

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

ID:390416 发表于 2021-4-20 22:50 | 显示全部楼层
你可以去看看我的贴子 关于595点阵的 希望能帮到你
回复

使用道具 举报

ID:332444 发表于 2021-4-21 16:40 | 显示全部楼层
代码需要整理,相同的部分归纳一下,不同的部分通过逻辑处理,就会简洁许多,维护也方便许多.
上次我的连接接上点阵可以说明级联运行的情况,从而可以推导用于3个1602是完全可以的.不过要把我的代码稍加修改成移位运算适应进制数据.
无标题.png

回复

使用道具 举报

ID:155507 发表于 2021-4-26 21:26 | 显示全部楼层

用三个74hc595控制三个lcd1602,程序分享出来给需要的人作参考
3_595_1602.jpg



  1. #include <reg51.h>
  2. #include <stdio.h>
复制代码



回复

使用道具 举报

ID:155507 发表于 2021-4-26 21:36 | 显示全部楼层
angmall 发表于 2021-4-26 21:26
用三个74hc595控制三个lcd1602,程序分享出来给需要的人作参考
  1. //用三个74hc595控制三个lcd1602,
  2. #include <reg51.h>
  3. #include <stdio.h>

  4. //引脚定义
  5. sbit LCD1602_SHCP=P3^4;
  6. sbit LCD1602_DS=P3^5;
  7. sbit LCD1602_STCP=P3^6;
  8. sbit LCD1602_STCP2=P3^7;
  9. sbit LCD1602_STCP3=P3^3;

  10. //两种数据类型
  11. typedef unsigned char uchar;
  12. typedef unsigned int uint;

  13. //定义数据槽
  14. uchar RS,RW,E,D4,D5,D6,D7;

  15. //二进制的形象表示方法,从左到右分别位第7 6 5 4 3 2 1 0位
  16. #define bin(_a,_b,_c,_d,_e,_f,_g,_h) ((_a)<<7|(_b)<<6|(_c)<<5|(_d)<<4|(_e)<<3|(_f)<<2|(_g)<<1|(_h))        //二进制的表示

  17. void Lcd1602_Delay1ms(uint c); //延时函数,延时1ms
  18. void LCD1602_DATAPINS(uchar value, uchar  num); //更改74HC595连接LCD1602的数据
  19. void LcdCalc(uchar i); //确定4位总线
  20. void LcdWriteCom(uchar com, uchar  num); //向LCD写入一个字节的命令
  21. void LcdWriteData(uchar dat, uchar  num); //向LCD写入一个字节的数据
  22. void LcdInit(); //初始化LCD屏
  23. void LcdPrintf(uchar *s, uchar  num); //向屏幕输出字符
  24. void LcdWriteCGRAM(uchar index,uchar *p, uchar  num); //建立一个自定义字符
  25. void LCDPrintNum(uint number,uchar wei, uchar  num); //显示数字

  26. /*******************************************************************************
  27. * 函 数 名         : Lcd1602_Delay1ms
  28. * 函数功能                   : 延时函数,延时1ms
  29. * 输    入         : c
  30. * 输    出         : 无
  31. * 说    名         : 该函数是在12MHZ晶振下,12分频单片机的延时。
  32. *******************************************************************************/
  33. void Lcd1602_Delay1ms(uint c)   //误差 0us
  34. {
  35.         uchar a,b;
  36.         for(;c>0;c--){
  37.                 for(b=199;b>0;b--){
  38.                         for(a=1;a>0;a--);
  39.                 }
  40.         }
  41. }
  42. /*******************************************************************************
  43. * 函 数 名         : LCD1602_DATAPINS
  44. * 函数功能                   : 更改74HC595连接LCD1602的数据
  45. * 输    入         : value
  46. * 输    出         : 无
  47. *******************************************************************************/   
  48. void LCD1602_DATAPINS(uchar value, uchar  num)
  49. {
  50.     uchar i;
  51.     for(i=0;i<8;i++)
  52.     {
  53.         LCD1602_DS=value&0x80;//取数据高位
  54.         if(LCD1602_DS==0x80){ //判断数据高位是否为1
  55.             LCD1602_DS=1;//如果高位为1,DS置1
  56.         }
  57.         else{
  58.             LCD1602_DS=0;//否则DS置0
  59.         }
  60.         LCD1602_SHCP=0;
  61.         LCD1602_SHCP=1;//上升沿使这一位写入移位寄存器
  62.         value<<=1;//数据左移1位,数据的第7位变为最高位,循环第8次时数据的最低位也变成最高位
  63.     }
  64. if (num==2)
  65. {
  66.     LCD1602_STCP3=0;
  67.     LCD1602_STCP3=1;//给STCP一个上升沿,将for循环中输入的数据移入输出锁存寄存器,刷新输出数据
  68. }
  69. else if(num==1)
  70. {
  71.     LCD1602_STCP2=0;
  72.     LCD1602_STCP2=1;//给STCP一个上升沿,将for循环中输入的数据移入输出锁存寄存器,刷新输出数据
  73. }
  74. else
  75. {
  76.     LCD1602_STCP=0;
  77.     LCD1602_STCP=1;//给STCP一个上升沿,将for循环中输入的数据移入输出锁存寄存器,刷新输出数据
  78. }

  79. }
  80. /*******************************************************************************
  81. * 函 数 名         : LcdCalc
  82. * 函数功能                   : 确定4位总线
  83. * 输    入         : i
  84. * 输    出         : 无
  85. *******************************************************************************/   
  86. void LcdCalc(uchar i)
  87. {
  88.         if(i==0x00){
  89.                 D4=0;
  90.                 D5=0;
  91.                 D6=0;
  92.                 D7=0;
  93.         }
  94.         if(i==0x01){
  95.                 D4=1;
  96.                 D5=0;
  97.                 D6=0;
  98.                 D7=0;
  99.         }
  100.         if(i==0x02){
  101.                 D4=0;
  102.                 D5=1;
  103.                 D6=0;
  104.                 D7=0;
  105.         }
  106.         if(i==0x03){
  107.                 D4=1;
  108.                 D5=1;
  109.                 D6=0;
  110.                 D7=0;
  111.         }
  112.         if(i==0x04){
  113.                 D4=0;
  114.                 D5=0;
  115.                 D6=1;
  116.                 D7=0;
  117.         }
  118.         if(i==0x05){
  119.                 D4=1;
  120.                 D5=0;
  121.                 D6=1;
  122.                 D7=0;
  123.         }
  124.         if(i==0x06){
  125.                 D4=0;
  126.                 D5=1;
  127.                 D6=1;
  128.                 D7=0;
  129.         }
  130.         if(i==0x07){
  131.                 D4=1;
  132.                 D5=1;
  133.                 D6=1;
  134.                 D7=0;
  135.         }
  136.         if(i==0x08){
  137.                 D4=0;
  138.                 D5=0;
  139.                 D6=0;
  140.                 D7=1;
  141.         }
  142.         if(i==0x09){
  143.                 D4=1;
  144.                 D5=0;
  145.                 D6=0;
  146.                 D7=1;
  147.         }
  148.         if(i==0x0a){
  149.                 D4=0;
  150.                 D5=1;
  151.                 D6=0;
  152.                 D7=1;
  153.         }
  154.         if(i==0x0b){
  155.                 D4=1;
  156.                 D5=1;
  157.                 D6=0;
  158.                 D7=1;
  159.         }
  160.         if(i==0x0c){
  161.                 D4=0;
  162.                 D5=0;
  163.                 D6=1;
  164.                 D7=1;
  165.         }
  166.         if(i==0x0d){
  167.                 D4=1;
  168.                 D5=0;
  169.                 D6=1;
  170.                 D7=1;
  171.         }
  172.         if(i==0x0e){
  173.                 D4=0;
  174.                 D5=1;
  175.                 D6=1;
  176.                 D7=1;
  177.         }
  178.         if(i==0x0f){
  179.                 D4=1;
  180.                 D5=1;
  181.                 D6=1;
  182.                 D7=1;
  183.         }
  184.         if(i==0x10){
  185.                 D4=1;
  186.                 D5=0;
  187.                 D6=0;
  188.                 D7=0;
  189.         }
  190.         if(i==0x20){
  191.                 D4=0;
  192.                 D5=1;
  193.                 D6=0;
  194.                 D7=0;
  195.         }
  196.         if(i==0x30){
  197.                 D4=1;
  198.                 D5=1;
  199.                 D6=0;
  200.                 D7=0;
  201.         }
  202.         if(i==0x40){
  203.                 D4=0;
  204.                 D5=0;
  205.                 D6=1;
  206.                 D7=0;
  207.         }
  208.         if(i==0x50){
  209.                 D4=1;
  210.                 D5=0;
  211.                 D6=1;
  212.                 D7=0;
  213.         }
  214.         if(i==0x60){
  215.                 D4=0;
  216.                 D5=1;
  217.                 D6=1;
  218.                 D7=0;
  219.         }
  220.         if(i==0x70){
  221.                 D4=1;
  222.                 D5=1;
  223.                 D6=1;
  224.                 D7=0;
  225.         }
  226.         if(i==0x80){
  227.                 D4=0;
  228.                 D5=0;
  229.                 D6=0;
  230.                 D7=1;
  231.         }
  232.         if(i==0x90){
  233.                 D4=1;
  234.                 D5=0;
  235.                 D6=0;
  236.                 D7=1;
  237.         }
  238.         if(i==0xa0){
  239.                 D4=0;
  240.                 D5=1;
  241.                 D6=0;
  242.                 D7=1;
  243.         }
  244.         if(i==0xb0){
  245.                 D4=1;
  246.                 D5=1;
  247.                 D6=0;
  248.                 D7=1;
  249.         }
  250.         if(i==0xc0){
  251.                 D4=0;
  252.                 D5=0;
  253.                 D6=1;
  254.                 D7=1;
  255.         }
  256.         if(i==0xd0){
  257.                 D4=1;
  258.                 D5=0;
  259.                 D6=1;
  260.                 D7=1;
  261.         }
  262.         if(i==0xe0){
  263.                 D4=0;
  264.                 D5=1;
  265.                 D6=1;
  266.                 D7=1;
  267.         }
  268.         if(i==0xf0){
  269.                 D4=1;
  270.                 D5=1;
  271.                 D6=1;
  272.                 D7=1;
  273.         }
  274. }
  275. /*******************************************************************************
  276. * 函 数 名         : LcdWriteCom
  277. * 函数功能                   : 向LCD写入一个字节的命令
  278. * 输    入         : com
  279. * 输    出         : 无
  280. *******************************************************************************/
  281. void LcdWriteCom(uchar com, uchar  num)          //写入命令
  282. {
  283.         E = 0;         //使能清零
  284.         RS = 0;         //选择写入命令
  285.         RW = 0;         //选择写入

  286.         LcdCalc(com>>4);        //发送高四位
  287.         Lcd1602_Delay1ms(1);

  288.         E = 1;         //写入时序
  289.         LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS),num);
  290.         Lcd1602_Delay1ms(5);
  291.         E = 0;
  292.         LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS),num);

  293.         LcdCalc(com<<4); //发送低四位
  294.         Lcd1602_Delay1ms(1);

  295.         E = 1;         //写入时序
  296.         LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS),num);
  297.         Lcd1602_Delay1ms(5);
  298.         E = 0;
  299.         LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS),num);
  300. }
  301. /****************************************************************************
  302. * 函 数 名         : LcdWriteData
  303. * 函数功能                   : 向LCD写入一个字节的数据
  304. * 输    入         : dat
  305. * 输    出         : 无
  306. *******************************************************************************/                             
  307. void LcdWriteData(uchar dat, uchar  num)                        //写入数据
  308. {
  309.         E = 0;         //使能清零
  310.         RS = 1;         //选择写入数据
  311.         RW = 0;         //选择写入

  312.         LcdCalc(dat>>4);        //发送高四位
  313.         Lcd1602_Delay1ms(1);

  314.         E = 1;         //写入时序
  315.         LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS),num);
  316.         Lcd1602_Delay1ms(5);
  317.         E = 0;
  318.         LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS),num);

  319.         LcdCalc(dat<<4); //发送低四位
  320.         Lcd1602_Delay1ms(1);

  321.         E = 1;         //写入时序
  322.         LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS),num);
  323.         Lcd1602_Delay1ms(5);
  324.         E = 0;
  325.         LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS),num);
  326. }
  327. /*******************************************************************************
  328. * 函 数 名       : LcdInit
  329. * 函数功能                 : 初始化LCD屏
  330. * 输    入       : 无
  331. * 输    出       : 无
  332. *******************************************************************************/                  
  333. void LcdInit()                                                  //LCD初始化子程序
  334. {
  335.         LcdWriteCom(0x32,0);         //将8位总线转为4位总线
  336.         LcdWriteCom(0x28,0);         //在四位线下的初始化
  337.         LcdWriteCom(0x0c,0);  //开显示不显示光标
  338.         LcdWriteCom(0x06,0);  //写一个指针加1
  339.         LcdWriteCom(0x01,0);  //清屏
  340.         LcdWriteCom(0x80,0);  //设置数据指针起点

  341.         LcdWriteCom(0x32,1);         //将8位总线转为4位总线
  342.         LcdWriteCom(0x28,1);         //在四位线下的初始化
  343.         LcdWriteCom(0x0c,1);  //开显示不显示光标
  344.         LcdWriteCom(0x06,1);  //写一个指针加1
  345.         LcdWriteCom(0x01,1);  //清屏
  346.         LcdWriteCom(0x80,1);  //设置数据指针起点

  347.         LcdWriteCom(0x32,2);         //将8位总线转为4位总线
  348.         LcdWriteCom(0x28,2);         //在四位线下的初始化
  349.         LcdWriteCom(0x0c,2);  //开显示不显示光标
  350.         LcdWriteCom(0x06,2);  //写一个指针加1
  351.         LcdWriteCom(0x01,2);  //清屏
  352.         LcdWriteCom(0x80,2);  //设置数据指针起点

  353. }
  354. /*******************************************************************************
  355. * 函 数 名       : LcdPrintf
  356. * 函数功能                 : 向屏幕输出字符
  357. * 输    入       : *s
  358. * 输    出       : 无
  359. *******************************************************************************/
  360. void LcdPrintf(uchar *s, uchar  num)
  361. {
  362.         while(*s>0)LcdWriteData(*s++, num);
  363. }
  364. /*******************************************************************************
  365. * 函 数 名       : LcdWriteCGRAM
  366. * 函数功能                 : 建立一个自定义字符
  367. * 输    入       : index、*p
  368. * 输    出       : 无
  369. *******************************************************************************/
  370. void LcdWriteCGRAM(uchar index,uchar *p, uchar  num)
  371. {
  372.         uchar i;
  373.         index <<=3; //index *= 8
  374.         for(i=0;i<8;++i){
  375.                 LcdWriteCom(0x40 | index+i, num);//写CGRAM地址
  376.                 LcdWriteData(*p++, num);
  377.         }
  378.         LcdWriteCom(0x80, num);
  379. }
  380. /*******************************************************************************
  381. * 函 数 名       : LcdPrintNum
  382. * 函数功能                 : 显示数字
  383. * 输    入       : num、wei
  384. * 输    出       : 无
  385. *******************************************************************************/
  386. void LCDPrintNum(uint number,uchar wei, uchar  num)//wei 数字占的位数
  387. {
  388.         uchar tempstring[6];
  389.         uchar n[5];
  390.         uchar i,j=0;
  391.         n[0]=number/10000;
  392.         n[1]=number%10000/1000;
  393.         n[2]=number%1000/100;
  394.         n[3]=number%100/10;
  395.         n[4]=number%10;
  396.         i=5-wei;
  397.         for(i;i<5;i++){
  398.                 tempstring[j++]=n[i]+'0';       
  399.         }
  400.         tempstring[j]='\0';
  401.         LcdPrintf(tempstring, num);
  402. }


  403. const uchar type_t[]={
  404.   0x1f,0x02,0x02,0x02,
  405.         0x02,0x02,0x02,0x00
  406. }; //显示一种用于以前的logo的“T”字符

  407. const uchar line1[]="Have a nice day!";
  408. const uchar line2[]="HE Wcommands";

  409. void main()
  410. {
  411.         uchar i;
  412.         LcdInit();
  413.         LcdWriteCGRAM(0x00,type_t,0);
  414.         LcdWriteData(0x00,0);
  415.         LcdWriteCom(0x81,0);
  416.         LcdPrintf("HE With",0);
  417.         LcdWriteCom(0xc0,0);
  418.         LcdPrintf("Commands",0);
  419.         Lcd1602_Delay1ms(1000);
  420.         LcdWriteCGRAM(0x00,type_t,1);
  421.         LcdWriteData(0x00,1);
  422.         LcdWriteCom(0x81,1);
  423.         LcdPrintf("HE With",1);
  424.         LcdWriteCom(0xc0,1);
  425.         LcdPrintf("2nd Display",1);
  426.         Lcd1602_Delay1ms(500);
  427.         LcdWriteCGRAM(0x00,type_t,2);
  428.         LcdWriteData(0x00,2);
  429.         LcdWriteCom(0x81,2);
  430.         LcdPrintf("HE With",2);
  431.         LcdWriteCom(0xc0,2);
  432.         LcdPrintf("3rd Display",2);
  433.         Lcd1602_Delay1ms(500);
  434.         LcdWriteCom(0x01,0);
  435.         while(1){
  436.                 for(i=0;i<16;i++){
  437.                         LcdWriteCom(0x80+i,0);
  438.                         LcdWriteData(line1[i],0);
  439.                         Lcd1602_Delay1ms(100);
  440.                 }
  441.                 Lcd1602_Delay1ms(500);
  442.                 LcdWriteCom(0xc1,0);
  443.                 LcdWriteData(0x00,0);
  444.                 Lcd1602_Delay1ms(100);
  445.                 for(i=0;i<12;i++){
  446.                         LcdWriteCom(0xc2+i,0);
  447.                         LcdWriteData(line2[i],0);
  448.                         Lcd1602_Delay1ms(100);
  449.                 }
  450.                 LcdWriteCom(0x01,0);
  451.                 Lcd1602_Delay1ms(100);
  452.         }
  453. }

复制代码
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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