树莓派开发笔记06-树莓派的SPI控制(点亮0.96OLED)

实验说明

我们这里会使用SPI去驱动一个0.96的OLED,首先需要打开SPI

sudo raspi-config
Interfacing Options------>SPI------>Yes------->OK------->finsh

然后将屏幕接到树莓派上,接mosi和sclk的脚,DC接28,RST接29,CE接CE0

这个实验有一个坑我还没找到,就是每次我使用了BCM库来控制屏幕后,就不能使用Python和WringPi来控制了,这时候把SPI关一次再开一次才可以使用,但是如果一个时间内只掉用他们中的单独一个,是不会有问题的。

在这里插入图片描述

代码编写

wiringPi

主要说一下怎么初始化和发送数据,具体的实现,参考开源链接。

1、选择SPI的通道和速度。

channel只有0和1这两个值,表示初始化哪个SPI通道;

speed的范围是500000 到32000000,这个是SPI通讯的速度范围,单位是Hz;

int wiringPiSPISetup     (int channel, int speed) ;

2、开始数据传输

channel只有0和1这两个值,表示初始化哪个SPI通道;
data要传输的字节,十六进制;
len传输的字节长度。

int wiringPiSPIDataRW    (int channel, unsigned char *data, int len) ;

下面是一个初始化SPI的代码,然后使用的OLED.c就是中景元开源的代码,将SPI部分做了修改。

这是main.c的代码

#include <wiringPi.h>
#include <stdio.h>
#include <wiringPiI2C.h>
#include "oled.h"
#include <wiringPiSPI.h>

#define LCD_DC  28     // 模式选择 1:写数据 0:写命令
#define LCD_DIN 12     // 串行数据线
#define LCD_CLK 14     // 串行时钟线
#define LCD_RST 29     // 复位信号  低电平有效
#define LCD_CE  10     // 芯片使能  低电平有效

#define SPI_CHANNEL 0

void oled_write_one_byte(uint8_t dat,uint8_t mode)
{ 
    digitalWrite(LCD_CE,LOW);
    if (mode == OLED_DATA) { // 写数据
        digitalWrite(LCD_DC,HIGH);
    }
    else { // 写命令
        digitalWrite(LCD_DC,LOW);
    }
    uint8_t *tempData = &dat;
    wiringPiSPIDataRW(SPI_CHANNEL, tempData, 1);
    digitalWrite (LCD_CE, HIGH);
}

void set_rst_level(uint8_t level)
{
    if(level == 1)
    {
        digitalWrite(LCD_RST,HIGH);
    }else
    {
        digitalWrite(LCD_RST,LOW);
    }
}

void delay_ms(uint8_t ms)
{
    delay(ms);
}

int main(void)
{ 
    if(wiringPiSetup() < 0) //当使用这个函数初始化树莓派引脚时,程序使用的是wiringPi 引脚编号表。
        return 1;

    pinMode(LCD_DC,OUTPUT);
    pinMode(LCD_RST,OUTPUT);
    pinMode(LCD_CE,OUTPUT);

    int isOK = wiringPiSPISetup(SPI_CHANNEL, 1000000);
    if (isOK == -1) {
        printf("SPI设置失败\n");
    }
    else {
        printf("SPI设置OK == %d\n",isOK);
    }
 
    OLED_Init();
    OLED_Clear();
    OLED_ShowString(0,0,(char*)"HELLO2",16,1);
    OLED_Refresh();//更新显示
 
    return 0;
}

这是oled.c主要修改的部分

extern void oled_write_one_byte(uint8_t dat,uint8_t mode);
extern void set_rst_level(uint8_t level);
extern void delay_ms(uint8_t ms);

void OLED_WR_Byte(uint8_t dat,uint8_t mode)
{
    oled_write_one_byte(dat,mode);
}

void OLED_RST_SET(uint8_t level)
{
    set_rst_level(level);
}

void LCD_DELAY_MS(uint8_t ms)
{
    delay_ms(ms);
}

