• 正文
  • 相关推荐
申请入驻 产业图谱

ZYNQ emio OLED显示屏的驱动

08/31 10:25
1282
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

1、OLED 简介

OLED,即有机发光二极管( Organic Light Emitting Diode)。 OLED 由于同时具备自发光,不需背光源、对比度高、厚度薄、视角广、反应速度快、可用于挠曲性面板、使用温度范围广、构造及制程较简单等优异之特性,被认为是下一代的平面显示器新兴应用技术。

LCD 都需要背光,而 OLED 不需要,因为它是自发光的。这样同样的显示 OLED 效果要来得好一些。以目前的技术,OLED 的尺寸还难以大型化,但是分辨率确可以做到很高。在此我们使用的是中景园电子的 0.96 寸 OLED 显示屏,该屏有以下特点:

1)0.96 寸 OLED 有黄蓝,白,蓝三种颜色可选;其中黄蓝是屏上 1/4 部分为黄光,下 3/4 为蓝;而且是固定区域显示固定颜色,颜色和显示区域均不能修改;白光则为纯白,也就是黑底白字:蓝色则为纯蓝,也就是黑底蓝字。

2)分辨率为 128*64

3)多种接口方式;OLED 裸屏总共种接口包括:6800、8080 两种并行接口方式、3线或 4 线的串行 SPI 接口方式、 l℃ 接口方式(只需要 2 根线就可以控制 OLED 了!),这五种接口是通过屏上的 BSO~BS2 来配置的。

2、0.96 寸 OLED模块

2.1 SPI/IIC 接口模块

模块接口定义:

1.GND 电源
2.VCC 电源正(3~5.5V)
3.D0 OLED 的 D0 脚,在 SPI 和 IIC 通信中为时钟管脚
4.D1 OLED 的 D1 脚,在 SPI 和 IIC 通信中为数据管脚
5.RES OLED 的 RES#脚,用来复位(低电平复位)
6.DC OLED 的 D/C#E 脚,数据和命令控制管脚
7. CS OLED 的CS#脚,也就是片选管脚

2.2 SPI模式

在 4 线 SPI 模式下,每个数据长度均为 8 位,在 SCLK 的上升沿,数据从 SDIN 移入到SSD1306,并且是高位在前的。 DC 线还是用作命令/数据的标志线。在 4 线 SPI 模式下,写操

作的时序如图

3、OLED显存

SD1306 的显存总共为 12864bit 大小, SSD1306 将这些显存分为了 8 页, 不使用显存对应的行列的重映射, 其对应关系如表

可以看出, SSD1306 的每页包含了 128 个字节,总共 8 页,这样刚好是 12864 的点阵大小。 当 GRAM 的写入模式为页模式时,需要设置低字节起始的列地址(0x00~0x0F) 和高字节的起始列地址(0x10~0x1F),芯片手册中给出了写入 GRAM 与显示的对应关系,写入列地址在写完一字节后自动按列增长, 如图

常用的命令:

第 0 个命令为 0X81,用于设置对比度的,这个命令包含了两个字节,第一个 0X81 为命令,随后发送的一个字节为要设置的对比度的值。这个值设置得越大屏幕就越亮。

第 1 个命令为 0XAE/0XAF。 0XAE 为关闭显示命令; 0XAF 为开启显示命令。

第 2 个命令为 0X8D,该指令也包含 2 个字节,第一个为命令字,第二个为设置值,第二个字节的 BIT2 表示电荷泵开关状态,该位为 1,则开启电荷泵,为 0 则关闭。在模块初始化的时候,这个必须要开启,否则是看不到屏幕显示的。

第 3 个命令为 0XB0~B7,该命令用于设置页地址,其低三位的值对应着 GRAM 的页地址。

第 4 个指令为 0X00~0X0F,该指令用于设置显示时的起始列地址低四位。

第 6 个指令为 0X10~0X1F,该指令用于设置显示时的起始列地址高四位。

4、硬件环境搭建

zynq配置gpio

引脚约束:

set_property?-dict{?PACKAGE_PIN Y16 ? ?IOSTANDARD LVCMOS33?}[get_ports?{?GPIO_OLED_tri_io[0]}];#CS
set_property?-dict{?PACKAGE_PIN Y14 ? ?IOSTANDARD LVCMOS33?}[get_ports?{?GPIO_OLED_tri_io[1]}];#DC
set_property?-dict{?PACKAGE_PIN U12 ? ?IOSTANDARD LVCMOS33?}[get_ports?{?GPIO_OLED_tri_io[2]}];#RES
set_property?-dict{?PACKAGE_PIN W13 ? ?IOSTANDARD LVCMOS33?}[get_ports?{?GPIO_OLED_tri_io[3]}];#D1 SCK
set_property?-dict{?PACKAGE_PIN R17 ? ?IOSTANDARD LVCMOS33?}[get_ports?{?GPIO_OLED_tri_io[4]}];#D2 SDIN
set_property?-dict{?PACKAGE_PIN V20 ? ?IOSTANDARD LVCMOS33?}[get_ports?{?GPIO_OLED_tri_io[5]}];#LED?

5、软件设计代码

oled.c

#include"myoled.h"
#include"oledfont.h"

/*
?* OLED的显存
?* 每个字节表示8个像素, 128,表示有128列, 8表示有64行, 高位表示高行数.
?* 比如:g_oled_gram[0][0],包含了第一列,第1~8行的数据. g_oled_gram[0][0].0,即表示坐标(0,0)
?* 类似的: g_oled_gram[1][0].1,表示坐标(1,1), g_oled_gram[10][1].2,表示坐标(10,10),
?*
?* 存放格式如下(高位表示高行数).
?* [0]0 1 2 3 ... 127
?* [1]0 1 2 3 ... 127
?* [2]0 1 2 3 ... 127
?* [3]0 1 2 3 ... 127
?* [4]0 1 2 3 ... 127
?* [5]0 1 2 3 ... 127
?* [6]0 1 2 3 ... 127
?* [7]0 1 2 3 ... 127
?*/
staticuint8_t?g_oled_gram[128][8];


intemio_init(){


	 ? XGpioPs_Config?*gpiops_cfg_ptr;//PS端 GPIO 配置信息

//根据器件ID查找配置信息
	 ? ?gpiops_cfg_ptr?=XGpioPs_LookupConfig(GPIOPS_ID);
//初始化器件驱动
XGpioPs_CfgInitialize(&gpiops_inst,?gpiops_cfg_ptr,?gpiops_cfg_ptr->BaseAddr);

//设置LED为输出
XGpioPs_SetDirectionPin(&gpiops_inst,?EMIO_CS,1);
XGpioPs_SetDirectionPin(&gpiops_inst,?EMIO_DC,1);
XGpioPs_SetDirectionPin(&gpiops_inst,?EMIO_RES,1);
XGpioPs_SetDirectionPin(&gpiops_inst,?EMIO_D1,1);
XGpioPs_SetDirectionPin(&gpiops_inst,?EMIO_D2,1);
XGpioPs_SetDirectionPin(&gpiops_inst,?EMIO_LED,1);
//使能LED输出
XGpioPs_SetOutputEnablePin(&gpiops_inst,?EMIO_CS,1);
XGpioPs_SetOutputEnablePin(&gpiops_inst,?EMIO_DC,1);
XGpioPs_SetOutputEnablePin(&gpiops_inst,?EMIO_RES,1);
XGpioPs_SetOutputEnablePin(&gpiops_inst,?EMIO_D1,1);
XGpioPs_SetOutputEnablePin(&gpiops_inst,?EMIO_D2,1);
XGpioPs_SetOutputEnablePin(&gpiops_inst,?EMIO_LED,1);

OLED_SDIN(1);
OLED_SCLK(1);
OLED_CS(1);
OLED_RS(1);

OLED_RST(0);
usleep(100000);
OLED_RST(1);

oled_wr_byte(0xAE,?OLED_CMD);/* 关闭显示 */
oled_wr_byte(0xD5,?OLED_CMD);/* 设置时钟分频因子,震荡频率 */
oled_wr_byte(80,?OLED_CMD);/* [3:0],分频因子;[7:4],震荡频率 */
oled_wr_byte(0xA8,?OLED_CMD);/* 设置驱动路数 */
oled_wr_byte(0X3F,?OLED_CMD);/* 默认0X3F(1/64) */
oled_wr_byte(0xD3,?OLED_CMD);/* 设置显示偏移 */
oled_wr_byte(0X00,?OLED_CMD);/* 默认为0 */

oled_wr_byte(0x40,?OLED_CMD);/* 设置显示开始行 [5:0],行数. */

oled_wr_byte(0x8D,?OLED_CMD);/* 电荷泵设置 */
oled_wr_byte(0x14,?OLED_CMD);/* bit2,开启/关闭 */
oled_wr_byte(0x20,?OLED_CMD);/* 设置内存地址模式 */
oled_wr_byte(0x02,?OLED_CMD);/* [1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10; */
oled_wr_byte(0xA1,?OLED_CMD);/* 段重定义设置,bit0:0,0->0;1,0->127; */
oled_wr_byte(0xC8,?OLED_CMD);/* 设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数 */
oled_wr_byte(0xDA,?OLED_CMD);/* 设置COM硬件引脚配置 */
oled_wr_byte(0x12,?OLED_CMD);/* [5:4]配置 */

oled_wr_byte(0x81,?OLED_CMD);/* 对比度设置 */
oled_wr_byte(0xEF,?OLED_CMD);/* 1~255;默认0X7F (亮度设置,越大越亮) */
oled_wr_byte(0xD9,?OLED_CMD);/* 设置预充电周期 */
oled_wr_byte(0xf1,?OLED_CMD);/* [3:0],PHASE 1;[7:4],PHASE 2; */
oled_wr_byte(0xDB,?OLED_CMD);/* 设置VCOMH 电压倍率 */
oled_wr_byte(0x30,?OLED_CMD);/* [6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc; */

oled_wr_byte(0xA4,?OLED_CMD);/* 全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏) */
oled_wr_byte(0xA6,?OLED_CMD);/* 设置显示方式;bit0:1,反相显示;0,正常显示 */
oled_wr_byte(0xAF,?OLED_CMD);/* 开启显示 */
oled_clear();

return?XST_SUCCESS;

}


