找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6038|回复: 2
收起左侧

用于Arduino UNO的完全使用3个IO口驱动1602(74HC595)

[复制链接]
ID:218023 发表于 2018-4-30 11:55 | 显示全部楼层 |阅读模式
第一次学Arduino......
还没有购买开发板
一般都在Proteus上进行
51单片机:http://www.51hei.com/bbs/dpj-114268-1.html


整体电路图

整体电路图

效果图

效果图

效果图

效果图



单片机代码如下:
  1. //引脚定义
  2. #define LCD1602_SHCP 0
  3. #define LCD1602_DS 1
  4. #define LCD1602_STCP 2

  5. //两种数据类型
  6. typedef unsigned char uchar;
  7. typedef unsigned int uint;

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

  10. //二进制的形象表示方法,从左到右分别位第7 6 5 4 3 2 1 0位
  11. #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))  //二进制的表示

  12. void LCD1602_DATAPINS(uchar value); //更改74HC595连接LCD1602的数据
  13. void LcdCalc(uchar i); //确定4位总线
  14. void LcdWriteCom(uchar com); //向LCD写入一个字节的命令
  15. void LcdWriteData(uchar dat); //向LCD写入一个字节的数据
  16. void LcdInit(); //初始化LCD屏
  17. void LcdPrintf(uchar *s); //向屏幕输出字符
  18. void LcdWriteCGRAM(uchar index,uchar *p); //建立一个自定义字符
  19. void LCDPrintNum(uint num,uchar wei); //显示数字

  20. /*******************************************************************************
  21. * 函 数 名         : setup
  22. * 函数功能       : 准备
  23. * 输    入         : 无
  24. * 输    出         : 无
  25. *******************************************************************************/
  26. void setup()
  27. {
  28.   pinMode(LCD1602_SHCP,OUTPUT);
  29.   pinMode(LCD1602_DS,OUTPUT);
  30.   pinMode(LCD1602_STCP,OUTPUT);
  31. }
  32. /*******************************************************************************
  33. * 函 数 名         : LCD1602_DATAPINS
  34. * 函数功能       : 更改74HC595连接LCD1602的数据
  35. * 输    入         : value
  36. * 输    出         : 无
  37. *******************************************************************************/   
  38. void LCD1602_DATAPINS(uchar value)
  39. {
  40.     uchar i,j;
  41.     for(i=0;i<8;i++)
  42.     {
  43.         j=value&0x80;//取数据高位
  44.         if(j==0x80){ //判断数据高位是否为1
  45.             digitalWrite(LCD1602_DS,HIGH);//如果高位为1,DS置1
  46.         }
  47.         else{
  48.             digitalWrite(LCD1602_DS,LOW);//否则DS置0
  49.         }
  50.         digitalWrite(LCD1602_SHCP,LOW);
  51.         digitalWrite(LCD1602_SHCP,HIGH);//上升沿使这一位写入移位寄存器
  52.         value<<=1;//数据左移1位,数据的第7位变为最高位,循环第8次时数据的最低位也变成最高位
  53.     }
  54.     digitalWrite(LCD1602_STCP,LOW);
  55.     digitalWrite(LCD1602_STCP,HIGH);//给STCP一个上升沿,将for循环中输入的数据移入输出锁存寄存器,刷新输出数据
  56. }
  57. /*******************************************************************************
  58. * 函 数 名         : LcdCalc
  59. * 函数功能       : 确定4位总线
  60. * 输    入         : i
  61. * 输    出         : 无
  62. *******************************************************************************/   
  63. void LcdCalc(uchar i)
  64. {
  65.   if(i==0x00){
  66.     D4=0;
  67.     D5=0;
  68.     D6=0;
  69.     D7=0;
  70.   }
  71.   if(i==0x01){
  72.     D4=1;
  73.     D5=0;
  74.     D6=0;
  75.     D7=0;
  76.   }
  77.   if(i==0x02){
  78.     D4=0;
  79.     D5=1;
  80.     D6=0;
  81.     D7=0;
  82.   }
  83.   if(i==0x03){
  84.     D4=1;
  85.     D5=1;
  86.     D6=0;
  87.     D7=0;
  88.   }
  89.   if(i==0x04){
  90.     D4=0;
  91.     D5=0;
  92.     D6=1;
  93.     D7=0;
  94.   }
  95.   if(i==0x05){
  96.     D4=1;
  97.     D5=0;
  98.     D6=1;
  99.     D7=0;
  100.   }
  101.   if(i==0x06){
  102.     D4=0;
  103.     D5=1;
  104.     D6=1;
  105.     D7=0;
  106.   }
  107.   if(i==0x07){
  108.     D4=1;
  109.     D5=1;
  110.     D6=1;
  111.     D7=0;
  112.   }
  113.   if(i==0x08){
  114.     D4=0;
  115.     D5=0;
  116.     D6=0;
  117.     D7=1;
  118.   }
  119.   if(i==0x09){
  120.     D4=1;
  121.     D5=0;
  122.     D6=0;
  123.     D7=1;
  124.   }
  125.   if(i==0x0a){
  126.     D4=0;
  127.     D5=1;
  128.     D6=0;
  129.     D7=1;
  130.   }
  131.   if(i==0x0b){
  132.     D4=1;
  133.     D5=1;
  134.     D6=0;
  135.     D7=1;
  136.   }
  137.   if(i==0x0c){
  138.     D4=0;
  139.     D5=0;
  140.     D6=1;
  141.     D7=1;
  142.   }
  143.   if(i==0x0d){
  144.     D4=1;
  145.     D5=0;
  146.     D6=1;
  147.     D7=1;
  148.   }
  149.   if(i==0x0e){
  150.     D4=0;
  151.     D5=1;
  152.     D6=1;
  153.     D7=1;
  154.   }
  155.   if(i==0x0f){
  156.     D4=1;
  157.     D5=1;
  158.     D6=1;
  159.     D7=1;
  160.   }
  161.   if(i==0x10){
  162.     D4=1;
  163.     D5=0;
  164.     D6=0;
  165.     D7=0;
  166.   }
  167.   if(i==0x20){
  168.     D4=0;
  169.     D5=1;
  170.     D6=0;
  171.     D7=0;
  172.   }
  173.   if(i==0x30){
  174.     D4=1;
  175.     D5=1;
  176.     D6=0;
  177.     D7=0;
  178.   }
  179.   if(i==0x40){
  180.     D4=0;
  181.     D5=0;
  182.     D6=1;
  183.     D7=0;
  184.   }
  185.   if(i==0x50){
  186.     D4=1;
  187.     D5=0;
  188.     D6=1;
  189.     D7=0;
  190.   }
  191.   if(i==0x60){
  192.     D4=0;
  193.     D5=1;
  194.     D6=1;
  195.     D7=0;
  196.   }
  197.   if(i==0x70){
  198.     D4=1;
  199.     D5=1;
  200.     D6=1;
  201.     D7=0;
  202.   }
  203.   if(i==0x80){
  204.     D4=0;
  205.     D5=0;
  206.     D6=0;
  207.     D7=1;
  208.   }
  209.   if(i==0x90){
  210.     D4=1;
  211.     D5=0;
  212.     D6=0;
  213.     D7=1;
  214.   }
  215.   if(i==0xa0){
  216.     D4=0;
  217.     D5=1;
  218.     D6=0;
  219.     D7=1;
  220.   }
  221.   if(i==0xb0){
  222.     D4=1;
  223.     D5=1;
  224.     D6=0;
  225.     D7=1;
  226.   }
  227.   if(i==0xc0){
  228.     D4=0;
  229.     D5=0;
  230.     D6=1;
  231.     D7=1;
  232.   }
  233.   if(i==0xd0){
  234.     D4=1;
  235.     D5=0;
  236.     D6=1;
  237.     D7=1;
  238.   }
  239.   if(i==0xe0){
  240.     D4=0;
  241.     D5=1;
  242.     D6=1;
  243.     D7=1;
  244.   }
  245.   if(i==0xf0){
  246.     D4=1;
  247.     D5=1;
  248.     D6=1;
  249.     D7=1;
  250.   }
  251. }
  252. /*******************************************************************************
  253. * 函 数 名         : LcdWriteCom
  254. * 函数功能       : 向LCD写入一个字节的命令
  255. * 输    入         : com
  256. * 输    出         : 无
  257. *******************************************************************************/
  258. void LcdWriteCom(uchar com)   //写入命令
  259. {
  260.   E = 0;   //使能清零
  261.   RS = 0;  //选择写入命令
  262.   RW = 0;  //选择写入

  263.   LcdCalc(com>>4);  //发送高四位

  264.   E = 1;   //写入时序
  265.   LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS));
  266.   E = 0;
  267.   LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS));

  268.   LcdCalc(com<<4); //发送低四位

  269.   E = 1;   //写入时序
  270.   LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS));
  271.   E = 0;
  272.   LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS));
  273. }
  274. /****************************************************************************
  275. * 函 数 名         : LcdWriteData
  276. * 函数功能       : 向LCD写入一个字节的数据
  277. * 输    入         : dat
  278. * 输    出         : 无
  279. *******************************************************************************/           
  280. void LcdWriteData(uchar dat)      //写入数据
  281. {
  282.   E = 0;   //使能清零
  283.   RS = 1;  //选择写入数据
  284.   RW = 0;  //选择写入

  285.   LcdCalc(dat>>4);  //发送高四位

  286.   E = 1;   //写入时序
  287.   LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS));
  288.   E = 0;
  289.   LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS));

  290.   LcdCalc(dat<<4); //发送低四位

  291.   E = 1;   //写入时序
  292.   LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS));
  293.   E = 0;
  294.   LCD1602_DATAPINS(bin(0,D7,D6,D5,D4,E,RW,RS));
  295. }
  296. /*******************************************************************************
  297. * 函 数 名       : LcdInit
  298. * 函数功能     : 初始化LCD屏
  299. * 输    入       : 无
  300. * 输    出       : 无
  301. *******************************************************************************/      
  302. void LcdInit()              //LCD初始化子程序
  303. {
  304.   LcdWriteCom(0x32);   //将8位总线转为4位总线
  305.   LcdWriteCom(0x28);   //在四位线下的初始化
  306.   LcdWriteCom(0x0c);  //开显示不显示光标
  307.   LcdWriteCom(0x06);  //写一个指针加1
  308.   LcdWriteCom(0x01);  //清屏
  309.   LcdWriteCom(0x80);  //设置数据指针起点
  310. }
  311. /*******************************************************************************
  312. * 函 数 名       : LcdPrintf
  313. * 函数功能     : 向屏幕输出字符
  314. * 输    入       : *s
  315. * 输    出       : 无
  316. *******************************************************************************/
  317. void LcdPrintf(uchar *s)
  318. {
  319.   while(*s>0)LcdWriteData(*s++);
  320. }
  321. /*******************************************************************************
  322. * 函 数 名       : LcdWriteCGRAM
  323. * 函数功能     : 建立一个自定义字符
  324. * 输    入       : index、*p
  325. * 输    出       : 无
  326. *******************************************************************************/
  327. void LcdWriteCGRAM(uchar index,uchar *p)
  328. {
  329.   uchar i;
  330.   index <<=3; //index *= 8
  331.   for(i=0;i<8;++i){
  332.     LcdWriteCom(0x40 | index+i);//写CGRAM地址
  333.     LcdWriteData(*p++);
  334.   }
  335.   LcdWriteCom(0x80);
  336. }
  337. /*******************************************************************************
  338. * 函 数 名       : LcdPrintNum
  339. * 函数功能     : 显示数字
  340. * 输    入       : num、wei
  341. * 输    出       : 无
  342. *******************************************************************************/
  343. void LCDPrintNum(uint num,uchar wei)//wei 数字占的位数
  344. {
  345.   uchar tempstring[6];
  346.   uchar n[5];
  347.   uchar i,j=0;
  348.   n[0]=num/10000;
  349.   n[1]=num%10000/1000;
  350.   n[2]=num%1000/100;
  351.   n[3]=num%100/10;
  352.   n[4]=num%10;
  353.   i=5-wei;
  354.   for(i;i<5;i++){
  355.     tempstring[j++]=n[i]+'0';
  356.   }
  357.   tempstring[j]='\0';
  358.   LcdPrintf(tempstring);
  359. }

  360. const uchar type_t[]={
  361.   0x1f,0x02,0x02,0x02,
  362.   0x02,0x02,0x02,0x00
  363. };

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

  366. void loop()
  367. {
  368.   uchar i;
  369.   LcdInit();
  370.   LcdWriteCGRAM(0x00,type_t);
  371.   LcdWriteData(0x00);
  372.   LcdWriteCom(0x81);
  373.   LcdPrintf("HE With");
  374.   LcdWriteCom(0xc0);
  375.   LcdPrintf("Commands");
  376.   delay(100);
  377.   LcdWriteCom(0x01);
  378.   while(1){
  379.     for(i=0;i<16;i++){
  380.       LcdWriteCom(0x80+i);
  381.       LcdWriteData(line1[i]);
  382.       delay(5);
  383.     }
  384.     delay(10);
  385.     LcdWriteCom(0xc1);
  386.     LcdWriteData(0x00);
  387.     delay(5);
  388.     for(i=0;i<12;i++){
  389.       LcdWriteCom(0xc2+i);
  390.       LcdWriteData(line2[i]);
  391.       delay(5);
  392.     }
  393.     LcdWriteCom(0x01);
  394.     delay(5);
  395.   }
  396. }
复制代码
0.png

全部资料51hei下载地址:
lcd595.zip (27.79 KB, 下载次数: 31)

评分

参与人数 1黑币 +80 收起 理由
admin + 80

查看全部评分

回复

使用道具 举报

ID:218023 发表于 2018-4-30 12:08 | 显示全部楼层
那时一直用51单片机为核心的我,这个假期彻底翻了身!
第一次使用Arduino

回复

使用道具 举报

ID:44037 发表于 2018-8-20 11:06 | 显示全部楼层
谢谢分享  学习Arduino  
  编译程序  出现错误   LcdWriteCGRAM(0x00,type_t);  
error: invalid conversion from 'const uchar* {aka const unsigned char*}' to 'uchar* {aka unsigned char*}' [-fpermissive]     转换无效
请求帮助   怎样修改程序
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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