//OLED的初始化
void OLED_Init(void)
{
    OLED_RST_SET(0); // 液晶复位
    LCD_DELAY_MS(20);
    OLED_RST_SET(1);
    LCD_DELAY_MS(20);
    ...
}

然后编译这段代码

cc -Wall -o main main.c oled.c -lwiringPi

-Wall 表示编译时显示所有警告,-lwiringPi 表示编译时动态加载 wiringPi 库

编译完成后调用生成的main文件

sudo ./main

想要停止这个程序,Ctrl+c即可。

bcm2835

主要说一下怎么初始化和发送数据,具体的实现,参考开源链接。

1、开始SPI操作

int bcm2835_i2c_begin(void);

2、设置高位在前还是低位在前

void bcm2835_spi_setBitOrder(uint8_t order);

3、设置工作模式

void bcm2835_spi_setDataMode(uint8_t mode);

4、设置分频系数

void bcm2835_spi_setClockDivider(uint16_t divider);

5、选择控制哪个CS

void bcm2835_spi_chipSelect(uint8_t cs);

6、选择激活时的CS电平,就是工作时候的CS电平

void bcm2835_spi_setChipSelectPolarity(uint8_t cs, uint8_t active);

7、结束SPI的操作

void bcm2835_spi_end(void);

注意,下面是一个实际例子,oled部分的处理和wiringPi一样这里就不写了。注意两种库的引脚编号不一样

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <bcm2835.h>
#include "oled.h"

#define LCD_DC  20     // 模式选择 1:写数据 0:写命令
#define LCD_DIN 10     // 串行数据线
#define LCD_CLK 11     // 串行时钟线
#define LCD_RST 21     // 复位信号  低电平有效
#define LCD_CE  8     // 芯片使能  低电平有效

void oled_write_one_byte(uint8_t dat,uint8_t mode)
{ 
    if (mode == OLED_DATA) { // 写数据
        bcm2835_gpio_write(LCD_DC,HIGH);
    }
    else { // 写命令
        bcm2835_gpio_write(LCD_DC,LOW);
    }
    bcm2835_spi_transfer(dat);
}

void set_rst_level(uint8_t level)
{
    if(level == 1)
    {
        bcm2835_gpio_write(LCD_RST,HIGH);
    }else
    {
        bcm2835_gpio_write(LCD_RST,LOW);
    }
}

void delay_ms(uint8_t ms)
{
    bcm2835_delay(ms);
}

int main(int argc, char **argv)
{
	if (!bcm2835_init())//所有外围io引脚初始化,之前已经分析过了
    {
        printf("bcm2835_init failed. Are you running as root??\n");
        return 1;
    }

    bcm2835_gpio_fsel(LCD_DC, BCM2835_GPIO_FSEL_OUTP); //设置为输出模式
    bcm2835_gpio_fsel(LCD_RST,BCM2835_GPIO_FSEL_OUTP); //设置为输出模式

    if (!bcm2835_spi_begin())    {
        printf("bcm2835_spi_begin failed. Are you running as root??\n");
        return 1;
    }

    bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST);  
    bcm2835_spi_setDataMode(BCM2835_SPI_MODE0); 
    bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_32);  
    bcm2835_spi_chipSelect(BCM2835_SPI_CS0);
    bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW); 

    OLED_Init();
    OLED_Clear();
    OLED_ShowString(0,0,(char*)"HELLO3 world",16,1);
    OLED_Refresh();//更新显示
    
     
    bcm2835_spi_end();  
    bcm2835_close();
 
    return 0;
}

然后编译这段代码

gcc -Wall main.c oled.c -o main -lbcm2835

-Wall 表示编译时显示所有警告,-lbcm2835 表示编译时动态加载bcm2835 库

编译完成后调用生成的main文件

sudo ./main

想要停止这个程序,Ctrl+c即可。

RPi.GPIO

python控制iic的话,是有专门的别人写好的库。有两个库可以选择luma和Adafruit,但是我们下面的使用只使用luma。

pip install luma.oled

