amoBBS 阿莫电子论坛

 找回密码
 注册
搜索
bottom↓
查看: 107646|回复: 1173

成功了!任意2个io直接驱动LCD1602,并且不需外加芯片。

  [复制链接]
发表于 2010-10-3 23:08:10 | 显示全部楼层 |阅读模式
上次发了个人肉驱动LCD1602的帖子,没什么技术含量,居然得裤子,有点不好意思,正好这几天有点时间,于是就再做一个小试验,用尽量少的IO来驱动1602,以适应在某些引脚较少的MCU,如Tiny系列等。废话少说,先上图,如果大家觉得有意思请起个哄...


(原文件名:001.jpg)


(原文件名:002.jpg)

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

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



=====================================================================================================================
【59楼】 更新:

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


(原文件名:003.jpg)



=====================================================================================================================
【167楼】 更新:

无线馈电及传送数据。


(原文件名:007.jpg)
发表于 2010-10-3 23:10:14 | 显示全部楼层
高手
发表于 2010-10-3 23:16:11 | 显示全部楼层
这样飞线真吓人
发表于 2010-10-3 23:30:38 | 显示全部楼层
怎么回事啊,没看懂
发表于 2010-10-3 23:34:15 | 显示全部楼层
太神奇了,是不是所有的1602的LCD都可以这样?真他妈的神奇了!
发表于 2010-10-3 23:46:38 | 显示全部楼层
祝贺成功,来起个哄!
发表于 2010-10-4 00:09:22 | 显示全部楼层
回复【5楼】JQ_Lin  
祝贺成功,来起个哄!

-----------------------------------------------------------------------

+1
发表于 2010-10-4 00:09:27 | 显示全部楼层
我等着。
发表于 2010-10-4 00:36:17 | 显示全部楼层
这也行??
发表于 2010-10-4 00:36:59 | 显示全部楼层
期待原理图和程序
 楼主| 发表于 2010-10-4 00:48:09 | 显示全部楼层
这就是电路,细心的朋友会发现实物图中有几个贴片的阻容件,秘密就在这里,利用电容的记忆效应,把并行的数据转为串行。

(原文件名:2wire_1602.PNG)

示范程序很简单,不用多注释应该都能看懂。作为演示用途,其中有些长时间延时没有没有使用定时器,在多任务系统中当然要用定时中断来代替了。

//         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("www.ourdev.cn");
  while(1);
}
发表于 2010-10-4 01:12:51 | 显示全部楼层
cowboy

不错,太浪费IO了,几十个脚就用两个,还焊接上了:)

打PP,现在AVR多贵呀,
发表于 2010-10-4 01:17:52 | 显示全部楼层
活学活用,牛。
发表于 2010-10-4 01:21:35 | 显示全部楼层
一个管脚通过RC,实现4个端口有点危险,
建议改成3个管脚实现。
发表于 2010-10-4 01:35:27 | 显示全部楼层
这个强哇

顶了
发表于 2010-10-4 01:38:11 | 显示全部楼层
强人啊·~~跟着起哄!!……
发表于 2010-10-4 02:03:58 | 显示全部楼层
呵呵,强,但这个有人敢这样做产品吗?
发表于 2010-10-4 02:28:23 | 显示全部楼层
呵呵,真能钻研,致敬
发表于 2010-10-4 04:27:07 | 显示全部楼层
真的很不错!有空我也来试试。
发表于 2010-10-4 07:06:46 | 显示全部楼层
呵呵,不佩服都不行了!!
发表于 2010-10-4 07:28:56 | 显示全部楼层
很具有钻研精神,已经举报了,哇哈哈...
发表于 2010-10-4 07:32:31 | 显示全部楼层
Roman Black has a similar idea and he got it down to 1 wire, and your code isn't too far off from that either.

according to Black, the concept actually came from 1950s but he is the first (I saw) who got it done with just 1 wire. Pretty impressive.

the key is to make the rc constants sufficiently apart so that you can output pretty much any bits / bytes.
发表于 2010-10-4 07:36:13 | 显示全部楼层
真是牛人一个。不过不敢用到产品中。
发表于 2010-10-4 07:43:35 | 显示全部楼层
牛人,顶帖
发表于 2010-10-4 08:20:43 | 显示全部楼层
牛人
发表于 2010-10-4 08:26:09 | 显示全部楼层
原来如此,靠相差很大的时间常数实现的
发表于 2010-10-4 08:31:59 | 显示全部楼层
"靠相差很大的时间常数实现的"

