马甲一号 发表于 2014-1-12 14:38:05

终于搞掂树莓派驱动I2C LCD1602 液晶 显示时间 附C 版源码

话说我我已经买了好几个液晶了。。。
第一个1602是普通的1602,包括背光共有16个脚,接上线那个乱!这我也忍了,就是在网上找了好多资料,试过N次,驱动不上来,后来我总结:这玩意脚多,不是好东西,于是网上又找了一个集成I2C模块的1602,共四个脚,两个电源,两个数据。

接着又是找了好多资料,我是想找C语言的,包括wiringPi里的examples,都不正常。倒是以下这个脚本能正常显示字来,实在没办法了,就把这个Python脚本用C改写了一下,效果还行,把程序贴出来,方便其他朋友。#!/usr/bin/python

import time
import smbus

BUS = smbus.SMBus(1)
LCD_ADDR = 0x27

#LCD_ADDR = 0x3F sudo i2cdetect -y -a 0

def send_command(comm):
        # Send bit7-4 firstly
        buf = comm & 0xF0
        buf |= 0x04               # RS = 0, RW = 0, EN = 1
        BUS.write_byte(LCD_ADDR ,buf)
        time.sleep(0.002)
        buf &= 0xFB               # Make EN = 0
        BUS.write_byte(LCD_ADDR ,buf)
       
        # Send bit3-0 secondly
        buf = (comm & 0x0F) << 4
        buf |= 0x04               # RS = 0, RW = 0, EN = 1
        BUS.write_byte(LCD_ADDR ,buf)
        time.sleep(0.002)
        buf &= 0xFB               # Make EN = 0
        BUS.write_byte(LCD_ADDR ,buf)

def send_data(data):
        # Send bit7-4 firstly
        buf = data & 0xF0
        buf |= 0x05               # RS = 1, RW = 0, EN = 1
        BUS.write_byte(LCD_ADDR ,buf)
        time.sleep(0.002)
        buf &= 0xFB               # Make EN = 0
        BUS.write_byte(LCD_ADDR ,buf)
       
        # Send bit3-0 secondly
        buf = (data & 0x0F) << 4
        buf |= 0x05               # RS = 1, RW = 0, EN = 1
        BUS.write_byte(LCD_ADDR ,buf)
        time.sleep(0.002)
        buf &= 0xFB               # Make EN = 0
        BUS.write_byte(LCD_ADDR ,buf)

def init_lcd():
        try:
                send_command(0x33) # Must initialize to 8-line mode at first
                time.sleep(0.005)
                send_command(0x32) # Then initialize to 4-line mode
                time.sleep(0.005)
                send_command(0x28) # 2 Lines & 5*7 dots
                time.sleep(0.005)
                send_command(0x0C) # Enable display without cursor
                time.sleep(0.005)
                send_command(0x01) # Clear Screen
        except:
                return False
        else:
                return True

def clear_lcd():
        send_command(0x01) # Clear Screen

def print_lcd(x, y, str):
        if x < 0:
                x = 0
        if x > 15:
                x = 15
        if y <0:
                y = 0
        if y > 1:
                y = 1

        # Move cursor
        addr = 0x80 + 0x40 * y + x
        send_command(addr)
       
        for chr in str:
                send_data(ord(chr))

if __name__ == '__main__':
        init_lcd()
       
        print_lcd(0, 0, 'Hello, world!')
        print_lcd(0, 1, 'ucat.taobao.com')
我改写的C语言版#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <wiringPi.h>
#include <lcd.h>

int xio;

void send_command(int comm)
{
        // Send bit7-4 firstly
        int buf;
        buf = comm & 0xF0;
        buf |= 0x04;               // RS = 0, RW = 0, EN = 1

        wiringPiI2CWrite(xio,buf);
        usleep(2000);
        buf &= 0xFB;               // Make EN = 0
        wiringPiI2CWrite(xio,buf);

        // Send bit3-0 secondly
        buf = (comm & 0x0F) << 4;
        buf |= 0x04;               // RS = 0, RW = 0, EN = 1
        wiringPiI2CWrite(xio,buf);
        usleep(2000);
        buf &= 0xFB;               // Make EN = 0
        wiringPiI2CWrite(xio,buf);
}


