找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 671|回复: 2
打印 上一主题 下一主题
收起左侧

51单片机1602液晶显示 有没有大佬给一个程序 试了很多次都不对 求分享

[复制链接]
跳转到指定楼层
#
ID:1026695 发表于 2022-5-15 14:14 来自手机 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
有没有大佬给一个程序 试了很多次 都不对
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1012735 发表于 2022-5-16 17:26 | 只看该作者
LCD1602.H
  1. #ifndef __LCD1604__H
  2. #define        __LCD1604__H

  3. #include "def.h"

  4. //行控制码1602&1604通用
  5. #define LINE0                0x80
  6. #define LINE1                0xC0
  7. #define        LINE2                0x90
  8. #define        LINE3                0xD0
  9.        
  10. #ifdef _USE_SHOP_A_
  11. //P2口接LCD的D0~D7
  12. #define LCD1602_DATA        P2
  13. //LCD的RS、RW、E脚
  14. sbit LCD1602_RS        = P0^4;
  15. sbit LCD1602_E  = P0^5;
  16. sbit LCD1602_RW        =        P0^6;
  17. //与LCD12864用同一P2口
  18. //置PSB=1插上也能亮
  19. sbit PSB        =        P0^7;
  20. #endif

  21. #ifdef _LY5A_L2A_
  22. sbit        BEEP        =        P1^5;
  23. #define        LED_PORT        P2
  24. //P2口接LCD的D0~D7
  25. #define LCD1602_DATA        P0
  26. //LCD的RS、RW、E脚
  27. sbit LCD1602_RS        = P1^0;
  28. sbit LCD1602_RW        =        P1^1;
  29. sbit LCD1602_E  = P1^2;
  30. //与LCD12864用同一P2口
  31. //置PSB=1插上也能亮
  32. sbit PSB        =        P1^6;

  33. #endif


  34. //LCD初如化
  35. void LcdInit();

  36. //LCD清屏
  37. void LcdClr();

  38. //清某一行
  39. void LcdClr0();
  40. void LcdClr1();
  41. //void LcdClr2();
  42. //void LcdClr3();


  43. /*****************************************************************************************
  44. * 在指定坐标显示整型数字
  45. *------------------------
  46. * x,y : 横纵屏幕坐标(列,行)
  47. * num : 要显示的整型数字
  48. * nDispW: 要显示的占位宽度(0~16个字符),0-基本的显示,不设定(后两位参就无意义了)
  49. * bRightAlign : 0-左对齐,1-右对齐
  50. * bLeftAdd0   : 右对齐时的数字前导空,左边是否补0,0-不补0,1-补0
  51. *******************************************************************************************/
  52. void LcdDisplayNum(u8 x, u8 y, const long num, u8 nDispW , bool bRightAlign, bool bLeftAdd0);



  53. /**********************************************
  54. * 在指定(列,行)位置显示字符串
  55. **********************************************/
  56. void LcdDisplayStr(u8 x, u8 y, const char *msg);



  57. #endif
复制代码


