工作原理

方式一 
    根据 LCD 的驱动原理可知,LCD 像素点上只能加上 AC 电压,LCD 显示器的对比度由 COM脚上的电压值减去 SEG 脚上的电压值决定,当这个电压差大于 LCD 的饱和电压就能打开像素点,小于 LCD 阈值电压就能关闭像素点,LCD 型 MCU 已经由内建的 LCD 驱动电路自动产生 LCD 驱动信号,因此只要 I/O 口能仿真输出该驱动信号,就能完成 LCD 的驱动。 由于LCD工作的最佳帖频率通常在25Hz~250Hz,一般设置刷新频率在 60Hz左右即可
现在考虑如何模拟出 COM 的波形
1/2 Bias 下 COM0~COM3 的 LCD 驱动波形如下: 

可以看出 4个COM 的输出,通过配置 IO口为高阻即可使其输出 VDD/2 电位,配置 IO为推挽输出即可输出高低电平。
    因此在一个 COM 周期内,只要每隔一段时间设置 COM0~COM3 输出对应的电压即可得到 COM0~COM3 的波形。具体来说就是第一次 Time Base 中断时设置 COM0 输出VDD,其它 COM 输出 VDD/2;第二次 Time Base 中断时设置 COM0 输出 VSS,COM1~COM3输出 VDD/2,第三次 Time Base 中断时设置 COM1 输出 VDD,其它 COM 输出 VDD/2;第四次 Time Base 中断时设置 COM1 输出 VSS,其它 COM 输出 VDD/2;……;第八次中断时设置 COM3 输出 VSS,其它 COM 输出 VDD/2。

因为点亮 LCD 像素点需要 COM 与 SEG 有大于饱和电压的电压差,也就是 COM 与 SEG 有+VDD 或者-VDD 的电压差,所以要点亮某个像素点,只要将对应的 SEG 输出与 COM 相反的电压即可。比如,当 COM0=VDD,只要 SEG=VSS 就可点亮对应像素点,当 COM0=VSS,只要 SEG=VDD 就可点亮对应像素点。考虑到 LCD 像素点点亮时先加+VDD 再加-VDD 可延长 LCD 的使用寿命,因此这里同一像素点也采用两次点亮的方式。

方式二
    由上面所述我们知道,只要 COM、SEG 的电压差为+VDD 或者-VDD 就可以点亮对应的 LCD笔段即像素点,因此,我们也可以不用模拟 COM 的 Timing 即可完成 LCD 的正常驱动。具体实现步骤如下: 
? 第一次中断时设置 COM0 输出 High,其它 COM 输出 VDD/2,再根据要显示的数据设置各个 SEG 的输出 
? 第二次中断时设置 COM1 输出 High,其它 COM 输出 VDD/2,再根据要显示的数据设置各个 SEG 的输出 
? 第三次中断时设置 COM2 输出 High,其它 COM 输出 VDD/2,再根据要显示的数据设置各个 SEG 的输出 
? 第四次中断时设置 COM3 输出 High,其它 COM 输出 VDD/2,再次根据要显示的数据设置各个 SEG 的输出 
? 第五次中断时设置 COM0 输出 Low,其它 COM 输出 VDD/2,再根据要显示的数据设置各个 SEG 的输出 
? 第六次中断、第七次中断、第八次中断参考上面的方法依次设置 COM1、COM2、COM3输出 Low 并设置要显示的数据 
? 循环进行以上的 8 次循环设置即可完成 LCD 的驱动 这种方式下 COM0~COM3 的 Timing 如下: 

    对比以上两种方法可以发现,COM 口的扫描频率也就是帖频率并没有改变,然而从占用的资源上来说,第二种方式比第一种方式会占用更少的 ROM 空间。

应用电路

可以根据实际使用情况取舍 COM 和增减 SEG,比如 LCD 可以是 1/2 Duty,那么只需要保留两个 COM 即可,SEG 同样可以参照范例程序扩展。 
根据上述说明,分 8 次依次设置 COM0~COM3 的输出,SEG 是输出 VDD 还是输出 VSS 需要根据要显示的数字判断,使用第一种驱动方式时 I/O 详细电位设置请参考下表:

<ignore_js_op>

这里也可以采用扫描的方式

