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

View File

@@ -9,8 +9,12 @@
#if PCA9685_USE_SOFT_IIC == 1
#define PCA9685_SOFT_IIC_SCL_PIN P1_5
#define PCA9685_SOFT_IIC_SDA_PIN P1_4
#define PCA9685_SOFT_IIC_SCL_PIN P15
#define PCA9685_SOFT_IIC_SDA_PIN P14
#define PCA9685_SDA_LEVEL(x) (PCA9685_SOFT_IIC_SDA_PIN = x)
#define PCA9685_SCL_LEVEL(x) (PCA9685_SOFT_IIC_SCL_PIN = x)
#define PCA9685_SDA_READ() (PCA9685_SOFT_IIC_SDA_PIN)
#else

View File

@@ -25,8 +25,10 @@ typedef enum
#define IIC_SEND_OK 0
#define IIC_SEND_FAIL 1
void iic_scan(void);
void iic_init(IICN_enum iic_n, uint8 wait_time);
uint8 iic_write_reg(uint8 dev_add, uint8 reg, uint8 dat);
uint8 iic_write_reg_bytes(uint8 dev_add, uint8 reg, uint8 *dat, uint8 num);
uint8 iic_read_reg(uint8 dev_add, uint8 reg, uint8 *dat);
uint8 iic_read_reg_bytes(uint8 dev_add, uint8 reg, uint8 *dat, uint8 num);
void iic_change_pin(IICN_enum iic_n);

View File

@@ -2,19 +2,25 @@
#define __IIC_SOFT_H__
#include "common.h"
#include "gpio.h"
// #include "gpio.h"
typedef struct
{
PIN_enum scl_pin; // SCL引脚
PIN_enum sda_pin; // SDA引脚
// PIN_enum scl_pin; // SCL引脚
// PIN_enum sda_pin; // SDA引脚
void (*SCL_SET)(void);
void (*SCL_CLR)(void);
void (*SDA_SET)(void);
void (*SDA_CLR)(void);
uint8 (*SDA_READ)(void);
uint16 wait_time; // 等待时间用于I2C总线速度控制
} IIC_Soft_Config;
void soft_iic_scan(IIC_Soft_Config *config);
void soft_iic_init(IIC_Soft_Config *config);
uint8 soft_iic_read_reg(IIC_Soft_Config *config, uint8 dev_addr, uint8 reg_addr, uint8 *dat);
void soft_iic_write_reg(IIC_Soft_Config *config, uint8 dev_addr, uint8 reg_addr, uint8 dat);
void soft_iic_write_reg_bytes(IIC_Soft_Config *config, uint8 dev_addr, uint8 reg, uint8 *dat, uint8 len);
uint8 soft_iic_read_reg(IIC_Soft_Config *config, uint8 dev_addr, uint8 reg_addr, uint8 *dat);
uint8 soft_iic_read_reg_bytes(IIC_Soft_Config *config, uint8 dev_addr, uint8 reg, uint8 *buf, uint8 len);
#endif

83
Header/ina226.h Normal file
View File

@@ -0,0 +1,83 @@
#ifndef __INA226_H__
#define __INA226_H__
#include "common.h"
#define INA226_USE_SOFT_IIC 0
#define INA226_NUM 1
#define INA226_READ_TIME_MS 1
#if (1==INA226_USE_SOFT_IIC)
#define INA226_SDA_PIN P24
#define INA226_SCL_PIN P25
#define INA226_SOFT_WAIT_TIME 5
#define INA226_SDA_LEVEL(x) (INA226_SDA_PIN = x)
#define INA226_SCL_LEVEL(x) (INA226_SCL_PIN = x)
#define INA226_SDA_READ() (INA226_SDA_PIN)
#else
#define INA226_IIC IIC_1
#define INA226_HARD_WAIT_TIME 10
#endif
#define INA226_CONFIG_REG 0x00
#define INA226_SHUNTVOT_REG 0x01
#define INA226_BUSVOT_REG 0x02
#define INA226_POWER_REG 0x03
#define INA226_CURRENT_REG 0x04
#define INA226_CALIBRATION_REG 0x05
#define INA226_DEF_ADDR 0x40
#define INA226_DEF_MODE {0x44, 0x4F}
#define INA226_DEF_CAL {0x0D, 0x1B}
typedef struct
{
uint8 addr;
float max_current_A;
float rshunt_mOhm;
float vot_fix_k;
float amp_fix_k;
uint8 mode[2];
} INA226_Config;
typedef struct
{
float c_lsb_mA;
uint8 cal[2];
} INA226_Calibration;
typedef struct
{
float voltage_V;
float current_A;
float power_W;
float shunt_voltage_mV;
float energy_J;
float quantity_C;
uint8 org_reg[4][2];
float past_voltage_V[10];
float past_current_A[10];
} INA226_Result;
typedef struct
{
INA226_Config config;
INA226_Calibration calibration;
INA226_Result result;
} INA226_t;
extern INA226_t ina226[INA226_NUM];
void INA226_Init(INA226_t *ina226, uint8 addr, uint8 mode[2], float max_current_A, float rshunt_mOhm, float amp_fix_k, float vot_fix_k);
void INA226_Read(INA226_t *ina226);
#endif

9
Header/oled_font.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef __OLED_FONT_H__
#define __OLED_FONT_H__
#include "common.h"
extern const uint8 code oled_6x8[][6];
extern const uint8 code ascii_font_8x16[][16];
#endif

64
Header/oled_iic_SSD1306.h Normal file
View File

@@ -0,0 +1,64 @@
#ifndef __OLED_IIC_SSD1306_H__
#define __OLED_IIC_SSD1306_H__
#include "common.h"
#define OLED_USE_SOFT_IIC 1
#define OLED_ADDR 0x3C
#if (1==OLED_USE_SOFT_IIC)
#define OLED_SDA_PIN P24
#define OLED_SCL_PIN P25
#define OLED_SOFT_WAIT_TIME 0
#define OLED_SDA_LEVEL(x) (OLED_SDA_PIN = x)
#define OLED_SCL_LEVEL(x) (OLED_SCL_PIN = x)
#define OLED_SDA_READ() (OLED_SDA_PIN)
#else
#define OLED_IIC IIC_2
#define OLED_HARD_WAIT_TIME 0
#endif
//定义显示方向
//0 横屏模式
//1 横屏模式 旋转180
#define OLED_DISPLAY_DIR 0
#if (0==OLED_DISPLAY_DIR || 1==OLED_DISPLAY_DIR)
#define X_WIDTH 128
#define Y_WIDTH 64
#else
#error "OLED_DISPLAY_DIR 定义错误"
#endif
#define Brightness 0x7f //设置OLED亮度 越大越亮 范围0-0XFF
#define XLevelL 0x00
#define XLevelH 0x10
#define XLevel ((XLevelH&0x0F)*16+XLevelL)
#define Max_Column 128
#define Max_Row 64
void oled_init(void);
void oled_fill(uint8 dat);
void oled_set_pos(uint8 x, uint8 y);
void oled_putpixel(uint8 x,uint8 y,uint8 data1);
void oled_clrpixel(uint8 x,uint8 y);
void oled_p6x8str(uint8 x,uint8 y,const int8 ch[]);
void oled_uint16(uint8 x, uint8 y, uint16 num);
void oled_int16(uint8 x, uint8 y, int16 num);
void oled_printf_int32(uint16 x,uint16 y,int32 dat,uint8 num);
void oled_printf_float(uint16 x,uint16 y,double dat,uint8 num,uint8 pointnum);
void oled_dis_bmp(uint16 high, uint16 width, uint8 *p,uint8 value);
void oled_print_chinese(uint8 x, uint8 y, uint8 size, const uint8 *p, uint8 len);
#endif

