切换到宽版
  • 17795阅读
  • 44回复

成功了!4根IO口线驱动1602,带PWM调光。 [复制链接]

上一主题 下一主题
离线rgwan
 

发帖
910
M币
43
专家
12
粉丝
128
只看楼主 倒序阅读 我要置顶 楼主  发表于: 2012-07-12
       呵呵,不用我说你们也知道为什么只需要4根线:因为咱用了74hc595啊!因为74HC595最近我手里一抓一大把。但是STC的单片机IO口紧缺。就算使用4线驱动模式也要8个IO(还要算上背光PWM)。这一次我几乎做到了他的一半。如果不用PWM的话。大概只需要3个IO,如果需要PWM就四个罗。
      MCU当然是老掉牙的死特惨89C52罗~

      也可以在595后面级联类似三极管开关……继电器之类的玩意。当然友情提醒,别超过4个595.否则速度会慢的可怕。我现在1个595.写1602都可以丢掉延时函数了。
       这一次硬件设计的比较简单,但是IO全反了。所以需要占用额外的CPU时间修正,但是毕竟方便洞洞板嘛。还有大家别看到我给A和B赋了好几次值而去“优化”代码。如果您“优化”的话,那么就根本驱动不起来,因为51的加法减法乘除都要经过ACC和B,如果不去重新赋值的话,那么就会发生改变的现象。不过我这种位寻址软件修正可比那种xx=xx & xx的效率高多了。如果我这么写的话。恐怕刷一个屏幕没1秒下不来啊。12T的51就这个速度……
       不过这一次焊板子实在是太仓促了。对比度电位器焊在液晶下面,结果初始化成功了显示两排方块。晕了半天。调试半天还是没用。后来捅了一下背面就好了……晕……!
       上代码:
  1. #include <stc89c5x.h>//STC89C52
  2. //串行驱动1602,powered by 595
  3. #define LCD1602_BACKLIGHT        P1_3//背光
  4. #define LCD1602_SDA                        P1_0//数据输入
  5. #define LCD1602_SCK                        P1_1//移位时钟,SHCP,11pin
  6. #define LCD1602_SCL                        P1_2//锁存时钟,STCP,12pin
  7. /*
  8. * 硬件连接:
  9. * 74HC595 Q7 - 1602 RS
  10. * GND - 1602 RW(595没有输入功能,所以判定忙只能靠延时,另外就是MCU的速度比较的慢。所以也可以直接去掉延时。但是在STC12系列上的表现,相当的不错
  11. * 在传统51上面。PWM占空比低于50%将会出现扫描线。12系列的,很高兴的告诉大家。T0X12开了以后。不会有扫描线出现。但是如果一定要在传统51上使用的话,请把10级调光改成4级。谢谢合作!
  12. * 74HC595 Q6 - 1602 EN
  13. * 74HC595 Q5~Q2 - 1602 D5~D7(这一次硬件设计不合理,才只能搞软件修正了。不过好处就是直接就可以洞洞板上对着联,减少了烧坏595的概率。坏处就是CPU时间消耗的多了点。但是可以取消延时函数啦~
  14. * 1602 D1~D4 直接悬空
  15. * LCD_BACKLIGHT加一级PNP三极管射随器加到液晶的A上,如果无需调光可以去掉这一部分电路和代码
  16. * 至于595的连接,只要不弄反SCL和SCK,就没有问题啦~
  17. */
  18. __sbit  __at  0xE0 A_0;//方便位操作,硬件设置真的是败笔 - -
  19. __sbit  __at  0xE1 A_1;
  20. __sbit  __at  0xE2 A_2;
  21. __sbit  __at  0xE3 A_3;
  22. __sbit  __at  0xE4 A_4;
  23. __sbit  __at  0xE5 A_5;
  24. __sbit  __at  0xE6 A_6;
  25. __sbit  __at  0xE7 A_7;
  26. __sbit  __at  0xF1 B_1;
  27. __sbit  __at  0xF2 B_2;
  28. __sbit  __at  0xF3 B_3;
  29. __sbit  __at  0xF4 B_4;
  30. __sbit  __at  0xF5 B_5;
  31. __sbit  __at  0xF6 B_6;
  32. __sbit  __at  0xF7 B_7;
  33. unsigned char PWM_Cycle=0;//PWM占空比
  34. unsigned char PWM_T=0;//PWM当前所处周期
  35. unsigned char OutBuf=0xff;//输出缓冲
  36. #define        LCD_OFF         lcd_wcmd(0x08)
  37. #define        LCD_CUR         lcd_wcmd(0x0E)
  38. #define        LCD_FCUR       lcd_wcmd(0x0F)
  39. void delay(unsigned int n)
  40. {
  41. unsigned int x,y;
  42. for(x=n;x>0;x--)
  43. for(y=100;y>0;y--);
  44. }
  45. void Send595()
  46. {
  47.         unsigned char i,j;
  48.         j=0x80;
  49.         LCD1602_SCK=0;
  50.         for(i=0;i<8;i++)
  51.         {
  52.                 LCD1602_SDA=OutBuf & j;
  53.                 j=j>>1;
  54.                 LCD1602_SCK=1;
  55.                 LCD1602_SCK=0;
  56.         }
  57.         LCD1602_SDA=1;
  58.         LCD1602_SCL=0;
  59.         LCD1602_SCL=1;
  60. }
  61. void lcd_en()
  62. {
  63.         //OutBuf=OutBuf|0x40;//E=1
  64.         B=OutBuf;
  65.         B_6=1;
  66.         OutBuf=B;
  67.         Send595();//输出数据
  68.         B=OutBuf;
  69.         B_6=0;
  70.         OutBuf=B;//E=0
  71.         Send595();
  72. }
  73. /**********************************************************/
  74. void lcd_wcmd(unsigned char i)
  75. {
  76. //写命令
  77.         B=OutBuf;
  78.         B_7=0;//RS=0,RW=0;
  79.         OutBuf=B;
  80.         Send595();
  81. //--------------
  82.         B=OutBuf;
  83.         ACC=i;
  84.         B_2=A_7;//D7=D7
  85.         B_3=A_6;//D6=D6
  86.         B_4=A_5;//D5=D5
  87.         B_5=A_4;//D4=D4
  88.         OutBuf=B;
  89.         Send595();
  90.         lcd_en();
  91. //================
  92.         ACC=i;
  93.         B=OutBuf;
  94.         B_2=A_3;//D7=D3
  95.         B_3=A_2;//D6=D2
  96.         B_4=A_1;//D5=D1
  97.         B_5=A_0;//D4=D0
  98.         OutBuf=B;        
  99.         Send595();
  100.         lcd_en();
  101. }
  102. void lcd_wdat(unsigned char i)
  103. {
  104. //写数据
  105.         B=OutBuf;
  106.         B_7=1;//RS=0,RW=0;
  107.         OutBuf=B;
  108.         Send595();
  109. //--------------
  110.         B=OutBuf;
  111.         ACC=i;
  112.         B_2=A_7;//D7=D7
  113.         B_3=A_6;//D6=D6
  114.         B_4=A_5;//D5=D5
  115.         B_5=A_4;//D4=D4
  116.         OutBuf=B;
  117.         Send595();
  118.         lcd_en();
  119. //================
  120.         ACC=i;
  121.         B=OutBuf;
  122.         B_2=A_3;//D7=D3
  123.         B_3=A_2;//D6=D2
  124.         B_4=A_1;//D5=D1
  125.         B_5=A_0;//D4=D0
  126.         OutBuf=B;        
  127.         Send595();
  128.         lcd_en();
  129. }
  130. void lcd_putchar(unsigned char addr,unsigned char ch)
  131. {//写一个字
  132.         lcd_wcmd(0x80+addr);
  133.         lcd_wdat(ch);
  134. }
  135. void lcd_display(unsigned char *l1,unsigned char *l2)
  136. {//写一屏幕
  137.         unsigned char i=0;
  138.         lcd_wcmd(0x80); //显示地址设为80H(即00H,)上排第一位
  139.         for(i=0;i<16;i++)
  140.         {
  141.                 lcd_wdat(l1[i]);
  142.         }
  143.         lcd_wcmd(0x80+0x40); //重新设定显示地址为0xc0,即下排第1位
  144.         for(i=0;i<16;i++)
  145.         {
  146.                 lcd_wdat(l2[i]);
  147.         }
  148. }
  149. void lcd_cls()
  150. {
  151.         lcd_wcmd(0x01); //清屏延时函数可以省略
  152. }
  153. //米有读函数,但是功能可以由上面的函数扩展哦~
  154. void lcd_init()
  155. {
  156.     OutBuf=0xff;
  157.     Send595();//复位VIO,这段代码必须加。否则MCU忽然RESET会导致液晶乱码
  158.     lcd_wcmd(0x30);//复位1602,这段代码必须加,同上
  159.     lcd_en();//唤醒
  160.         lcd_wcmd(0x20);
  161.         lcd_en();//唤醒
  162.         lcd_wcmd(0x28); //四位,5x7
  163.         lcd_wcmd(0x0c); //开启显示屏,关光标,光标不闪烁
  164.         lcd_wcmd(0x06); //显示地址递增,即写一个数据后,显示位置右移一位
  165.         lcd_wcmd(0x01); //清屏        
  166.         //调试的时候被设计失误的对比度电位器坑死了:就是两排小方块死都不显示
  167.         //查了半天都不知道
  168.         //最后捅了下电位器就正常了……
  169. }
  170. void lcd_print(unsigned char *str)
  171. {
  172.     unsigned char addr=0x80,len=0;
  173.     lcd_wcmd(addr); //显示地址设为80H(即00H,)上排第一位
  174.     while(*str!='\0')
  175.     {//等待末尾
  176.         if(len >= 16)
  177.         {
  178.             lcd_wcmd(0x80+0x40);//下排第一位,换行
  179.             len=0;
  180.         }
  181.         if(*str=='\n')
  182.         {
  183.             lcd_wcmd(0x80+0x40);//下排第一位,换行
  184.         }
  185.         else
  186.         {
  187.             lcd_wdat(*str);    
  188.         }
  189.         str++;
  190.         len++;
  191.     }
  192. }//写字符串函数
  193. void PWM() __interrupt 1 __using 1
  194. {
  195.         ET0=0;
  196.         TF0=0;//CLR
  197.         TR0=0;
  198.         EA=0;
  199.         TH0=0xFC;TL0=0x00;//十级调光,频率400Hz
  200.         if(PWM_T>10) {PWM_T=0;}
  201.         if(PWM_Cycle>PWM_T){ LCD1602_BACKLIGHT=0;}
  202.         if(PWM_Cycle<PWM_T)  {LCD1602_BACKLIGHT=1;}
  203.         PWM_T++;
  204.         TR0=1;
  205.         ET0=1;
  206.         EA=1;
  207. }
  208. void main()
  209. {//主函数
  210.         TMOD = 0x01 ;
  211.         TH0=0xFC;TL0=0x00;
  212.         TR0=1;ET0=1;
  213.         EA=1;//开中断
  214.         //-----------------
  215.         lcd_init();
  216.         PWM_Cycle=10;//背光100%
  217.         //液晶初始化---------
  218.         while(1)
  219.         {
  220.                 lcd_display("  Hello world!  ","Serial mode 1602");
  221.                 delay(2000);
  222.                 lcd_display("Drive by 74HC595","Design by rgwan ");
  223.                 delay(2000);
  224.                 lcd_display("Website address:"," www.rwzy.co.cc ");
  225.                 delay(2000);
  226.                 lcd_display("Backlight ctl by","  T0 PWM 400Hz  ");
  227.                 delay(2000);
  228.         }
  229. }