/**
?* @brief ? ? ? 更新显存到OLED
?* @param ? ? ? 无
?* @retval ? ? ?无
?*/
voidoled_refresh_gram(void)
{
uint8_t?i,?n;

for(i?=0;?i?<8;?i++)
{
oled_wr_byte(0xb0+?i,?OLED_CMD);/* 设置页地址(0~7) */
oled_wr_byte(0x00,?OLED_CMD);/* 设置显示位置—列低地址 */
oled_wr_byte(0x10,?OLED_CMD);/* 设置显示位置—列高地址 */

for(n?=0;?n?<128;?n++)
{
oled_wr_byte(g_oled_gram[n][i],?OLED_DATA);
}
}
}

#ifOLED_MODE?==1/* 使用8080并口驱动OLED */

/**
?* @brief ? ? ? 通过拼凑的方法向OLED输出一个8位数据
?* @param ? ? ? data: 要输出的数据
?* @retval ? ? ?无
?*/
staticvoidoled_data_out(uint8_t?data)
{
uint16_t?dat?=?data?&0X0F;
? ? GPIOC->ODR?&=~(0XF<<6);/* 清空6~9 */
? ? GPIOC->ODR?|=?dat?<<6;/* D[3:0]-->PC[9:6] */

? ? GPIOC->ODR?&=~(0X1<<11);/* 清空11 */
? ? GPIOC->ODR?|=((data?>>4)&0x01)<<11;/* D4 */

? ? GPIOD->ODR?&=~(0X1<<3);/* 清空3 */
? ? GPIOD->ODR?|=((data?>>5)&0x01)<<3;/* D5 */

? ? GPIOB->ODR?&=~(0X3<<8);/* 清空8,9 */
? ? GPIOB->ODR?|=((data?>>6)&0x01)<<8;/* D6 */
? ? GPIOB->ODR?|=((data?>>7)&0x01)<<9;/* D7 */
}

/**
?* @brief ? ? ? 向OLED写入一个字节
?* @param ? ? ? data: 要输出的数据
?* @param ? ? ? cmd: 数据/命令标志 0,表示命令;1,表示数据;
?* @retval ? ? ?无
?*/
staticvoidoled_wr_byte(uint8_t?data,uint8_t?cmd)
{
oled_data_out(data);
OLED_RS(cmd);
OLED_CS(0);
OLED_WR(0);
OLED_WR(1);
OLED_CS(1);
OLED_RS(1);
}

#else/* 使用SPI驱动OLED */

/**
?* @brief ? ? ? 向OLED写入一个字节
?* @param ? ? ? data: 要输出的数据
?* @param ? ? ? cmd: 数据/命令标志 0,表示命令;1,表示数据;
?* @retval ? ? ?无
?*/
staticvoidoled_wr_byte(uint8_t?data,uint8_t?cmd)
{
uint8_t?i;
OLED_RS(cmd);/* 写命令 */
OLED_CS(0);

for(i?=0;?i?<8;?i++)
{
OLED_SCLK(0);

if(data?&0x80)
{
OLED_SDIN(1);
}
else
{
OLED_SDIN(0);
}
OLED_SCLK(1);
? ? ? ? data?<<=1;
}

OLED_CS(1);
OLED_RS(1);
}