8
Header/printfs.h Normal file
View File

@@ -0,0 +1,8 @@
#ifndef __PRINTFS_H__
#define __PRINTFS_H__
#include "common.h"
uint32 zf_sprintf (int8 *buff, const int8 *format, ...);
#endif

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -15,3 +15,4 @@ SelfDefineBaud=9600
SelfDefineFormat=0
SelfDefineSize=8
SelfDefineCommand=405354434953502339
WaitForHidIsp=1

BIN
STC32_FPMU_LARGE.LIB.remove Normal file

Binary file not shown.

View File

@@ -10,12 +10,45 @@ static IIC_Soft_Config config;
static uint8 has_init = 0;
#if (1==PCA9685_USE_SOFT_IIC)
void pca9685_scl_set()
{
PCA9685_SCL_LEVEL(1);
}
void pca9685_sda_set()
{
PCA9685_SDA_LEVEL(1);
}
void pca9685_sda_clr()
{
PCA9685_SDA_LEVEL(0);
}
void pca9685_scl_clr()
{
PCA9685_SCL_LEVEL(0);
}
uint8 pca9685_sda_read()
{
return PCA9685_SDA_READ();
}
#endif
void pca9685_init()
{
if(has_init) return; // 如果已经初始化过,则直接返回
#if PCA9685_USE_SOFT_IIC == 1
config.scl_pin = PCA9685_SOFT_IIC_SCL_PIN;
config.sda_pin = PCA9685_SOFT_IIC_SDA_PIN;
// config.scl_pin = PCA9685_SOFT_IIC_SCL_PIN;
// config.sda_pin = PCA9685_SOFT_IIC_SDA_PIN;
config.SCL_SET = pca9685_scl_set;
config.SCL_CLR = pca9685_scl_clr;
config.SDA_SET = pca9685_sda_set;
config.SDA_CLR = pca9685_sda_clr;
config.SDA_READ = pca9685_sda_read;
config.wait_time = 10;
soft_iic_init(&config); // 初始化软件IIC
soft_iic_write_reg(&config, PCA9685_I2C_ADDR, PCA9685_MODE1, 0x00); // 设置PCA9685模式寄存器为正常模式

View File

@@ -16,13 +16,6 @@ void iic_delay_us(uint16 x) //33.1776Mhz
}
}
//-------------------------------------------------------------------------------------------------------------------
// @brief 内部使用用户无需关心
// @param NULL
// @return void
// Sample usage: 无需用户调用用户请使用h文件中的宏定义
//-------------------------------------------------------------------------------------------------------------------
uint8 wait(void)
{
uint16 count = 0;
@@ -40,12 +33,6 @@ uint8 wait(void)
return ret;
}
//-------------------------------------------------------------------------------------------------------------------
// @brief 内部使用用户无需关心
// @param NULL
// @return void
// Sample usage: 无需用户调用用户请使用h文件中的宏定义
//-------------------------------------------------------------------------------------------------------------------
uint8 start(void)
{
uint8 ret;
@@ -54,12 +41,6 @@ uint8 start(void)
return ret;
}
//-------------------------------------------------------------------------------------------------------------------
// @brief 内部使用用户无需关心
// @param NULL
// @return void
// Sample usage: 无需用户调用用户请使用h文件中的宏定义
//-------------------------------------------------------------------------------------------------------------------
uint8 send_data(char dat)
{
uint8 ret;
@@ -69,12 +50,6 @@ uint8 send_data(char dat)
return ret;
}
//-------------------------------------------------------------------------------------------------------------------
// @brief 内部使用用户无需关心
// @param NULL
// @return void
// Sample usage: 无需用户调用用户请使用h文件中的宏定义
//-------------------------------------------------------------------------------------------------------------------
uint8 recv_ack(void)
{
uint8 ret;
@@ -83,12 +58,6 @@ uint8 recv_ack(void)
return ret;
}
//-------------------------------------------------------------------------------------------------------------------
// @brief 内部使用用户无需关心
// @param NULL
// @return void
// Sample usage: 无需用户调用用户请使用h文件中的宏定义
//-------------------------------------------------------------------------------------------------------------------
char recv_data(void) //接收数据
{
I2CMSCR = 0x04; //发送RECV命令
@@ -96,12 +65,6 @@ char recv_data(void) //接收数据
return I2CRXD;
}
//-------------------------------------------------------------------------------------------------------------------
// @brief 内部使用用户无需关心
// @param NULL
// @return void
// Sample usage: 无需用户调用用户请使用h文件中的宏定义
//-------------------------------------------------------------------------------------------------------------------
uint8 send_ack(void)
{
uint8 ret;
@@ -111,12 +74,6 @@ uint8 send_ack(void)
return ret;
}
//-------------------------------------------------------------------------------------------------------------------
// @brief 内部使用用户无需关心
// @param NULL
// @return void
// Sample usage: 无需用户调用用户请使用h文件中的宏定义
//-------------------------------------------------------------------------------------------------------------------
void send_nak(void)
{
I2CMSST = 0x01; //设置NAK信号
@@ -124,12 +81,6 @@ void send_nak(void)
wait();
}
//-------------------------------------------------------------------------------------------------------------------
// @brief 内部使用用户无需关心
// @param NULL
// @return void
// Sample usage: 无需用户调用用户请使用h文件中的宏定义
//-------------------------------------------------------------------------------------------------------------------
uint8 stop(void)
{
uint8 ret;
@@ -139,6 +90,33 @@ uint8 stop(void)
}
void iic_scan(void)
{
uint8 i;
for(i = 0; i <= 0x7F; i++) { //7位SlaveAddress
uint8 ACK_or_NACK = 0;
start();
printf(".");
send_data((i << 1) | 0); //I2C从地址+写标志
I2CMSCR = 0x03;
while(!(I2CMSST & 0x40));
if(I2CMSST & 0x02) //判断I2CMSST的bit1 MSACKI,读入的ACK信号为低即是ACK,为高为NACK.
ACK_or_NACK = 0; //MSACKI=1=NACK=没有正确收到ACK信号
else
ACK_or_NACK = 1; //MSACKI=0=ACK=正确收到ACK信号
I2CMSST &= ~0x40; //清除中断标志
if(ACK_or_NACK) {
printf("\r\nFound Device Address:0x%02X\r\n", i);
// UART_SendHex(i);
// printf("%02x",i);
} else {
stop();
}
}
}
//#define UNUSED(expr1, expr2) do { if(scl_pin == sda_pin); } while (0)
@@ -213,6 +191,40 @@ uint8 iic_write_reg(uint8 dev_add, uint8 reg, uint8 dat)
return IIC_SEND_OK;
}
//-------------------------------------------------------------------------------------------------------------------
// @brief 写入多个字节数据到I2C设备指定寄存器地址
//-------------------------------------------------------------------------------------------------------------------
uint8 iic_write_reg_bytes(uint8 dev_add, uint8 reg, uint8 *dat, uint8 num)
{
if(start() != IIC_SEND_OK)
return IIC_SEND_FAIL;
if(send_data((dev_add<<1) | 0x00) != IIC_SEND_OK)
return IIC_SEND_FAIL;
if(recv_ack() != IIC_SEND_OK)
return IIC_SEND_FAIL;
if(send_data(reg) != IIC_SEND_OK)
return IIC_SEND_FAIL;
if(recv_ack() != IIC_SEND_OK)
return IIC_SEND_FAIL;
while(num--)
{
if(send_data(*dat) != IIC_SEND_OK)
return IIC_SEND_FAIL;
if(recv_ack() != IIC_SEND_OK)
return IIC_SEND_FAIL;
dat++;
}
// if(recv_ack() != IIC_SEND_OK)
// return IIC_SEND_FAIL;
if(stop() != IIC_SEND_OK)
return IIC_SEND_FAIL;
return IIC_SEND_OK;
}
//-------------------------------------------------------------------------------------------------------------------
// @brief 读取I2C设备指定地址寄存器的数据
// @param iic_n I2C通道号及引脚
@@ -237,8 +249,10 @@ uint8 iic_read_reg(uint8 dev_add, uint8 reg, uint8 *dat)
return IIC_SEND_FAIL;
if(recv_ack() != IIC_SEND_OK)
return IIC_SEND_FAIL;
// if(stop() != IIC_SEND_OK)
// return IIC_SEND_FAIL;
if(start() != IIC_SEND_OK)
return IIC_SEND_FAIL;
// if(start() != IIC_SEND_OK)
// return IIC_SEND_FAIL;
@@ -288,26 +302,38 @@ uint8 iic_read_reg_bytes(uint8 dev_add, uint8 reg
return IIC_SEND_FAIL;
if(recv_ack() != IIC_SEND_OK)
return IIC_SEND_FAIL;
// if(stop() != IIC_SEND_OK)
// return IIC_SEND_FAIL;
if(start() != IIC_SEND_OK)
return IIC_SEND_FAIL;
if(send_data((dev_add<<1) | 0x01) != IIC_SEND_OK)
return IIC_SEND_FAIL;
if(recv_ack() != IIC_SEND_OK)
return IIC_SEND_FAIL;
while(--num)
while(num--)
{
*dat = recv_data(); //读取数据
if(send_ack() != IIC_SEND_OK)
{
return IIC_SEND_FAIL;
}
dat++;
if(num==0)
{
send_nak();
}
else
{
if(send_ack() != IIC_SEND_OK)
{
return IIC_SEND_FAIL;
}
dat++;
}
}
*dat = recv_data();
// *dat = recv_data();
if(send_ack() != IIC_SEND_OK)
return IIC_SEND_FAIL;
// if(send_ack() != IIC_SEND_OK)
// return IIC_SEND_FAIL;
if(stop() != IIC_SEND_OK)
return IIC_SEND_FAIL;

View File

@@ -15,45 +15,45 @@ void soft_iic_delay(uint16 delay_time)
void soft_iic_init(IIC_Soft_Config *config)
{
// 设置SCL和SDA引脚为推挽输出模式
gpio_mode(config->scl_pin, GPIO);
gpio_mode(config->sda_pin, GPIO);
// gpio_mode(config->scl_pin, GPIO);
// gpio_mode(config->sda_pin, GPIO);
// 初始化SCL和SDA引脚为高电平
gpio_set_level(config->scl_pin, 1);
gpio_set_level(config->sda_pin, 1);
config->SCL_SET();
config->SDA_SET();
}
void soft_iic_start(IIC_Soft_Config *config)
{
gpio_set_level(config->sda_pin, 0); // SDA拉低
config->SDA_CLR(); // SDA拉低
soft_iic_delay(config->wait_time); // 等待一段时间
gpio_set_level(config->scl_pin, 0); // SCL拉低
config->SCL_CLR(); // SCL拉低
soft_iic_delay(config->wait_time); // 等待一段时间
}
void soft_iic_stop(IIC_Soft_Config *config)
{
gpio_set_level(config->sda_pin, 0); // SDA拉低
config->SDA_CLR(); // SDA拉低
soft_iic_delay(config->wait_time); // 等待一段时间
gpio_set_level(config->scl_pin, 1); // SCL拉高
config->SCL_SET(); // SCL拉高
soft_iic_delay(config->wait_time); // 等待一段时间
gpio_set_level(config->sda_pin, 1); // SDA拉高
config->SDA_SET(); // SDA拉高
soft_iic_delay(config->wait_time); // 等待一段时间
}
uint8 soft_iic_read(IIC_Soft_Config *config)
{
uint8 dat = 0,i;
gpio_set_level(config->sda_pin, 1); // 设置SDA为输入模式
config->SDA_SET(); // 设置SDA为输入模式
for (i = 0; i < 8; i++)
{
gpio_set_level(config->scl_pin, 1); // SCL拉高
config->SCL_SET(); // SCL拉高
soft_iic_delay(config->wait_time); // 等待一段时间
if (gpio_get_level(config->sda_pin)) // 读取SDA的状态
if (config->SDA_READ()) // 读取SDA的状态
{
dat |= (1 << (7 - i)); // 将读取的位存入dat
}
gpio_set_level(config->scl_pin, 0); // SCL拉低
config->SCL_CLR(); // SCL拉低
soft_iic_delay(config->wait_time); // 等待一段时间
}
return dat;
@@ -62,58 +62,113 @@ uint8 soft_iic_read(IIC_Soft_Config *config)
void soft_iic_write(IIC_Soft_Config *config, uint8 dat)
{
uint8 i;
gpio_set_level(config->sda_pin, 0); // 设置SDA为输出模式
config->SDA_CLR(); // 设置SDA为输出模式
for (i = 0; i < 8; i++)
{
soft_iic_delay(config->wait_time); // 等待一段时间
if (dat & (1 << (7 - i))) // 检查当前位
{
gpio_set_level(config->sda_pin, 1); // 写入1
config->SDA_SET(); // 写入1
}
else
{
gpio_set_level(config->sda_pin, 0); // 写入0
config->SDA_CLR(); // 写入0
}
gpio_set_level(config->scl_pin, 1); // SCL拉高
config->SCL_SET(); // SCL拉高
soft_iic_delay(config->wait_time); // 等待一段时间
gpio_set_level(config->scl_pin, 0); // SCL拉低
config->SCL_CLR(); // SCL拉低
}
soft_iic_delay(config->wait_time); // 等待一段时间
}
uint8 soft_iic_ack(IIC_Soft_Config *config)
uint8 soft_iic_rev_ack(IIC_Soft_Config *config)
{
gpio_set_level(config->sda_pin, 0); // 发送ACK
uint8 err_count = 0;
config->SDA_SET(); // 发送
soft_iic_delay(config->wait_time); // 等待一段时间
gpio_set_level(config->scl_pin, 1); // SCL拉高
config->SCL_SET(); // SCL拉高
soft_iic_delay(config->wait_time); // 等待一段时间
gpio_set_level(config->scl_pin, 0); // SCL拉低
while(config->SDA_READ() == 1)
{
err_count++;
if(err_count > 30)
{
return 0; // 返回ACK失败
}
soft_iic_delay(config->wait_time); // 等待一段时间
}
config->SCL_CLR(); // SCL拉低
soft_iic_delay(config->wait_time); // 等待一段时间
return 0; // 返回ACK成功
return 1;
}
void soft_iic_scan(IIC_Soft_Config *config)
{
uint8 i;
for(i = 0; i <= 0x7F; i++) { //7位SlaveAddress
uint8 ACK_or_NACK = 0;
soft_iic_start(config);
printf(".");
soft_iic_write(config,(i << 1) | 0); //I2C从地址+写标志
if(soft_iic_rev_ack(config) ) {
printf("\r\nFound Device Address:0x%02X\r\n", i);
// UART_SendHex(i);
// printf("%02x",i);
} else {
soft_iic_stop(config);
}
}
}
void soft_iic_nack(IIC_Soft_Config *config)
{
gpio_set_level(config->sda_pin, 1); // 发送NACK
config->SDA_SET(); // 发送NACK
soft_iic_delay(config->wait_time); // 等待一段时间
gpio_set_level(config->scl_pin, 1); // SCL拉高
config->SCL_SET(); // SCL拉高
soft_iic_delay(config->wait_time); // 等待一段时间
gpio_set_level(config->scl_pin, 0); // SCL拉低
config->SCL_CLR(); // SCL拉低
soft_iic_delay(config->wait_time); // 等待一段时间
}
void soft_iic_ack(IIC_Soft_Config *config)
{
config->SDA_CLR(); // 发送ACK
soft_iic_delay(config->wait_time); // 等待一段时间
config->SCL_SET(); // SCL拉高
soft_iic_delay(config->wait_time); // 等待一段时间
config->SCL_CLR(); // SCL拉低
soft_iic_delay(config->wait_time); // 等待一段时间
}
void soft_iic_write_reg(IIC_Soft_Config *config, uint8 dev_addr, uint8 reg, uint8 dat)
{
soft_iic_start(config); // 发送起始信号
soft_iic_write(config, (dev_addr << 1) | 0); // 发送设备地址和写命令
soft_iic_ack(config); // 等待ACK
soft_iic_rev_ack(config); // 等待ACK
soft_iic_write(config, reg); // 发送寄存器地址
soft_iic_ack(config); // 等待ACK
soft_iic_rev_ack(config); // 等待ACK
soft_iic_write(config, dat); // 发送数据
soft_iic_ack(config); // 等待ACK
soft_iic_rev_ack(config); // 等待ACK
soft_iic_stop(config); // 发送停止信号
}
void soft_iic_write_reg_bytes(IIC_Soft_Config *config, uint8 dev_addr, uint8 reg, uint8 *dat, uint8 len)
{
soft_iic_start(config); // 发送起始信号
soft_iic_write(config, (dev_addr << 1) | 0); // 发送设备地址和写命令
soft_iic_rev_ack(config); // 等待ACK
soft_iic_write(config, reg); // 发送寄存器地址
soft_iic_rev_ack(config); // 等待ACK
while(len--)
{
soft_iic_write(config, *dat); // 发送数据
soft_iic_rev_ack(config); // 等待ACK
dat++;
}
soft_iic_stop(config); // 发送停止信号
}
@@ -121,14 +176,42 @@ uint8 soft_iic_read_reg(IIC_Soft_Config *config, uint8 dev_addr, uint8 reg, uint
{
soft_iic_start(config); // 发送起始信号
soft_iic_write(config, (dev_addr << 1) | 0); // 发送设备地址和写命令
soft_iic_ack(config); // 等待ACK
soft_iic_rev_ack(config); // 等待ACK
soft_iic_write(config, reg); // 发送寄存器地址
soft_iic_ack(config); // 等待ACK
soft_iic_rev_ack(config); // 等待ACK
soft_iic_start(config); // 重新发送起始信号
soft_iic_write(config, (dev_addr << 1) | 1); // 发送设备地址和读命令
soft_iic_ack(config); // 等待ACK
soft_iic_rev_ack(config); // 等待ACK
*dat = soft_iic_read(config); // 读取数据
soft_iic_nack(config); // 发送NACK
soft_iic_stop(config); // 发送停止信号
return *dat; // 返回读取的数据
}
}
uint8 soft_iic_read_reg_bytes(IIC_Soft_Config *config, uint8 dev_addr, uint8 reg, uint8 *buf, uint8 len)
{
soft_iic_start(config); // 发送起始信号
soft_iic_write(config, (dev_addr << 1) | 0); // 发送设备地址和写命令
soft_iic_rev_ack(config); // 等待ACK
soft_iic_write(config, reg); // 发送寄存器地址
soft_iic_rev_ack(config); // 等待ACK
soft_iic_start(config); // 重新发送起始信号
soft_iic_write(config, (dev_addr << 1) | 1); // 发送设备地址和读命令
soft_iic_rev_ack(config); // 等待ACK
while(len--)
{
*buf = soft_iic_read(config); // 读取数据
if(len==0)
{
soft_iic_nack(config); // 发送NACK
}
else
{
soft_iic_ack(config); // 发送ACK
buf++;
}
}
soft_iic_stop(config); // 发送停止信号
return *buf; // 返回成功
}

123
Source/ina226.c Normal file
View File

@@ -0,0 +1,123 @@
#include "ina226.h"
static uint8 is_iic_init = 0;
INA226_t ina226[INA226_NUM];
#if (1==INA226_USE_SOFT_IIC)
#include "iic_soft.h"
static IIC_Soft_Config ina226_soft_config;
void ina226_scl_set()
{
INA226_SCL_LEVEL(1);
}
void ina226_sda_set()
{
INA226_SDA_LEVEL(1);
}
void ina226_sda_clr()
{
INA226_SDA_LEVEL(0);
}
void ina226_scl_clr()
{
INA226_SCL_LEVEL(0);
}
uint8 ina226_sda_read()
{
return INA226_SDA_READ();
}
#else
#include "iic.h"
#endif
void INA226_Init(INA226_t *ina226, uint8 addr, uint8 mode[2], float max_current_A, float rshunt_mOhm, float amp_fix_k, float vot_fix_k)
{
float cal;
if(!is_iic_init)
{
#if (1==INA226_USE_SOFT_IIC)
ina226_soft_config.SCL_SET = ina226_scl_set;
ina226_soft_config.SCL_CLR = ina226_scl_clr;
ina226_soft_config.SDA_SET = ina226_sda_set;
ina226_soft_config.SDA_CLR = ina226_sda_clr;
ina226_soft_config.SDA_READ = ina226_sda_read;
ina226_soft_config.wait_time = INA226_SOFT_WAIT_TIME;
soft_iic_init(&ina226_soft_config);
#else
iic_init(INA226_IIC, INA226_HARD_WAIT_TIME);
#endif
is_iic_init = 1;
}
ina226->config.addr = addr;
ina226->config.mode[0] = mode[0];
ina226->config.mode[1] = mode[1];
ina226->config.max_current_A = max_current_A;
ina226->config.rshunt_mOhm = rshunt_mOhm;
ina226->config.vot_fix_k = vot_fix_k;
ina226->config.amp_fix_k = amp_fix_k;
ina226->calibration.c_lsb_mA = max_current_A / 65.535f; // Current LSB
cal = (5120.0f) / (ina226->calibration.c_lsb_mA * ina226->config.rshunt_mOhm) * ina226->config.amp_fix_k;
ina226->calibration.cal[0] = (uint8)((uint16)cal >> 8);
ina226->calibration.cal[1] = (uint8)((uint16)cal & 0xFF);
memset(&ina226->result, 0, sizeof(ina226->result));
#if (1==INA226_USE_SOFT_IIC)
soft_iic_write_reg_bytes(&ina226_soft_config, ina226->config.addr, INA226_CONFIG_REG, ina226->config.mode, 2);
soft_iic_write_reg_bytes(&ina226_soft_config, ina226->config.addr, INA226_CALIBRATION_REG, ina226->calibration.cal, 2);
#else
iic_write_reg_bytes(ina226->config.addr, INA226_CONFIG_REG, ina226->config.mode, 2);
iic_write_reg_bytes(ina226->config.addr, INA226_CALIBRATION_REG, ina226->calibration.cal, 2);
#endif
}
void INA226_Read(INA226_t *ina226)
{
uint8 counter;
if(!is_iic_init) return;
// Read voltage, current, power, and shunt voltage registers
#if (1==INA226_USE_SOFT_IIC)
soft_iic_read_reg_bytes(&ina226_soft_config, ina226->config.addr, INA226_BUSVOT_REG, ina226->result.org_reg[1],2);
soft_iic_read_reg_bytes(&ina226_soft_config, ina226->config.addr, INA226_CURRENT_REG, ina226->result.org_reg[3],2);
soft_iic_read_reg_bytes(&ina226_soft_config, ina226->config.addr, INA226_POWER_REG, ina226->result.org_reg[2],2);
soft_iic_read_reg_bytes(&ina226_soft_config, ina226->config.addr, INA226_SHUNTVOT_REG, ina226->result.org_reg[0],2);
#else
iic_read_reg_bytes(ina226->config.addr, INA226_BUSVOT_REG, ina226->result.org_reg[1],2);
iic_read_reg_bytes(ina226->config.addr, INA226_CURRENT_REG, ina226->result.org_reg[3],2);
iic_read_reg_bytes(ina226->config.addr, INA226_POWER_REG, ina226->result.org_reg[2],2);
iic_read_reg_bytes(ina226->config.addr, INA226_SHUNTVOT_REG, ina226->result.org_reg[0],2);
#endif
ina226->result.voltage_V = (int16)((ina226->result.org_reg[1][0] << 8) | ina226->result.org_reg[1][1]) * 0.00125f;
ina226->result.current_A = (int16)((ina226->result.org_reg[3][0] << 8) | ina226->result.org_reg[3][1]) * ina226->calibration.c_lsb_mA * 0.001f;
ina226->result.power_W = (int16)((ina226->result.org_reg[2][0] << 8) | ina226->result.org_reg[2][1]) * ina226->calibration.c_lsb_mA * 0.025f;
ina226->result.shunt_voltage_mV = (int16)((ina226->result.org_reg[0][0] << 8) | ina226->result.org_reg[0][1]) * 0.0025f;
ina226->result.voltage_V = ina226->result.voltage_V > 0 ? ina226->result.voltage_V : 0;
ina226->result.current_A = ina226->result.current_A > 0 ? ina226->result.current_A : 0;
ina226->result.power_W = ina226->result.power_W > 0.016 && ina226->result.current_A > 0 && ina226->result.voltage_V > 0 ? ina226->result.power_W : 0;
ina226->result.shunt_voltage_mV = ina226->result.shunt_voltage_mV > 0 ? ina226->result.shunt_voltage_mV : 0;
for(counter = 0; counter < 9; counter++)
{
ina226->result.past_voltage_V[counter] = ina226->result.past_voltage_V[counter+1];
ina226->result.past_current_A[counter] = ina226->result.past_current_A[counter+1];
}
ina226->result.past_voltage_V[9] = ina226->result.voltage_V;
ina226->result.past_current_A[9] = ina226->result.current_A;
ina226->result.energy_J += (ina226->result.past_voltage_V[9] * ina226->result.past_current_A[9] + ina226->result.past_voltage_V[8] * ina226->result.past_current_A[8]) * (INA226_READ_TIME_MS / 2000.0f);
ina226->result.quantity_C += (ina226->result.past_current_A[9] + ina226->result.past_current_A[8]) * (INA226_READ_TIME_MS / 2000.0f);
}

View File

@@ -1,6 +1,6 @@
#include "isr.h"
#include "command.h"
#include "ina226.h"
//UART1中断
void UART1_Isr() interrupt 4
@@ -112,7 +112,8 @@ void TM0_Isr() interrupt 1
}
void TM1_Isr() interrupt 3
{
INA226_Read(&ina226[0]);
P07 ^= 0x01;
}
void TM2_Isr() interrupt 12
{

View File

@@ -1,18 +1,90 @@
#include "common.h"
#include "delay.h"
#include "oled_iic_SSD1306.h"
#include "ina226.h"
#include "tim.h"
#include "iic.h"
#include "iic_soft.h"
#include "printfs.h"
#include "pwm.h"
uint8 mode[2] = INA226_DEF_MODE;
// uint8 m5[2] = {0x0D, 0x1B};
// int8 s_buff[30];
// uint8 ttt = 0;
// extern IIC_Soft_Config ina226_soft_config;
void main()
{
board_init(); // 初始化板子
delay_ms(1000);
printf("System Init...\r\n");
// delay_ms(1000);
// printf("System Init...\r\n");
P05 = 0;
oled_init();
INA226_Init(&ina226[0], INA226_DEF_ADDR, mode, 20, 5, 1.0683, 1.002393);
pit_timer_ms(TIM_1,INA226_READ_TIME_MS);
pwm_init(PWMA_CH1P_P60,100000,5000);
// oled_fill(0xff);
// iic_init(IIC_1,10);
// ttt += iic_write_reg_bytes(0x40, 0x00, mode, 2);
// ttt += iic_write_reg_bytes(0x40, 0x05, m5, 2);
// // printf("ttt: %d",ttt);
P06 = 0;
// iic_scan();
while(1)
{
delay_ms(1000);
printf("System Running...\r\n");
// soft_iic_scan(&ina226_soft_config);
// uint8 vot[2] = {0};
// uint8 cru[2] = {0};
// uint8 pow[2] = {0};
// int16 vott, crut, powt;
// float votf, cruf, powf;
// // // iic_scan();
// iic_read_reg_bytes(0x40, 0x02, vot, 2);
// iic_read_reg_bytes(0x40, 0x04, cru, 2);
// iic_read_reg_bytes(0x40, 0x03, pow, 2);
// zf_sprintf(s_buff, "VOT: %d,%d\r\n", 45, 1234);
// // printf("%s", s_buff);
// // printf("VOT: %d,%d\r\n", (int32)(vot[0] << 8 | vot[1]), 1234);
// vott = (int16)(vot[0] << 8 | vot[1]);
// votf = (float)vott * 1.25 /1000.0f;
// crut = (int16)(cru[0] << 8 | cru[1]);
// cruf = (float)crut * 0.30518 /1000.0f;
// powt = (int16)(pow[0] << 8 | pow[1]);
// powf = (float)powt * 0.30518*25 /1000.0f;
oled_printf_float(0, 0, ina226[0].result.voltage_V,2,4);oled_p6x8str(55, 0, "V");
oled_printf_float(0, 1, ina226[0].result.current_A,2,4);oled_p6x8str(55, 1, "A");
oled_printf_float(0, 2, ina226[0].result.power_W,2,4);oled_p6x8str(55, 2, "W");
oled_printf_float(0, 3, ina226[0].result.energy_J,5,2);oled_p6x8str(55, 3, "J");
oled_printf_float(0, 4, ina226[0].result.energy_J/3600.0f,5,3);oled_p6x8str(55, 4, "Wh");
oled_printf_float(0, 5, ina226[0].result.quantity_C,5,2);oled_p6x8str(55, 5, "C");
// // oled_int16(0, 0, (int16)(vot[0] << 8 | vot[1]));
// oled_int16(0, 1, vot[0]);
// oled_int16(40, 1, vot[1]);
// oled_int16(80, 1, ttt);
// oled_int16(0, 2, -12345);
// oled_printf_float(0, 0, 45.6,2,4);oled_p6x8str(55, 0, "V");
// oled_p6x8str(0,3,s_buff);
// // printf("System Running...\r\n");
// // USB_SendData("wewe",4);
P53 ^= 0x01;
// if(P53)
// {
// oled_fill(0xff);
// }
// else
// {
// oled_fill(0x00);
// }
// delay_ms(1000);
}
}
}

223
Source/oled_font.c Normal file
View File

@@ -0,0 +1,223 @@
#include "oled_font.h"
const uint8 code ascii_font_8x16[][16]=
{
// <阴码> <列行式> <逆向> <8*16>
// <纵向 8bit 为一个数据模型> <横向取模>
// 字模数据储存格式为:{byte1, byte2,....byte16}
// 字模数据与像素对应关系
// byte 1 2 3 4 5 6 7 8
// bit [ 0] [ 8] [ 16] [ 24] [ 32] [ 40] [ 48] [ 56]
// bit [ 1] [ 9] [ 17] [ 25] [ 33] [ 41] [ 49] [ 57]
// bit [ 2] [ 10] [ 18] [ 26] [ 34] [ 42] [ 50] [ 58]
// bit [ 3] [ 11] [ 19] [ 37] [ 35] [ 43] [ 51] [ 59]
// bit [ 4] [ 12] [ 20] [ 38] [ 36] [ 44] [ 52] [ 60]
// bit [ 5] [ 13] [ 21] [ 39] [ 37] [ 45] [ 53] [ 61]
// bit [ 6] [ 14] [ 22] [ 30] [ 38] [ 46] [ 54] [ 62]
// bit [ 7] [ 15] [ 23] [ 31] [ 39] [ 47] [ 55] [ 63]
// byte 9 10 11 12 13 14 15 16
// bit [ 64] [ 72] [ 80] [ 88] [ 96] [104] [112] [120]
// bit [ 65] [ 73] [ 81] [ 89] [ 97] [105] [113] [121]
// bit [ 66] [ 74] [ 82] [ 90] [ 98] [106] [114] [122]
// bit [ 67] [ 75] [ 83] [ 91] [ 99] [107] [115] [123]
// bit [ 68] [ 76] [ 84] [ 92] [100] [108] [116] [124]
// bit [ 69] [ 77] [ 85] [ 93] [101] [109] [117] [125]
// bit [ 70] [ 78] [ 86] [ 94] [102] [110] [118] [126]
// bit [ 71] [ 79] [ 87] [ 95] [103] [111] [119] [127]
{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
{0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00}, // # 3
{0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00}, // $ 4
{0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00}, // % 5
{0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10}, // & 6
{0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // ' 7
{0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00}, // ( 8
{0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00}, // ) 9
{0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00}, // * 10
{0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00}, // + 11
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00}, // , 12
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, // - 13
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00}, // . 14
{0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00}, // / 15
{0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00}, // 0 16
{0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00}, // 1 17
{0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00}, // 2 18
{0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00}, // 3 19
{0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00}, // 4 20
{0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00}, // 5 21
{0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00}, // 6 22
{0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00}, // 7 23
{0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00}, // 8 24
{0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00}, // 9 25
{0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00}, // : 26
{0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00}, // ; 27
{0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00}, // < 28
{0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00}, // = 29
{0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00}, // > 30
{0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00}, // ? 31
{0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00}, // @ 32
{0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20}, // A 33
{0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00}, // B 34
{0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00}, // C 35
{0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00}, // D 36
{0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00}, // E 37
{0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00}, // F 38
{0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00}, // G 39
{0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20}, // H 40
{0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00}, // I 41
{0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00}, // J 42
{0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00}, // K 43
{0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00}, // L 44
{0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00}, // M 45
{0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00}, // N 46
{0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00}, // O 47
{0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00}, // P 48
{0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00}, // Q 49
{0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20}, // R 50
{0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00}, // S 51
{0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00}, // T 52
{0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00}, // U 53
{0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00}, // V 54
{0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00}, // W 55
{0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20}, // X 56
{0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00}, // Y 57
{0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00}, // Z 58
{0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00}, // [ 59
{0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00}, // \ 60
{0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00}, // ] 61
{0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // ^ 62
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80}, // _ 63
{0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // ` 64
{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20}, // a 65
{0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00}, // b 66
{0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00}, // c 67
{0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20}, // d 68
{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00}, // e 69
{0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00}, // f 70
{0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00}, // g 71
{0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20}, // h 72
{0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00}, // i 73
{0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00}, // j 74
{0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00}, // k 75
{0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00}, // l 76
{0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F}, // m 77
{0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20}, // n 78
{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00}, // o 79
{0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00}, // p 80
{0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80}, // q 81
{0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00}, // r 82
{0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00}, // s 83
{0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00}, // t 84
{0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20}, // u 85
{0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00}, // v 86
{0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00}, // w 87
{0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00}, // x 88
{0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00}, // y 89
{0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00}, // z 90
{0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40}, // { 91
{0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00}, // | 92
{0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00}, // } 93
{0x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00} // ~ 94
};
const uint8 code oled_6x8[][6] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, // sp
{ 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00 }, // !
{ 0x00, 0x00, 0x07, 0x00, 0x07, 0x00 }, // "
{ 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14 }, // #
{ 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12 }, // $
{ 0x00, 0x62, 0x64, 0x08, 0x13, 0x23 }, // %
{ 0x00, 0x36, 0x49, 0x55, 0x22, 0x50 }, // &
{ 0x00, 0x00, 0x05, 0x03, 0x00, 0x00 }, // '
{ 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00 }, // (
{ 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00 }, // )
{ 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14 }, // *
{ 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08 }, // +
{ 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00 }, // ,
{ 0x00, 0x08, 0x08, 0x08, 0x08, 0x08 }, // -
{ 0x00, 0x00, 0x60, 0x60, 0x00, 0x00 }, // .
{ 0x00, 0x20, 0x10, 0x08, 0x04, 0x02 }, // /
{ 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E }, // 0
{ 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00 }, // 1
{ 0x00, 0x42, 0x61, 0x51, 0x49, 0x46 }, // 2
{ 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31 }, // 3
{ 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10 }, // 4
{ 0x00, 0x27, 0x45, 0x45, 0x45, 0x39 }, // 5
{ 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30 }, // 6
{ 0x00, 0x01, 0x71, 0x09, 0x05, 0x03 }, // 7
{ 0x00, 0x36, 0x49, 0x49, 0x49, 0x36 }, // 8
{ 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E }, // 9
{ 0x00, 0x00, 0x36, 0x36, 0x00, 0x00 }, // :
{ 0x00, 0x00, 0x56, 0x36, 0x00, 0x00 }, // ;
{ 0x00, 0x08, 0x14, 0x22, 0x41, 0x00 }, // <
{ 0x00, 0x14, 0x14, 0x14, 0x14, 0x14 }, // =
{ 0x00, 0x00, 0x41, 0x22, 0x14, 0x08 }, // >
{ 0x00, 0x02, 0x01, 0x51, 0x09, 0x06 }, // ?
{ 0x00, 0x32, 0x49, 0x59, 0x51, 0x3E }, // @
{ 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C }, // A
{ 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36 }, // B
{ 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22 }, // C
{ 0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C }, // D
{ 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41 }, // E
{ 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01 }, // F
{ 0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A }, // G
{ 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F }, // H
{ 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00 }, // I
{ 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01 }, // J
{ 0x00, 0x7F, 0x08, 0x14, 0x22, 0x41 }, // K
{ 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40 }, // L
{ 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F }, // M
{ 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F }, // N
{ 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E }, // O
{ 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06 }, // P
{ 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E }, // Q
{ 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46 }, // R
{ 0x00, 0x46, 0x49, 0x49, 0x49, 0x31 }, // S
{ 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01 }, // T
{ 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F }, // U
{ 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F }, // V
{ 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F }, // W
{ 0x00, 0x63, 0x14, 0x08, 0x14, 0x63 }, // X
{ 0x00, 0x07, 0x08, 0x70, 0x08, 0x07 }, // Y
{ 0x00, 0x61, 0x51, 0x49, 0x45, 0x43 }, // Z
{ 0x00, 0x00, 0x7F, 0x41, 0x41, 0x00 }, // [
{ 0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55 }, // 55
{ 0x00, 0x00, 0x41, 0x41, 0x7F, 0x00 }, // ]
{ 0x00, 0x04, 0x02, 0x01, 0x02, 0x04 }, // ^
{ 0x00, 0x40, 0x40, 0x40, 0x40, 0x40 }, // _
{ 0x00, 0x00, 0x01, 0x02, 0x04, 0x00 }, // '
{ 0x00, 0x20, 0x54, 0x54, 0x54, 0x78 }, // a
{ 0x00, 0x7F, 0x48, 0x44, 0x44, 0x38 }, // b
{ 0x00, 0x38, 0x44, 0x44, 0x44, 0x20 }, // c
{ 0x00, 0x38, 0x44, 0x44, 0x48, 0x7F }, // d
{ 0x00, 0x38, 0x54, 0x54, 0x54, 0x18 }, // e
{ 0x00, 0x08, 0x7E, 0x09, 0x01, 0x02 }, // f
{ 0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C }, // g
{ 0x00, 0x7F, 0x08, 0x04, 0x04, 0x78 }, // h
{ 0x00, 0x00, 0x44, 0x7D, 0x40, 0x00 }, // i
{ 0x00, 0x40, 0x80, 0x84, 0x7D, 0x00 }, // j
{ 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00 }, // k
{ 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00 }, // l
{ 0x00, 0x7C, 0x04, 0x18, 0x04, 0x78 }, // m
{ 0x00, 0x7C, 0x08, 0x04, 0x04, 0x78 }, // n
{ 0x00, 0x38, 0x44, 0x44, 0x44, 0x38 }, // o
{ 0x00, 0xFC, 0x24, 0x24, 0x24, 0x18 }, // p
{ 0x00, 0x18, 0x24, 0x24, 0x18, 0xFC }, // q
{ 0x00, 0x7C, 0x08, 0x04, 0x04, 0x08 }, // r
{ 0x00, 0x48, 0x54, 0x54, 0x54, 0x20 }, // s
{ 0x00, 0x04, 0x3F, 0x44, 0x40, 0x20 }, // t
{ 0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C }, // u
{ 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C }, // v
{ 0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C }, // w
{ 0x00, 0x44, 0x28, 0x10, 0x28, 0x44 }, // x
{ 0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C }, // y
{ 0x00, 0x44, 0x64, 0x54, 0x4C, 0x44 }, // z
{ 0x14, 0x14, 0x14, 0x14, 0x14, 0x14 } // horiz lines
};

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++;
}
}
}
}