结论
    本范例驱动 4×8 LCD 显示正常,用户只需要稍加改造即可套用到所选用的 1/2 Bias 规格的LCD 上。

我使用的是第一种扫描方式,大致流程图如下,其中有些地方对的不怎么齐

void LCD_Control(void)

{

static unsigned char state = 0;

if(!Back_Light_Is_Open)                // 背光检测

{

P1CFG1 = _b01101010;        // 配置COM1,COM2,COM3为高阻

P3CFG0 = _b01010110;        // 配置COM4为高阻

return;

}

LCD_BACK_LIGHT_CONTROL();        // 背光控制

Refresh_Wrod();         // 刷新字幕

Refresh_Light_Flash();  // 刷新灯光动画

Refresh_Fan_Flash();    // 刷新风扇动画

Refresh_UV_Lamp_Flash();// 刷新消毒动画

Refresh_Down_Flash();   // 刷新下降动画

Refresh_Up_Flash();     // 刷新上升动画

switch(state)

{   // 01强推,10高阻

case 0:                // 扫描 COM1

{

COM_L(1);

P1CFG1 = _b01100110;        // 配置COM1为强推,COM2,COM3为高阻

P3CFG0 = _b01010110;        // 配置COM4为高阻

COM1_SEG_SET();

state = 1;

}break;

case 1:                // 扫描 COM1

{

COM_H(1);

COM1_SEG_SET_NOT();

state = 2;

}break;

case 2:                // 扫描 COM2

{

COM_L(2);

P1CFG1 = _b01101001;        // 配置COM2为强推,COM1,COM3为高阻

COM2_SEG_SET();

state = 3;

}break;

case 3:                // 扫描 COM2

{

COM_H(2);

COM2_SEG_SET_NOT();

state = 4;

}break;

case 4:                // 扫描 COM3

{

COM_L(3);

P1CFG1 = _b01011010;        // 配置COM3为强推,COM1,COM2为高阻

COM3_SEG_SET();

state = 5;

}break;

case 5:                // 扫描 COM3

{

COM_H(3);

COM3_SEG_SET_NOT();

state = 6;

}break;

case 6:                // 扫描 COM4

{

COM_L(4);

P1CFG1 = _b01101010;        // 配置COM1,COM2,COM3为高阻

P3CFG0 = _b01010101;        // 配置COM4为强推

COM4_SEG_SET();

state = 7;

}break;

case 7:                // 扫描 COM4

{

COM_H(4);

COM4_SEG_SET_NOT();

state = 0;

}break;

default:

{

state = 0;

}break;

}

}

代码中 COM4_SEG_SET_NOT(); 是 COM4_SEG_SET(); IO对应段取反所得

COM_L(4); 拉低 COM4口

其他类似

这里说明一点,我是先将 IO口电平输出再配置功能的,因为在实际操作过程中会发现从高阻态转换至强推模式时会有 零点几微秒的脉冲干扰,具体宽度根据单片机速度来决定。
大概是因为单片机在从强推模式转换至高阻态时 IO配置虽被改变,但输出寄存器中的数据还会继续保持,所以才会有脉冲干扰的吧,先将 IO口输出电平改变再将 IO口状态从高阻切换至强推时就不会有脉冲干扰了

<ignore_js_op> 
这是先配置 IO输出状态再修改输出电平的,后来想了下,寄存器中应该是保存了最后一次 IO输出的电平,所以从高阻态切换至强推后直接将输出相应的电平,等到再次配置 IO口输出的电平时这是才会改变,所以才会在开始的时候有一个低脉冲

