用RaspberryPi 3B 驱动LCD1602(八位总线)液晶显示屏(使用iwringPi库,C语言编写)

作为CSDN专业技术IT社区的一个新手小白,第一篇文章就从LCD1602起步吧。
也是刚刚接触到树莓派,装的是Raspbian官方的桌面版本系统,虽然这似乎并不重要,手头上的树莓派只有空溜溜的开发板装上了散热片,以及16GB的SD卡和读写器以及一个USB线的供电插头,因此用SSH网线连接到笔记本电脑,远程桌面连接进行控制。其中的安装步骤,网上教程也多了去,在此也不加以赘述了。

总的硬件电路模块

 在此申明一点,其实私以为一般对LCD1602的应用,只是将其作为一个显示屏而已,
 (虽然本身LCD1602是个低速CPU,双方可以进行互相传递数据)
 那么就意味着我的硬件电路RW端杜邦线接出来接到VSS(GND)即可,保证RW=0,并且实现起来,我没有按照手册上所说每次进行忙检测,RW=0意味着lcd1602发送不了忙标志位给树莓派(或者我第一次用单片机),实测问题不大,
 故我的代码实现不包含忙检测、RW(自己实践得到只要保证2ms 以上的延时,LCD能正常显示数据)
 因此程序代码里只用树莓派的各个端口输出高低电平给LCD即可实现字符啦~

 同时为了避免每次给LCD诸多引脚进行接线,自己DIY做了一个转接板电路,有电阻调节液晶显示屏亮度,并且有个短接帽,短接时lcd发光显示,拔掉背光。
 

 

其中V0端的青色杜邦线 本可以避免的,奈何背面走锡把路堵死了,所以只能用杜邦线桥接了,这里的短接帽被我拔了
 黄色的杜邦线即将RW接K、VSS(GND端)


有关LCD1602的硬件连接,很重要的一点:
LCD的供电VDD保证5v(记住只需要这个供电端5v即可),
DB0-DB7、EN\RS端的高低电平写入,用3.3v的通用推挽输出能驱动,并且不需要在树莓派(或者单片机)IO输出端接电阻进入DB0-DB7端或者EN、RW端
以下是我截取LCD1602一个英文手册里的:这里的引脚输入电压最小值为0.7*vdd约接近3.3V

(至于为什么可以不加电阻,以后得看看LCD1602这个低速CPU里的主芯片数据手册方能知道,大概率是芯片内自有电阻保护,防止电流过大?)之前用stm32F407走了挺大的一个坑,设置成端口开漏,并且5v上拉10k电阻,保证IO口可以进行双向,可读可写,那么LCD1602进行的忙检测就能实现了。具体的心得,另起一个博客写吧。

话不多说,直接上代码吧,第一次写博客,有很多纰漏之处,词不达意,以后回来再修改吧。

#include<wiringPi.h>
#include<stdio.h>
#define uchar unsigned char
void port_init(){
    int i ;
    for(i=0;i<8;i++)
         pinMode(i,OUTPUT);
    pinMode(27,OUTPUT); //RS Setpin
    pinMode(28,OUTPUT);	//EN Setpin
}
void write_cmd(uchar cmd){
	digitalWrite(27,LOW); //RS = 0	
	digitalWriteByte(cmd);//GPIO0=cmd
	digitalWrite(28,HIGH);
	delay(5);
	digitalWrite(28,LOW);
}
void write_dat(uchar dat){
	digitalWrite(27,HIGH); //RS=1
	digitalWriteByte(dat);//GPIO0=dat
	digitalWrite(28,HIGH);// EN=1;
	delay(5);			
	digitalWrite(28,LOW);// EN=0;
        
}
void init_LCD1602(void){
	write_cmd(0x38);//八线模式下两行显示 
	write_cmd(0x0c);//开启显示
	write_cmd(0x06);//地址+1
	write_cmd(0x01);//清屏
}
void showstring(uchar *p,int row_number){
	int i=0;
	row_number==1?write_cmd(0x80):write_cmd(0xc0);
	while(p[i]!='\0'){
		write_dat(p[i]);
		i++;
	}
}
int main(void){
	wiringPiSetup();
	port_init();
	init_LCD1602();
	showstring("2018.11.25",1);
	showstring("Hello,Raspberry",2);
	printf("hello\n");
	return 0;
}

这里补充下函数的声明:
void pinMode(int pin, int mode);
pinMode(pinNumber,OUTPUT); // set mode to output
pinMode(pinNumber, INPUT); // set mode to input