241
Source/printfs.c Normal file
View File

@@ -0,0 +1,241 @@
#include "printfs.h"
#include <stdarg.h>
#include <string.h>
uint8 number_conversion_ascii(uint32 dat, int8 *p, uint8 neg_type, uint8 radix)
{
int32 neg_dat;
uint32 pos_dat;
uint8 temp_data = 0;
uint8 valid_num = 0;
if(neg_type)
{
neg_dat = (int32)dat;
if(neg_dat<0) neg_dat = -neg_dat;
while(1)
{
*p = neg_dat%radix + '0';
neg_dat = neg_dat/radix;
valid_num++;
if(!neg_dat) break;
p++;
}
}
else
{
pos_dat = dat;
while(1)
{
temp_data = pos_dat%radix;
if(10 <= temp_data) temp_data += 'A'-10;
else temp_data += '0';
*p = temp_data;
pos_dat = pos_dat/radix;
valid_num++;
if(!pos_dat) break;
p++;
}
}
return valid_num;
}
void printf_reverse_order(int8 *d_buff, uint32 len)
{
uint32 i;
int8 temp_data;
for(i=0;i<len/2;i++)
{
temp_data = d_buff[len-1-i];
d_buff[len-1-i] = d_buff[i];
d_buff[i] = temp_data;
}
}
uint32 zf_sprintf(char *buff, const int8 *format, ...)
{
uint32 buff_len=0;
va_list arg;
va_start(arg, format);
while (*format)
{
int8 ret = *format;
if (ret == '%')
{
switch (*++format)
{
case 'a':// 十六进制p计数法输出浮点数 暂未实现
{
}break;
case 'c':// 一个字符
{
int8 ch = (int8)va_arg(arg, uint32);
*buff = ch;
buff++;
buff_len++;
}break;
case 'd':
case 'i':// 有符号十进制整数
{
int8 vstr[33];
int32 ival = (int32)va_arg(arg, int32);
uint8 vlen = number_conversion_ascii((uint32)ival, vstr, 1, 10);
if(ival<0)
{
vstr[vlen] = '-';
vlen++;
}
printf_reverse_order(vstr,vlen);
memcpy(buff,vstr,vlen);
buff += vlen;
buff_len += vlen;
}break;
case 'f':// 浮点数,输出小数点后六位 不能指定输出精度
case 'F':// 浮点数,输出小数点后六位 不能指定输出精度
{
int8 vstr[33];
double ival = (double)va_arg(arg, double);
uint8 vlen = number_conversion_ascii((uint32)(int32)ival, vstr, 1, 10);
if(ival<0)
{
vstr[vlen] = '-';
vlen++;
}
printf_reverse_order(vstr,vlen);
memcpy(buff,vstr,vlen);
buff += vlen;
buff_len += vlen;
ival = ((double)ival - (int32)ival)*1000000;
if(ival)
{
vlen = number_conversion_ascii((uint32)(int32)ival, vstr, 1, 10);
}
else
{
vstr[0] = vstr[1] = vstr[2] = vstr[3] = vstr[4] = vstr[5] = '0';
vlen = 6;
}
while(6>vlen)
{
vstr[vlen] = '0';
vlen++;
}
vstr[vlen] = '.';
vlen++;
printf_reverse_order(vstr,vlen);
memcpy(buff,vstr,vlen);
buff += vlen;
buff_len += vlen;
break;
}
case 'u':// 无符号十进制整数
{
int8 vstr[33];
uint32 ival = (uint32)va_arg(arg, uint32);
uint8 vlen = number_conversion_ascii(ival, vstr, 0, 10);
printf_reverse_order(vstr,vlen);
memcpy(buff,vstr,vlen);
buff += vlen;
buff_len += vlen;
}break;
case 'o':// 无符号八进制整数
{
int8 vstr[33];
uint32 ival = (uint32)va_arg(arg, uint32);
uint8 vlen = number_conversion_ascii(ival, vstr, 0, 8);
printf_reverse_order(vstr,vlen);
memcpy(buff,vstr,vlen);
buff += vlen;
buff_len += vlen;
}break;
case 'x':// 无符号十六进制整数
case 'X':// 无符号十六进制整数
{
int8 vstr[33];
uint32 ival = (uint32)va_arg(arg, uint32);
uint8 vlen = number_conversion_ascii(ival, vstr, 0, 16);
printf_reverse_order(vstr,vlen);
memcpy(buff,vstr,vlen);
buff += vlen;
buff_len += vlen;
}break;
case 's':// 字符串
{
int8 *pc = va_arg(arg, int8 *);
while (*pc)
{
*buff = *pc;
buff++;
buff_len++;
pc++;
}
}break;
case 'p':// 以16进制形式输出指针
{
int8 vstr[33];
uint32 ival = (uint32)va_arg(arg, uint32);
//uint8 vlen = number_conversion_ascii(ival, vstr, 0, 16);
number_conversion_ascii(ival, vstr, 0, 16);
printf_reverse_order(vstr,8);
memcpy(buff,vstr,8);
buff += 8;
buff_len += 8;
}break;
case '%':// 输出字符%
{
*buff = '%';
buff++;
buff_len++;
}break;
default:break;
}
}
else
{
*buff = (int8)(*format);
buff++;
buff_len++;
}
format++;
}
va_end(arg);
return buff_len;
}

