STM32-HAL库-TM650数码管显示

这里写自定义目录标题

#ifndef __MAIN_H
#define __MAIN_H

unsigned char  SEG_CODE[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,
                               0x38,0x30,0x76,0x74,0x3E,0x1C,0x37,0x54,0x73,0x73,0x1E,0x1E,0x3F,0x5C,0x6D,0x6D,
                               0x6E,0x6E,0x00,0x40,0x77,0x7C,0x39,0x5E,0x79,0x71};   //段码表,与下面支持显示的字符一一对应
unsigned char char_tab[]={"0123456789ABCDEFLlHhUuNnPpJjOoSsYy -abcdef"};        //支持显示的字符集合,与上面段码必须一一对应

#endif


#include "./BSP/IIC/myiic.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/main.h"
/**
 * @brief       初始化IIC
 * @param       无
 * @retval      无
 */
void iic1_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;

    IIC1_SCL_GPIO_CLK_ENABLE();      /* SCL引脚时钟使能 */
    IIC1_SDA_GPIO_CLK_ENABLE();      /* SDA引脚时钟使能 */

    gpio_init_struct.Pin = IIC1_SCL_GPIO_PIN;
    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_OD;        /* 推挽输出 */
    gpio_init_struct.Pull = GPIO_PULLUP;                /* 上拉 */
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_HIGH;      /* 高速 */
    HAL_GPIO_Init(IIC1_SCL_GPIO_PORT, &gpio_init_struct);/* SCL */

    gpio_init_struct.Pin = IIC1_SDA_GPIO_PIN;
    gpio_init_struct.Mode = GPIO_MODE_OUTPUT_OD;        /* 开漏输出 */
    HAL_GPIO_Init(IIC1_SDA_GPIO_PORT, &gpio_init_struct);/* SDA */
    /* SDA引脚模式设置,开漏输出,上拉, 这样就不用再设置IO方向了, 开漏输出的时候(=1), 也可以读取外部信号的高低电平 */
    iic1_stop();     /* 停止总线上所有设备 */
    TM1650_cfg_display(0x51);   //初始化为5级亮度,打开显示
    Clear();     //将显存内容清0
}


/**
 * @brief       产生IIC起始信号
 * @param       无
 * @retval      无
 */
void iic1_start(void)
{
    IIC1_SCL(1);
    IIC1_SDA(1);     
    delay_us(4);
    IIC1_SDA(0);      /* START信号: 当SCL为高时, SDA从高变成低, 表示起始信号 */
    delay_us(4);
    IIC1_SCL(0);     /* 钳住I2C总线,准备发送或接收数据 */
}

/**
 * @brief       产生IIC停止信号
 * @param       无
 * @retval      无
 */
void iic1_stop(void)
{
    IIC1_SCL(0);
    IIC1_SDA(0);     /* STOP信号: 当SCL为高时, SDA从低变成高, 表示停止信号 */
    delay_us(4);
    IIC1_SCL(1);
    delay_us(4);
    IIC1_SDA(1);     /* 发送I2C总线结束信号 */
}

/**
 * @brief       等待应答信号到来
 * @param       无
 * @retval      1,接收应答失败
 *              0,接收应答成功
 */
uint8_t iic1_wait_ack(void)
{
    uint8_t rack = 0;

    IIC1_SDA(1);     /* 主机释放SDA线(此时外部器件可以拉低SDA线) */
    delay_us(2);
    IIC1_SCL(1);     /* SCL=1, 此时从机可以返回ACK */
    delay_us(2);

    if (IIC1_READ_SDA) rack=1;    /* 等待应答 */
   
    IIC1_SCL(0);     /* SCL=0, 结束ACK检查 */
    delay_us(2);
    return rack;
}



/**
 * @brief       IIC发送一个字节
 * @param       data: 要发送的数据
 * @retval      无
 */
