首先我是借鉴TM1650数码管驱动芯片-CSDN博客的,感谢作者的分享,我就是移植了一下
tm1650.c
#include "tm1650.h"
#include "tm1650_config.h"
/* 往一个指定的数码管位写入指定的显示数据 */
/* 共阴数码管段码表 */
/* 此处不知道是不是数码管接错了 现在的变化示例:1 0000 0110 6、7位 2、3位分别反过来后交换位置 *?
/* 这个地方如果数码管接对了直接用通用的数就行 */
const uint8_t TUBE_TABLE_0[16] = {0xf3,0x82,0x5b,0xcb,0xaa,0xe9,0xf9,0x83,0xfb,0xeb,0xbb,0xf8,0x71,0xda,0x79,0x39}; //共阴,0~9~A~F
//产生IIC总线起始信号
static void TM1650_IIC_start(void)
{
TM1650_IIC_SCL_HIGH; //SCL=1
TM1650_IIC_SDA_HIGH; //SDA=1
TM1650_IIC_DELAY_4US;
TM1650_IIC_SDA_LOW; //SDA=0
TM1650_IIC_DELAY_4US;
TM1650_IIC_SCL_LOW; //SCL=0
}
//产生IIC总线结束信号
static void TM1650_IIC_stop(void)
{
TM1650_IIC_SCL_LOW; //SCL=0
TM1650_IIC_SDA_LOW; //SDA=0
TM1650_IIC_DELAY_4US;
TM1650_IIC_SCL_HIGH; //SCL=1
TM1650_IIC_DELAY_4US;
TM1650_IIC_SDA_HIGH; //SDA=1
}
//通过IIC总线发送一个字节
static void TM1650_IIC_write_byte(uint8_t dat)
{
uint8_t i;
TM1650_IIC_SCL_LOW;
for(i=0;i<8;i++)
{
TM1650_IIC_SDA_WR(dat&0x80);
dat<<=1;
TM1650_IIC_DELAY_2US;
TM1650_IIC_SCL_HIGH;
TM1650_IIC_DELAY_2US;
TM1650_IIC_SCL_LOW;
TM1650_IIC_DELAY_2US;
}
}
//通过IIC总线接收从机响应的ACK信号
static uint8_t TM1650_IIC_wait_ack(void)
{
uint8_t ack_signal = 0;
TM1650_IIC_SDA_HIGH; //SDA=1
TM1650_IIC_DELAY_2US;
TM1650_IIC_SCL_HIGH;
TM1650_IIC_DELAY_2US;
if(TM1650_IIC_SDA_RD()) ack_signal = 1; //濡傛灉璇诲彇鍒扮殑鏄疦ACK淇″彿
TM1650_IIC_SCL_LOW;
TM1650_IIC_DELAY_2US;
printf("ack_signal = %d\n", ack_signal);
return ack_signal;
}
//TM1650初始化
void TM1650_init(void)
{
GPIO_Config_T gpioConfig;
RCM_EnableAHBPeriphClock(TM1650_IIC_SCL_CLK);
/* TM1650_IIC_SCL GPIO configuration */
gpioConfig.pin = TM1650_IIC_SCL_PIN;
gpioConfig.mode = GPIO_MODE_OUT;
gpioConfig.outtype = GPIO_OUT_TYPE_PP;
gpioConfig.speed = GPIO_SPEED_50MHz;
gpioConfig.pupd = GPIO_PUPD_NO;
GPIO_Config(TM1650_IIC_SCL_PORT, &gpioConfig);
/* TM1650_IIC_SCL GPIO configuration */
gpioConfig.pin = TM1650_IIC_SDA_PIN;
GPIO_Config(TM1650_IIC_SDA_PORT, &gpioConfig);
TM1650_IIC_SDA_HIGH; //释放SDA线
TM1650_IIC_SCL_HIGH; //释放SCL线
TM1650_cfg_display(TM1650_BRIGHT1);
TM1650_clear();
}
//作用:设置显示参数
//备注:这个操作不影响显存中的数据
//用例:
// 设置亮度并打开显示:TM1650_cfg_display(TM1650_BRIGHTx)
// 关闭显示:TM1650_cfg_display(TM1650_DSP_OFF)
void TM1650_cfg_display(uint8_t param)
{
TM1650_IIC_start();
TM1650_IIC_write_byte(0x48); //固定命令
TM1650_IIC_wait_ack();
TM1650_IIC_write_byte(param); //参数值
TM1650_IIC_wait_ack();
TM1650_IIC_stop();
}
//将显存数据全部刷为0,清空显示
void TM1650_clear(void)
{
uint8_t dig;
for(dig = TM1650_DIG1 ; dig<= TM1650_DIG4 ;dig++)
{
TM1650_print(dig,TUBE_TABLE_0[1]); //将显存数据刷为0
}
}
//用例:
// 在DIG1位上显示数字3: TM1650_print(TM1650_DIG1,TUBE_TABLE_0[3]);
void TM1650_print(uint8_t dig,uint8_t seg_data)
{
TM1650_IIC_start();
TM1650_IIC_write_byte(dig*2+0x68);
TM1650_IIC_wait_ack(); //显存起始地址为0x68
TM1650_IIC_write_byte(seg_data);
TM1650_IIC_wait_ack(); //发送段码
TM1650_IIC_stop();
}
tm1650.h
#ifndef TM1650_H_
#define TM1650_H_
#include "stdint.h"
#include "apm32f0xx_rcm.h"
#include "apm32f0xx_gpio.h"
#include "uart_debug.h"
//显示参数
#define TM1650_BRIGHT1 0x11 /*一级亮度,打开LED显示*/
#define TM1650_BRIGHT2 0x21 /*二级亮度,打开LED显示*/
#define TM1650_BRIGHT3 0x31 /*三级亮度,打开LED显示*/
#define TM1650_BRIGHT4 0x41 /*四级亮度,打开LED显示*/
#define TM1650_BRIGHT5 0x51 /*五级亮度,打开LED显示*/
#define TM1650_BRIGHT6 0x61 /*六级亮度,打开LED显示*/
#define TM1650_BRIGHT7 0x71 /*七级亮度,打开LED显示*/
#define TM1650_BRIGHT8 0x01 /*八级亮度,打开LED显示*/
#define TM1650_DSP_OFF 0x00 /*关闭LED显示*/
//数码管位选
#define TM1650_DIG1 0
#define TM1650_DIG2 1
#define TM1650_DIG3 2
#define TM1650_DIG4 3
extern const uint8_t TUBE_TABLE_0[16];
void TM1650_init(void);
void TM1650_cfg_display(uint8_t param);
void TM1650_clear(void);
void TM1650_print(uint8_t dig,uint8_t seg_data);
#endif //TM1650_H_
tm1650_config.h
#ifndef TM1650_CONFIG_H_
#define TM1650_CONFIG_H_
#include "tm1650.h"
//==========【配置IIC驱动引脚】========
#define TM1650_IIC_SCL_PIN GPIO_PIN_8
#define TM1650_IIC_SCL_PORT GPIOB
#define TM1650_IIC_SCL_CLK RCM_AHB_PERIPH_GPIOB
#define TM1650_IIC_SDA_PIN GPIO_PIN_9
#define TM1650_IIC_SDA_PORT GPIOB
#define TM1650_IIC_SDA_CLK RCM_AHB_PERIPH_GPIOB
//=====================================
//========【配置IIC总线的信号读写和时序】=======
//主机拉高SCL
#define TM1650_IIC_SCL_HIGH GPIO_SetBit(TM1650_IIC_SCL_PORT,TM1650_IIC_SCL_PIN)
//主机拉低SCL
#define TM1650_IIC_SCL_LOW GPIO_ClearBit(TM1650_IIC_SCL_PORT,TM1650_IIC_SCL_PIN)
//主机拉高SDA
#define TM1650_IIC_SDA_HIGH GPIO_SetBit(TM1650_IIC_SDA_PORT,TM1650_IIC_SDA_PIN)
//主机拉低SDA
#define TM1650_IIC_SDA_LOW GPIO_ClearBit(TM1650_IIC_SDA_PORT,TM1650_IIC_SDA_PIN)
//参数b为0时主机拉低SDA,非0则拉高SDA
#define TM1650_IIC_SDA_WR(b) do{ \
if(b) GPIO_SetBit(TM1650_IIC_SDA_PORT,TM1650_IIC_SDA_PIN); \
else GPIO_ClearBit(TM1650_IIC_SDA_PORT,TM1650_IIC_SDA_PIN); \
}while(0)
//主机读取SDA线电平状态,返回值为0为低电平,非0则为高电平
#define TM1650_IIC_SDA_RD() GPIO_ReadInputBit(TM1650_IIC_SDA_PORT,TM1650_IIC_SDA_PIN)
//软件延时2us
#define TM1650_IIC_DELAY_2US do{for(int ii_=0;ii_<50;ii_++);}while(0)
//软件延时4us
#define TM1650_IIC_DELAY_4US do{for(int ii_=0;ii_<90;ii_++);}while(0)
//================================
#endif //TM1650_CONFIG_H_