OLED示波器的实现

OLED示波器是一种使用有机发光二极管(OLED)显示屏来显示波形的仪器。它可以实时显示电压、电流、频率等信号的波形。

OLED显示屏具有高对比度、高亮度、广视角和快速响应时间等优点,使得OLED示波器在波形显示方面具有更好的表现。与传统的液晶显示屏相比,OLED显示屏的黑色更加纯正,并且可以显示更细小的细节。

OLED示波器通常具有多个通道,可以同时显示多个信号的波形。它还可以通过调整时间、电压和触发等参数,更好地观察和分析信号的特性。

我们移植了OLED示波器后可以用杜邦线接出单片机引脚,可用于查看某个模块的波形等,方便程序调试。

我使用了FreeRTOS,要移植把任务改成int main 即可,注意引脚初始化。

#define accur 0.015295//accur=18*3.3/4096(3.3/4096就是ADC采样精度,18是为了让波形转化一下能够显示在适当位子)/* wave开始任务 */
void wave_task(void *pvParameters)
{	u16 x=0;uint16_t ConvData=0;//ADC采样数据while(1){	if(x<128){xQueueReceive(xQueue4,&ConvData,0);OLED_DrawWave(x,accur*ConvData);//这是个画波形的函数//ConvData=0; 不注释就是柱形x=(x+1)%128;}vTaskDelay(10);}
}

oled.c