#endif

/**
?* @brief ? ? ? 开启OLED显示
?* @param ? ? ? 无
?* @retval ? ? ?无
?*/
voidoled_display_on(void)
{
oled_wr_byte(0X8D,?OLED_CMD);/* SET DCDC命令 */
oled_wr_byte(0X14,?OLED_CMD);/* DCDC ON */
oled_wr_byte(0XAF,?OLED_CMD);/* DISPLAY ON */
}

/**
?* @brief ? ? ? 关闭OLED显示
?* @param ? ? ? 无
?* @retval ? ? ?无
?*/
voidoled_display_off(void)
{
oled_wr_byte(0X8D,?OLED_CMD);/* SET DCDC命令 */
oled_wr_byte(0X10,?OLED_CMD);/* DCDC OFF */
oled_wr_byte(0XAE,?OLED_CMD);/* DISPLAY OFF */
}

/**
?* @brief ? ? ? 清屏函数,清完屏,整个屏幕是黑色的!和没点亮一样!!!
?* @param ? ? ? 无
?* @retval ? ? ?无
?*/
voidoled_clear(void)
{
uint8_t?i,?n;

for(i?=0;?i?<8;?i++)for(n?=0;?n?<128;?n++)g_oled_gram[n][i]=0X00;

oled_refresh_gram();/* 更新显示 */
}

/**
?* @brief ? ? ? OLED画点
?* @param ? ? ? x ?: 0~127
?* @param ? ? ? y ?: 0~63
?* @param ? ? ? dot: 1 填充 0,清空
?* @retval ? ? ?无
?*/
voidoled_draw_point(uint8_t?x,uint8_t?y,uint8_t?dot)
{
uint8_t?pos,?bx,?temp?=0;

if(x?>127||?y?>63)return;/* 超出范围了 */

? ? pos?=?y?/8;/* 计算GRAM里面的y坐标所在的字节, 每个字节可以存储8个行坐标 */

? ? bx?=?y?%8;/* 取余数,方便计算y在对应字节里面的位置,及行(y)位置 */
? ? temp?=1<<?bx;/* 高位表示高行号, 得到y对应的bit位置,将该bit先置1 */

if(dot)/* 画实心点 */
{
? ? ? ? g_oled_gram[x][pos]|=?temp;
}
else/* 画空点,即不显示 */
{
? ? ? ? g_oled_gram[x][pos]&=~temp;
}
}

/**
?* @brief ? ? ? OLED填充区域填充
?* ? @note: ? ? 注意:需要确保: x1<=x2; y1<=y2 ?0<=x1<=127 ?0<=y1<=63
?* @param ? ? ? x1,y1: 起点坐标
?* @param ? ? ? x2,y2: 终点坐标
?* @param ? ? ? dot: 1 填充 0,清空
?* @retval ? ? ?无
?*/
voidoled_fill(uint8_t?x1,uint8_t?y1,uint8_t?x2,uint8_t?y2,uint8_t?dot)
{
uint8_t?x,?y;

for(x?=?x1;?x?<=?x2;?x++)
{
for(y?=?y1;?y?<=?y2;?y++)oled_draw_point(x,?y,?dot);
}

oled_refresh_gram();/* 更新显示 */
}

/**
?* @brief ? ? ? 在指定位置显示一个字符,包括部分字符
?* @param ? ? ? x ? : 0~127
?* @param ? ? ? y ? : 0~63
?* @param ? ? ? size: 选择字体 12/16/24
?* @param ? ? ? mode: 0,反白显示;1,正常显示
?* @retval ? ? ?无
?*/
voidoled_show_char(uint8_t?x,uint8_t?y,uint8_t?chr,uint8_t?size,uint8_t?mode)
{
uint8_t?temp,?t,?t1;
uint8_t?y0?=?y;
uint8_t*pfont?=0;
uint8_t?csize?=(size?/8+((size?%8)?1:0))*(size?/2);/* 得到字体一个字符对应点阵集所占的字节数 */
? ? chr?=?chr?-' ';/* 得到偏移后的值,因为字库是从空格开始存储的,第一个字符是空格 */

if(size?==12)/* 调用1206字体 */
{
? ? ? ? pfont?=(uint8_t*)oled_asc2_1206[chr];
}
elseif(size?==16)/* 调用1608字体 */
{
? ? ? ? pfont?=(uint8_t*)oled_asc2_1608[chr];
}
elseif(size?==24)/* 调用2412字体 */
{
? ? ? ? pfont?=(uint8_t*)oled_asc2_2412[chr];
}
else/* 没有的字库 */
{
return;
}

for(t?=0;?t?<?csize;?t++)
{
? ? ? ? temp?=?pfont[t];
for(t1?=0;?t1?<8;?t1++)
{
if(temp?&0x80)oled_draw_point(x,?y,?mode);
elseoled_draw_point(x,?y,!mode);

? ? ? ? ? ? temp?<<=1;
? ? ? ? ? ? y++;

if((y?-?y0)==?size)
{
? ? ? ? ? ? ? ? y?=?y0;
? ? ? ? ? ? ? ? x++;
break;
}
}
}
}

