由于BPI-CanMV-K230D-Zero开发板并未配置相应的显示器件,为此需要自行为其配置显示器件。
为了与开发板的小巧身材相匹配,便选取了一款I2C接口的0.96寸单色OLED屏。
要驱动显示屏,通常有2种方式,一种是采用模拟的方式来驱动,另一种则通过硬件的方式来驱动。
鉴于厂家在例程方面提供了一个I2C应用的基本驱动框架,就利用该驱动框架来实现其显示功能。
例程所提供的驱动程序框架为:
from machine import FPIOA, I2C
if HARD_I2C:
fpioa = FPIOA()
fpioa.set_function(11, FPIOA.IIC2_SCL)
fpioa.set_function(12, FPIOA.IIC2_SDA)
i2c=I2C(2, freq = 400 * 1000)
print(i2c.scan())
else:
i2c=I2C(5, scl = 11, sda = 12, freq = 400 * 1000)
print(i2c.scan())
OLED_I2C_ADDR = 0x3C
def send_command(command):
i2c.writeto(OLED_I2C_ADDR, bytearray([0x00, command]))
def send_data(data):
i2c.writeto(OLED_I2C_ADDR, bytearray([0x40] + data))
def send_data1(data):
i2c.writeto(OLED_I2C_ADDR, bytearray([0x40, data]))
def oled_init():
send_command(0xAE) # Display OFF
send_command(0xA8) # Set MUX Ratio
send_command(0x3F) # 64MUX
send_command(0xD3) # Set display offset
send_command(0x00) # Offset = 0
send_command(0x40) # Set display start line to 0
send_command(0xA1) # Set segment re-map (A1 for reverse, A0 for normal)
send_command(0xC8) # Set COM output scan direction (C8 for reverse, C0 for normal)
send_command(0xDA) # Set COM pins hardware configuration
send_command(0x12) # Alternative COM pin config, disable left/right remap
send_command(0x81) # Set contrast control
send_command(0x7F) # Max contrast
send_command(0xA4) # Entire display ON, resume to RAM content display
send_command(0xA6) # Set Normal display (A6 for normal, A7 for inverse)
send_command(0xD5) # Set oscillator frequency
send_command(0x80) # Frequency
send_command(0x8D) # Enable charge pump regulator
send_command(0x14) # Enable charge pump
send_command(0xAF) # Display ON
def oled_clear():
for page in range(0, 8): # 8 pages in 64px tall screen
send_command(0xB0 + page) # Set page start address (0xB0 to 0xB7)
send_command(0x00) # Set low column address
send_command(0x10) # Set high column address
send_data([0x00] * 128)
由程序可以得知,显示屏的引脚连接关系为:
SCL-------GPIO11
SDA------GPIO12
经程序运行,其测试效果如图1所示,说明它对显示屏的驱动有效。

图1 驱动测试
为在此基础上实现数据的显示功能,需为其配置字库及相应的显示函数。
其中字库的存储结构为:
F8X16=[
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,#0
0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,#! 1
0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,#" 2
... ...
}
由于这里采用的编程语言是Python,因此在程序设计时是会与C语言存在一定差别的,有些功能的实现甚至需要绕行来解决。
为进行显示位置的定位,所配置的函数为:
def OLED_Set_Pos(x, y):
send_command(0xb0+y)
send_command(((x&0xf0)>>4)|0x10)
send_command(x&0x0f)
依托于该函数的支持,实现数字符号显示的函数为:
def OLED_ShowCharm(x,y,chr):
c=chr
OLED_Set_Pos(x,y)
i=0
for i in range(8):
u=F8X16[c*16+i]
send_data([u]*1)
OLED_Set_Pos(x,y+1)
i=0
for i in range(8):
u=F8X16[c*16+i+8]
send_data([u]*1)
为在数据显示过程中,为能逐位的提取数值,所配置的函数为:
def oled_pow( m,n):
result=1
while (n>0) :
n=n-1
result*=m
return result
依托前面2个函数的支持,实现数值显示的函数为:
def OLED_ShowNum(x,y,num,len):
enshow=0
for t in range(len):
temp=(num/oled_pow(10,len-t-1))%10
if (enshow==0 & t<(len-1)):
if(temp>0):
enshow=1
OLED_ShowCharm(x+8*t,y,int(temp)+16)
至此,就可以在OLED屏上来实现数据信息了。
为使用RTC来实现电子时钟功能,需导入RTC和time,并对RTC进行实例化,其对应的程序为:
import time
from machine import RTC
rtc = RTC()
print(rtc.datetime())
rtc.init((2025,6,28,2,23,59,0,0))
这样就有了实现电子时钟功能的基础,由于 RTC的计时值是以组元的方式来管理数据的,因此读取当前时间后,所显示内容的显示为:
(2025,6,28,2,23,59,0,0)
而这样的显示数据是无法直接拿来实现的,为此需要以如下的方式来提取时间值并予以显示:
z=rtc.datetime()
OLED_ShowNum(0,2,z[4],2)
OLED_ShowNum(24,2,z[5],2)
OLED_ShowNum(48,2,z[6],2)
至此,提供添加下面的循环处理就可为此电子时钟的计时功能:
oled_init()
oled_clear()
OLED_ShowChar(16, 2, 26)
OLED_ShowChar(40, 2, 26)
while 1:
z=rtc.datetime()
OLED_ShowNum(0,2,z[4],2)
OLED_ShowNum(24,2,z[5],2)
OLED_ShowNum(48,2,z[6],2)
time.sleep(1)
经程序的运行,其显示效果如图2和图3所示。

图2整体显示效果

图3 详细显示效果
此外,在os和machine的情况下,还可以对片内温度进行检测,实现电子时钟与片温显示的主程序为:
import os
import machine
oled_init()
oled_clear()
OLED_ShowChar(16, 2, 26)
OLED_ShowChar(40, 2, 26)
OLED_ShowChar(8, 4, 52)
OLED_ShowChar(16, 4, 29)
while True:
os.exitpoint()
z=rtc.datetime()
OLED_ShowNum(0,2,z[4],2)
OLED_ShowNum(24,2,z[5],2)
OLED_ShowNum(48,2,z[6],2)
temp = machine.temperature()
OLED_ShowNum(24,4,temp,2)
time.sleep_ms(500)
在执行后,其显示效果如图4所示。

图4 显示效果
为便于字符串的显示,所配置的显示函数为:
def OLED_ShowString(x,y,chr):
array1=bytearray(chr, 'utf-8')
for value in array1:
OLED_ShowChar(x,y,value-32)
x+=8
由于系统配置的Python,没有提供获取字符内码的函数,为此是借助bytearray的特点来解决了这个问题。
在添加字符串显示功能后,其程序主程序为:
oled_init()
oled_clear()
OLED_ShowChar(26, 3, 26)
OLED_ShowChar(50, 3, 26)
OLED_ShowChar(8, 5, 52)
OLED_ShowChar(16, 5, 29)
OLED_ShowString(5,0,"BPI-CanMV-K230D")
while True:
os.exitpoint()
z=rtc.datetime()
OLED_ShowNum(10,3,z[4],2)
OLED_ShowNum(34,3,z[5],2)
OLED_ShowNum(58,3,z[6],2)
temp = machine.temperature()
OLED_ShowNum(24,5,temp,2)
time.sleep_ms(500)
经测试,其显示效果图5和图6所示,说明设计符号预期要求。

图5 整体显示效果

图6 显示效果
演示视频:
[]()