yes. that points to the problem with this approach: the time to send multi-bits gets exponentially longer.
发表于 2010-10-4 08:38:42 | 显示全部楼层
来起个哄!
发表于 2010-10-4 08:48:34 | 显示全部楼层
强!
这样都成.
真的是只有想不到,没有做不到
发表于 2010-10-4 08:50:08 | 显示全部楼层
mark
 楼主| 发表于 2010-10-4 09:25:30 | 显示全部楼层
回复【13楼】zhonghua_li 蓝色天空
一个管脚通过rc,实现4个端口有点危险,
建议改成3个管脚实现。
-----------------------------------------------------------------------

回复【25楼】longquan 巅
原来如此,靠相差很大的时间常数实现的
-----------------------------------------------------------------------

回复【26楼】millwood0
"靠相差很大的时间常数实现的"
yes. that points to the problem with this approach: the time to send multi-bits gets exponentially longer.

-----------------------------------------------------------------------

    上面各位都看出了门道,为了保证数据传输的可靠性,相邻的两bit数据,RC时间常数相差需很大,我这里设定为22倍左右,差距越大,可靠性就越高。事实上,我试了12倍的间隔,仍能正常工作,但考虑到阻容的误差和温漂,以及电磁干扰等因素,选用了22倍间隔。太长的等比间隔,会带来了数据传送速度很慢的问题,如楼主位的RC参数,传送一字节数据约需32ms,正如millwood0所说,连续发送多个字节时,通讯线将会忙不过来,必须等待。为解决此问题,我另外写了个程序,设立发送缓冲区,环状FIFO结构,来暂存待显示的内容,并用定时中断来完成自动发送。IO是省了,却带来几十字节的内存开销,还要占用一个定时器。
    比较实用的方案,正如 zhonghua_li 蓝色天空 所说,多用一个IO,这样每个IO只驱动LCD1602的两个PIN,上面问题就能得到完美解决,包括RC时间常数的选择,也大大放宽了要求,传送速度和普通的驱动方式相当。
    大多数人会有疑问,就那么几个阻容,能可靠工作吗?我也考虑了这问题,在实际的应用中,常常看到数据线上都有小电阻与小电容组成的低通滤波网络来提高数据传输的可靠性。这里的RC用法类似,选用更大的RC,理论上对抵抗外界EMC干扰更有效,设计上只要保证时钟脉冲的下降沿时刻,各数据线的上电平符合LCD1602的要求(VH>4V,VL<1V)。实际测试表现如何?用了简单的方法进行模拟:1.不断发送数据,然后打通手机瞬间,把手机天线紧靠数据线,未发现异常。 2.用工作中的示波器信号线的地线,不断触碰LCD1602相关引脚,也未发现异常。当然这种测试并不规范,所以这种驱动方式玩玩可以,用在产品上还得慎重考虑。




编辑原因:改错别字
发表于 2010-10-4 09:27:46 | 显示全部楼层
牛犇的不得了啊!!!

原来单片机最小系统能长成这个样子,厉害!
发表于 2010-10-4 09:29:45 | 显示全部楼层
mark
发表于 2010-10-4 09:30:27 | 显示全部楼层
学习了。
发表于 2010-10-4 10:07:37 | 显示全部楼层
这个资料真不错 收藏了
发表于 2010-10-4 10:36:35 | 显示全部楼层
不错,不错,比较实用的一种方式,MARK
发表于 2010-10-4 11:00:30 | 显示全部楼层
楼主乃歪门邪道高手啊,佩服佩服,我觉得在某些低成本应用上真可以用。
发表于 2010-10-4 11:24:29 | 显示全部楼层
学习
发表于 2010-10-4 12:16:05 | 显示全部楼层
标记
发表于 2010-10-4 12:25:25 | 显示全部楼层
高人
发表于 2010-10-4 12:29:33 | 显示全部楼层
回复【11楼】3232RE2E2
-----------------------------------------------------------------------

