#关于STM32F051C8T6项目总结(二)

关于STM32F051C8T6某项目总述

1. 总述目录

  1. 项目简介
  2. 主控总述
  3. 模块总述
    1. TM1640
    2. R25_F3950
  4. 硬件总述
    1. 差分运放
    2. 电流稳定
    3. 温控开关

3. 模块总结(重点)

​ 模块总结是对功能的解决方法进行总结,要实现单片机某种功能一定是软硬件配合,所以在叙述这段内容一定是先介绍硬件,再说明对应代码。

  1. TM1640

    1. 功能说明

      TM1640是一款电子数码管驱动芯片,当我们需要驱动多个数码管时,就需要外部数码管驱动芯片进行控制。那么TM1640数码管驱动的详细过程是什么样的?在引脚分析中说明。

    2. 引脚分析

      下面是对我们要用到的引脚进行分析,先上两个图:

    在这里插入图片描述
    在这里插入图片描述

    由文档中引脚定义可知DIN和SCLK两个引脚分别是数据输入线和时钟线,根据时序图(如下)可知TM1640芯片数据传输遵守I2C协议(时钟线信号为低电平,数据线信号发生跳变,时钟线信号为高电平,数据线信号不可改变即有效),则DIN和SCLK代表I2C协议的数据线和时钟线。
    在这里插入图片描述

    ​ SEG1-SEG8引脚文档中说此为段输出,何为段?在引脚图上看只能看出它是一个引脚,改引脚所代表的意义就需要看文档中的另一个图,如下:
    在这里插入图片描述

    从图中可看出SEG后面有一个字母(a~g,dp),而数码管的每一条灯管也有一个字母,那么SEG就代表一个一个灯管,具体0和1代表亮灭看电路连接。

    ​ 那GRID1~GRID16引脚代表的是一整个数字的数码管,也就是一组数码管的开关控制。有引脚数量可得TM1640最多可支持16个数码管。

    ​ 至此引脚分析完毕。

    1. 思路解析

      ​ 那么TM1640是怎样对每个数码管进行启动的呢?地址和数据发送时序又是怎样的呢?

      ​ 先来分析TM1640的指令格式:在这里插入图片描述

      指令分为数据指令、地址指令和控制指令三种。

      ​ 数据指令是指TM1640将以怎样的方式加载数据,一共有两种方式,一种是地址自动加一(后文说),另一种是固定地址加载数据。这里所说的地址就是数码管地址(后文说),即地址指令,控制指令值数码管亮度和状态。TM1640在进行通信时首先要求主控要发送一个数据指令用来告诉TM1640用那种方式加载数据。其次要发送一个数码管地址作为数据加载的起始地址,然后根据如下图一和图二分析到底发送多少数据,最后再发送一个控制命令,这便是通讯时序思路。

      接下来是三张图:

      图一:

      在这里插入图片描述

      图二:

      在这里插入图片描述

      图三:

      在这里插入图片描述

      ​ 图一是固定地址时序,图二是写地址自动加一的时序,两者最大的区别在于数据的发送数量。数码管地址就是图三的显存地址。一个显存地址代表对一个数码管的操作。地址自动加一代表对起始地址之后的所有数码管操作。如果使用自动加一模式就需要传多个数据以I2C的end信号结束数据传输阶段。

    2. 代码解析

      接下来是代码解析,首先是配置:

      static I2C_Init_t TM1640_I2C_init          = {
                   .GPIO_Scl_Portx          = GPIOB,
                   .GPIO_Scl_Pinx           = GPIO_Pin_3,
                   .GPIO_Sda_Portx          = GPIOA,
                   .GPIO_Sda_Pinx           = GPIO_Pin_15,
                   .RCC_AHBPeriph_Scl_GPIOx = RCC_AHBPeriph_GPIOB,
                   .RCC_AHBPeriph_Sda_GPIOx = RCC_AHBPeriph_GPIOA
      };
      

      接着是初始化函数:

      void I2C_OutputInit(I2C_Init_t *I2C_t)
      {
      
          GPIO_InitTypeDef GPIO_CFG;
          RCC_AHBPeriphClockCmd(I2C_t->RCC_AHBPeriph_Scl_GPIOx, ENABLE);
          RCC_AHBPeriphClockCmd(I2C_t->RCC_AHBPeriph_Sda_GPIOx, ENABLE);
          // 配置CLK和DATA引脚为输出模式
          GPIO_CFG.GPIO_Pin   = I2C_t->GPIO_Scl_Pinx | I2C_t->GPIO_Sda_Pinx;
          GPIO_CFG.GPIO_Mode  = GPIO_Mode_OUT;
          GPIO_CFG.GPIO_OType = GPIO_OType_PP;
          GPIO_CFG.GPIO_PuPd  = GPIO_PuPd_UP;
      
          GPIO_CFG.GPIO_Speed = GPIO_Speed_Level_3;
          GPIO_Init(I2C_t->GPIO_Scl_Portx, &GPIO_CFG);
          GPIO_Init(I2C_t->GPIO_Sda_Portx, &GPIO_CFG);
      }
      

      然后是头文件指令格式:

      
      // Data Cmd
      #define ADDR_INCR (0x40)
      #define ADDR_SET  (0x41)
      // Display Contrl Cmd
      #define DISPLAY_CMD (0x88)
      // Addr Cmd
      #define ADDR_CMD      (0xC0)
      #define ADDR_WORK_LED (0xC6)
      // 亮度
      #define ON_1_16  (DISPLAY_CMD + 0)
      #define ON_2_16  (DISPLAY_CMD + 1)
      #define ON_4_16  (DISPLAY_CMD + 2)
      #define ON_10_16 (DISPLAY_CMD + 3)
      #define ON_11_16 (DISPLAY_CMD + 4)
      #define ON_12_16 (DISPLAY_CMD + 5)
      #define ON_13_16 (DISPLAY_CMD + 6)
      #define ON_14_16 (DISPLAY_CMD + 7)
      #define OFF      (0x80)
      
      union EightSegmentCode {
          uint8_t uint8_LED;
          struct {
              unsigned char A : 1;
              unsigned char B : 1;
              unsigned char C : 1;
              unsigned char D : 1;
              unsigned char E : 1;
              unsigned char F : 1;
              unsigned char G : 1;
              unsigned char DP : 1;
      
          } Bits;
          struct {
              uint8_t ABCDEFG : 7;
              uint8_t DP : 1;
          } Bits1;
      };
      

      下面是设置两种加载模式:

      void TM1640_SetAddrINC_Mode(void)
      {
          I2C_Start(&TM1640_I2C_init);
          TM1640_SendByte(ADDR_INCR);
          I2C_Stop(&TM1640_I2C_init);
      }
      void TM1640_SetAddrSET_Mode(void)
      {
          I2C_Start(&TM1640_I2C_init);
          TM1640_SendByte(ADDR_SET);
          I2C_Stop(&TM1640_I2C_init);
      }
      

      下面是分别用两种方式发送数据实现:

      void TM1640_Display(uint8_t addr, uint8_t data)
      {
          TM1640_SetAddrSET_Mode();
          I2C_Start(&TM1640_I2C_init);
          TM1640_SendByte(addr);
          TM1640_SendByte(data);
          I2C_Stop(&TM1640_I2C_init);
          TM1640_SetBrightNess(ON_14_16);
      }
      void TM1640_Display_all(uint8_t *data)
      {
          uint8_t i;
          I2C_Start(&TM1640_I2C_init);
          TM1640_SendByte(ADDR_CMD);
          for (i = 0; i < 16; i++) {
              TM1640_SendByte(*data);
              data++;
          }
          I2C_Stop(&TM1640_I2C_init);
          TM1640_SetBrightNess(ON_14_16);
      }
      

      下面是打开自动加一模式全部灯光和关闭全部灯光:

      void TM1640_All_ON(void)
      {
          uint8_t i;
          for (i = 0; i < 16; i++) {
              TM1640_InitCode[i].uint8_LED = 0xFF;
          }
          TM1640_SetAddrINC_Mode();
          TM1640_Display_all((uint8_t*)TM1640_InitCode);
          TM1640_SetBrightNess(ON_14_16);
      }
      void TM1640_All_OFF(void)
      {
          uint8_t i;
          for (i = 0; i < 16; i++) {
              TM1640_InitCode[i].uint8_LED = 0x00;
          }
          TM1640_SetAddrINC_Mode();
          TM1640_Display_all((uint8_t*)TM1640_InitCode);
      }
      

      下面是操作固定模式下的数码管:

      
      void TM1640_Work_Led_ON(void)
      {
          TM1640_Display(ADDR_WORK_LED, TM1640_ADDR_WORKE_ON);
      }
      

      由于工作要求不能发完整工程。以上是对TM1640的使用总结

  2. R25_F3950

  3. 自行转载即可,转载请注明出处
    内容代表个人感悟,不保证正确性
  • 26
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值