#include "OLED.h"
#include "codetab.h"
#include "at32f435_437_board.h"
#include "at32f435_437_clock.h"
#include "at32f435_437_gpio.h"
#define OLED_CMD  0	//
#define OLED_DATA 1	//
#define OLED_MODE 0//OLED模式设置
//0:4线串行模式
//1:并行8080模式#define SIZE 16
#define XLevelL		0x02
#define XLevelH		0x10
#define Max_Column	128
#define Max_Row		64
#define	Brightness	0xFF 
#define X_WIDTH 	128
#define Y_WIDTH 	64	    
#define WriteCmd(x) oledWriteByte(x,OLED_CMD)
#define WriteDat(x) oledWriteByte(x,OLED_DATA)
#define OLED_DC_Set() gpio_bits_write(GPIOD, GPIO_PINS_6, TRUE)
#define OLED_DC_Clr() gpio_bits_write(GPIOD, GPIO_PINS_6, FALSE)
#define OLED_CS_Set() gpio_bits_write(GPIOD, GPIO_PINS_3, TRUE)
#define OLED_CS_Clr() gpio_bits_write(GPIOD, GPIO_PINS_3, FALSE)
/*
#define OLED_CS_Set() gpio_bits_write(GPIOC, GPIO_PINS_3, TRUE)
#define OLED_CS_Clr() gpio_bits_write(GPIOC, GPIO_PINS_3, FALSE)
#define OLED_DC_Set() gpio_bits_write(GPIOB, GPIO_PINS_1, TRUE)
#define OLED_DC_Clr() gpio_bits_write(GPIOB, GPIO_PINS_1, FALSE)*/
#define OLED_RST_Set() gpio_bits_write(GPIOE, GPIO_PINS_6, TRUE)
#define OLED_RST_Clr() gpio_bits_write(GPIOE, GPIO_PINS_6, FALSE)uint8_t Bef[3];//保存前一个数据的几个参数1.要写在第几页2.0x01要移动几位3.写什么数据
uint8_t Cur[3];//当前前一个数据1.要写在第几页2.0x01要移动几位3.写什么数据
/*** @brief  spi configuration.* @param  none* @retval none*/
static void spi_config(void)
{spi_init_type spi_init_struct;crm_periph_clock_enable(CRM_SPI3_PERIPH_CLOCK, TRUE);spi_default_para_init(&spi_init_struct);spi_init_struct.transmission_mode = SPI_TRANSMIT_HALF_DUPLEX_TX;spi_init_struct.master_slave_mode = SPI_MODE_MASTER;spi_init_struct.mclk_freq_division = SPI_MCLK_DIV_32;spi_init_struct.first_bit_transmission = SPI_FIRST_BIT_MSB;spi_init_struct.frame_bit_num = SPI_FRAME_8BIT;spi_init_struct.clock_polarity = SPI_CLOCK_POLARITY_LOW;spi_init_struct.clock_phase = SPI_CLOCK_PHASE_1EDGE;spi_init_struct.cs_mode_selection = SPI_CS_SOFTWARE_MODE;spi_init(SPI3, &spi_init_struct);spi_enable(SPI3, TRUE);
}/*** @brief  gpio configuration.* @param  none* @retval none*/
static void oled_gpio_config(void)
{gpio_init_type gpio_initstructure;crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE);crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);crm_periph_clock_enable(CRM_GPIOE_PERIPH_CLOCK, TRUE);gpio_default_para_init(&gpio_initstructure);/* spi3 sck pin  PB 3*/ gpio_initstructure.gpio_out_type       = GPIO_OUTPUT_PUSH_PULL;gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;gpio_initstructure.gpio_pull           = GPIO_PULL_DOWN;gpio_initstructure.gpio_mode           = GPIO_MODE_MUX;gpio_initstructure.gpio_pins = GPIO_PINS_3;gpio_init(GPIOB, &gpio_initstructure);gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE3, GPIO_MUX_6);/* spi3 mosi pin */gpio_initstructure.gpio_pull           = GPIO_PULL_DOWN;gpio_initstructure.gpio_pins           = GPIO_PINS_5;gpio_init(GPIOB, &gpio_initstructure);gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE5, GPIO_MUX_6);/* set default parameter */gpio_default_para_init(&gpio_initstructure);/* configure the led gpio */gpio_initstructure.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;gpio_initstructure.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;gpio_initstructure.gpio_mode = GPIO_MODE_OUTPUT;gpio_initstructure.gpio_pins = GPIO_PINS_3;gpio_initstructure.gpio_pull = GPIO_PULL_NONE;gpio_init(GPIOD, &gpio_initstructure);gpio_initstructure.gpio_pins = GPIO_PINS_6;gpio_init(GPIOD, &gpio_initstructure);}void SPI_OLED_Init(void){oled_gpio_config();spi_config();OLED_CS_Clr();OLED_RST_Set();delay_ms(10);OLED_RST_Clr();delay_ms(10);OLED_RST_Set();}void spitransferByte(char data)
{spi_i2s_data_transmit(SPI3, data);while(spi_i2s_flag_get(SPI3, SPI_I2S_BF_FLAG) == SET);}void oledWriteByte(u8 dat, u8 cmd)
{if (cmd){OLED_DC_Set();}else if (cmd != 1){OLED_DC_Clr();}OLED_CS_Clr();spitransferByte(dat);OLED_CS_Set();OLED_DC_Set();
}void OLED_Init(void)
{SPI_OLED_Init();OLED_RST_Set();delay_ms(10);OLED_RST_Clr();delay_ms(10);OLED_RST_Set();WriteCmd(0xAE); //display offWriteCmd(0x20);	//Set Memory Addressing Mode	WriteCmd(0x10);	//00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,InvalidWriteCmd(0xb0);	//Set Page Start Address for Page Addressing Mode,0-7WriteCmd(0xc8);	//Set COM Output Scan DirectionWriteCmd(0x00); //---set low column addressWriteCmd(0x10); //---set high column addressWriteCmd(0x40); //--set start line addressWriteCmd(0x81); //--set contrast control registerWriteCmd(0xff); //亮度调节 0x00~0xffWriteCmd(0xa1); //--set segment re-map 0 to 127WriteCmd(0xa6); //--set normal displayWriteCmd(0xa8); //--set multiplex ratio(1 to 64)WriteCmd(0x3F); //WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM contentWriteCmd(0xd3); //-set display offsetWriteCmd(0x00); //-not offsetWriteCmd(0xd5); //--set display clock divide ratio/oscillator frequencyWriteCmd(0xf0); //--set divide ratioWriteCmd(0xd9); //--set pre-charge periodWriteCmd(0x22); //WriteCmd(0xda); //--set com pins hardware configurationWriteCmd(0x12);WriteCmd(0xdb); //--set vcomhWriteCmd(0x20); //0x20,0.77xVccWriteCmd(0x8d); //--set DC-DC enableWriteCmd(0x14); //WriteCmd(0xaf); //--turn on oled panel
}void OLED_SetPos(unsigned char x, unsigned char y) //设置起始点坐标
{ WriteCmd(0xb0+x);WriteCmd((y&0x0f)|0x00);//LOWWriteCmd(((y&0xf0)>>4)|0x10);//HIGHT
}void OLED_Fill(unsigned char fill_Data)
{unsigned char m,n;for(m=0;m<8;m++){WriteCmd(0xb0+m);		//page0-page1WriteCmd(0x00);		//low column start addressWriteCmd(0x10);		//high column start addressfor(n=0;n<128;n++){WriteDat(fill_Data);}}
}void OLED_CLS(void)//清屏
{OLED_Fill(0x00);
}//--------------------------------------------------------------
// Prototype      : void OLED_ON(void)
// Calls          : 
// Parameters     : none
// Description    : 将OLED从休眠中唤醒
//--------------------------------------------------------------
void OLED_ON(void)
{WriteCmd(0X8D);  //设置电荷泵WriteCmd(0X14);  //开启电荷泵WriteCmd(0XAF);  //OLED唤醒
}//--------------------------------------------------------------
// Prototype      : void OLED_OFF(void)
// Calls          : 
// Parameters     : none
// Description    : 让OLED休眠 -- 休眠模式下,OLED功耗不到10uA
//--------------------------------------------------------------
void OLED_OFF(void)
{WriteCmd(0X8D);  //设置电荷泵WriteCmd(0X10);  //关闭电荷泵WriteCmd(0XAE);  //OLED休眠
}//--------------------------------------------------------------
// Prototype      : void OLED_ShowChar(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
// Calls          : 
// Parameters     : x,y -- 起始点坐标(x:0~127, y:0~7); ch[] -- 要显示的字符串; TextSize -- 字符大小(1:6*8 ; 2:8*16)
// Description    : 显示codetab.h中的ASCII字符,有6*8和8*16可选择
//--------------------------------------------------------------
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned char TextSize)
{unsigned char c = 0,i = 0,j = 0;switch(TextSize){case 1:{while(ch[j] != '\0'){c = ch[j] - 32;if(x > 126){x = 0;y++;}//OLED_SetPos(x,y);OLED_SetPos(y,x);for(i=0;i<6;i++)WriteDat(F6x8[c][i]);x += 6;j++;}}break;case 2:{while(ch[j] != '\0'){c = ch[j] - 32;if(x > 120){x = 0;y++;}//OLED_SetPos(x,y);OLED_SetPos(y,x);for(i=0;i<8;i++)WriteDat(F8X16[c*16+i]);//OLED_SetPos(x,y+1);OLED_SetPos(y+1,x);for(i=0;i<8;i++)WriteDat(F8X16[c*16+i+8]);x += 8;j++;}}break;}
}//--------------------------------------------------------------
// Prototype      : void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
// Calls          : 
// Parameters     : x,y -- 起始点坐标(x:0~127, y:0~7); N:汉字在codetab.h中的索引
// Description    : 显示codetab.h中的汉字,16*16点阵
//--------------------------------------------------------------
void OLED_ShowCN(unsigned char x, unsigned char y, unsigned char N)
{// Parameters     : x,y -- 起始点坐标(x:0~127, y:0~7); N:汉字在codetab.h中的索引// Description    : 显示codetab.h中的汉字,16*16点阵unsigned char wm=0;unsigned int  adder=32*N;//OLED_SetPos(x , y);OLED_SetPos(y,x);for(wm = 0;wm < 16;wm++){WriteDat(F16x16[adder]);adder += 1;}//OLED_SetPos(x,y + 1);OLED_SetPos(y+1,x);for(wm = 0;wm < 16;wm++){WriteDat(F16x16[adder]);adder += 1;}
}//--------------------------------------------------------------
// Prototype      : void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[]);
// Calls          : 
// Parameters     : x0,y0 -- 起始点坐标(x0:0~127, y0:0~7); x1,y1 -- 起点对角线(结束点)的坐标(x1:1~128,y1:1~8)
// Description    : 显示BMP位图
//--------------------------------------------------------------
void OLED_DrawBMP(unsigned char x0,unsigned char y0,unsigned char x1,unsigned char y1,unsigned char BMP[])
{// Parameters     : x0,y0 -- 起始点坐标(x0:0~127, y0:0~7); x1,y1 -- 起点对角线(结束点)的坐标(x1:1~128,y1:1~8)// Description    : 显示BMP位图unsigned int j=0;unsigned char x,y;if(y1%8==0)y = y1/8;elsey = y1/8 + 1;for(y=y0;y<y1;y++){//OLED_SetPos(x0,y);OLED_SetPos(y,x0);for(x=x0;x<x1;x++){WriteDat(BMP[j++]);}}
}由B站Up主“尔等小众”开源
///打波函数//
void Before_State_Update(uint8_t y)//根据y的值,求出前一个数据的有关参数
{Bef[0]=7-y/8;Bef[1]=7-y%8;Bef[2]=1<<Bef[1];
}
void Current_State_Update(uint8_t y)//根据Y值,求出当前数据的有关参数
{Cur[0]=7-y/8;//数据写在第几页Cur[1]=7-y%8;//0x01要移动的位数Cur[2]=1<<Cur[1];//要写什么数据
}void OLED_DrawWave(uint8_t x,uint8_t y)
{int8_t page_sub;uint8_t page_buff,i,j;Current_State_Update(y);//根据Y值,求出当前数据的有关参数page_sub=Bef[0]-Cur[0];//当前值与前一个值的页数相比较//确定当前列,每一页应该写什么数据if(page_sub>0){page_buff=Bef[0];OLED_SetPos(page_buff,x);WriteDat(Bef[2]-0x01);page_buff--;for(i=0;i<page_sub-1;i++){OLED_SetPos(page_buff,x);WriteDat(0xff);page_buff--;}OLED_SetPos(page_buff,x);WriteDat(0xff<<Cur[1]);}else if(page_sub==0){if(Cur[1]==Bef[1]){OLED_SetPos(Cur[0],x);WriteDat(Cur[2]);}else if(Cur[1]>Bef[1]){OLED_SetPos(Cur[0],x);WriteDat((Cur[2]-Bef[2])|Cur[2]);}else if(Cur[1]<Bef[1]){OLED_SetPos(Cur[0],x);WriteDat(Bef[2]-Cur[2]);}}else if(page_sub<0){page_buff=Cur[0];OLED_SetPos(page_buff,x);WriteDat((Cur[2]<<1)-0x01);page_buff--;for(i=0;i<0-page_sub-1;i++){OLED_SetPos(page_buff,x);WriteDat(0xff);page_buff--;}OLED_SetPos(page_buff,x);WriteDat(0xff<<(Bef[1]+1));}Before_State_Update(y);//把下一列,每一页的数据清除掉for(i=0;i<8;i++){OLED_SetPos(i, x+1) ;for(j=0;j<1;j++)WriteDat(0x00);}
}

移植参考说明

本文OLED示波器参考【0.96寸OLED示波】 https://www.bilibili.com/video/BV11E411V72p

他的oled是iic 我的是spi

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/40352.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙开发设备管理:【@ohos.usb (USB管理)】

USB管理 本模块主要提供管理USB设备的相关功能&#xff0c;包括查询USB设备列表、批量数据传输、控制命令传输、权限控制等。 说明&#xff1a; 本模块首批接口从API version 8开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 导入模块 import …

【JavaScript脚本宇宙】优化你的Web色彩:精选JavaScript颜色工具对比

万能色彩助手&#xff1a;详解最受欢迎的JavaScript颜色库 前言 在现代Web开发中&#xff0c;颜色处理和转换是一个不可忽视的环节。无论是网站设计、数据可视化还是用户界面开发&#xff0c;都离不开对颜色的精确控制和转换。为了满足这一需求&#xff0c;众多JavaScript库应…

Toocaa Studio已开发的功能

2024年07月01日 Toocaa Studio 一个激光切割雕刻机的上位机&#xff0c; 未来会对标Xtool的xTool Creative Space和LightBurn&#xff0c;同时它也是一款图形编辑器&#xff0c;矢量图形编辑器。 工具类 鼠标画矩形或正方形 鼠标画椭圆或画圆 鼠标画直线或轨迹路径 往画布中…

你的机器人购物新体验——安全、高效、无忧

如果你跟我一样&#xff0c;对找到那些“恰到好处”的商品充满渴望&#xff0c;那么&#xff0c;让我来告诉你为什么BFT会成为你的下一个购物“心头好”。 BFT的优势 高效安全的支付体系&#xff1a;BFT交易系统保障了交易的安全性和透明性&#xff0c;让你的每一笔消费都安全…

Build a Large Language Model (From Scratch)附录B(gpt-4o翻译版)

来源&#xff1a;https://github.com/rasbt/LLMs-from-scratch?tabreadme-ov-file https://www.manning.com/books/build-a-large-language-model-from-scratch

《More Effective C++》《杂项讨论——34、如何在同一个程序中结合C++和C》

文章目录 1、Terms34:如何在同一个程序中结合C和C1.1 名称重整1.2 statics的初始化1.3 动态内存的分配1.4 数据结构的兼容性 2、总结3、参考 1、Terms34:如何在同一个程序中结合C和C 在大型项目中一般都用C进行开发&#xff0c;但是不可避免会用一些C语言进行底层的调用。在确…

【宠粉赠书】UML 2.5基础、建模与设计实践

为了回馈粉丝们的厚爱&#xff0c;今天小智给大家送上一套系统建模学习的必备书籍——《UML 2.5基础、建模与设计实践》。下面我会详细给大家介绍这本书&#xff0c;文末留有领取方式。 图书介绍 《UML 2.5基础、建模与设计实践》以实战为主旨&#xff0c;结合draw.io免费软件…

匿名内部类

下面代码中&#xff0c;Person24 是一个抽象类&#xff0c;这意味着它不能被直接实例化&#xff0c;只能通过继承它的子类来实现其抽象方法。代码片段中展示了如何使用匿名内部类来实现一个抽象类的实例。 package chapter04;public class Java24_Object_匿名内部类 {public s…

verilog行为建模(三):块语句

目录 1.块语句2.延迟赋值语句 微信公众号获取更多FPGA相关源码&#xff1a; 1.块语句 块语句用来将多个语句组织在一起&#xff0c;使得他们在语法上如同一个语句。 块语句分为两类&#xff1a; 顺序块&#xff1a;语句置于关键字begin和end之间&#xff0c;块中的语句以顺…

鸿蒙‘ohpm‘ 不是内部或外部命令,也不是可运行的程序-解决方案

&#x1f525; 博客主页&#xff1a; 小韩本韩&#xff01; ❤️ 感谢大家点赞&#x1f44d;收藏⭐评论✍️ 在鸿蒙的DevEco Studio的终端下输入 onpm -v 或者 你需要下载第三方ohpm包的时候提示‘ohpm‘ 不是内部或外部命令&#xff0c;也不是可运行的程序- 主要是因为我们…

学习测试1

计算机基础 1、计算机范式&#xff1a;冯诺依曼机 2、存储单元 bit、byte、KB、MB、GB3、网络 ip、域名、ping 域名、 ipconfig测试工作的流程 ------------------------------------------------------------------------------------------- 一 编写测试大纲 罗列测试…

C++STL函数对象的应用

STL函数对象 文章目录 STL函数对象1.基本概念2.使用方法1. 简单函数对象示例2. 函数对象作为算法参数3. Lambda表达式作为函数对象 2.一元谓词和二元谓词1.一元谓词2.二元谓词3.总结 3.算术仿函数1.使用示例2.Lambda表达式的替代 4.关系仿函数5.逻辑仿函数 C中的函数对象&#…

文化创新与社交媒体:探索Facebook的足迹

在过去的十多年里&#xff0c;Facebook从一个简单的校园社交网络发展成为全球最大的社交媒体平台之一。它不仅改变了人们的沟通方式&#xff0c;更在许多方面推动了文化的创新和变革。本文将深入探索Facebook如何通过其平台的演进和功能创新&#xff0c;成为文化创新的重要推动…

Ubuntu / Debian安装FTP服务

本章教程,记录在Ubuntu中安装FTP服务的具体步骤。FTP默认端口:21 1、安装 pure-ftpd sudo apt-get install pure-ftpd2、修改默认配置 # 与 centos 不同,这里需要在 /etc/pure-ftpd/conf 文件夹下执行下列命令,增加对应配置文件: # 创建 /etc/pure-ftpd/conf/PureDB 文件…

【数据结构】(6.2)堆的应用——Top-K问题(C语言)

系列文章目录 文章目录 系列文章目录问题引入一、TopK 问题 是什么&#xff1f;二、TopK 问题解决思路2.1 TopK 思路2.2 随机产生数字2.2 完整代码2.3 验证结果 问题引入 TopK 问题 (在一堆数据里面找到前 K 个最大 / 最小的数)。 一、TopK 问题 是什么&#xff1f; 生活中也…

2024 最新docker仓库镜像,6月,7月

目前下面的docker仓库镜像源还能使用。 vi /etc/docker/daemon.json添加如下配置{"registry-mirrors": ["https://hub.uuuadc.top", "https://docker.anyhub.us.kg", "https://dockerhub.jobcher.com", "https://dockerhub.icu&…

船舶雷达与导航系统选择7/8防水插座的原因分析

概述 船舶雷达与导航系统在现代航海中扮演着至关重要的角色&#xff0c;它们为船舶提供准确的导航信息&#xff0c;确保航行的安全和效率。在这些系统中&#xff0c;7/8防水插座的使用尤为重要&#xff0c;因为它们能够在恶劣的海上环境中提供稳定的电力和信号连接。接下来&am…

python的os.walk()

os.walk() 是一个非常有用的函数&#xff0c;用于在Python中遍历文件夹树。它返回一个生成器&#xff0c;该生成器在每次迭代时返回一个包含三个元素的元组&#xff1a;(当前文件夹的路径&#xff0c;文件夹中的子文件夹的列表&#xff0c;文件夹中的文件的列表)。这个函数对于…

左耳听风_007_06_如何才能拥有技术领导力

你好&#xff0c;我是陈浩老明左耳朵house.那通过上节课呢&#xff0c;相信你现在已经理解了什么才是技术领导力。 那今天呢我就来跟你继续聊一聊怎样才能拥有技术领导力。 首先呢你需要吃透基础技术。 因为基础技术啊是各种上层技术共同的技术。 吃透基础技术是为了更好的…

Outlook发送大文件的问题是什么?怎么解决?

Outlook不仅是一款电子邮件客户端&#xff0c;还包括日历、任务、笔记、联系人等功能&#xff0c;同时与Microsoft Office套件中的其他应用程序&#xff08;如Word、Excel、PowerPoint等&#xff09;集成紧密&#xff0c;方便用户在不同应用程序之间切换&#xff0c;提高工作效…