补上低清无码ImageMagick压制图……


自己DIY的最小系统,旁边是串口转接器。这个板子上有两个晶振跳线选择
外加一个外界晶振。现在这个晶振跳在内置的11.0592上。


来张背面的,没布局好,那飞线……

去掉1602后……

HELLO WORLD……

远一点……

来一张我的正在建设的网站……欢迎参观……(现在服务器还没到位。谁支援下。如果没支援就只能24小时挂机了 - -

Mydigit 万致远原创。转载请注明出处~
另外求M啊。图已补~
[ 此帖被rgwan在2012-07-12 23:43重新编辑 ]
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共21条打赏 ,M币+118 ,专家+1
离线magicyjh

发帖
457
M币
3189
专家
3
粉丝
47
只看该作者 1楼 发表于: 2012-07-12
请登录后查看
离线飙风人生

发帖
139803
M币
29855
专家
22
粉丝
305
只看该作者 2楼 发表于: 2012-07-12
请登录后查看
离线rgwan

发帖
910
M币
43
专家
12
粉丝
128
只看该作者 3楼 发表于: 2012-07-12
请登录后查看
离线Ω囿圉Ω

发帖
11295
M币
8437
专家
11
粉丝
210
只看该作者 4楼 发表于: 2012-07-12
请登录后查看
离线huhu2207

发帖
1438
M币
923
专家
18
粉丝
52
只看该作者 5楼 发表于: 2012-07-12
请登录后查看
离线eglic

发帖
1077
M币
16
专家
4
粉丝
39
只看该作者 6楼 发表于: 2012-07-12
请登录后查看
离线yetsky

发帖
1066
M币
5318
专家
9
粉丝
86
只看该作者 7楼 发表于: 2012-07-12
请登录后查看
本文内容包含图片或附件,获取更多资讯,请 登录 后查看;或者 注册 成为会员获得更多权限
本帖最近打赏记录:共2条打赏 ,M币+10
离线sdf15937

发帖
1748
M币
14
专家
8
粉丝
61
只看该作者 8楼 发表于: 2012-07-12
请登录后查看
离线rgwan

发帖
910
M币
43
专家
12
粉丝
128
只看该作者 9楼 发表于: 2012-07-12
回 7楼(yetsky) 的帖子
请登录后查看
[ 此帖被rgwan在2012-07-13 05:45重新编辑 ]
快速回复
限80 字节
“新手上路”发帖需审核后才能显示(请认真发帖),达到数码9级后取消此限制
 
上一个 下一个