论坛发了个人肉驱动LCD1602的帖子,没什么技术含量,居然得裤子,有点不好意思,正好这几天有点时间,于是就再做一个小试验,用尽量少的IO来驱动1602,以适应在某些引脚较少的MCU,如Tiny系列等。废话少说,先上图,如果大家觉得有意思请起个哄...
image.png


image.png

说明一下,连接LCD1602的四根引线,除了红黑两根电源,两根黄色的就是信号线,其中一根传送RS和E信号,另一根传送D4~D7信号,即用四位总线驱动。

电路和程序整理中,迟些上传。[已上传]



=====================================================================================================================
更新:

挑战一下极限,再减少一根线,仍然好使,不过要另加一个电容和一个二极管
image.png

更新:

无线馈电及传送数据。
image.png

===更新程序和电路===============================================

这就是电路,细心的朋友会发现实物图中有几个贴片的阻容件,秘密就在这里,利用电容的记忆效应,把并行的数据转为串行。


image.png

<div style="text-align: left;">示范程序很简单,不用多注释应该都能看懂。作为演示用途,其中有些长时间延时没有没有使用定时器,在多任务系统中当然要用定时中断来代替了。
复制代码
//         Drive a LCD1602 with 2 wire

//===================================================

//ICC-AVR application builder : 2010-10-3 19:30:02

// Target : M16

// Crystal: 4.0000Mhz


#include <iom16v.h>

#include <macros.h>


#define Set_E PORTB|=2

#define Clr_E PORTB&=~2

#define Set_D PORTB|=1

#define Clr_D PORTB&=~1

#define Set_xy(y,x) Send(0,(y<<6)|(x&15)|0x80)


//===================================================

void init_devices(void)

{

CLI(); //disable all interrupts

DDRB  = 0x03;

MCUCR = 0x00;

GICR  = 0x00;

SEI(); //re-enable interrupts

}


//===================================================

void Delay(unsigned int i)

{

while(i--);

}


//===================================================

void Send(unsigned char RS, unsigned char dat)

{

unsigned char i;

for (i = 2; i > 0; i--)

{

if (dat & 0x80) Set_D; else Clr_D;

Delay(10608);//14520us

if (RS) Set_E;

if (dat & 0x40) Set_D; else Clr_D;

Delay(462);  //660us

if (dat & 0x20) Set_D; else Clr_D;

Delay(18);   //30us

Set_E;

if (dat & 0x10) Set_D; else Clr_D;

_NOP();      //0.5us < t < 1.36us

Clr_E;

dat <<= 4;

}

}


//===================================================

void init_1602(void)

{

unsigned char i = 3;

Clr_D;

Clr_E;

Delay(10608);

do{

Clr_D;

Delay(462);

Set_D;

Set_E;

Delay(18);

if (i == 0) Clr_D;

_NOP();_NOP();_NOP();

Clr_E;

}while(i--);

Send(0,0x28);

Send(0,0x01);

Send(0,0x0f);

}


//===================================================

void Send_S(unsigned char *p)

{

while(*p) Send(1,*p++);

}


//===================================================

void main(void)

{

unsigned char i;

init_devices();

init_1602();

  
Set_xy(0,2);

Send_S("Hello world!");

Set_xy(1,3);

Send_S("I'm COWBOY.");

for (i=0;i<255;i++) Delay(10000);

  
Send(0,0x01);

Set_xy(0,3);

Send_S("Welcome to");

Set_xy(1,1);

Send_S("12345678");

while(1);

}