我们使用python安装的时候,应该会报错error: externally-managed-environment,网上有几种方法解决,可以参考这篇博文,我使用的是他说的创建venv的方式。

python -m venv ~/myenv        #创建虚拟环境,myenv就是环境名
source ~/myenv/bin/activate   #使能我们创建的虚拟环境
pip install luma.oled         #再次Pip安装

其他env操作

deactivate #退出环境

直接给代码了,python应该比较好理解

from luma.core.interface.serial import i2c, spi
from luma.core.render import canvas
from luma.oled.device import ssd1306

# 创建 SPI 设备,使用 SPI-0
serial = spi(device=0, port=0, gpio_RST=21, gpio_DC=20)

# 创建屏幕的驱动实例
device = ssd1306(serial)

# 开始往屏幕上绘图。draw 是 Pillow 的实例,它里面还有非常多的绘图 API。
with canvas(device) as draw:
  draw.rectangle(device.bounding_box, outline="white", fill="black")
  draw.text((30, 40), "Hello World!", fill="white")

# 这行是为了阻止程序退出,因为退出的时候会调用析构函数,清空屏幕。防止一闪而过,什么也看不到。
while (True):
  pass

更多资料可查看https://github.com/rm-hull/luma.examples

  • 7
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: 树莓派Pico是树莓派推出的一款微型电脑,Pico中文版是针对中国市场推出的版本。Pico-Python-SDK是树莓派官方提供的软件开发工具包,用于编写和运行Python程序。Pico-Python-SDK中文版是根据中国用户的需求进行本土化开发的版本。 树莓派Pico是一款体积小巧但功能强大的微型电脑,搭载了ARM Cortex-M0+处理器和26个GPIO口,可用于连接各种传感器、执行各种控制任务。同时,Pico支持MicroPython和C/C++两种编程语言,非常适合初学者和嵌入式系统开发人员。 Pico-Python-SDK中文版是官方提供的软件开发工具包,它提供了一系列的API和库函数,可以帮助开发者更方便地编写和调试Python程序。无论是控制外部硬件设备还是实现各种功能,Pico-Python-SDK都提供了丰富的功能和示例代码,使开发工作更加便捷。 Pico-Python-SDK中文版还提供了中文文档和教程,有助于开发者更快速地上手。通过学习这些文档和教程,开发者可以了解Pico的基本原理、功能特性以及编程方法,从而高效地开发出各种应用。 总的来说,树莓派Pico-Python-SDK中文版为中国用户提供了一个方便、易用的软件开发平台,帮助开发者快速上手并实现各种创意和项目。无论是学习编程还是进行嵌入式系统开发,Pico-Python-SDK中文版都是一个不错的选择。 ### 回答2: 树莓派pico-python-sdk-中文版是为了方便中国开发者使用而推出的一款软件开发工具包。它是基于树莓派pico微控制器设计的,通过使用Python语言进行开发。该SDK提供了丰富的功能和接口,使得使用者能够轻松地进行树莓派pico的开发工作。 树莓派pico-python-sdk-中文版包含了各种模块和库,如GPIO库、PWM库、I2C库、SPI库等,这些库可以帮助开发者通过编写Python代码来操控各种外设和传感器。例如,使用GPIO库可以控制LED灯的开关,使用PWM库可以控制舵机的转动,使用I2C库可以与其他设备进行通信,使用SPI库可以实现高速数据传输等等。 此外,树莓派pico-python-sdk-中文版还提供了丰富的示例代码和文档,帮助开发者快速上手。开发者可以参考这些示例代码和文档,了解如何使用SDK中的功能和接口,从而加速自己的开发进程。 总之,树莓派pico-python-sdk-中文版是一款功能强大、易于学习和使用的软件开发工具包。它不仅方便中国开发者使用树莓派pico进行开发工作,还提供了丰富的功能和接口,使得开发者能够更加便捷地实现各种应用和项目。无论是初学者还是有经验的开发者,都可以通过使用这个SDK来实现自己的创意和想法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

少年、潜行

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值