void iic1_send_byte(uint8_t data)     //指定地址写入数据
{
    uint8_t t;
    IIC1_SCL(0);
    for (t = 0; t < 8; t++)
    {
        IIC1_SDA(data & 0x80);    /* 高位先发送 */
        data <<= 1;     /* 左移1位,用于下一次发送 */
     
        delay_us(2);
        IIC1_SCL(1);
        delay_us(2);
        IIC1_SCL(0);
        delay_us(2);
    }
}

void icc1_Write_DATA(unsigned char add,unsigned char DATA) //指定地址写入数据
{
    iic1_start();
    iic1_send_byte(add);
    iic1_wait_ack();
    iic1_send_byte(DATA);
    iic1_wait_ack();
    iic1_stop();
}



//作用:设置显示参数
//备注:这个操作不影响显存中的数据
//用例:
//	设置亮度并打开显示:TM1650_cfg_display(TM1650_BRIGHTx)
//	关闭显示:TM1650_cfg_display(TM1650_DSP_OFF)
void TM1650_cfg_display(uint8_t param)
{
	iic1_start();
	iic1_send_byte(0x48);  iic1_wait_ack();     //固定命令
	iic1_send_byte(param); iic1_wait_ack();    //参数值
	iic1_stop();
}


void Clear(void)
{
    unsigned char i;
    for(i=0;i<4;i++)
    {
        icc1_Write_DATA(0x68+2*i,0);
    }
}

void Disp_Char_Fix(unsigned char add,unsigned char dis_char)   //指定地址显示数据,add代表数码管位置,dis_char为要显示的字符
{
    unsigned char i,point_flag;

    if(add>3) return;
    point_flag=dis_char & point;         //先把小数点分离出来	
    dis_char&=0x7f;
    if(dis_char<0x10)
    {   
        icc1_Write_DATA(0x68+2*add,SEG_CODE[dis_char]|point_flag); //如果是0-F,直接显示
    }
     else
    {
        for(i=0;i<sizeof(char_tab);i++)              //如果是字符,则在支持的字符中查找
        if(char_tab[i]==dis_char)           //找到,则把对应的段码送显示
         icc1_Write_DATA(0x68+2*add,SEG_CODE[i]|point_flag);
     }
}

void display(uint16_t date)
{
    unsigned char i,t;
    for(i=3;i>0;i--)
    {
        t=date%10;
        Disp_Char_Fix(i,t);
        date=(date-t)/10;
    }
}

void Disp_Num(unsigned long Num)	//按十进制显示数字,超出范围直接返回
{
    unsigned char i=0;
    if(Num>9999)return;
    Clear();
    do{Disp_Char_Fix(3-i,Num%10);Num/=10;i++;}while(Num>0);	

}


#ifndef __MYIIC_H
#define __MYIIC_H

#include "./SYSTEM/sys/sys.h"


/******************************************************************************************/
/* 引脚 定义 */

#define IIC1_SCL_GPIO_PORT               GPIOB
#define IIC1_SCL_GPIO_PIN                GPIO_PIN_6
#define IIC1_SCL_GPIO_CLK_ENABLE()       do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)   /* PB口时钟使能 */

#define IIC1_SDA_GPIO_PORT               GPIOB
#define IIC1_SDA_GPIO_PIN                GPIO_PIN_7
#define IIC1_SDA_GPIO_CLK_ENABLE()       do{ __HAL_RCC_GPIOB_CLK_ENABLE(); }while(0)   /* PB口时钟使能 */

/******************************************************************************************/

/* IO操作 */
#define IIC1_SCL(x)        do{ x ? \
                              HAL_GPIO_WritePin(IIC1_SCL_GPIO_PORT, IIC1_SCL_GPIO_PIN, GPIO_PIN_SET) : \
                              HAL_GPIO_WritePin(IIC1_SCL_GPIO_PORT, IIC1_SCL_GPIO_PIN, GPIO_PIN_RESET); \
                          }while(0)       /* SCL */

