本帖最后由 xwkm 于 2012-7-12 21:54 编辑
呵呵,不用我说你们也知道为什么只需要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就这个速度……
不过这一次焊板子实在是太仓促了。对比度电位器焊在液晶下面,结果初始化成功了显示两排方块。晕了半天。调试半天还是没用。后来捅了一下背面就好了……晕……!
上代码:
- #include <stc89c5x.h>//STC89C52
- //串行驱动1602,powered by 595
- #define LCD1602_BACKLIGHT P1_3//背光
- #define LCD1602_SDA P1_0//数据输入
- #define LCD1602_SCK P1_1//移位时钟,SHCP,11pin
- #define LCD1602_SCL P1_2//锁存时钟,STCP,12pin
- /*
- * 硬件连接:
- * 74HC595 Q7 - 1602 RS
- * GND - 1602 RW(595没有输入功能,所以判定忙只能靠延时,另外就是MCU的速度比较的慢。所以也可以直接去掉延时。但是在STC12系列上的表现,我可不知道会怎么样
- * 74HC595 Q6 - 1602 EN
- * 74HC595 Q5~Q2 - 1602 D5~D7(这一次硬件设计不合理,才只能搞软件修正了。不过好处就是直接就可以洞洞板上对着联,减少了烧坏595的概率。坏处就是CPU时间消耗的多了点。但是可以取消延时函数啦~
- * 1602 D1~D4 直接悬空
- * LCD_BACKLIGHT加一级PNP三极管射随器加到液晶的A上,如果无需调光可以去掉这一部分电路和代码
- * 至于595的连接,只要不弄反SCL和SCK,就没有问题啦~
- */
-
- __sbit __at 0xE0 A_0;//方便位操作,硬件设置真的是败笔 - -
- __sbit __at 0xE1 A_1;
- __sbit __at 0xE2 A_2;
- __sbit __at 0xE3 A_3;
- __sbit __at 0xE4 A_4;
- __sbit __at 0xE5 A_5;
- __sbit __at 0xE6 A_6;
- __sbit __at 0xE7 A_7;
- __sbit __at 0xF1 B_1;
- __sbit __at 0xF2 B_2;
- __sbit __at 0xF3 B_3;
- __sbit __at 0xF4 B_4;
- __sbit __at 0xF5 B_5;
- __sbit __at 0xF6 B_6;
- __sbit __at 0xF7 B_7;
- unsigned char PWM_Cycle=0;//PWM占空比
- unsigned char PWM_T=0;//PWM当前所处周期
- unsigned char OutBuf=0xff;//输出缓冲
- #define LCD_OFF lcd_wcmd(0x08)
- #define LCD_CUR lcd_wcmd(0x0E)
- #define LCD_FCUR lcd_wcmd(0x0F)
- void delay(unsigned int n)
- {
- unsigned int x,y;
- for(x=n;x>0;x--)
- for(y=100;y>0;y--);
- }
- void Send595()
- {
- unsigned char i,j;
- j=0x80;
- LCD1602_SCK=0;
- for(i=0;i<8;i++)
- {
- LCD1602_SDA=OutBuf & j;
- j=j>>1;
- LCD1602_SCK=1;
- LCD1602_SCK=0;
- }
- LCD1602_SDA=1;
- LCD1602_SCL=0;
- LCD1602_SCL=1;
- }
- void lcd_en()
- {
- //OutBuf=OutBuf|0x40;//E=1
- B=OutBuf;
- B_6=1;
- OutBuf=B;
- Send595();//输出数据
- B=OutBuf;
- B_6=0;
- OutBuf=B;//E=0
- Send595();
- }
- /**********************************************************/
- void lcd_wcmd(unsigned char i)
- {
- //写命令
- B=OutBuf;
- B_7=0;//RS=0,RW=0;
- OutBuf=B;
- Send595();
- //--------------
- B=OutBuf;
- ACC=i;
- B_2=A_7;//D7=D7
- B_3=A_6;//D6=D6
- B_4=A_5;//D5=D5
- B_5=A_4;//D4=D4
- OutBuf=B;
- Send595();
- lcd_en();
- //================
- ACC=i;
- B=OutBuf;
- B_2=A_3;//D7=D3
- B_3=A_2;//D6=D2
- B_4=A_1;//D5=D1
- B_5=A_0;//D4=D0
- OutBuf=B;
- Send595();
- lcd_en();
- }
- void lcd_wdat(unsigned char i)
- {
- //写数据
- B=OutBuf;
- B_7=1;//RS=0,RW=0;
- OutBuf=B;
- Send595();
- //--------------
- B=OutBuf;
- ACC=i;
- B_2=A_7;//D7=D7
- B_3=A_6;//D6=D6
- B_4=A_5;//D5=D5
- B_5=A_4;//D4=D4
- OutBuf=B;
- Send595();
- lcd_en();
- //================
- ACC=i;
- B=OutBuf;
- B_2=A_3;//D7=D3
- B_3=A_2;//D6=D2
- B_4=A_1;//D5=D1
- B_5=A_0;//D4=D0
- OutBuf=B;
- Send595();
- lcd_en();
- }
- void lcd_putchar(unsigned char addr,unsigned char ch)
- {//写一个字
- lcd_wcmd(0x80+addr);
- lcd_wdat(ch);
- }
- void lcd_display(unsigned char *l1,unsigned char *l2)
- {//写一屏幕
- unsigned char i=0;
- lcd_wcmd(0x80); //显示地址设为80H(即00H,)上排第一位
- for(i=0;i<16;i++)
- {
- lcd_wdat(l1[i]);
- }
- lcd_wcmd(0x80+0x40); //重新设定显示地址为0xc0,即下排第1位
- for(i=0;i<16;i++)
- {
- lcd_wdat(l2[i]);
- }
- }
- void lcd_cls()
- {
- lcd_wcmd(0x01); //清屏延时函数可以省略
- }
- //米有读函数,但是功能可以由上面的函数扩展哦~
- void lcd_init()
- {
- lcd_wcmd(0x20);
- lcd_en();//唤醒
- lcd_wcmd(0x28); //四位,5x7
- lcd_wcmd(0x0c); //开启显示屏,关光标,光标不闪烁
- lcd_wcmd(0x06); //显示地址递增,即写一个数据后,显示位置右移一位
- lcd_wcmd(0x01); //清屏
- //调试的时候被设计失误的对比度电位器坑死了:就是两排小方块死都不显示
- //查了半天都不知道
- //最后捅了下电位器就正常了……
- }
- void PWM() __interrupt 1 __using 1
- {
- ET0=0;
- TF0=0;//CLR
- TR0=0;
- EA=0;
- TH0=0xFC;TL0=0x00;//十级调光,频率400Hz
- if(PWM_T>10) {PWM_T=0;}
- if(PWM_Cycle>PWM_T){ LCD1602_BACKLIGHT=0;}
- if(PWM_Cycle<PWM_T) {LCD1602_BACKLIGHT=1;}
- PWM_T++;
- TR0=1;
- ET0=1;
- EA=1;
- }
- void main()
- {//主函数
- TMOD = 0x01 ;
- TH0=0xFC;TL0=0x00;
- TR0=1;ET0=1;
- EA=1;//开中断
- //-----------------
- lcd_init();
- PWM_Cycle=10;//背光100%
- //液晶初始化---------
- while(1)
- {
- lcd_display(" Hello world! ","Serial mode 1602");
- delay(2000);
- lcd_display("Drive by 74HC595","Design by rgwan ");
- delay(2000);
- lcd_display("Website address:"," www.rwzy.co.cc ");
- delay(2000);
- lcd_display("Backlight Ctl by"," T0 PWM 400Hz ");
- delay(2000);
- }
- }
复制代码补上低清无码ImageMagick压制图……
thumb-DSC03558.JPG.jpg (231.14 KB, 下载次数: 0)
下载附件
2012-7-12 21:50 上传
背面,没布局好,那飞线……
接口在左边是GND,VCC,BACKLIGHT.前面是SCK SCL SDA.
万致远原创。第二发于amoBBS(OURDEV)转载请注明出处~
下一次做一个串行驱动12864……
2个io+cowboy阻容电路
2片74164,也是2个io驱动,
3个io+2片595,亦可
好象不是真实木的。
一周热门 更多>