LCD1604.c
  1. ///////////////////////////////////////////////////////////////////////////////////////
  2. // LCD1602&LCD1604字符显示功能
  3. //
  4. // LCD1602_RW 不用功能电路不接入这个脚
  5. //-----------------------------------------------------------------------------------

  6. #include <string.h>
  7. #include <intrins.h>
  8. #include "LCD1602.h"


  9. void delay1Cycle(unsigned int cycle)
  10. {
  11.         unsigned int i;
  12.         for(i=0; i<cycle; i++)
  13.         {
  14.                 _nop_();
  15.         }
  16. }

  17. /*OK
  18. bool LcdBusy()
  19. {
  20.                 bit b;
  21.                 LCD1602_RS = 0;
  22.                 LCD1602_RW = 1;
  23.                 delay1Cycle(5);
  24.                 LCD1602_E = 1;
  25.                 delay1Cycle(5);
  26.                 b = LCD1602_DATA & 0x80;
  27.                 LCD1602_E = 0;
  28.        
  29.                 return b;
  30. }
  31. */
  32. //------------------------------------------------
  33. //LCD E口跳变时,LCD显示一个字符/接收一个指令
  34. //RS=0:命令指令,RS=1:显示数据指令
  35. //------------------------------------------------
  36. void LcdWriteInfo( u8 RS, u8 RW, u8 dat )
  37. {
  38.         //while(LcdBusy());
  39.        
  40.         LCD1602_RS = RS;
  41.         LCD1602_E  = 0;
  42.         LCD1602_RW = RW;
  43.        
  44.         LCD1602_DATA = dat;
  45.         delay1Cycle(5);
  46.        
  47.         LCD1602_E  = 1;
  48.         delay1Cycle(5);
  49.         LCD1602_E  = 0;
  50.         delay1Cycle(25);
  51. }


  52. //---------------------------
  53. //RS=0,指令寄存器
  54. //RW=0,写数据
  55. //---------------------------
  56. void LcdWriteCom( u8 com )
  57. {
  58.         LcdWriteInfo( 0, 0, com );
  59. }

  60. //--------------------------
  61. //RS=1,数据寄存器
  62. //--------------------------
  63. void LcdWriteData(u8 dat)
  64. {
  65.         LcdWriteInfo( 1, 0, dat );
  66. }


  67. //---------------
  68. //LCD初如化
  69. //---------------
  70. void LcdInit()
  71. {
  72.         //要等待开机启稳
  73.         //否则显示错位不全
  74.         delay1Cycle(1000);
  75.         PSB = 1;                                                //与开发板LCD12864同一数据口
  76.                                                                                         //让12864插上也能有字,但...
  77.         LcdWriteCom(0x38); //开显示:0011 1000
  78.         LcdWriteCom(0x38); //刚开机,各方电位还不稳定
  79.         LcdWriteCom(0x38); //重要的事情说三便
  80.         LcdWriteCom(0x0c); //不显示光标:0000 1100
  81.         LcdWriteCom(0x06); //光标右移:0000 0110
  82.         LcdWriteCom(0x01); //清屏
  83.         //别着急,抽根烟
  84.         delay1Cycle(1000);
  85. }

  86. //---------------
  87. //LCD清屏
  88. //---------------
  89. /*OK
  90. void LcdClr()
  91. {
  92.         LcdWriteCom(0x01); //清屏
  93. }
  94. */
  95. /**********************************************
  96. * 在指定位置显示字符串
  97. **********************************************/
  98. void LcdDisplayStr(u8 x, u8 y, const char *msg)
  99. {
  100.         char *p1 = msg;
  101.         char *p2 = 0;
  102.         u8 xx, nlen=0;;
  103.        
  104.         if( x>15 || y>3 ) return;       

  105.         //取显示字串长度
  106.         nlen = strlen(msg);
  107.         if(nlen==0) return;
  108.         if(nlen>32) nlen=32;

  109.         //p2-折行字串指针
  110.         //只显示一个折行
  111.         if(nlen<=16-x)
  112.                         p2 = 0;                                                                                                                        //字串只用显示一行
  113.         else
  114.                         p2 = p1 +16 - x;                                                                                //字串长度过长有折行
  115.        
  116.         //显示列控制码
  117.   if(y==0)                LcdWriteCom(LINE0+x);                                //第一行显示
  118.         if(y==1)                LcdWriteCom(LINE1+x);                                //第二行
  119.         if(y==2)                LcdWriteCom(LINE2+x);                                //第三行
  120.         if(y==3)
  121.         {        p2 = 0;                LcdWriteCom(LINE3+x);}                        //第四行
  122.        
  123.         for(xx = x; xx<16; xx++)
  124.         {
  125.                 LcdWriteData( *p1 );
  126.                 p1++;
  127.                 if(*p1=='\0') break;
  128.         }
  129.        
  130.         //有折行时
  131.         if(p2!=0)
  132.         {
  133.                 if(y==0) LcdWriteCom(LINE1);
  134.                 if(y==1) LcdWriteCom(LINE2);
  135.                 if(y==2) LcdWriteCom(LINE3);

  136.                 for(xx = 0; x<16; xx++)
  137.                 {
  138.                         LcdWriteData( *p2 );
  139.                         p2++;
  140.                         if(*p2=='\0') break;
  141.                 }
  142.         }
  143. }


  144. /*****************************************************************************************
  145. * 在指定坐标显示整型数字
  146. *------------------------
  147. * x,y : 横纵屏幕坐标
  148. * num : 显示整型数字
  149. * nDispW: 显示占位宽度,当宽度小于显示数字宽度时,此值无效
  150. * bRightAlign : 0-左对齐,1-右对齐
  151. * bLeftAdd0   : 数字前导空左边是否补0,0-不补0,1-补0
  152. *******************************************************************************************/
  153. void LcdDisplayNum(u8 x, u8 y, const long num, u8 nDispW, bool bRightAlign, bool bLeftAdd0)
  154. {
  155.                 u8 w=0, i=0;
  156.                 char        num_str[17]={'*'};
  157.                 char strBuff[17]={0x20};
  158.                 long tmp = 0;
  159.                
  160.                 if(x>15 || y>3) return;
  161.                 if(nDispW>16) nDispW=16;
  162.                 //负数不支持左补0
  163.                 if(num<0) bLeftAdd0 = 0;
  164.                 tmp = num>0 ? num : num * (-1);       

  165.                 //取字长度,数字到临时字符串中
  166.                 while(1)
  167.                 {               
  168.                         w++;
  169.                         strBuff[i] = tmp%10 + '0';
  170.                         if(tmp<10) break;
  171.                         tmp = tmp/10;
  172.                         i++;
  173.                 }
  174.                 //负号(-)
  175.                 if(num<0) {strBuff[i+1]='-';w++;}
  176.                 if(nDispW<w) nDispW=0;
  177.                
  178.                 //宽度内填空格
  179.                 if(nDispW>0)
  180.                 {
  181.                         for(i=0; i<nDispW; i++)
  182.                                 num_str[i] = 0x20;
  183.                 }               
  184.                 //左补0的条件:给定宽度是否右对齐
  185.                 if(bLeftAdd0==1 && nDispW>0 && bRightAlign==1 )
  186.                 {
  187.                         for(i=0; i<nDispW; i++)
  188.                                 num_str[i] = '0';
  189.                 }
  190.                
  191.                 if(nDispW>0)
  192.                 {
  193.                         if(bRightAlign)
  194.                                 memcpy(num_str, strBuff, w);
  195.                         else
  196.                                 memcpy(num_str+nDispW-w, strBuff, w);
  197.                 }
  198.                 else
  199.                 {
  200.                         memcpy(num_str, strBuff, w);
  201.                 }
  202.                
  203.                 //应以最宽的值
  204.                 w = (nDispW > w ? nDispW : w);

  205.                 if(y==0)                LcdWriteCom(LINE0+x);
  206.                 if(y==1)                LcdWriteCom(LINE1+x);
  207.                 if(y==2)                LcdWriteCom(LINE2+x);
  208.                 if(y==3)                LcdWriteCom(LINE3+x);
  209.                
  210.                 for( i=w; i>0; i-- )
  211.                 {//LCD显示
  212.                         LcdWriteData( num_str[i-1] );
  213.                 }
  214. }



  215. /********************
  216. *清行
  217. ********************
  218. OK
  219. void LcdClrLine(u8 y)
  220. {
  221.         u8 x;
  222.        
  223.         if(y>3) return;
  224.         //
  225.   if(y==0)                LcdWriteCom(LINE0);                                //第一行
  226.         if(y==1)                LcdWriteCom(LINE1);                                //第二行
  227.         if(y==2)                LcdWriteCom(LINE2);                                //第三行
  228.         if(y==3)                LcdWriteCom(LINE3);                                //第四行

  229.         for(x = 0; x<16; x++)
  230.         {
  231.                 LcdWriteData( 0x20 );
  232.         }
  233. }


  234. void LcdClr0()
  235. {
  236.         LcdClrLine(0);
  237. }
  238. void LcdClr1()
  239. {
  240.         LcdClrLine(1);
  241. }
  242. /*OK
  243. void LcdClr2()
  244. {
  245.         LcdClrLine(2);
  246. }
  247. void LcdClr3()
  248. {
  249.         LcdClrLine(3);
  250. }
  251. */