#define IIC1_SDA(x)        do{ x ? \
                              HAL_GPIO_WritePin(IIC1_SDA_GPIO_PORT, IIC1_SDA_GPIO_PIN, GPIO_PIN_SET) : \
                              HAL_GPIO_WritePin(IIC1_SDA_GPIO_PORT, IIC1_SDA_GPIO_PIN, GPIO_PIN_RESET); \
                          }while(0)       /* SDA */

#define IIC1_READ_SDA     HAL_GPIO_ReadPin(IIC1_SDA_GPIO_PORT, IIC1_SDA_GPIO_PIN) /* 读取SDA */

#define point  0x80	//定义小数点


/* IIC所有操作函数 */
void iic1_init(void);                        /* 初始化IIC1的IO口 */
void iic1_start(void);                       /* 发送IIC1开始信号 */
void iic1_stop(void);                        /* 发送IIC1停止信号 */
uint8_t iic1_wait_ack(void);
void iic1_send_byte(uint8_t data);             //指定地址写入数据
void icc_Write_DATA(unsigned char add,unsigned char DATA);    //指定地址写入数据
void TM1650_cfg_display(uint8_t param);
void Clear(void);                                  //清屏
void Disp_Char_Fix(unsigned char add,unsigned char dis_char);  //指定地址显示数据,add代表数码管位置,dis_char为要显示的字符                        
void display(uint16_t date);
void Disp_Num(unsigned long Num);             //按十进制显示数字,超出范围直接返回

