[技术问题解答] 【FRDM-KL02】+I2C模块驱动1602

[复制链接]
 楼主| quray1985 发表于 2015-12-21 20:53 | 显示全部楼层 |阅读模式
凡是学过51单片机的,相信你手边一定有块1602。       顾名思义,它能够同时显示16x02即32个字符。由若干个5X7或者5X10等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,正因为如此所以它不能很好地显示图形(用自定义CGRAM,显示效果也不好)。       目前市面上字符液晶绝大多数是基于HD44780 液晶芯片的,控制原理是完全相同的,因此基于HD44780写的控制程序可以很方便地应用于市面上大部分的字符型液晶。

1602采用标准的16脚接口,其中:

第1脚:VSS为电源地
第2脚:VCC接5V电源正极
第3脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高(对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度)。
第4脚:RS为寄存器选择,高电平1时选择数据寄存器、低电平0时选择指令寄存器。
第5脚:RW为读写信号线,高电平(1)时进行读操作,低电平(0)时进行写操作。
第6脚:E(或EN)端为使能(enable)端,高电平(1)时读取信息,负跳变时执行指令。
第7~14脚:D0~D7为8位双向数据端。

 楼主| quray1985 发表于 2015-12-21 20:54 | 显示全部楼层
第15~16脚:空脚或背灯电源。15脚背光正极,16脚背光负极。
       使用I2C转并口模块可以节约好几个I/O口,真好。主要元件PCF8574Apcf8574a.pdf(1.28 MB, 下载次数: 7),即便用洞洞板制作也很简单。

