OLED INA226基本完成

This commit is contained in:
2025-09-01 22:43:03 +08:00
parent be600d0769
commit 8154cad6bc
22 changed files with 3258 additions and 1177 deletions

491
Source/oled_iic_SSD1306.c Normal file
View File

@@ -0,0 +1,491 @@
#include "oled_iic_SSD1306.h"
#include "oled_font.h"
#include "delay.h"
#include "printfs.h"
#if (1==OLED_USE_SOFT_IIC)
#include "iic_soft.h"
static IIC_Soft_Config oled_soft_iic;
#else
#include "iic.h"
#endif
//-------------------------------------------------------------------------------------------------------------------
// @brief 内部调用,用户无需关心
// @param void
// @return
// @since v1.0
// Sample usage:
//-------------------------------------------------------------------------------------------------------------------
void oled_wrdat(uint8 dat)
{
#if (1==OLED_USE_SOFT_IIC)
soft_iic_write_reg(&oled_soft_iic, OLED_ADDR, 0x40, dat);
#else
iic_write_reg(OLED_ADDR, 0x40, dat);
#endif
}
//-------------------------------------------------------------------------------------------------------------------
// @brief 内部调用,用户无需关心
// @param void
// @return
// @since v1.0
// Sample usage:
//-------------------------------------------------------------------------------------------------------------------
void oled_wrcmd(uint8 cmd)
{
#if (1==OLED_USE_SOFT_IIC)
soft_iic_write_reg(&oled_soft_iic, OLED_ADDR, 0x00, cmd);
#else
iic_write_reg(OLED_ADDR, 0x00, cmd);
#endif
}
//-------------------------------------------------------------------------------------------------------------------
// @brief 内部调用,用户无需关心
// @param void
// @return
// @since v1.0
// Sample usage:
//-------------------------------------------------------------------------------------------------------------------
void oled_hexascii(uint16 hex,int8 * Print)
{
uint8 edata hexcheck ;
uint8 edata TEMP ;
TEMP = 6 ;
Print[TEMP ]='\0';
while(TEMP)
{
TEMP -- ;
hexcheck = hex%10 ;
hex /=10 ;
Print[TEMP ] = hexcheck + 0x30 ;
}
}
#if (1==OLED_USE_SOFT_IIC)
void oled_scl_set()
{
OLED_SCL_LEVEL(1);
}
void oled_sda_set()
{
OLED_SDA_LEVEL(1);
}
void oled_sda_clr()
{
OLED_SDA_LEVEL(0);
}
void oled_scl_clr()
{
OLED_SCL_LEVEL(0);
}
uint8 oled_sda_read()
{
return OLED_SDA_READ();
}
#endif
//-------------------------------------------------------------------------------------------------------------------
// @brief OLED初始化函数
// @param NULL
// @return void
// @since v1.0
// Sample usage:
//-------------------------------------------------------------------------------------------------------------------
void oled_init(void)
{
// unsigned char i;
// unsigned char initData[] = {0xAE,0x00,0x10,0x40,0xB0,0x81,0xFF,0xA0,0xA6,0xA8,0x3F,0xC8,0xD3,0x00,0xD5,0x80,0xD9,0xF1,0xDA,0x12,0xDB,0x30,0x8D,0x14,0xAF};
#if (1==OLED_USE_SOFT_IIC)
// oled_soft_iic.sda_pin = OLED_SDA_PIN;
// oled_soft_iic.scl_pin = OLED_SCL_PIN;
oled_soft_iic.SCL_SET = oled_scl_set;
oled_soft_iic.SCL_CLR = oled_scl_clr;
oled_soft_iic.SDA_SET = oled_sda_set;
oled_soft_iic.SDA_CLR = oled_sda_clr;
oled_soft_iic.SDA_READ = oled_sda_read;
oled_soft_iic.wait_time = OLED_SOFT_WAIT_TIME;
soft_iic_init(&oled_soft_iic);
#else
iic_init(OLED_IIC,OLED_HARD_WAIT_TIME);
#endif
// for(i=0;i<25;i++){
// oled_wrcmd(initData[i]);
// }
// oled_wrcmd(0xAE);
// oled_wrcmd(0x40);
// oled_wrcmd(0xB0);
// oled_wrcmd(0xC8);
// oled_wrcmd(0x81);
// oled_wrcmd(0xFF);
// oled_wrcmd(0xA1);
// oled_wrcmd(0xA6);
// oled_wrcmd(0xA8);
// oled_wrcmd(0x1F);
// oled_wrcmd(0xD3);
// oled_wrcmd(0x00);
// oled_wrcmd(0xD5);
// oled_wrcmd(0xF0);
// oled_wrcmd(0xD9);
// oled_wrcmd(0x22);
// oled_wrcmd(0xDA);
// oled_wrcmd(0x02);
// oled_wrcmd(0xDB);
// oled_wrcmd(0x49);
// oled_wrcmd(0x8D);
// oled_wrcmd(0x14);
// oled_wrcmd(0xAF);
oled_wrcmd(0xae);//--turn off oled panel
oled_wrcmd(0x00);//---set low column address
oled_wrcmd(0x10);//---set high column address
oled_wrcmd(0x40);//--set start line address Set Mapping RAM Display Start Line (0x00~0x3F)
oled_wrcmd(0x81);//--set contrast control register
oled_wrcmd(Brightness); // Set SEG Output Current Brightness
#if (0 == OLED_DISPLAY_DIR)
oled_wrcmd(0xa1);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
oled_wrcmd(0xc8);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
#else
oled_wrcmd(0xa0);//--Set SEG/Column Mapping 0xa0左右反置 0xa1正常
oled_wrcmd(0xc0);//Set COM/Row Scan Direction 0xc0上下反置 0xc8正常
#endif
oled_wrcmd(0xa6);//--set normal display
oled_wrcmd(0xa8);//--set multiplex ratio(1 to 64)
oled_wrcmd(0x3f);//--1/64 duty
oled_wrcmd(0xd3);//-set display offset Shift Mapping RAM Counter (0x00~0x3F)
oled_wrcmd(0x00);//-not offset
oled_wrcmd(0xd5);//--set display clock divide ratio/oscillator frequency
oled_wrcmd(0x80);//--set divide ratio, Set Clock as 100 Frames/Sec
oled_wrcmd(0xd9);//--set pre-charge period
oled_wrcmd(0xf1);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
oled_wrcmd(0xda);//--set com pins hardware configuration
oled_wrcmd(0x12);
oled_wrcmd(0xdb);//--set vcomh
oled_wrcmd(0x40);//Set VCOM Deselect Level
oled_wrcmd(0x20);//-Set Page Addressing Mode (0x00/0x01/0x02)
oled_wrcmd(0x02);//
oled_wrcmd(0x8d);//--set Charge Pump enable/disable
oled_wrcmd(0x14);//--set(0x10) disable
oled_wrcmd(0xa4);// Disable Entire Display On (0xa4/0xa5)
oled_wrcmd(0xa6);// Disable Inverse Display On (0xa6/a7)
oled_wrcmd(0xaf);//--turn on oled panel
oled_fill(0x00); //初始清屏
oled_set_pos(0,0);
}
//-------------------------------------------------------------------------------------------------------------------
// @brief OLED显示坐标设置
// @param x x轴坐标设置0-127
// @param y y轴坐标设置0-7
// @return void
// @since v1.0
// Sample usage:
//-------------------------------------------------------------------------------------------------------------------
void oled_set_pos(uint8 x, uint8 y)
{
oled_wrcmd((uint8)(0xb0+y));
oled_wrcmd((uint8)(((x&0xf0)>>4)|0x10));
oled_wrcmd((uint8)((x&0x0f)));
}
//-------------------------------------------------------------------------------------------------------------------
// @brief OLED清屏函数
// @param bmp_data 填充颜色选着(0x00 or 0xff)
// @return void
// @since v1.0
// Sample usage:
//-------------------------------------------------------------------------------------------------------------------
void oled_fill(uint8 bmp_data)
{
uint8 edata y,x;
for(y=0;y<8;y++)
{
oled_wrcmd((uint8)(0xb0+y));
oled_wrcmd((uint8)(0x01));
oled_wrcmd((uint8)(0x10));
for(x=0;x<X_WIDTH;x++) oled_wrdat(bmp_data);
}
}
//-------------------------------------------------------------------------------------------------------------------
// @brief OLED控制一个坐标下8个像素的点亮与熄灭
// @param x x轴坐标设置0-127
// @param y y轴坐标设置0-7
// @return void
// @since v1.0
// Sample usage: oled_putpixel(0,0,0xff);//将0,0坐标 8个点全部点亮
// Sample usage: oled_putpixel(0,0,0x01);//将0,0坐标 最低位点亮其余7个熄灭
// @note 同理可以任意控制一个坐标下8个像素的点亮与熄灭
//-------------------------------------------------------------------------------------------------------------------
void oled_putpixel(uint8 x,uint8 y,uint8 data1)
{
oled_set_pos(x,y);
oled_wrcmd((uint8)(0xb0+y));
oled_wrcmd((uint8)(((x&0xf0)>>4)|0x10));
oled_wrcmd((uint8)((x&0x0f)|0x00));
oled_wrdat(data1);
}
//-------------------------------------------------------------------------------------------------------------------
// @brief OLED关闭一个坐标所有亮点
// @param x x轴坐标设置0-127
// @param y y轴坐标设置0-7
// @return void
// @since v1.0
// Sample usage:
//-------------------------------------------------------------------------------------------------------------------
void oled_clrpixel(uint8 x,uint8 y)
{
oled_set_pos(x,y);
oled_wrcmd((uint8)(0xb0+y));
oled_wrcmd((uint8)(((x&0xf0)>>4)|0x10));
oled_wrcmd((uint8)((x&0x0f)|0x00));
oled_wrdat(0x00);
}
//-------------------------------------------------------------------------------------------------------------------
// @brief OLED显示字符串(6*8字体)
// @param x x轴坐标设置0-127
// @param y y轴坐标设置0-7
// @param ch[] 字符串
// @return void
// @since v1.0
// Sample usage:
//-------------------------------------------------------------------------------------------------------------------
void oled_p6x8str(uint8 x,uint8 y,const int8 ch[])
{
uint8 edata c=0,i=0,j=0;
while (ch[j]!='\0')
{
c =ch[j]-32;
if(x>126){x=0;y++;}
oled_set_pos(x,y);
for(i=0;i<6;i++) oled_wrdat(oled_6x8[c][i]);
x+=6;
j++;
}
}
//-------------------------------------------------------------------------------------------------------------------
// @brief OLED显示无符号数(6*8字体)
// @param x x轴坐标设置0-127
// @param y y轴坐标设置0-7
// @param num 无符号数
// @return void
// @since v1.0
// Sample usage:
//-------------------------------------------------------------------------------------------------------------------
void oled_uint16(uint8 x, uint8 y, uint16 num)
{
int8 ch[7];
oled_hexascii(num,ch);
oled_p6x8str(x, y, &ch[1]); //显示数字 6*8字体
//oled_p8x16str(x, y, &ch[1]); //显示数字 8*16字体
}
//-------------------------------------------------------------------------------------------------------------------
// @brief OLED显示有符号数(6*8字体)
// @param x x轴坐标设置0-127
// @param y y轴坐标设置0-7
// @param num 有符号数
// @return void
// @since v1.0
// Sample usage:
//-------------------------------------------------------------------------------------------------------------------
void oled_int16(uint8 x, uint8 y, int16 num)
{
int8 ch[7];
if(num<0) {num = -num;oled_p6x8str(x, y, "-");}
else oled_p6x8str(x, y, " ");
x+=6;
oled_hexascii(num,ch);
oled_p6x8str(x, y, &ch[1]); //显示数字 6*8字体
}
//-------------------------------------------------------------------------------------------------------------------
// @brief OLED显示32位有符号(去除整数部分无效的0)
// @param x x轴坐标设置0-127
// @param y y轴坐标设置0-7
// @param dat 需要显示的变量数据类型uint32
// @param num 需要显示的位数 最高10位 不包含正负号
// @return void
// @since v1.0
// Sample usage: oled_printf_int32(0,0,x,5);//x可以为int32 uint16 int16 uint8 int8类型
// Sample usage: 负数会显示一个 -’号 正数显示一个空格
//-------------------------------------------------------------------------------------------------------------------
void oled_printf_int32(uint16 x,uint16 y,int32 dat,uint8 num)
{
int8 buff[34];
uint8 length;
if(10<num) num = 10;
num++;
if(0>dat) length = zf_sprintf( &buff[0],"%d",dat);//负数
else
{
buff[0] = ' ';
length = zf_sprintf( &buff[1],"%d",dat);
length++;
}
while(length < num)
{
buff[length] = ' ';
length++;
}
buff[num] = '\0';
oled_p6x8str((uint8)x, (uint8)y, (int *)buff); //显示数字
}
//-------------------------------------------------------------------------------------------------------------------
// @brief OLED显示浮点数(去除整数部分无效的0)
// @param x x轴坐标设置0-127
// @param y y轴坐标设置0-7
// @param dat 需要显示的变量数据类型float或double
// @param num 整数位显示长度 最高10位
// @param pointnum 小数位显示长度 最高6位
// @return void
// @since v1.0
// Sample usage: oled_printf_float(0,0,x,2,3);//显示浮点数 整数显示2位 小数显示三位
// @note 特别注意当发现小数部分显示的值与你写入的值不一样的时候,
// 可能是由于浮点数精度丢失问题导致的,这并不是显示函数的问题,
// 有关问题的详情,请自行百度学习 浮点数精度丢失问题。
// 负数会显示一个 -’号 正数显示一个空格
//-------------------------------------------------------------------------------------------------------------------
void oled_printf_float(uint16 x,uint16 y,double dat,uint8 num,uint8 pointnum)
{
uint8 length;
int8 buff[34];
int8 start,end,point;
if(6<pointnum) pointnum = 6;
if(10<num) num = 10;
if(0>dat) length = zf_sprintf( &buff[0],"%f",dat);//负数
else
{
length = zf_sprintf( &buff[1],"%f",dat);
length++;
}
point = length - 7; //计算小数点位置
start = point - num - 1; //计算起始位
end = point + pointnum + 1; //计算结束位
while(0>start)//整数位不够 末尾应该填充空格
{
buff[end] = ' ';
end++;
start++;
}
if(0>dat) buff[start] = '-';
else buff[start] = ' ';
buff[end] = '\0';
oled_p6x8str((uint8)x, (uint8)y, (int8 *)buff); //显示数字
}
//-------------------------------------------------------------------------------------------------------------------
// @brief OLED显示图像
// @param high 图像高度
// @param width 图像宽度
// @param *p 图像地址(数组)
// @param value 二值化阀值
// @return void
// @since v1.0
// Sample usage:
// @Note 使用Image2lcd V3.2软件取模 C语言数组 水平扫描
// 宽度高度自行设置 颜色反转 256色
//-------------------------------------------------------------------------------------------------------------------
void oled_dis_bmp(uint16 high, uint16 width, uint8 *p,uint8 value)
{
uint16 i = 0;
uint16 edata j = 0;
uint16 temp = 0,temp1 = 0;
uint8 dat = 0;
temp1 = high%8;
if(temp1 == 0) temp = high/8;
else temp = high/8+1;
for(i=0; i<temp; i++)
{
oled_set_pos((uint8)0,(uint8)i);
for(j=0; j<width; j++)
{
dat = 0;
if( (i<(temp-1)) || !temp1 || (temp1>=1))dat |= (*(p+i*8*width+j+width*0) > value? 1: 0)<<0;
if( (i<(temp-1)) || !temp1 || (temp1>=2))dat |= (*(p+i*8*width+j+width*1) > value? 1: 0)<<1;
if( (i<(temp-1)) || !temp1 || (temp1>=3))dat |= (*(p+i*8*width+j+width*2) > value? 1: 0)<<2;
if( (i<(temp-1)) || !temp1 || (temp1>=4))dat |= (*(p+i*8*width+j+width*3) > value? 1: 0)<<3;
if( (i<(temp-1)) || !temp1 || (temp1>=5))dat |= (*(p+i*8*width+j+width*4) > value? 1: 0)<<4;
if( (i<(temp-1)) || !temp1 || (temp1>=6))dat |= (*(p+i*8*width+j+width*5) > value? 1: 0)<<5;
if( (i<(temp-1)) || !temp1 || (temp1>=7))dat |= (*(p+i*8*width+j+width*6) > value? 1: 0)<<6;
if( (i<(temp-1)) || !temp1 || (temp1>=8))dat |= (*(p+i*8*width+j+width*7) > value? 1: 0)<<7;
oled_wrdat(dat);
}
}
}
//-------------------------------------------------------------------------------------------------------------------
// @brief 汉字显示
// @param x 横坐标 0-127
// @param y 纵坐标 0-7
// @param size 取模的时候设置的汉字字体大小,也就是一个汉字占用的点阵长宽为多少个点,取模的时候需要长宽是一样的。
// @param *p 需要显示的汉字数组
// @param len 需要显示多少位
// @return void
// @since v1.0
// Sample usage:
// @Note 使用PCtoLCD2002软件取模 阴码、逐行式、顺向 16*16
//-------------------------------------------------------------------------------------------------------------------
void oled_print_chinese(uint8 x, uint8 y, uint8 size, const uint8 *p, uint8 len)
{
uint16 i,j,k;
for(i=0; i<len; i++)
{
for(j=0; j<(size/8); j++)
{
oled_set_pos((uint8)(x+i*size), (uint8)(y+j));
for(k=0; k<16; k++)
{
oled_wrdat(*p);
p++;
}
}
}
}