#endif


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用STM32 HAL库实现四段共阳数码管动态显示的代码: ```c #include "main.h" #include "stm32f1xx_hal.h" // 数码管共阳极接口,定义数字0-9的数码管段码 const uint8_t DIGITS[10] = { 0b01111110, // 0 0b00110000, // 1 0b01101101, // 2 0b01111001, // 3 0b00110011, // 4 0b01011011, // 5 0b01011111, // 6 0b01110000, // 7 0b01111111, // 8 0b01111011 // 9 }; // 数码管的引脚定义 #define DIGIT1_Pin GPIO_PIN_0 #define DIGIT1_GPIO_Port GPIOA #define DIGIT2_Pin GPIO_PIN_1 #define DIGIT2_GPIO_Port GPIOA #define DIGIT3_Pin GPIO_PIN_2 #define DIGIT3_GPIO_Port GPIOA #define DIGIT4_Pin GPIO_PIN_3 #define DIGIT4_GPIO_Port GPIOA #define SEG_A_Pin GPIO_PIN_4 #define SEG_A_GPIO_Port GPIOA #define SEG_B_Pin GPIO_PIN_5 #define SEG_B_GPIO_Port GPIOA #define SEG_C_Pin GPIO_PIN_6 #define SEG_C_GPIO_Port GPIOA #define SEG_D_Pin GPIO_PIN_7 #define SEG_D_GPIO_Port GPIOA #define SEG_E_Pin GPIO_PIN_8 #define SEG_E_GPIO_Port GPIOA #define SEG_F_Pin GPIO_PIN_9 #define SEG_F_GPIO_Port GPIOA #define SEG_G_Pin GPIO_PIN_10 #define SEG_G_GPIO_Port GPIOA #define SEG_DP_Pin GPIO_PIN_11 #define SEG_DP_GPIO_Port GPIOA // 数码管显示缓存数组,用于存储要显示的数字 uint8_t display_buffer[4]; // 数码管显示位置,用于控制哪一个数码管显示 uint8_t display_position = 0; // 定时器回调函数,用于驱动数码管动态显示 void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { // 关闭当前数码管 switch (display_position) { case 0: HAL_GPIO_WritePin(DIGIT1_GPIO_Port, DIGIT1_Pin, GPIO_PIN_SET); break; case 1: HAL_GPIO_WritePin(DIGIT2_GPIO_Port, DIGIT2_Pin, GPIO_PIN_SET); break; case 2: HAL_GPIO_WritePin(DIGIT3_GPIO_Port, DIGIT3_Pin, GPIO_PIN_SET); break; case 3: HAL_GPIO_WritePin(DIGIT4_GPIO_Port, DIGIT4_Pin, GPIO_PIN_SET); break; default: break; } // 显示下一个数字 display_position++; if (display_position > 3) { display_position = 0; } switch (display_position) { case 0: HAL_GPIO_WritePin(DIGIT1_GPIO_Port, DIGIT1_Pin, GPIO_PIN_RESET); break; case 1: HAL_GPIO_WritePin(DIGIT2_GPIO_Port, DIGIT2_Pin, GPIO_PIN_RESET); break; case 2: HAL_GPIO_WritePin(DIGIT3_GPIO_Port, DIGIT3_Pin, GPIO_PIN_RESET); break; case 3: HAL_GPIO_WritePin(DIGIT4_GPIO_Port, DIGIT4_Pin, GPIO_PIN_RESET); break; default: break; } // 显示当前数字 uint8_t digit = display_buffer[display_position]; HAL_GPIO_WritePin(SEG_A_GPIO_Port, SEG_A_Pin, (digit & 0x01) ? GPIO_PIN_RESET : GPIO_PIN_SET); HAL_GPIO_WritePin(SEG_B_GPIO_Port, SEG_B_Pin, (digit & 0x02) ? GPIO_PIN_RESET : GPIO_PIN_SET); HAL_GPIO_WritePin(SEG_C_GPIO_Port, SEG_C_Pin, (digit & 0x04) ? GPIO_PIN_RESET : GPIO_PIN_SET); HAL_GPIO_WritePin(SEG_D_GPIO_Port, SEG_D_Pin, (digit & 0x08) ? GPIO_PIN_RESET : GPIO_PIN_SET); HAL_GPIO_WritePin(SEG_E_GPIO_Port, SEG_E_Pin, (digit & 0x10) ? GPIO_PIN_RESET : GPIO_PIN_SET); HAL_GPIO_WritePin(SEG_F_GPIO_Port, SEG_F_Pin, (digit & 0x20) ? GPIO_PIN_RESET : GPIO_PIN_SET); HAL_GPIO_WritePin(SEG_G_GPIO_Port, SEG_G_Pin, (digit & 0x40) ? GPIO_PIN_RESET : GPIO_PIN_SET); HAL_GPIO_WritePin(SEG_DP_GPIO_Port, SEG_DP_Pin, GPIO_PIN_SET); } int main(void) { HAL_Init(); // 初始化GPIO口 GPIO_InitTypeDef GPIO_InitStructure; __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStructure.Pin = DIGIT1_Pin | DIGIT2_Pin | DIGIT3_Pin | DIGIT4_Pin; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.Pin = SEG_A_Pin | SEG_B_Pin | SEG_C_Pin | SEG_D_Pin | SEG_E_Pin | SEG_F_Pin | SEG_G_Pin | SEG_DP_Pin; GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStructure); // 初始化定时器 TIM_HandleTypeDef htim; __HAL_RCC_TIM2_CLK_ENABLE(); htim.Instance = TIM2; htim.Init.Period = 1000; // 定时器周期为1ms htim.Init.Prescaler = 72 - 1; // 定时器预分频系数为72 htim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim.Init.CounterMode = TIM_COUNTERMODE_UP; HAL_TIM_Base_Init(&htim); HAL_TIM_Base_Start_IT(&htim); while (1) { // 更新显示缓存数组 for (uint8_t i = 0; i < 10; i++) { display_buffer[0] = DIGITS[i]; display_buffer[1] = DIGITS[(i + 1) % 10]; display_buffer[2] = DIGITS[(i + 2) % 10]; display_buffer[3] = DIGITS[(i + 3) % 10]; // 延时,调整显示速度 HAL_Delay(500); } } } ``` 以上代码中,首先定义了数码管共阳极接口和数字0-9的数码管段码。然后定义了数码管引脚的宏定义,以及显示缓存数组和当前显示位置的全局变量。在定时器回调函数`HAL_TIM_PeriodElapsedCallback`中,每隔一定时间切换要显示的数码管,并将对应的数字显示在数码管上。在主循环中,通过循环更新显示缓存数组,实现数码管动态显示。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值