注意看图一,他没有焊在AVR的腿上。
发表于 2010-10-4 12:31:23 | 显示全部楼层
学习了
发表于 2010-10-4 12:32:39 | 显示全部楼层
牛人!
发表于 2010-10-4 12:45:34 | 显示全部楼层
牛人
发表于 2010-10-4 12:52:55 | 显示全部楼层
牛人啊
发表于 2010-10-4 12:54:39 | 显示全部楼层
这个强!!!
发表于 2010-10-4 13:03:29 | 显示全部楼层
不得不顶.
发表于 2010-10-4 13:18:08 | 显示全部楼层
牛人啊!
发表于 2010-10-4 13:24:17 | 显示全部楼层
很happy
仔细优化的话,一个IO也不是不可能(虽然很慢吧……)
发表于 2010-10-4 13:25:23 | 显示全部楼层
佩服,牛人
发表于 2010-10-4 13:29:26 | 显示全部楼层
在单片机内搞个小的频率合成器(类似DTMF调制器的),用PWM输出,外面用6组LC带通滤波器,后面接检波和RC输出
应该可以让6组速度一致
发表于 2010-10-4 13:38:14 | 显示全部楼层
果然高手!
发表于 2010-10-4 14:02:15 | 显示全部楼层
厉害!
发表于 2010-10-4 14:45:04 | 显示全部楼层
太利害了
发表于 2010-10-4 15:16:41 | 显示全部楼层
强人!起哄!
发表于 2010-10-4 15:26:15 | 显示全部楼层
厉害,收藏此贴
发表于 2010-10-4 16:02:35 | 显示全部楼层
NB
发表于 2010-10-4 16:43:06 | 显示全部楼层
方法很妙。
发表于 2010-10-4 16:46:17 | 显示全部楼层
mark
 楼主| 发表于 2010-10-4 16:54:50 | 显示全部楼层
挑战一下极限,再减少一根线,仍然好使,不过要另加一个电容和一个二极管。


(原文件名:003.jpg)
发表于 2010-10-4 16:58:09 | 显示全部楼层
回复【59楼】cowboy
-----------------------------------------------------------------------

可以再搞得极限一点,把电源线也省了,用IO通过肖特基二极管给电源电容充电
 楼主| 发表于 2010-10-4 17:09:19 | 显示全部楼层
回复【60楼】h2feo4 无机酸
-----------------------------------------------------------------------
呵呵,上面用的就是这种方法,减少的是电源线,而不是信号线。
LCD1602如果不接背光,工作电流也就一两个mA,对于AVR这类芯片的IO,窃电几个mA只是小菜一碟。
发表于 2010-10-4 17:23:19 | 显示全部楼层
顶顶。。。。。。。。
发表于 2010-10-4 17:59:56 | 显示全部楼层
回复【61楼】cowboy
回复【60楼】h2feo4 无机酸
-----------------------------------------------------------------------
呵呵,上面用的就是这种方法,减少的是电源线,而不是信号线。
lcd1602如果不接背光,工作电流也就一两个ma,对于avr这类芯片的io,窃电几个ma只是小菜一碟。
-----------------------------------------------------------------------

要不要再狠一点,只用一个IO一条地线就可以了呢。貌似SONY已经有这技术用于数据通信(基于芯片完成的数据通信)。
COWBOY   加油!
发表于 2010-10-4 18:06:33 | 显示全部楼层
太牛了,佩服呀
发表于 2010-10-4 18:08:33 | 显示全部楼层
顶牛仔,不是一般狠
发表于 2010-10-4 18:15:08 | 显示全部楼层
膜拜……
发表于 2010-10-4 19:07:52 | 显示全部楼层
what happend?
mark
发表于 2010-10-4 20:29:54 | 显示全部楼层
mark
发表于 2010-10-4 22:38:35 | 显示全部楼层
太牛了
发表于 2010-10-4 23:50:58 | 显示全部楼层
我服了 高人太多了
发表于 2010-10-5 00:02:46 | 显示全部楼层
牛X,只能膜拜和憧憬
发表于 2010-10-5 00:11:31 | 显示全部楼层
牛人,不过单线通信可以选用别的格式,如uart,不过这个方式确实厉害,我想都没有想到过。
发表于 2010-10-5 00:31:53 | 显示全部楼层
牛仔V5!
发表于 2010-10-5 02:03:45 | 显示全部楼层
HOHO, 有本事一根线都不要接...
发表于 2010-10-5 02:56:43 | 显示全部楼层
太牛啦!顶牛!
推荐置酷。
发表于 2010-10-5 07:44:17 | 显示全部楼层
mark
发表于 2010-10-5 08:01:14 | 显示全部楼层
顶!
发表于 2010-10-5 08:14:49 | 显示全部楼层
佩服!!!
发表于 2010-10-5 09:01:49 | 显示全部楼层
牛人,MARK
 楼主| 发表于 2010-10-5 09:47:08 | 显示全部楼层
