Linux驱动开发(十一)---树莓派SPI驱动学习(OLED)

前文回顾

《Linux驱动开发(一)—环境搭建与hello world》
《Linux驱动开发(二)—驱动与设备的分离设计》
《Linux驱动开发(三)—设备树》
《Linux驱动开发(四)—树莓派内核编译》
《Linux驱动开发(五)—树莓派设备树配合驱动开发》
《Linux驱动开发(六)—树莓派配合硬件进行字符驱动开发》
《Linux驱动开发(七)—树莓派按键驱动开发》
《Linux驱动开发(八)—树莓派SR04驱动开发》
《Linux驱动开发(九)—树莓派I2C设备驱动开发(BME280)》
《Linux驱动开发(十)—树莓派输入子系统学习(红外接收)》
继续宣传一下韦老师的视频

70天30节Linux驱动开发快速入门系列课程【实战教学、技术讨论、直播答疑】

在这里插入图片描述
今天来学习一下SPI设备驱动流程,顺带驱动一下之前的OLED小显示屏。
不过今天的内容,作为操作oled来说,很笨重,就像单片机一样,并没有体现出高级系统的优越性,所以只是学习一下相关SPI设备驱动就足够了。
Linux驱动开发(十一)---树莓派SPI驱动学习(OLED)_第1张图片

硬件背景

引脚图
Linux驱动开发(十一)---树莓派SPI驱动学习(OLED)_第2张图片
注意这里还有个2个spi之外的引脚,
DC引脚用来控制输入命令还是数据,这个就选取一个GPIO,那么我们比较熟悉的就是GPIO17;
RES引脚,用来复位显示屏,选取GPIO18;

设备树

看到引脚图中提供的引脚描述,找到SPI引脚
Linux驱动开发(十一)---树莓派SPI驱动学习(OLED)_第3张图片
根据原有的DTS中提供的描述
Linux驱动开发(十一)---树莓派SPI驱动学习(OLED)_第4张图片
修改为自己的描述
Linux驱动开发(十一)---树莓派SPI驱动学习(OLED)_第5张图片
注意多了两个引脚,后续我们要用到。而且必须会用到,尤其是复位,没有的话不能初始化成功的。
Linux驱动开发(十一)---树莓派SPI驱动学习(OLED)_第6张图片

然后测试一下DTS,看能否生成对应的设备节点

root@raspberrypi:/home/pgg# find / -name "*oled*"
/sys/firmware/devicetree/base/soc/spi@7e204000/myoled@0

           
root@raspberrypi:/home/pgg# cd /sys/bus/spi/devices/
root@raspberrypi:/sys/bus/spi/devices# ls
spi0.0  spi0.1
root@raspberrypi:/sys/bus/spi/devices# 

查看一下设备中的链接,正是我们的设备
Linux驱动开发(十一)---树莓派SPI驱动学习(OLED)_第7张图片

没毛病,老铁。
Linux驱动开发(十一)---树莓派SPI驱动学习(OLED)_第8张图片

驱动中的重点

重点在于注册的是spi_driver结构体

static struct spi_driver oled_driver = {
	.driver = {
		.name	= "myoled_drv",
		.of_match_table = oled_of_match,
	},
	.probe		= oled_probe,
	.remove		= oled_remove,
};

int oled_init(void)
{
	return spi_register_driver(&oled_driver);
}

static void oled_exit(void)
{
	spi_unregister_driver(&oled_driver);
}

然后probe函数的入参就是一个spi_device
Linux驱动开发(十一)---树莓派SPI驱动学习(OLED)_第9张图片
然后在驱动初始化屏幕的时候,需要先进行复位操作,否则初始化无法成功
Linux驱动开发(十一)---树莓派SPI驱动学习(OLED)_第10张图片
最后就是两个基础操作函数,用来给屏幕写命令或者数据,也就是SPI相关传输的使用。

static void oled_write_cmd_data(unsigned char uc_data,unsigned char uc_cmd)
{
	if(uc_cmd==0)
	{
		gpiod_set_value(oled_dc, 0);//拉低,表示写入指令
	}
	else
	{
		gpiod_set_value(oled_dc, 1);//拉高,表示写入数据
	}
	spi_write(oled_dev, &uc_data, 1);//写入
}

static void oled_write_datas(unsigned char *buf, int len)
{
	gpiod_set_value(oled_dc, 1);//拉高,表示写入数据
	spi_write(oled_dev, buf, len);//写入
}

后续的所有操作,和单片机操作屏幕是一样的。
所有代码可以在下面下载
《传送门》

测试效果

韦老师提供的用户侧程序,将显示过程分开操作了一下,效果如下

问题

屏幕不亮

过程中按照韦老师的代码进行测试,发现屏幕不亮,然后就参考之前手表的程序,把复位的步骤加了进来,就成功点亮了。
这里可能和韦老师的板子不一样,或者屏幕不一样,不得而知,反正如果你遇到这个问题,可以尝试这个操作。
另外,初始化的参数也不太一样,或许也有影响,分开参考,多试几次。
Linux驱动开发(十一)---树莓派SPI驱动学习(OLED)_第11张图片

结束语

学习成为习惯之后,也是挺可怕的,周六大早晨起来学习,不过目的也很简单,争取白天更新一篇,休息一下,晚上还能继续看个电影,《独行月球》还是要等老婆孩子回来,一家人整整齐齐的去看吧
Linux驱动开发(十一)---树莓派SPI驱动学习(OLED)_第12张图片
昨天看了一部韩国电影,马东锡主演的,话说韩国的电影还是比较好看的,能够反应的社会现实比较深刻,以至于多部电影影响了韩国的法律。不过话又说回来,影响的还是不够,谁不羡慕韩国的财阀呢
Linux驱动开发(十一)---树莓派SPI驱动学习(OLED)_第13张图片

你可能感兴趣的:(驱动开发,操作系统,linux知识,驱动开发,linux,12860,oled)