/**
?* @brief ? ? ? 平方函数, m^n
?* @param ? ? ? m: 底数
?* @param ? ? ? n: 指数
?* @retval ? ? ?无
?*/
staticuint32_toled_pow(uint8_t?m,uint8_t?n)
{
uint32_t?result?=1;

while(n--)
{
? ? ? ? result?*=?m;
}

return?result;
}

/**
?* @brief ? ? ? 显示len个数字
?* @param ? ? ? x,y : 起始坐标
?* @param ? ? ? num : 数值(0 ~ 2^32)
?* @param ? ? ? len : 显示数字的位数
?* @param ? ? ? size: 选择字体 12/16/24
?* @retval ? ? ?无
?*/
voidoled_show_num(uint8_t?x,uint8_t?y,uint32_t?num,uint8_t?len,uint8_t?size)
{
uint8_t?t,?temp;
uint8_t?enshow?=0;

for(t?=0;?t?<?len;?t++)/* 按总显示位数循环 */
{
? ? ? ? temp?=(num?/oled_pow(10,?len?-?t?-1))%10;/* 获取对应位的数字 */

if(enshow?==0&&?t?<(len?-1))/* 没有使能显示,且还有位要显示 */
{
if(temp?==0)
{
oled_show_char(x?+(size?/2)*t,?y,' ',?size,1);/* 显示空格,站位 */
continue;/* 继续下个一位 */
}
else
{
? ? ? ? ? ? ? ? enshow?=1;/* 使能显示 */
}
}

oled_show_char(x?+(size?/2)*t,?y,?temp?+'0',?size,1);/* 显示字符 */
}
}

/**
?* @brief ? ? ? 显示字符串
?* @param ? ? ? x,y : 起始坐标
?* @param ? ? ? size: 选择字体 12/16/24
?* @param ? ? ? *p ?: 字符串指针,指向字符串首地址
?* @retval ? ? ?无
?*/
voidoled_show_string(uint8_t?x,uint8_t?y,constchar*p,uint8_t?size)
{
while((*p?<='~')&&(*p?>=' '))/* 判断是不是非法字符! */
{
if(x?>(128-(size?/2)))/* 宽度越界 */
{
? ? ? ? ? ? x?=0;
? ? ? ? ? ? y?+=?size;/* 换行 */
}

if(y?>(64-?size))/* 高度越界 */
{
? ? ? ? ? ? y?=?x?=0;
oled_clear();
}

oled_show_char(x,?y,*p,?size,1);/* 显示一个字符 */
? ? ? ? x?+=?size?/2;/* ASCII字符宽度为汉字宽度的一半 */
? ? ? ? p++;
}
}

oled.h

#ifndef__OLED_H
#define__OLED_H

#include"xparameters.h"
#include"xgpiops.h"
#include"sleep.h"

/* OLED模式设置
?* 0: 4线串行模式 ?(模块的BS1,BS2均接GND)
?* 1: 并行8080模式 (模块的BS1,BS2均接VCC)
?*/
#defineOLED_MODE0/* 默认使用SPI模式 */

#defineGPIOPS_IDXPAR_XGPIOPS_0_DEVICE_ID ??//PS端 ?GPIO器件 ID
//SPI --EMIO
#defineEMIO_CS54// 连接到EMIO0
#defineEMIO_DC55//连接到EMIO1
#defineEMIO_RES56//连接到EMIO2
#defineEMIO_D157//连接到EMIO3
#defineEMIO_D258//连接到EMIO4
#defineEMIO_LED59//连接到EMIO5

XGpioPs gpiops_inst;//PS端 GPIO 驱动实例


