ch455官方提供的示例代码是51单片机的io模拟iic,地址如下:
但是处于效率原因,还是希望使用单片机本身的硬件IIC来与ch455通信。
首先我们先了解ch455时序

STM32CubeMX部分配置

下面是ch455的驱动,这里我使用的是三位数码管,所以代码主要数据是三位数码管的代码。
Core\Inc\ch455.h
/**
******************************************************************************
* @file : ch455.h
* @brief : Header for ch455.c file.
* CH455 Seven-Segment Display Driver
******************************************************************************
*/
#ifndef __CH455_H
#define __CH455_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes */
#include "main.h"
// 设置系统参数命令
#define CH455_BIT_ENABLE 0x01 // 开启/关闭位
#define CH455_BIT_SLEEP 0x04 // 睡眠控制位
#define CH455_BIT_7SEG 0x08 // 7段控制位
#define CH455_BIT_INTENS1 0x10 // 1级亮度
#define CH455_BIT_INTENS2 0x20 // 2级亮度
#define CH455_BIT_INTENS3 0x30 // 3级亮度
#define CH455_BIT_INTENS4 0x40 // 4级亮度
#define CH455_BIT_INTENS5 0x50 // 5级亮度
#define CH455_BIT_INTENS6 0x60 // 6级亮度
#define CH455_BIT_INTENS7 0x70 // 7级亮度
#define CH455_BIT_INTENS8 0x00 // 8级亮度
#define CH455_BIT_KOFF 0x80 // 关闭键盘
#define CH455_SYSCMD 0x4800 // 操作命令,需另加8位数据
// 加载字数据命令
#define CH455_DIG0 0x6800 // 数码管位0显示,需另加8位数据
#define CH455_DIG1 0x6A00 // 数码管位1显示,需另加8位数据
#define CH455_DIG2 0x6C00 // 数码管位2显示,需另加8位数据
#define CH455_DIG3 0x6E00 // 数码管位3显示,需另加8位数据
#define BCD_decode_DP 0x0080
#define BCD_decode_NG 0x0040
/* Seven-Segment Display Character Macros */
#define CH455_CHAR_0 0x00
#define CH455_CHAR_1 0x01
#define CH455_CHAR_2 0x02
#define CH455_CHAR_3 0x03
#define CH455_CHAR_4 0x04
#define CH455_CHAR_5 0x05
#define CH455_CHAR_6 0x06
#define CH455_CHAR_7 0x07
#define CH455_CHAR_8 0x08
#define CH455_CHAR_9 0x09
#define CH455_CHAR_A 0x0A
#define CH455_CHAR_B 0x0B
#define CH455_CHAR_C 0x0C
#define CH455_CHAR_D 0x0D
#define CH455_CHAR_E 0x0E
#define CH455_CHAR_F 0x0F
#define CH455_CHAR_G 0x10
#define CH455_CHAR_H 0x11
#define CH455_CHAR_I 0x12
#define CH455_CHAR_J 0x13
#define CH455_CHAR_K 0x14
#define CH455_CHAR_L 0x15
#define CH455_CHAR_M 0x16
#define CH455_CHAR_N 0x17
#define CH455_CHAR_O 0x18
#define CH455_CHAR_P 0x19
#define CH455_CHAR_Q 0x1A
#define CH455_CHAR_R 0x1B
#define CH455_CHAR_S 0x1C
#define CH455_CHAR_T 0x1D
#define CH455_CHAR_U 0x1E
#define CH455_CHAR_V 0x1F
#define CH455_CHAR_W 0x20
#define CH455_CHAR_X 0x21
#define CH455_CHAR_Y 0x22
#define CH455_CHAR_Z 0x23
#define CH455_CHAR_SPACE 0x24
#define CH455_CHAR_DASH 0x25
/* Exported functions prototypes */
void CH455G_Init(uint8_t intens);
void CH455G_SetDigit(uint8_t position, uint8_t value);
void CH455G_SetDigits(uint8_t d0, uint8_t d1, uint8_t d2);
void CH455G_SetNumber(uint16_t number);
void CH455G_SetAllSegments(void);
void CH455G_SetRaw(uint8_t position, uint8_t data);
#ifdef __cplusplus
}
#endif
#endif /* __CH455_H */
Core\Src\ch455.c
/**
******************************************************************************
* @file : ch455.c
* @brief : CH455 Seven-Segment Display Driver
* Common Cathode 3-Digit Display
* DIG0=Left, DIG1=Middle, DIG2=Right
* SEG0=A, SEG1=B, SEG2=C, SEG3=D, SEG4=E, SEG5=F, SEG6=DP
******************************************************************************
*/
#include "ch455.h"
#include "main.h"
#include "i2c.h"
/* Common Cathode 7-Segment Display Code Table */
/* Segments: A=SEG0, B=SEG1, C=SEG2, D=SEG3, E=SEG4, F=SEG5, G=SEG6, DP=SEG7 */
static const uint8_t ch455_seg_code[] = {
0x3F, /* 0: A+B+C+D+E+F */
0x06, /* 1: B+C */
0x5B, /* 2: A+B+G+E+D */
0x4F, /* 3: A+B+G+C+D */
0x66, /* 4: F+G+B+C */
0x6D, /* 5: A+F+G+C+D */
0x7D, /* 6: A+F+G+C+D+E */
0x07, /* 7: A+B+C */
0x7F, /* 8: All segments (A-G) */
0x6F, /* 9: A+B+C+D+F+G */
0x77, /* A: A+B+C+E+F+G */
0x7C, /* b: F+G+C+D+E */
0x39, /* C: A+D+E+F */
0x5E, /* d: B+C+D+E+G */
0x79, /* E: A+D+E+F+G */
0x71, /* F: A+E+F+G */
0x3D, /* G: A+B+C+D+E+F */
0x76, /* H: B+C+E+F+G */
0x06, /* I: B+C (same as 1) */
0x1F, /* J: A+B+C+D+G */
0x76, /* K: Same as H */
0x38, /* L: A+D+E+F */
0x55, /* M: A+B+C+E+G (double-height) */
0x74, /* N: A+B+C+E+F+G */
0x3F, /* O: A+B+C+D+E+F (same as 0) */
0x73, /* P: A+B+C+E+F+G */
0x67, /* Q: A+B+C+D+F+G */
0x50, /* R: A+E+F+G */
0x6D, /* S: Same as 5 */
0x78, /* T: E+F+G */
0x3E, /* U: A+B+C+D+E */
0x1C, /* V: A+B+C+D+E (slant) */
0x3E, /* W: Same as U */
0x6E, /* X: Same as H */
0x6F, /* Y: A+B+C+D+F+G (same as 9) */
0x5B, /* Z: Same as 2 */
0x00, /* Space */
0x40, /* - (Dash) */
};
/**
* @brief Write command to CH455
* @param cmd: Command byte
* @retval HAL status
*/
static HAL_StatusTypeDef CH455G_Write(uint16_t cmd)
{
uint8_t data1 = 0;
uint8_t data2 = 0;
data1 = (uint8_t)(cmd >> 8);
data2 = (uint8_t)(cmd & 0x00ff);
return HAL_I2C_Master_Transmit(&hi2c1, data1, &data2, 1, 1000);
// __NOP();
}
/**
* @brief Initialize CH455
* @param intens: CH455_BIT_INTENS1-8
* @retval None
*/
void CH455G_Init(uint8_t intens)
{
if ((intens != CH455_BIT_INTENS1) && (intens != CH455_BIT_INTENS2) && (intens != CH455_BIT_INTENS3) &&
(intens != CH455_BIT_INTENS4) && (intens != CH455_BIT_INTENS5) && (intens != CH455_BIT_INTENS6) &&
(intens != CH455_BIT_INTENS7) && (intens != CH455_BIT_INTENS8)) {
CH455G_Write(CH455_SYSCMD | CH455_BIT_ENABLE | CH455_BIT_INTENS4);
} else {
CH455G_Write(CH455_SYSCMD | CH455_BIT_ENABLE | intens);
}
/* Clear all digits */
CH455G_SetDigits(CH455_CHAR_SPACE, CH455_CHAR_SPACE, CH455_CHAR_SPACE);
}
/**
* @brief Set a single digit
* @param position: 0=Left, 1=Middle, 2=Right
* @param value: 0-15=0-F, 16=Space, 17=Dash
* @retval None
*/
void CH455G_SetDigit(uint8_t position, uint8_t value)
{
if (position > 2) return;
if (value > sizeof(ch455_seg_code) - 1) value = CH455_CHAR_SPACE; /* Default to space */
switch (position)
{
case 0:
/* Leftmost digit */
CH455G_Write(CH455_DIG0 | ch455_seg_code[value]);
break;
case 1:
/* Middle digit */
CH455G_Write(CH455_DIG1 | ch455_seg_code[value]);
break;
case 2:
/* Rightmost digit */
CH455G_Write(CH455_DIG2 | ch455_seg_code[value]);
break;
default:
break;
}
}
/**
* @brief Set all three digits at once
* @param d0: Left digit (0-17)
* @param d1: Middle digit (0-17)
* @param d2: Right digit (0-17)
* @retval None
*/
void CH455G_SetDigits(uint8_t d0, uint8_t d1, uint8_t d2)
{
CH455G_SetDigit(0, d0);
CH455G_SetDigit(1, d1);
CH455G_SetDigit(2, d2);
}
/**
* @brief Display a number (0-999)
* @param number: Number to display (0-999)
* @retval None
*/
void CH455G_SetNumber(uint16_t number)
{
if (number > 999) number = 999;
uint8_t d0 = (number / 100) % 10; /* Hundreds */
uint8_t d1 = (number / 10) % 10; /* Tens */
uint8_t d2 = number % 10; /* Ones */
CH455G_SetDigits(d0, d1, d2);
}
/**
* @brief Turn on all segments of all digits (test mode)
* @param None
* @retval None
*/
void CH455G_SetAllSegments(void)
{
/* 0x7F = All segments + decimal point */
CH455G_Write(CH455_DIG0 | 0xFF);
CH455G_Write(CH455_DIG1 | 0xFF);
CH455G_Write(CH455_DIG2 | 0xFF);
}
/**
* @brief Set raw segment data directly
* @param position: 0=Left, 1=Middle, 2=Right
* @param data: 8-bit raw segment data (bit7=DP, bit6=G, bit5=F, bit4=E, bit3=D, bit2=C, bit1=B, bit0=A)
* @retval None
*/
void CH455G_SetRaw(uint8_t position, uint8_t data)
{
if (position > 2) return;
switch (position)
{
case 0:
CH455G_Write(CH455_DIG0 | data);
break;
case 1:
CH455G_Write(CH455_DIG1 | data);
break;
case 2:
CH455G_Write(CH455_DIG2 | data);
break;
default:
break;
}
}
使用方法距离如下
CH455G_SetRaw(0, 0x20);
CH455G_SetNumber(123);
CH455G_SetDigits(CH455_CHAR_SPACE, CH455_CHAR_SPACE, CH455_CHAR_SPACE);
这个ch455并不是标准的iic器件,所以没有iic地址,使用的是命令码+数据的方式通信。