复制代码


def.h
  1. #ifndef                __DEF__H__
  2. #define                __DEF__H__
  3. #include <reg52.h>


  4. #ifndef                u8
  5. #define                u8        unsigned char
  6. #endif
  7. #ifndef                bool
  8. #define                bool        bit
  9. #define                false        0
  10. #define                true        1
  11. #endif
  12. #ifndef                u16
  13. #define                u16                unsigned int
  14. #endif
  15. #ifndef                u32
  16. #define                u32                unsigned long
  17. #endif
  18. #ifndef NULL
  19. #define NULL        0
  20. #endif
  21. #define        ON                        1
  22. #define OFF                        0
  23. #define _ON                        0
  24. #define _OFF                1

  25. //ShopAxxx开发板
  26. #ifdef                _USE_SHOP_A_
  27. sbit BEEP  = P1^2;                                //1 - off 蜂鸣器
  28. sbit RELAY = P1^0;                                //1 - off 继电器
  29. sbit _LE   = P1^5;                                //0 - off 74HC573(/LE),控制P2口的LED
  30. #endif

  31. #endif
复制代码
回复

使用道具 举报

楼主
ID:161164 发表于 2022-5-16 10:35 | 只看该作者
试试这个
  1. #include <reg51.h>
  2. #include"intrins.h"

  3. #define LCD_Dat P0
  4. sbit lcd_rs = P2 ^ 0;
  5. sbit lcd_rw = P2 ^ 1;
  6. sbit lcd_e = P2 ^ 2;

  7. void delay(unsigned int x)//t = 18.45 + x * 9.77 us @11.0592Mhz
  8. {
  9.     while(x--);
  10. }

  11. void lcd_write_cmd(unsigned char cmd) //写命令函数
  12. {
  13.     lcd_rs = 0;
  14.     lcd_rw = 0;
  15.     LCD_Dat = cmd;
  16.     lcd_e = 1;
  17.     lcd_e = 0;
  18.     delay(3);//>40us
  19. }

  20. void lcd_write_date(unsigned char date) //写数据函数
  21. {
  22.     lcd_rs = 1;
  23.     lcd_rw = 0;
  24.     LCD_Dat = date;
  25.     lcd_e = 1;
  26.     lcd_e = 0;
  27.     delay(3);//>40us
  28. }

  29. void lcd_init()        //LCD初始化函数
  30. {
  31.     lcd_write_cmd(0x38);
  32.     lcd_write_cmd(0x0c);
  33.     lcd_write_cmd(0x06);
  34.     lcd_write_cmd(0x01);
  35.     delay(200);//>1.7ms
  36. }

  37. void lcd_show_char(unsigned char column, unsigned char dat)
  38. {

  39.     if(column == 1)
  40.         lcd_write_cmd(0x80);
  41.     else
  42.         lcd_write_cmd(0xC0);

  43.     lcd_write_date(dat);
  44. }

  45. void lcd_show_str(unsigned char column, unsigned char *dat)
  46. {

  47.     if(column == 1)
  48.         lcd_write_cmd(0x80);
  49.     else
  50.         lcd_write_cmd(0xC0);
  51.     do
  52.     {
  53.         lcd_write_date(*dat);
  54.     } while(*dat++);
  55. }

  56. void main()
  57. {
  58.     lcd_init();
  59.     lcd_show_str(1, "LCD1602 Demo");
  60.     lcd_show_str(2, "Hello World!");
  61.     while(1)
  62.     {

  63.     }
  64. }
复制代码



回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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