//#define OLED_CS(x) XGpioPs_WritePin(&gpiops_inst, EMIO_CS,x);
#defineLED(x)do{?x??
XGpioPs_WritePin(&gpiops_inst,?EMIO_LED,1):
XGpioPs_WritePin(&gpiops_inst,?EMIO_LED,0);
}while(0)/* 设置LED引脚 */

#defineOLED_RST(x)do{?x??
XGpioPs_WritePin(&gpiops_inst,?EMIO_RES,1):
XGpioPs_WritePin(&gpiops_inst,?EMIO_RES,0);
}while(0)/* 设置EMIO_RES引脚 */

#defineOLED_CS(x)do{?x??
XGpioPs_WritePin(&gpiops_inst,?EMIO_CS,1):
XGpioPs_WritePin(&gpiops_inst,?EMIO_CS,0);
}while(0)/* 设置EMIO_CS引脚 */

#defineOLED_RS(x)do{?x??
XGpioPs_WritePin(&gpiops_inst,?EMIO_DC,1):
XGpioPs_WritePin(&gpiops_inst,?EMIO_DC,0);
}while(0)/* 设置EMIO_DC引脚 */

#defineOLED_SDIN(x)do{?x??
XGpioPs_WritePin(&gpiops_inst,?EMIO_D1,1):
XGpioPs_WritePin(&gpiops_inst,?EMIO_D1,0);
}while(0)/* 设置EMIO_D1引脚 */

#defineOLED_SCLK(x)do{?x??
XGpioPs_WritePin(&gpiops_inst,?EMIO_D2,1):
XGpioPs_WritePin(&gpiops_inst,?EMIO_D2,0);
}while(0)/* 设置EMIO_D1引脚 */

/* 命令/数据 定义 */
#defineOLED_CMD0/* 写命令 */
#defineOLED_DATA1/* 写数据 */

intemio_init();

staticvoidoled_wr_byte(uint8_t?data,uint8_t?cmd);/* 写一个字节到OLED */
staticuint32_toled_pow(uint8_t?m,uint8_t?n);/* OLED求平方函数 */

voidoled_clear(void);/* OLED清屏 */
voidoled_display_on(void);/* 开启OLED显示 */
voidoled_display_off(void);/* 关闭OLED显示 */
voidoled_refresh_gram(void);/* 更新显存到OLED */
voidoled_draw_point(uint8_t?x,uint8_t?y,uint8_t?dot);/* OLED画点 */
voidoled_fill(uint8_t?x1,uint8_t?y1,uint8_t?x2,uint8_t?y2,uint8_t?dot);/* OLED区域填充 */
voidoled_show_char(uint8_t?x,uint8_t?y,uint8_t?chr,uint8_t?size,uint8_t?mode);/* OLED显示字符 */
voidoled_show_num(uint8_t?x,uint8_t?y,uint32_t?num,uint8_t?len,uint8_t?size);/* OLED显示数字 */
voidoled_show_string(uint8_t?x,uint8_t?y,constchar*p,uint8_t?size);/* OLED显示字符串 */


#endif

main.c

#include<stdio.h>
#include"xil_printf.h"
#include"myoled.h"

intmain()
{
uint8_t?t?=0;
emio_init();
print("OLED TESnr");
oled_show_string(0,0,"LEEE FPGA",24);
oled_show_string(0,24,"0.96' OLED TEST",16);
oled_show_string(0,40,"ATOM 2025/7/22",12);
oled_show_string(0,52,"ASCII:",12);
oled_show_string(64,52,"CODE:",12);
oled_refresh_gram();/* 更新显示到OLED */

while(1){
? ? ? ? t?=' ';
while(1)
{
oled_show_char(36,52,?t,12,1);/* 显示ASCII字符 */
oled_show_num(94,52,?t,3,12);/* 显示ASCII字符的码值 */
oled_refresh_gram();/* 更新显示到OLED */
? ? ? ? ? ? t++;

if(t?>'~')t?=' ';
LED(1);/* LED0闪烁 */
sleep(1);
LED(0);/* LED0闪烁 */
}
}

return0;
}

6、下板效果


源码链接:

链接: https://pan.baidu.com/s/1w3Q-b5KW1A0ezbf5cUC9Zg?pwd=14ck 提取码: 14ck

相关推荐

登录即可解锁
  • 海量技术文章
  • 设计资源下载
  • 产业链客户资源
  • 写文章/发需求
立即登录
lee
lee

从数字出发,走进图像世界,聆听音频的美妙旋律。从电路出发,实现美妙的算法,展示代码的美奂。从知识到实现,欢迎大家关注公众号FPGA开源工作室。