IO 模拟 1/2 Bias、1/4 Duty的 LCD 驱动相关推荐

  1. 晶联讯12864液晶+STM32+HAL库 IO模拟SPI成功实现显示。

    液晶型号:JLX12864G-290-PN不带字库 芯片型号:STM32F030F4 SPI连接方式:IO口模拟 STM32CubeMX  中引脚设置 JLX12864G_290_PN.h文件 #if ...

  2. 关于IO模拟时序(SPI)的注意事项

    原则:有硬件I2C.SPI时尽量用硬件操作,省去IO模拟繁琐的时序调试.但在内部资源不够时就要用IO模拟总线了. 关于短延时:模拟时序时是否需要延时要看MCU与device的相对速度.比如I2C如果4 ...

  3. STM32任意IO模拟8080时序驱动TFTLCD屏

    本篇硬件平台STM32F103ZET6.TFTLCD屏采用2.8寸.320*240分辨率.16bitRGB.37pin.ILI9341驱动. 本来准备使用STM32F429平台的,因为它有LTDC,顺 ...

  4. AT32 421 IO模拟can通信

    421 IO模拟can通信 1. 测试代码:包含外部晶振16M及8M版本. 2. 连线:PA5–CAN_TX:PA4-CAN_RX.(外接3.3V电平CAN收发器). 3. Demo功能: –波特率1 ...

  5. 51单片机(IO模拟IIC通信)

    单片机作为主机 sbit SDA = P1^0; sbit SCL = P1^1; IIC数据操作:在iic总线上,数据伴随时钟脉冲,一位一位的传送的,数据位由高到低传送,每位数据占一个时钟脉冲.在时 ...

  6. STM32学习笔记一、 IO模拟串行通讯

    代码下载链接:实验五.USART-IO模拟.zip-嵌入式文档类资源-CSDN下载 文档下载链接:UART数据波形分析_uart波形-硬件开发文档类资源-CSDN下载 首先对UART数据波形进行分析: ...

  7. 单片机IO模拟串口发送数据

    单片机IO模拟串口发送数据 由于项目上用的STM32单片机串口资源不够用,但是还是想看调试输出,所以就多引出了一个IO,使用IO模拟串口发送数据的时序来当做串口打印用了,本章实验工程以8bit数据位. ...

  8. SGP30传感器示例程序(基于51单片机、IO模拟I2C)

    SGP30传感器示例程序(基于51单片机.IO模拟I2C) SGP30传感器I2C地址:0x58 说明:这里采用使用IO模拟的方式来实现I2C 点击这里下载SGP30测试源码及数据手册 /*SGP30 ...

  9. Rector模式和同步IO模拟Reactor模式,proactor模式和异步IO模拟proactor模式

    Reactor模式本身就是一种同步IO模式 Reactor模式的流程如下: 1.应用程序注册socket的读写就绪事件,和事件处理器 2.事件分类器等待读写就绪事件 3.当事件分离器监听到读写就绪事件 ...

最新文章

  1. codeforces round #576 div2 D Welfare State(线段树)[单点修改+区间修改]
  2. 备忘录模式(Memento)的原版与简化版实现
  3. Ecshop购物流程结算步骤 显示商品缩略图
  4. java script w3c study notes
  5. GitHub上的编程语言:JavaScript领衔Java次之
  6. 挖掘机实现“无人驾驶”!协作机器人“魔法之手”取代人工操作
  7. html函数属性的赋予,你可以将javascript函数名称设置为html属性吗?
  8. Openwrt中ppp拨号总结
  9. Win11系统创建虚拟桌面的方法
  10. dropdownList级联刷新gridView
  11. C语言实现:输出明天的日期
  12. ANU COMP1100 Lab1简介
  13. java那块最难_Java哪块最难学?
  14. 2018最新Python视频教程
  15. 读书笔记之张潇雨个人投资课
  16. openwrt软路由怎么中止执行/怎么向上翻屏/怎么清屏
  17. NorFlash和NandFlash区别
  18. linux启动服务命令
  19. 【Python成长之路】Python爬虫 --requests库爬取网站乱码(\xe4\xb8\xb0\xe5\xaf\x8c\xe7\x9)的解决方法
  20. 全国行政区划码(国家统计局数据)

热门文章

  1. 软工作业2:硬币游戏——代码的分析与改进
  2. centos7加固手册
  3. 【转】 asp.net从视频文件中抓取一桢并生成图像文件的方法 实现多语言本地化应用程序 自动返回上次请求页面...
  4. Linq To Xml学习 - 1.LINQ to XML 概述
  5. python安装成功第三方库但import出问题_为什么会在pyspark在RDD中调用python第三方库失败?...
  6. 用神经网络分类连续与离散
  7. Leetcode 相关资料
  8. 【控制】复杂度定义及计算
  9. 1.5 卷积步长-深度学习第四课《卷积神经网络》-Stanford吴恩达教授
  10. 4.2 数据集划分-机器学习笔记-斯坦福吴恩达教授