看看我的实拍图:

 楼主| quray1985 发表于 2015-12-21 20:54 | 显示全部楼层
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "gpio.h"
  4. #include "common.h"
  5. #include "i2c.h"
  6. #include "uart.h"
  7. void Check_lcd(void)
  8. {     
  9.       uint8_t temp=0;
  10.       I2C_WriteSingleRegister(HW_I2C0, 0x27, 0x00, 0xf8);
  11.       DelayMs(2);
  12.       I2C_ReadSingleRegister(HW_I2C0, 0x27, 0x00, &temp) ;         
  13.       while(temp & 0x80);
  14.       I2C_WriteSingleRegister(HW_I2C0, 0x27, 0x00, 0xf8);
  15. }
 楼主| quray1985 发表于 2015-12-21 20:55 | 显示全部楼层
  1. void Wcom_lcd(uint8_t Lcd_com,uint8_t BuysC)
  2. {
  3.         uint8_t temp;
  4.         if(BuysC)
  5.         Check_lcd();
  6.         DelayMs(1);
  7.         temp=Lcd_com&0xf0;        
  8.         I2C_WriteSingleRegister(HW_I2C0, 0x27, 0x00, temp);
  9.         I2C_WriteSingleRegister(HW_I2C0, 0x27, 0x00, temp|0x0c);
  10.         I2C_WriteSingleRegister(HW_I2C0, 0x27, 0x00, temp|0x08);
  11.         
  12.         temp= Lcd_com<<4;         
  13.         I2C_WriteSingleRegister(HW_I2C0, 0x27, 0x00, temp);
  14.         I2C_WriteSingleRegister(HW_I2C0, 0x27, 0x00, temp|0x0c);
  15.         I2C_WriteSingleRegister(HW_I2C0, 0x27, 0x00, temp|0x08);
  16. }
 楼主| quray1985 发表于 2015-12-21 20:56 | 显示全部楼层
  1. void Wdat_lcd(uint8_t Lcd_dat)

  2. {
  3.         uint8_t temp;
  4.         Check_lcd();
  5.         DelayMs(1);
  6.         temp=Lcd_dat&0xf0;
  7.         I2C_WriteSingleRegister(HW_I2C0, 0x27, 0x00, temp);
  8.         I2C_WriteSingleRegister(HW_I2C0, 0x27, 0x00, temp|0x0d);
  9.         I2C_WriteSingleRegister(HW_I2C0, 0x27, 0x00, temp|0x09);
  10.         
  11.         temp= Lcd_dat<<4;      
  12.         I2C_WriteSingleRegister(HW_I2C0, 0x27, 0x00,temp);        
  13.         I2C_WriteSingleRegister(HW_I2C0, 0x27, 0x00, temp|0x0d);               
  14.         I2C_WriteSingleRegister(HW_I2C0, 0x27, 0x00, temp|0x09);
  15. }
 楼主| quray1985 发表于 2015-12-21 20:56 | 显示全部楼层
  1. void DisplayOneChar(uint8_t X, uint8_t Y, uint8_t DData)
  2. {
  3.         Y &= 0x01;
  4.         X &= 0x0F; //限制X不能大于15,Y不能大于1
  5.         if (Y)
  6.         {
  7.                 X |= 0x40; //当要显示第二行时地址码+0x40;
  8.         }
  9.         X |= 0x80;
  10.         Wcom_lcd(X, 1);
  11.         Wdat_lcd(DData);
  12. }
  13. void DisplayString(uint8_t X, uint8_t Y, char *str)
  14. {
  15.         uint8_t Length=0;        
  16.         Y &= 0x01;
  17.         X &= 0x0F; //限制X不能大于15,Y不能大于1
  18.         while (str[Length]!='\0') //若到达字串尾则退出
  19.         {
  20.                 if (X <= 0x0F) //X坐标应小于0xF
  21.                 {
  22.                         DisplayOneChar(X, Y, str[Length]); //显示单个字符
  23.                         Length++;
  24.                         X++;
  25.                 }
  26.         }
  27.    
  28. }
 楼主| quray1985 发表于 2015-12-21 20:57 | 显示全部楼层
  1. void Lcd_Init(void)
  2. {
  3.         DelayMs(240);
  4.         DelayMs(240);
  5.         DelayMs(240);        
  6.         Wcom_lcd(0x30,0); //三次显示模式设置,不检测忙信号
  7.         DelayMs(20);
  8.         Wcom_lcd(0x30,0); //三次显示模式设置,不检测忙信号
  9.         DelayMs(20);
  10.         Wcom_lcd(0x30,0); //三次显示模式设置,不检测忙信号
  11.         DelayMs(20);
  12.         Wcom_lcd(0x20,0);
  13.         DelayMs(20);
  14.         Wcom_lcd(0x2c,1); //显示模式设置,开始要求每次检测忙信号,4Bit模式
  15.         Wcom_lcd(0x08,1); //关闭显示        
  16.         Wcom_lcd(0x0C,1); // 显示开及光标设置
  17.         Wcom_lcd(0x06,1); // 显示光标移动设置        
  18.         Wcom_lcd(0x01,1); //显示清屏
  19.         DelayMs(5);   
  20. }
 楼主| quray1985 发表于 2015-12-21 20:57 | 显示全部楼层
  1. int main(void)
  2. {
  3.    
  4.     /* 开机延时 */
  5.     DelayInit();
  6.     /* UART 初始化 */
  7.     GPIO_QuickInit(HW_GPIOB, 6, kGPIO_Mode_OPP);
  8.     UART_QuickInit(UART0_RX_B2_TX_B1, 9600);
  9. //    UART_ITConfig(HW_UART0, kUART_IT_Rx, true);
  10.     I2C_QuickInit(I2C0_SCL_PB03_SDA_PB04, 576000);
  11.        Lcd_Init();      
  12.        DisplayString(2, 0,"Hello,world!");
  13.        DisplayString(0, 1,"Guess YL-KL26Z!");
  14. while(1)
  15.     {
  16.   }     
  17. }

qagainc 发表于 2015-12-22 22:45 | 显示全部楼层
楼主 我是赶上直播了吗。。。楼主 有没有向51一样 直接驱动1602的?并口驱动。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

156

主题

1488

帖子

5

粉丝
快速回复 在线客服 返回列表 返回顶部

156

主题

1488

帖子

5

粉丝
快速回复 在线客服 返回列表 返回顶部