View File

@@ -379,6 +379,54 @@
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>18</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\Source\oled_iic_SSD1306.c</PathWithFileName>
<FilenameWithoutPath>oled_iic_SSD1306.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>19</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\Source\oled_font.c</PathWithFileName>
<FilenameWithoutPath>oled_font.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>20</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\Source\printfs.c</PathWithFileName>
<FilenameWithoutPath>printfs.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>1</GroupNumber>
<FileNumber>21</FileNumber>
<FileType>1</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\Source\ina226.c</PathWithFileName>
<FilenameWithoutPath>ina226.c</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
<Group>
@@ -389,7 +437,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>18</FileNumber>
<FileNumber>22</FileNumber>
<FileType>0</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -401,7 +449,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>19</FileNumber>
<FileNumber>23</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -413,7 +461,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>20</FileNumber>
<FileNumber>24</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -425,7 +473,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>21</FileNumber>
<FileNumber>25</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -437,7 +485,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>22</FileNumber>
<FileNumber>26</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -449,7 +497,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>23</FileNumber>
<FileNumber>27</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -461,7 +509,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>24</FileNumber>
<FileNumber>28</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -473,7 +521,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>25</FileNumber>
<FileNumber>29</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -485,7 +533,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>26</FileNumber>
<FileNumber>30</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -497,7 +545,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>27</FileNumber>
<FileNumber>31</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -509,7 +557,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>28</FileNumber>
<FileNumber>32</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -521,7 +569,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>29</FileNumber>
<FileNumber>33</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -533,7 +581,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>30</FileNumber>
<FileNumber>34</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -545,7 +593,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>31</FileNumber>
<FileNumber>35</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -557,7 +605,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>32</FileNumber>
<FileNumber>36</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -569,7 +617,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>33</FileNumber>
<FileNumber>37</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -581,7 +629,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>34</FileNumber>
<FileNumber>38</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -593,7 +641,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>35</FileNumber>
<FileNumber>39</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -605,7 +653,7 @@
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>36</FileNumber>
<FileNumber>40</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
@@ -615,6 +663,54 @@
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>41</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\Header\oled_iic_SSD1306.h</PathWithFileName>
<FilenameWithoutPath>oled_iic_SSD1306.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>42</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\Header\oled_font.h</PathWithFileName>
<FilenameWithoutPath>oled_font.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>43</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\Header\printfs.h</PathWithFileName>
<FilenameWithoutPath>printfs.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
<File>
<GroupNumber>2</GroupNumber>
<FileNumber>44</FileNumber>
<FileType>5</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>
<bDave2>0</bDave2>
<PathWithFileName>.\Header\ina226.h</PathWithFileName>
<FilenameWithoutPath>ina226.h</FilenameWithoutPath>
<RteFlg>0</RteFlg>
<bShared>0</bShared>
</File>
</Group>
<Group>
@@ -625,7 +721,7 @@
<RteFlg>0</RteFlg>
<File>
<GroupNumber>3</GroupNumber>
<FileNumber>37</FileNumber>
<FileNumber>45</FileNumber>
<FileType>4</FileType>
<tvExp>0</tvExp>
<tvExpOptDlg>0</tvExpOptDlg>

