ssd1606扫描方式 2021-12-10

ssd1306 之前使用的是页地址模式,今天改为 水平地址模式

页地址模式:只是列地址会自动增加,页地址不会自动增加,页地址需要手动增加;

行地址模式:列地址和页地址都会自动增加,横向扫描方式

列地址模式:列地址和页地址都会自动增加,是列扫描方式,

行扫描方式测试代码

oled.c

#include "oled.h"
#include "stdlib.h"
#include "oledfont.h"
//#include "delay.h"u8 OLED_GRAM[144][8];void delay(u32 t)
{while (t--);
}//反显函数
void OLED_ColorTurn(u8 i)
{if (i == 0){OLED_WR_Byte(0xA6, OLED_CMD); //正常显示}if (i == 1){OLED_WR_Byte(0xA7, OLED_CMD); //反色显示}
}//屏幕旋转180度
void OLED_DisplayTurn(u8 i)
{if (i == 0){OLED_WR_Byte(0xC8, OLED_CMD); //正常显示OLED_WR_Byte(0xA1, OLED_CMD);}if (i == 1){OLED_WR_Byte(0xC0, OLED_CMD); //反转显示OLED_WR_Byte(0xA0, OLED_CMD);}
}//起始信号
void I2C_Start(void)
{OLED_SDIN_Set();delay(1);OLED_SCLK_Set();delay(1);OLED_SDIN_Clr();delay(1);OLED_SCLK_Clr();delay(1);
}//结束信号
void I2C_Stop(void)
{OLED_SCLK_Clr();delay(1);OLED_SCLK_Set();delay(1);OLED_SDIN_Clr();delay(1);OLED_SDIN_Set();delay(1);
}//等待信号响应
void I2C_WaitAck(void) //测数据信号的电平
{OLED_SCLK_Set();delay(1);OLED_SCLK_Clr();delay(1);
}//IIC写入一个字节
void Send_Byte(u8 dat)
{u8 i;for (i = 0; i < 8; i++){//OLED_SCLK_Clr();//将时钟信号设置为低电平//delay(1);if (dat & 0x80) //将dat的8位从最高位依次写入{OLED_SDIN_Set();delay(1);}else{OLED_SDIN_Clr();delay(1);}OLED_SCLK_Set(); //将时钟信号设置为高电平delay(1);OLED_SCLK_Clr(); //将时钟信号设置为低电平  必须这里需要一个低电平,否则在最后的一个bit期间会出错delay(1);dat <<= 1;}
}//发送一个字节
//向SSD1306写入一个字节。
//mode:数据/命令标志 0,表示命令;1,表示数据;
void OLED_WR_Byte(u8 dat, u8 mode)
{I2C_Start();Send_Byte(0x78);I2C_WaitAck();if (mode){Send_Byte(0x40);}else{Send_Byte(0x00);}I2C_WaitAck();Send_Byte(dat);I2C_WaitAck();I2C_Stop();
}//开启OLED显示
void OLED_DisPlay_On(void)
{OLED_WR_Byte(0x8D, OLED_CMD); //电荷泵使能OLED_WR_Byte(0x14, OLED_CMD); //开启电荷泵OLED_WR_Byte(0xAF, OLED_CMD); //点亮屏幕
}//关闭OLED显示
void OLED_DisPlay_Off(void)
{OLED_WR_Byte(0x8D, OLED_CMD); //电荷泵使能OLED_WR_Byte(0x10, OLED_CMD); //关闭电荷泵OLED_WR_Byte(0xAF, OLED_CMD); //关闭屏幕
}/*循环调用更新显示屏
*/
//更新显存到OLED
void OLED_Refresh(void)
{u8 i, n;for (i = 0; i < 8; i++){//如果是页模式需要以下3句代码
//      OLED_WR_Byte(0xb0 + i, OLED_CMD); //设置行起始地址
//      OLED_WR_Byte(0x00, OLED_CMD);     //设置 低 列起始地址
//      OLED_WR_Byte(0x10, OLED_CMD);     //设置 高 列起始地址for (n = 0; n < 128; n++)OLED_WR_Byte(OLED_GRAM[n][i], OLED_DATA);}
}
//清屏函数
void OLED_Clear(void)
{u8 i, n;for (i = 0; i < 8; i++){for (n = 0; n < 128; n++){OLED_GRAM[n][i] = 0; //清除所有数据}}OLED_Refresh(); //更新显示
}//画点
//x:0~127
//y:0~63
void OLED_DrawPoint(u8 x, u8 y)
{u8 i, m, n;i = y / 8;m = y % 8;n = 1 << m;OLED_GRAM[x][i] |= n;
}//清除一个点
//x:0~127
//y:0~63
void OLED_ClearPoint(u8 x, u8 y)
{u8 i, m, n;i = y / 8;m = y % 8;n = 1 << m;OLED_GRAM[x][i] = ~OLED_GRAM[x][i];OLED_GRAM[x][i] |= n;OLED_GRAM[x][i] = ~OLED_GRAM[x][i];
}//画线
//x:0~128
//y:0~64
void OLED_DrawLine(u8 x1, u8 y1, u8 x2, u8 y2)
{u8 i, k, k1, k2, y0;if ((x1 < 0) || (x2 > 128) || (y1 < 0) || (y2 > 64) || (x1 > x2) || (y1 > y2))return;if (x1 == x2) //画竖线{for (i = 0; i < (y2 - y1); i++){OLED_DrawPoint(x1, y1 + i);}}else if (y1 == y2) //画横线{for (i = 0; i < (x2 - x1); i++){OLED_DrawPoint(x1 + i, y1);}}else //画斜线{k1 = y2 - y1;k2 = x2 - x1;k = k1 * 10 / k2;for (i = 0; i < (x2 - x1); i++){OLED_DrawPoint(x1 + i, y1 + i * k / 10);}}
}
//x,y:圆心坐标
//r:圆的半径
void OLED_DrawCircle(u8 x, u8 y, u8 r)
{int a, b, num;a = 0;b = r;while (2 * b * b >= r * r){OLED_DrawPoint(x + a, y - b);OLED_DrawPoint(x - a, y - b);OLED_DrawPoint(x - a, y + b);OLED_DrawPoint(x + a, y + b);OLED_DrawPoint(x + b, y + a);OLED_DrawPoint(x + b, y - a);OLED_DrawPoint(x - b, y - a);OLED_DrawPoint(x - b, y + a);a++;num = (a * a + b * b) - r * r; //计算画的点离圆心的距离if (num > 0){b--;a--;}}
}//在指定位置显示一个字符,包括部分字符
//x:0~127
//y:0~63
//size:选择字体 12/16/24
//取模方式 逐列式
void OLED_ShowChar(u8 x, u8 y, u8 chr, u8 size1)
{u8 i, m, temp, size2, chr1;u8 y0 = y;size2 = (size1 / 8 + ((size1 % 8) ? 1 : 0)) * (size1 / 2); //得到字体一个字符对应点阵集所占的字节数chr1 = chr - ' ';                                          //计算偏移后的值for (i = 0; i < size2; i++){if (size1 == 12){temp = asc2_1206[chr1][i];} //调用1206字体else if (size1 == 16){temp = asc2_1608[chr1][i];} //调用1608字体else if (size1 == 24){temp = asc2_2412[chr1][i];} //调用2412字体elsereturn;for (m = 0; m < 8; m++) //写入数据{if (temp & 0x80)OLED_DrawPoint(x, y);elseOLED_ClearPoint(x, y);temp <<= 1;y++;if ((y - y0) == size1){y = y0;x++;break;}}}
}//显示字符串
//x,y:起点坐标
//size1:字体大小
//*chr:字符串起始地址
void OLED_ShowString(u8 x, u8 y, u8 *chr, u8 size1)
{while ((*chr >= ' ') && (*chr <= '~')) //判断是不是非法字符!{OLED_ShowChar(x, y, *chr, size1);x += size1 / 2;if (x > 128 - size1) //换行{x = 0;y += 2;}chr++;}
}//m^n
u32 OLED_Pow(u8 m, u8 n)
{u32 result = 1;while (n--){result *= m;}return result;
}显示2个数字
x,y :起点坐标
len :数字的位数
size:字体大小
void OLED_ShowNum(u8 x, u8 y, u32 num, u8 len, u8 size1)
{u8 t, temp;for (t = 0; t < len; t++){temp = (num / OLED_Pow(10, len - t - 1)) % 10;if (temp == 0){OLED_ShowChar(x + (size1 / 2) * t, y, '0', size1);}else{OLED_ShowChar(x + (size1 / 2) * t, y, temp + '0', size1);}}
}//显示汉字
//x,y:起点坐标
//num:汉字对应的序号
//取模方式 列行式
void OLED_ShowChinese(u8 x, u8 y, u8 num, u8 size1)
{u8 i, m, n = 0, temp, chr1;u8 x0 = x, y0 = y;u8 size3 = size1 / 8;while (size3--){chr1 = num * size1 / 8 + n;n++;for (i = 0; i < size1; i++){if (size1 == 16){temp = Hzk1[chr1][i];} //调用16*16字体else if (size1 == 24){temp = Hzk2[chr1][i];} //调用24*24字体else if (size1 == 32){temp = Hzk3[chr1][i];} //调用32*32字体else if (size1 == 64){temp = Hzk4[chr1][i];} //调用64*64字体elsereturn;for (m = 0; m < 8; m++){if (temp & 0x01)OLED_DrawPoint(x, y);elseOLED_ClearPoint(x, y);temp >>= 1;y++;}x++;if ((x - x0) == size1){x = x0;y0 = y0 + 8;}y = y0;}}
}//num 显示汉字的个数
//space 每一遍显示的间隔
void OLED_ScrollDisplay(u8 num, u8 space)
{u8 i, n, t = 0, m = 0, r;while (1){if (m == 0){OLED_ShowChinese(128, 24, t, 16); //写入一个汉字保存在OLED_GRAM[][]数组中t++;}if (t == num){for (r = 0; r < 16 * space; r++) //显示间隔{for (i = 0; i < 144; i++){for (n = 0; n < 8; n++){OLED_GRAM[i - 1][n] = OLED_GRAM[i][n];}}OLED_Refresh();}t = 0;}m++;if (m == 16){m = 0;}for (i = 0; i < 144; i++) //实现左移{for (n = 0; n < 8; n++){OLED_GRAM[i - 1][n] = OLED_GRAM[i][n];}}OLED_Refresh();}
}//配置写入数据的起始位置
void OLED_WR_BP(u8 x, u8 y)
{OLED_WR_Byte(0xb0 + y, OLED_CMD); //设置行起始地址OLED_WR_Byte(((x & 0xf0) >> 4) | 0x10, OLED_CMD);OLED_WR_Byte((x & 0x0f), OLED_CMD);
}//x0,y0:起点坐标
//x1,y1:终点坐标
//BMP[]:要写入的图片数组
void OLED_ShowPicture(u8 x0, u8 y0, u8 x1, u8 y1, u8 BMP[])
{u32 j = 0;u8 x = 0, y = 0;if (y % 8 == 0)y = 0;elsey += 1;for (y = y0; y < y1; y++){OLED_WR_BP(x0, y);for (x = x0; x < x1; x++){OLED_WR_Byte(BMP[j], OLED_DATA);j++;}}
}
//OLED的初始化
void OLED_Init(void)
{OLED_WR_Byte(0xAE, OLED_CMD); //--turn off oled panelOLED_WR_Byte(0x00, OLED_CMD); //---set low column addressOLED_WR_Byte(0x10, OLED_CMD); //---set high column addressOLED_WR_Byte(0x40, OLED_CMD); //--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)OLED_WR_Byte(0x81, OLED_CMD); //--set contrast control registerOLED_WR_Byte(0xCF, OLED_CMD); // Set SEG Output Current BrightnessOLED_WR_Byte(0xA1, OLED_CMD); //--Set SEG/Column Mapping     0xa0左右反置 0xa1正常OLED_WR_Byte(0xC8, OLED_CMD); //Set COM/Row Scan Direction   0xc0上下反置 0xc8正常OLED_WR_Byte(0xA6, OLED_CMD); //--set normal displayOLED_WR_Byte(0xA8, OLED_CMD); //--set multiplex ratio(1 to 64)OLED_WR_Byte(0x3f, OLED_CMD); //--1/64 dutyOLED_WR_Byte(0xD3, OLED_CMD); //-set display offset  Shift Mapping RAM Counter (0x00~0x3F)OLED_WR_Byte(0x00, OLED_CMD); //-not offsetOLED_WR_Byte(0xd5, OLED_CMD); //--set display clock divide ratio/oscillator frequencyOLED_WR_Byte(0x80, OLED_CMD); //--set divide ratio, Set Clock as 100 Frames/SecOLED_WR_Byte(0xD9, OLED_CMD); //--set pre-charge periodOLED_WR_Byte(0xF1, OLED_CMD); //Set Pre-Charge as 15 Clocks & Discharge as 1 ClockOLED_WR_Byte(0xDA, OLED_CMD); //--set com pins hardware configurationOLED_WR_Byte(0x12, OLED_CMD);OLED_WR_Byte(0xDB, OLED_CMD); //--set vcomhOLED_WR_Byte(0x40, OLED_CMD); //Set VCOM Deselect LevelOLED_WR_Byte(0x20, OLED_CMD); //-Set Page Addressing Mode (0x00/0x01/0x02)//OLED_WR_Byte(0x02, OLED_CMD); //OLED_WR_Byte(0x00, OLED_CMD); //在这里修改位行扫描方式OLED_WR_Byte(0x8D, OLED_CMD); //--set Charge Pump enable/disableOLED_WR_Byte(0x14, OLED_CMD); //--set(0x10) disableOLED_WR_Byte(0xA4, OLED_CMD); // Disable Entire Display On (0xa4/0xa5)OLED_WR_Byte(0xA6, OLED_CMD); // Disable Inverse Display On (0xa6/a7)OLED_WR_Byte(0xAF, OLED_CMD);OLED_Clear();//设置起始页和起始地址OLED_WR_Byte(0xb0 , OLED_CMD); //设置行起始地址OLED_WR_Byte(0x00, OLED_CMD);     //设置 低 列起始地址OLED_WR_Byte(0x10, OLED_CMD);   //设置 高 列起始地址
}

oled.h

#ifndef __OLED_H
#define __OLED_H#include "sys.h"
#include "stdlib.h"
#include "main.h"
//-----------------OLED端口定义----------------#define OLED_SCLK_Clr()   HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8,GPIO_PIN_RESET) //SCL
#define OLED_SCLK_Set() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_8,GPIO_PIN_SET)#define OLED_SDIN_Clr() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9,GPIO_PIN_RESET) //DIN
#define OLED_SDIN_Set() HAL_GPIO_WritePin(GPIOB, GPIO_PIN_9,GPIO_PIN_SET)#define OLED_CMD 0  //写命令
#define OLED_DATA 1 //写数据
#define u8 unsigned char
#define u32 unsigned intvoid OLED_ClearPoint(u8 x, u8 y);
void OLED_ColorTurn(u8 i);
void OLED_DisplayTurn(u8 i);
void I2C_Start(void);
void I2C_Stop(void);
void I2C_WaitAck(void);
void Send_Byte(u8 dat);
void OLED_WR_Byte(u8 dat, u8 cmd);
void OLED_DisPlay_On(void);
void OLED_DisPlay_Off(void);
void OLED_Refresh(void);
void OLED_Clear(void);
void OLED_DrawPoint(u8 x, u8 y);
void OLED_DrawLine(u8 x1, u8 y1, u8 x2, u8 y2);
void OLED_DrawCircle(u8 x, u8 y, u8 r);
void OLED_ShowChar(u8 x, u8 y, u8 chr, u8 size1);
void OLED_ShowString(u8 x, u8 y, u8 *chr, u8 size1);
void OLED_ShowNum(u8 x, u8 y, u32 num, u8 len, u8 size1);
void OLED_ShowChinese(u8 x, u8 y, u8 num, u8 size1);
void OLED_ScrollDisplay(u8 num, u8 space);
void OLED_WR_BP(u8 x, u8 y);
void OLED_ShowPicture(u8 x0, u8 y0, u8 x1, u8 y1, u8 BMP[]);
void OLED_Init(void);#endif

ssd1306 oled 行扫描方式相关推荐

  1. SSD1306(OLED驱动芯片)指令详解

    在介绍0.96寸 SSD1306之前先附上模块链接:点击购买SSD1306 OLED显示模块 更多OLED系列请看专栏:点击进入 基础命令: 1.页地址模式下设置列起始地址低位(Set Lower C ...

  2. F411-WeAct(二)IIC 驱动SSD1306 OLED(0.96寸)

    F411-WeAct(二)IIC 驱动SSD1306 OLED(0.96寸) 硬件资源介绍 F411-WeAct开发板 OLED STM32初始化 初始化时钟 外设初始化 正式开始 下载源代码 硬件资 ...

  3. 0.91寸 SSD1306 OLED介绍(四) --- 用上位机验证OLED显示屏

    在介绍0.91寸 SSD1306之前先附上模块链接:点击购买SSD1306 OLED显示模块 前面的文章已经详细说明了OLED的原理,指令,代码 0.91寸 SSD1306 OLED介绍(一) - 整 ...

  4. ESP32开发之旅——ssd1306 OLED屏的使用

    ESP32开发之旅--ssd1306 OLED屏的使用 前言 在本文中,您将学会ssd1306 OLED屏在ESP32中的使用,本文提供了简单的示例供学习参考. 需要注意的是,本文中的ESP32是使用 ...

  5. 0.91寸 SSD1306 OLED介绍(二) --- 命令介绍

    在介绍0.91寸 SSD1306之前先附上模块链接:点击购买SSD1306 OLED显示模块 寄存器设置介绍 其实要驱动一颗IC,说白了即使根据寄存器来通过特定的硬件协议来发送特定的数据就OK了,SS ...

  6. STC单片机DS1307+ssd1306 oled时钟显示

    STC单片机DS1307+ssd1306 oled时钟显示

  7. 基于51单片机的OLED驱动方式(iic通讯方式)

    基于51单片机的OLED驱动方式(iic通讯方式) 前言: 本人从事硬件开发,自学软件,因为发现在学习过程中,有很多问题对于没有项目实战经验的新手来讲太难解决了,可以说基本上是无从下手.现将自己学习过 ...

  8. 0.91寸 SSD1306 OLED介绍(一) --- 整体介绍/IIC时序介绍

    在介绍0.91寸 SSD1306之前先附上模块链接:点击购买SSD1306 OLED显示模块 1. SSD1306 OLED介绍 OLED,即有机发光二极管(Organic Light-Emittin ...

  9. 苹果亮度突然变暗_iPhone 12调光策略延续三星OLED经典方式 低于25%亮度将采用PWM调光_手机新闻...

    华强北电脑网10月23日消息 众所周知,苹果iPhone 12的屏幕是采用三星的OLED屏幕,大家也都知道,关于手机屏幕的亮度可以自动调节,在强光下,手机屏幕亮度就会调高,在弱光下,亮度就会变暗,就是 ...

  10. 【Renesas RA6M4开发板之I2C(模拟)驱动ssd1306 OLED屏幕】

    [Renesas RA6M4开发板之I2C(模拟)驱动ssd1306 OLED屏幕] 1.0 OLED 1.1产品特性: 1.2产品参数: 2. RT-theard配置 2.1 硬件需求 2.2 软件 ...

最新文章

  1. php生成背景并加字,PHP给图片添加文字水印实例
  2. 即将消失的十大热门技术---竟然有java,还是学asp.net去吧.跟微软混没错!
  3. 分布式架构知识体系必读
  4. html里面超链接alt_前端html--超链接,表格,表单属性
  5. 访问数,每次访问页数,平均停留时间,跳出率
  6. python 语音播放_基于Python编写的语音播放软件
  7. 循环次数几次_圆柱模板循环使用次数是多少呢
  8. MyBatis之Mapper动态代理开发
  9. Could not link against boost_system 解决办法
  10. defaultcharacterset mysql_C# .Net+MySQL组合开发Character set ‘gbk’ is not supported的解决方法...
  11. android butterknife 自定义view,ButterKnife用法详解.md
  12. 以太坊2.0合约余额新增8768 ETH
  13. 船舶网络搭建项目案例
  14. oc渲染器实时预览用的是编辑器细分,不是渲染器细分。
  15. 自然语言处理核心期刊_计算机核心期刊
  16. 数据库与MPP数仓(三十):pigsty部署
  17. 如何在Idea一个窗口打开多个项目
  18. XL4001 典型应用电路
  19. 大家好,我是浪啦啦啦啦啦!
  20. HTML网页设计期末课程大作业 ~中国茶文化5页面带轮播(HTML+CSS+JS)~ 学生网页设计作业源码

热门文章

  1. Origin绘制带标签热图
  2. Laravel框架简介与环境搭建
  3. 2021年中国鱼油发展现状及进出口状况分析:我国鱼油需求进一步扩大 [图]
  4. 机电工程专业技术-测量技术
  5. 六年级上学期计算机上册教案,最新人教版六年级上册数学全册教案
  6. wifi 联想小新_联想小新如何开启wifi
  7. 马哥linux视频笔记,马哥linux视频的学习笔记
  8. 三对角矩阵的存储和获取(C++版)
  9. 伺服电机转矩常数的标定方法
  10. Javassist框架研究