void digitalWriteByte(int value)
将一个8位的字节写入到前8个GPIO管脚中。这是一次性设置8个管脚的最快的方法,尽管将会花费两个写入操作到树莓派的GPIO硬件上。

定时函数:
void delay (unsigned int howLong)
这个是毫秒级的延时函数

vim编辑保存为lcd1602.c文件后,
在终端执行gcc -o lcd_driver lcd1602.c -lwiringPi 编译生成可执行文件obj,
再./lcd_driver即可看到LCD的显示了

最后实验效果:


ps:四线模式下需要注意的点,这里我还没试过四线模式下树莓派的驱动。仅仅对51单片机和32试过并成功了。
四线模式,主要目的是为了减少连线,但是51和32的经历让我发现四线模式下,我单片机复位按下会出现乱码,或者一行黑块,需要在write(0x32);write_cmd(0x28);函数前加入一段复位语句,这里注意是针对lcd进行复位,所以我觉得还是八线稳定些,省去这些麻烦。加入复位之后,我51单片机复位按键按下,lcd显示成功率刚开始50%,因为用的是学习版,有许多外设模块,有点干扰,而且16p母座直接插上去就好了,后来我也像树莓派一样杜邦线直接从IO端口引出来接lcd,单片机复位之后lcd正常显示100%,但是32就不一定了,虽然是最小系统板,但还是存在一些外设之类的,这待解决吧。。。
复位语句如下:

一个中文手册里的操作步骤:

         介绍完树莓派驱动程序后,想在此记录下个人对单片机接触历史吧。
   大二的时候导师让学51单片机,于是买了51QX的开发学习板进行学习,当时对单片机可谓是一无所知,听到51这一词汇更是不知所云,稀里糊涂地学着,从看视频教程出来,慢慢了解了单片机这玩意,但即使把视频教程看了底朝天,有时候还是处于一无所知的状态,总得从更底层出发,学汇编指令,了解寄存器等玩意(因此目前刚开始接触),学单片机第一步私以为先看一遍视频,手册这玩意到现在也没怎么看过,主要是想看可是看不懂啊,乍一看实在感觉难以下咽。
  可是这种东西就是需要慢慢地,静下心去看,先大概浏览一遍,再逐行把语句读下去,总能读懂一点东西。
  51学了中断、矩阵键盘这类知识后,也不深入,当初就是那种浅尝辄止后又接触到32这东西,32单片机相比较51更为复杂,刚开始看视频教程也看不明白,尤其是前面介绍概念性的东西,后面慢慢地发现也就多了些配置函数,由此才觉得51好简单,也不是简单啦,就是端口似乎是开漏输出,这一特性使得端口的状态既能当输入又能当输出,在代码编程里方便很多,从32的学习经历来看,端口配置有很多门道,什么开漏输出啊,通用推挽输出**,刚开始根本不知道这些东西有什么用**,
  可是后来实现矩阵键盘,先看明白51怎么实现的,然后转到32就有很多门道,比如要动态配置成输入输出,获取什么行、列线值,或者设置成开漏模式,手册里都清楚有讲,这样就能实现双向IO功能。
  因此我第一次真正静下心去看芯片数据手册GPIO那边的内容,看明白了很多,也将例程里那些别人写好的gpio库函数里看了看,懂得了一些gpio->ODR,GPIO->BSRR这些东西,我记得没错的话是叫做寄存器操作。
  昨晚第二次看数据手册,是针对lcd1602,虽然还是看不太明白,但也是慢慢地来,大概看明白30%,学习这东西是越学越深入的,因为那个lcd,复位出现了问题,我问别人,去百度,才发现有时候会遇到单片机热启动、冷启动方面的知识,虽然我现在还是不太懂,但是至少先有个基础性的概念,所有学习也都是这样,没有一蹴而就的。同时以前学数电,RAM\ROM那一章跳过了,近几天要翻看这些底层的东西,基础还是很重要的。
  以前对单片机外设很不了解,以为那个开发板外面接什么电机,或者红外遥控,就叫做外设,其实后来才恍然知道整个开发板上几乎都是外设,针对芯片这几个引脚来着。。。。这些电机、红外遥控现阶段也是跟视频试了一下,就没深入,
  学习还是得迂回前进的,以后我还是会重新来过的,目前想做智能小车,寒假试试吧,都已经大三了,是该懂得什么叫做学习了,而不是只是为了考个好成绩,拿个奖学金,应应试。
 

猜你喜欢

转载自blog.csdn.net/wa779478028/article/details/84498017