STM32+TM1650(从手册到实现)【模拟I2C】

本文介绍了如何利用I2C协议和单片机的IO口高效管理LED数码管。通过设置Start和Stop信号,以及数据传输,实现对数码管的八级亮度和7/8段显示的控制。在实际操作中,需要注意信号时序和电源稳定性,确保所有LED能正常工作。
摘要由CSDN通过智能技术生成

在一段时间里,我的高中只能看数码管的十几个引脚发愣,觉得点灯是一个非常大且重要的工程之一,到了大学,才后知后觉有一种特殊的芯片可以对引脚进行管理,仅需要两个单片机的IO口就可以进行管理这个庞大的LED组合

目录

一、准备工作

 读图:

二、信号的组成部分

理论上需要供电必须足够,要不就会造成部分能亮起来,一下设置太多的时候就直接全灭了


一、准备工作

在手册中我们去了解是如何做到的通信

 读图:

一、我们可以将CLK线作为“眼睛”,当CLK睁开的时候,SDA的信号才当真

二、信号的组成部分

①Start

②data1

③wait ask

④data2

⑤wait ask

⑥Stop

至此我们已经完成了最基本的一次模拟I2C的基本时序

我们去查接下来的所有需要的东西

 显然我们需要使用模式命令,以及下面组合成八级亮度,7/8段显示以及开启

//开始信号
void Start_I2C()
{
    //先将全部拉高_前提是输出模式
    SDA_OUT_MODE();
    SDA_1();
    CLK_1();//睁开眼

    //拉高两个为start做准备

    SDA_0();//其下降沿就是start信号
    //因为信号建立的速度在ns级别,所以延时1ms就够了
    SDA_0();
    CLK_0();//为下个信号埋伏笔
}
void Stop_I2C()
{
    SDA_OUT_MODE();
    CLK_0();//初始状态闭上眼_免得误会
    SDA_0();

    CLK_1();//睁开眼
    SDA_1();
    CLK_0();//闭上眼,避免误会
    SDA_0();
}

void I2C_SendByte(uint8_t data)
{
    //使用for写将需要输出的数据拆开,对应位设置好后让clk睁开眼
    SDA_OUT_MODE();
    //复位
    CLK_0();
    SDA_0();
    for (int i = 0; i < 8; ++i) {

        //拆_无保留必要
        if((data&128) == 128)
        {
            SDA_1();//拉高
        }
        else
        {
            SDA_0();
        }
        CLK_1();
        CLK_0();
        ///完成一次写入
        //数据更新左移
        data<<=1;
    }
}

void Wait_Ask()
{
    uint8_t timeout =1;//用来计时,等待SDA被拉低
    SDA_IN_MODE();
    //判断是否变成了预计中sda被拉低了,然后再把clk抬高
    //给一段时间
    while(timeout <=10 && HAL_GPIO_ReadPin(SDA_GPIO_Port,SDA_Pin) != 0)
        timeout++;
        CLK_1();//抬高clk
        //printf("we have not recall");
}
void set_tm(uint8_t add,uint8_t data)
{
    //完成一次设

    Start_I2C();
    I2C_SendByte(add);//第一个显存104**
    Wait_Ask();
    I2C_SendByte(data);//128
    Wait_Ask();
    Stop_I2C();

}



void RCCdelay_us(uint32_t udelay)
{
    __IO uint32_t Delay = udelay * 72 / 8;//(SystemCoreClock / 8U / 1000000U)
    //见stm32f1xx_hal_rcc.c -- static void RCC_Delay(uint32_t mdelay)
    do
    {
        __NOP();
    }
    while (Delay --);
}

static void SDA_OUT_MODE()
{
    //重新设置为输出
    GPIO_InitTypeDef SDA;
    SDA.Pin = SDA_Pin;
    SDA.Mode = GPIO_MODE_OUTPUT_PP;
    SDA.Pull = GPIO_PULLUP;
    SDA.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &SDA);

}
static void  SDA_IN_MODE()
{
    //重新设置为输入
    GPIO_InitTypeDef SDA;
    SDA.Pin = SDA_Pin;
    SDA.Mode = GPIO_MODE_INPUT;
    HAL_GPIO_Init(GPIOB, &SDA);
}

 使用宏简便输入

理论上需要供电必须足够,要不就会造成部分能亮起来,一下设置太多的时候就直接全灭了

 

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值