void send_data(data)
{
        // Send bit7-4 firstly
        int buf;
        buf = data & 0xF0;
        buf |= 0x05;//               # RS = 1, RW = 0, EN = 1
        wiringPiI2CWrite(xio,buf);
        usleep(2000);
        buf &= 0xFB;//               # Make EN = 0
        wiringPiI2CWrite(xio,buf);
       
        // Send bit3-0 secondly
        buf = (data & 0x0F) << 4;
        buf |= 0x05;//               # RS = 1, RW = 0, EN = 1
        wiringPiI2CWrite(xio,buf);
        usleep(2000);
        buf &= 0xFB;//               # Make EN = 0
        wiringPiI2CWrite(xio,buf);
}

void init_lcd(void)
{
                send_command(0x33);// # Must initialize to 8-line mode at first
                usleep(5000);
                send_command(0x32);// # Then initialize to 4-line mode
                usleep(5000);
                send_command(0x28);// # 2 Lines & 5*7 dots
                usleep(5000);
                send_command(0x0C);// # Enable display without cursor
                usleep(5000);
                send_command(0x01);// # Clear Screen
}
               
               
void print_lcd(int x, int y, char* str)
{
        int addr;
       
        if( x < 0)
                x = 0;
        if(x > 15)
                x = 15;
        if(y <0)
                y = 0;
        if(y > 1)
                y = 1;

        //# Move cursor
        addr = 0x80 + 0x40 * y + x;
        send_command(addr);
       
        while(*str)
                send_data(*str++);
}
               
int main (void)
{
struct tm *t ;
time_t tim ;

char buf ;

printf ("Raspberry Pi LCD test program\n") ;

xio = wiringPiI2CSetup (0x27);
if (xio < 0){
    fprintf (stderr, "xio: Unable to initialise I2C: %s\n", strerror (errno));
    return 1;
}
wiringPiI2CWriteReg8 (xio, 0x0a, 0x84) ;// IOCON - set BANK bit
wiringPiI2CWriteReg8 (xio, 0x05, 0x84) ;// IOCON - set ODR in bank 0
wiringPiI2CWriteReg8 (xio, 0x00, 0x00) ;// Port A -> Outputs

init_lcd();
       

while(1)
        {
    tim = time (NULL) ;
    t = localtime (&tim) ;
    sprintf (buf, "    %02d:%02d:%02d    ", t->tm_hour, t->tm_min, t->tm_sec) ;

        print_lcd(0, 0, "ucat.taobao.com");
    print_lcd (0, 1, buf) ;
        }
       
return 0;
}
C 版运行效果



这几天天冷,我想做一个即时显示温度的设备,温度传感器方面以前已测试过了,就是这显示折腾了我好久。
python版的代码,我忘记出处了,好像也是这个论坛的。

马甲一号 发表于 2014-1-12 14:40:12

大家看图上的接线,是不是好清爽啊?:P

树老大 发表于 2014-1-13 10:23:33

赞一个,好东西

080809089t 发表于 2014-1-13 19:26:53

....浪费电,5V 1A5瓦的时钟、、、、不过喜欢就好

法克鱿 发表于 2014-1-14 18:14:52

编程完全看不懂,过年这段时间打算买几本书补一补

lison 发表于 2014-2-18 08:45:31

好酷啊 :lol

熵之矢 发表于 2014-2-22 11:31:54

楼主,我想做一个uart的部分,但是搜不到什么资料,你有相关资料吗?1058306167@qq.com

fefahl 发表于 2014-3-5 16:39:07

好东西,谢谢分享
页: [1]
查看完整版本: 终于搞掂树莓派驱动I2C LCD1602 液晶 显示时间 附C 版源码