View File

@@ -409,6 +409,26 @@
<FileType>1</FileType>
<FilePath>.\Source\stc32_stc8_usb.c</FilePath>
</File>
<File>
<FileName>oled_iic_SSD1306.c</FileName>
<FileType>1</FileType>
<FilePath>.\Source\oled_iic_SSD1306.c</FilePath>
</File>
<File>
<FileName>oled_font.c</FileName>
<FileType>1</FileType>
<FilePath>.\Source\oled_font.c</FilePath>
</File>
<File>
<FileName>printfs.c</FileName>
<FileType>1</FileType>
<FilePath>.\Source\printfs.c</FilePath>
</File>
<File>
<FileName>ina226.c</FileName>
<FileType>1</FileType>
<FilePath>.\Source\ina226.c</FilePath>
</File>
</Files>
</Group>
<Group>
@@ -509,6 +529,26 @@
<FileType>5</FileType>
<FilePath>.\Header\stc32_stc8_usb.h</FilePath>
</File>
<File>
<FileName>oled_iic_SSD1306.h</FileName>
<FileType>5</FileType>
<FilePath>.\Header\oled_iic_SSD1306.h</FilePath>
</File>
<File>
<FileName>oled_font.h</FileName>
<FileType>5</FileType>
<FilePath>.\Header\oled_font.h</FilePath>
</File>
<File>
<FileName>printfs.h</FileName>
<FileType>5</FileType>
<FilePath>.\Header\printfs.h</FilePath>
</File>
<File>
<FileName>ina226.h</FileName>
<FileType>5</FileType>
<FilePath>.\Header\ina226.h</FilePath>
</File>
</Files>
</Group>
<Group>