回复【63楼】winmcu

要不要再狠一点,只用一个io一条地线就可以了呢。貌似sony已经有这技术用于数据通信(基于芯片完成的数据通信)。
-----------------------------------------------------------------------

winmcu说的是类似消防总线的通讯方式吧,直接把串行数据调制在电源线上,不过这是需要专用芯片来解调,不能光靠几个RC就能搞掂。类似的方式,我两年前也做过,不知大家对下面这张图片是否熟悉,这就是之前我发过的贴子中一张图片,参照:
    http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=2243715
其中的示范程序中就提及到 One Wire 总线的驱动,显示模块解调所用的芯片也不是什么专用芯片,只是一片我们最熟悉不过的 74HC595 ,就能完成任务。


(原文件名:ourdev_611029.jpg)

当时为了方便没在电源上加载数据,而单独引了一根数据线,所以看到是三根引线(VCC,GND,DAT),实际上完全可以把数据加载在电源上。
发个显示模块的底面图,就可以看到利用一片 74HC595 解调 OneWire 通讯,并驱动三位数码管的情况。
发送端(MCU)的调制也很简单,就一个IO输出,加一个三极管扩流。
如果大家有兴趣,有空时我可以另开个贴子讨论。
不过种方式用在LCD1602上,不另加芯片,我还是没想到好办法,除非外围电路弄得很复杂,但这样就失去意义了。


(原文件名:004.jpg)


(原文件名:005.jpg)
发表于 2010-10-5 09:55:53 | 显示全部楼层
奶牛男孩很牛!
发表于 2010-10-5 10:11:11 | 显示全部楼层
强人一个!
发表于 2010-10-5 10:17:46 | 显示全部楼层
酷得没法说啊!
发表于 2010-10-5 10:19:18 | 显示全部楼层
学习了
发表于 2010-10-5 10:39:50 | 显示全部楼层
极限设计
发表于 2010-10-5 10:56:31 | 显示全部楼层
太狠了,把1602当18B20搞,还是寄生供电,哈哈!
发表于 2010-10-5 11:06:52 | 显示全部楼层
看了30楼的解释,不知道理解为单总线合不合理,也就是通过RC时间常数去控制两位数据传输时的间隔,没四位数据为一个单元,另外的一个端口相当于使能端口,控制数据与命令间的切换,不知道理解的是否正确。
发表于 2010-10-5 23:00:52 | 显示全部楼层
其实厂家生产一个串口的LCD什么问题就都解决了
发表于 2010-10-6 00:02:58 | 显示全部楼层
不错啊!
发表于 2010-10-6 00:08:42 | 显示全部楼层
"其实厂家生产一个串口的LCD什么问题就都解决了"

there are such chips.

and you can simply make one by using a mcu as the front-end.
发表于 2010-10-6 01:08:11 | 显示全部楼层
牛的没话说了!
发表于 2010-10-6 01:10:36 | 显示全部楼层
mark
发表于 2010-10-6 06:04:43 | 显示全部楼层
回复【86楼】ckvlhf
太狠了,把1602当18b20搞,还是寄生供电,哈哈!
-----------------------------------------------------------------------
发表于 2010-10-6 08:25:15 | 显示全部楼层
呵呵 果然厉害 顶起!
发表于 2010-10-6 08:30:58 | 显示全部楼层
学习,这点子很伟大
发表于 2010-10-6 09:40:10 | 显示全部楼层
牛人
发表于 2010-10-6 09:42:13 | 显示全部楼层
楼主厉害!!!
发表于 2010-10-6 10:04:40 | 显示全部楼层
牛啊
发表于 2010-10-6 10:06:15 | 显示全部楼层
厉害
友情提示:标题不合格、重复发帖,将会被封锁ID。详情请参考:论坛通告:封锁ID、获得注册邀请码、恢复被封ID、投诉必读
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|阿莫电子论坛(原ourAVR/ourDEV) ( 工信部备案:粤ICP备09047143号 公安备案:44190002001997(交互式论坛) )

GMT+8, 2018-7-23 11:30

阿莫电子论坛, 原"中国电子开发网"

© 2004-2018 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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