找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 282|回复: 0
收起左侧

TM1650驱动数码管的STM32F103单片机程序

[复制链接]
ID:1115064 发表于 2024-4-5 20:14 | 显示全部楼层 |阅读模式
最近用TM1650驱动的数码管做了一个万年历,特地把TM1650的STM32驱动程序分享出来以供大家使用,亲测可以用!!!!
接线:
1.SCL接PB10;
2.SDA接PB11;
源程序如下:
tm1650.c:
  1. #include "stm32f10x.h"
  2. #include "sys_conf.h"
  3. #include <stdio.h>

  4. void DelayXms(unsigned int count)
  5. {
  6.         unsigned int i,j;
  7.          for(i=0; i<count; i++)
  8.          {
  9.                  //WatchDOG();
  10.                   for(j=0; j<7968; j++)
  11.                  {
  12.                          __NOP();
  13.       
  14.                  }
  15.                   
  16.          }         
  17. }


  18. void DelayXus(unsigned int count)
  19. {
  20.         unsigned int i,j;
  21.          for(i=0; i<count; i++)
  22.          {
  23.                   for(j=0; j<8; j++)
  24.                  {
  25.                          __NOP();
  26.                      
  27.                  }
  28.                   
  29.          }         
  30. }
  31. void IIC_Init(void)
  32. {
  33.         GPIO_InitTypeDef GPIO_InitStructure;

  34.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);


  35.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11;
  36.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  37.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  38.         GPIO_Init(GPIOB, &GPIO_InitStructure);   
  39.   
  40.        
  41. }

  42. void SDA_IN(void)
  43. {
  44.         GPIO_InitTypeDef GPIO_InitStructure;       
  45.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);       
  46.         GPIO_InitStructure.GPIO_Pin = IIC_SDA_PIN;
  47.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  48.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  49.         GPIO_Init(IIC_SDA_PORT,&GPIO_InitStructure);
  50. }

  51. void SDA_OUT(void)
  52. {
  53.         GPIO_InitTypeDef GPIO_InitStructure;       
  54.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);       
  55.         GPIO_InitStructure.GPIO_Pin = IIC_SDA_PIN;
  56.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  57.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  58.         GPIO_Init(IIC_SDA_PORT,&GPIO_InitStructure);
  59. }



  60. /***************************************************************************
  61.     - 功能描述:STM32f103 模拟IIC起始信号函数
  62.     - 隶属模块:STM32 IIC操作
  63.         - 函数属性:外部,使用户使用
  64.         - 参数说明:无
  65.         - 返回说明:无
  66.     - 函数实现步骤:
  67.                 (1)首先将SDA配置为输出
  68.                 (2)在SCL为高电平期间,SDA有下降沿的变化
  69. ***************************************************************************/
  70. void IIC_Start(void)
  71. {
  72.         SDA_OUT();     //sda线输出
  73.         Set_IIC_SDA;                    
  74.         Set_IIC_SCL;
  75.         DelayXus(4);
  76.         Clr_IIC_SDA;//START:when CLK is high,DATA change form high to low
  77.         DelayXus(4);
  78.         Clr_IIC_SCL;//钳住I2C总线,准备发送或接收数据
  79. }          
  80. /***************************************************************************
  81.     - 功能描述:STM32f103 模拟IIC终止信号函数
  82.     - 隶属模块:STM32 IIC操作
  83.         - 函数属性:外部,使用户使用
  84.         - 参数说明:无
  85.         - 返回说明:无
  86.     - 函数实现步骤:
  87.                 (1)首先将SDA配置为输出
  88.                 (2)在SCL为高电平期间,SDA有上升沿的变化
  89. ***************************************************************************/
  90. void IIC_Stop(void)
  91. {
  92.         SDA_OUT();//sda线输出
  93.         Clr_IIC_SCL;
  94.         Clr_IIC_SDA;//STOP:when CLK is high DATA change form low to high
  95.         DelayXus(4);
  96.         Set_IIC_SCL;
  97.         Set_IIC_SDA;//发送I2C总线结束信号
  98.         DelayXus(4);                                                                  
  99. }

  100. /***************************************************************************
  101.     - 功能描述:STM32f103 模拟IIC等待应答函数
  102.     - 隶属模块:STM32 IIC操作
  103.         - 函数属性:外部,使用户使用
  104.         - 参数说明:无               
  105.         - 返回说明:返回值:1,接收应答失败;0,接收应答成功
  106.     - 函数说明:
  107.                 (1)首先将SDA配置为输入
  108.                 (2)如果返回0,表示接收应答成功;如果为1,接收应答失败
  109.                 (3)注意在IIC_STOP()中        ,将SDA置为了输出,所以再满足250条件后,产中IIC停止线号,
  110.                          对输出线SDA读SDA输入值是为0的,所以才退出循环。
  111. ***************************************************************************/
  112. u8 IIC_Wait_Ack(void)
  113. {
  114.         u8 ucErrTime=0;
  115.         SDA_IN();      //SDA设置为输入  
  116.         Set_IIC_SDA;
  117.         DelayXus(1);          
  118.         Set_IIC_SCL;
  119.         DelayXus(1);         
  120.         while(READ_SDA)
  121.         {
  122.                 ucErrTime++;
  123.                 if(ucErrTime>250)
  124.                 {
  125.                         IIC_Stop();
  126.                         return 1;
  127.                 }
  128.         }
  129.         Clr_IIC_SCL;//时钟输出0           
  130.         return 0;  
  131. }
  132. /***************************************************************************
  133.     - 功能描述:STM32f103 模拟IIC应答信号函数
  134.     - 隶属模块:STM32 IIC操作
  135.         - 函数属性:外部,使用户使用
  136.         - 参数说明:无
  137.         - 返回说明:无
  138.     - 函数实现步骤:
  139.                 (1)首先将SDA配置为输出
  140.                 (2)在SCL的一个时钟周期期间,SDA为低
  141. ***************************************************************************/
  142. //产生ACK应答
  143. void IIC_Ack(void)
  144. {
  145.         Clr_IIC_SCL;
  146.         SDA_OUT();
  147.         Clr_IIC_SDA;
  148.         DelayXus(2);
  149.         Set_IIC_SCL;
  150.         DelayXus(2);
  151.         Clr_IIC_SCL;
  152. }
  153. /***************************************************************************
  154.     - 功能描述:STM32f103 模拟IIC不应答信号函数
  155.     - 隶属模块:STM32 IIC操作
  156.         - 函数属性:外部,使用户使用
  157.         - 参数说明:无
  158.         - 返回说明:无
  159.     - 函数实现步骤:
  160.                 (1)首先将SDA配置为输出
  161.                 (2)在SCL的一个时钟周期期间,SDA为高电平
  162. ***************************************************************************/            
  163. void IIC_NAck(void)
  164. {
  165.         Clr_IIC_SCL;
  166.         SDA_OUT();
  167.         Set_IIC_SDA;
  168.         DelayXus(2);
  169.         Set_IIC_SCL;
  170.         DelayXus(2);
  171.         Clr_IIC_SCL;
  172. }                                                                              
  173. /***************************************************************************
  174.     - 功能描述:STM32f103 模拟IIC 发送一个字节函数
  175.     - 隶属模块:STM32 IIC操作
  176.         - 函数属性:外部,使用户使用
  177.         - 参数说明:无
  178.         - 返回说明:无
  179.     - 函数实现步骤:
  180.                 (1)首先将SDA配置为输出
  181.                 (2)在SCL为低电平期间,置位SDA的数据为0或者1,延时后拉高SCL,取走数据,循环8次
  182. ***************************************************************************/                  
  183. void IIC_Send_Byte(u8 txd)
  184. {                        
  185.     u8 t;   
  186.           SDA_OUT();             
  187.     Clr_IIC_SCL;//拉低时钟开始数据传输
  188.     for(t=0;t<8;t++)
  189.     {              
  190.         //IIC_SDA=(txd&0x80)>>7;
  191.                 if ((txd&0x80)>>7)        
  192.                         Set_IIC_SDA;
  193.                 else Clr_IIC_SDA;
  194.                 txd<<=1;           
  195.                 DelayXus(2);   //对TEA5767这三个延时都是必须的
  196.                 Set_IIC_SCL;
  197.                 DelayXus(2);
  198.                 Clr_IIC_SCL;       
  199.                 DelayXus(2);
  200.     }         
  201. }

  202. /***************************************************************************
  203.     - 功能描述:STM32f103 模拟IIC 发送一个字节函数
  204.     - 隶属模块:STM32 IIC操作
  205.         - 函数属性:外部,使用户使用
  206.         - 参数说明:ack 用于决定是是否回应ACK
  207.         - 返回说明:无
  208.     - 函数实现步骤:
  209.                 (1)首先将SDA配置为输入
  210.                 (2)在SCL的一个时钟周期后,读SDA的数据,保存在receive中
  211.                 (3)读1个字节,ack=1时,发送ACK,ack=0,发送nACK  

  212. ***************************************************************************/             
  213. u8 IIC_Read_Byte(unsigned char ack)
  214. {
  215.         unsigned char i,receive=0;
  216.         SDA_IN();//SDA设置为输入
  217.             for(i=0;i<8;i++ )
  218.         {
  219.                 Clr_IIC_SCL;
  220.                 DelayXus(2);
  221.                             Set_IIC_SCL;
  222.                 receive<<=1;
  223.                 if(READ_SDA)receive++;   
  224.                         DelayXus(1);
  225.         }                                         
  226.         if (!ack)
  227.                 IIC_NAck();//发送nACK
  228.         else
  229.                 IIC_Ack(); //发送ACK   
  230.         return receive;
  231. }



  232. void TM1650_Set(unsigned char add,unsigned char dat) //数码管显示
  233. {
  234.    
  235.                 IIC_Start();       
  236.                 IIC_Send_Byte(add);       
  237.                 IIC_Ack();
  238.                 IIC_Send_Byte(dat);
  239.                 IIC_Ack();
  240.                 IIC_Stop();
  241. }

  242. void LCD_Init(void)
  243. {
  244.    IIC_Init();
  245.          TM1650_Set(0x48,0x01);  
  246. }
  247.        
  248. void LCD_Display(unsigned char state,unsigned int NUM)
  249. {
  250.   unsigned char CODE[20]  = {0xdd,0x05,0xb9,0xad,0x65,0xec,0xfc,0x85,0xfd,0xed,0xf5,0xfd,0xd8,0xdd,0xf8,0xf0,0x00}; //0~9  dot: +2
  251.                             //  0   1    2    3   4    5    6     7   8    9    A    B    C     D    E    F
  252.   unsigned char CODE1[20]  = {0x00,0x05,0xb9,0xad,0x65,0xec,0xfc,0x85,0xfd,0xed,0xf5,0xfd,0xd8,0xdd,0xf8,0xf0,0x00}; //0~9  dot: +2
  253.        
  254.         TM1650_Set(0x48,0x01);  
  255.         switch(state)
  256.   {
  257.     case led_normal:
  258.           TM1650_Set(0x68,CODE1[NUM/100]);
  259.                                         TM1650_Set(0x6A,CODE[NUM%100/10]+2);
  260.           TM1650_Set(0x6C,CODE[NUM%100%10]);
  261.     break;
  262.     case led_set1:
  263.                             if(timer_count < TIME_500MS)
  264.              TM1650_Set(0x68,CODE[1]+2);
  265.                                         else
  266.                                                  TM1650_Set(0x68,CODE[16]);
  267.                                                  
  268.           TM1650_Set(0x6A,CODE1[NUM/10]);
  269.           TM1650_Set(0x6C,CODE[NUM%10]+2);
  270.     break;
  271.     case led_set2:
  272.           if(timer_count < TIME_500MS)
  273.              TM1650_Set(0x68,CODE[2]+2);
  274.                                         else
  275.                                                  TM1650_Set(0x68,CODE[16]);
  276.           TM1650_Set(0x6A,CODE1[NUM/10]);
  277.           TM1650_Set(0x6C,CODE[NUM%10]+2);
  278.     break;
  279.     case led_error:
  280.           TM1650_Set(0x68,CODE[14]+2);
  281.           TM1650_Set(0x6A,CODE[NUM/10]);
  282.           TM1650_Set(0x6C,CODE[NUM%10]);
  283.     break;
  284.                 case led_no_dis:
  285.           TM1650_Set(0x68,CODE[11]);
  286.           TM1650_Set(0x6A,CODE[11]);
  287.           TM1650_Set(0x6C,CODE[11]);
  288.     break;
  289.     default:
  290.                             TM1650_Set(0x68,CODE1[8]+2);
  291.           TM1650_Set(0x6A,CODE1[8]+2);
  292.           TM1650_Set(0x6C,CODE1[8]+2);
  293.                         break;
  294.   }
  295. }



复制代码

tm1650.h
  1. #ifndef _I2C_H  //宏定义,定义文件名称
  2. #define _I2C_H

  3. /*---------------------------头文件引用--------------------------------------*/
  4. #include "stm32f10x.h"
  5. #include "sys_conf.h"
  6. #include <stdio.h>

  7. #define IIC_SCL_PIN                       GPIO_Pin_10
  8. #define IIC_SCL_PORT                             GPIOB
  9. #define IIC_SCL_CLK                       RCC_APB2Periph_GPIOB

  10. #define IIC_SDA_PIN                       GPIO_Pin_11
  11. #define IIC_SDA_PORT                GPIOB
  12. #define IIC_SDA_CLK                 RCC_APB2Periph_GPIOB  



  13. /*********************************************************
  14.         - I2C宏定义:
  15.         - I2C时钟操作:
  16.     - Set_IIC_SCL: 此处是将SCL拉为高电平
  17.         - Clr_IIC_SCL: 此处是将SCL拉为低电平
  18.         - 说明:通过这两个宏定义就可以模拟IIC的时钟电平SCL的高低变化了                          
  19. *********************************************************/
  20. #define Set_IIC_SCL  GPIO_SetBits(IIC_SCL_PORT,IIC_SCL_PIN)
  21. #define Clr_IIC_SCL  GPIO_ResetBits(IIC_SCL_PORT,IIC_SCL_PIN)


  22. /*********************************************************
  23.         - I2C宏定义:
  24.         - I2C数据线操作:
  25.     - Set_IIC_SDA: 此处是将SDA拉为高电平
  26.         - Clr_IIC_SDA: 此处是将SDA拉为低电平
  27.         - READ_SDA         : 此处是读取SDA线上的位数据
  28.         - 说明:通过这两个宏定义就可以模拟IIC的数据线SDA电平的高低变化了                          
  29. *********************************************************/
  30. #define Set_IIC_SDA  GPIO_SetBits(IIC_SDA_PORT,IIC_SDA_PIN)
  31. #define Clr_IIC_SDA  GPIO_ResetBits(IIC_SDA_PORT,IIC_SDA_PIN)
  32. #define READ_SDA     GPIO_ReadInputDataBit(IIC_SDA_PORT, IIC_SDA_PIN)









  33. /*********************************************************
  34.         - I2C模拟操作函数的声明:          
  35. *********************************************************/
  36. //IIC所有操作函数
  37. void IIC_Init(void);                //初始化IIC的IO口                                 
  38. void IIC_Start(void);                                //发送IIC开始信号
  39. void IIC_Stop(void);                                  //发送IIC停止信号
  40. void IIC_Send_Byte(u8 txd);                        //IIC发送一个字节
  41. u8 IIC_Read_Byte(unsigned char ack);//IIC读取一个字节
  42. u8 IIC_Wait_Ack(void);                                 //IIC等待ACK信号
  43. void IIC_Ack(void);                                        //IIC发送ACK信号
  44. void IIC_NAck(void);                                //IIC不发送ACK信号
  45. void LCD_Init(void);
  46. void SDA_IN(void);
  47. void SDA_OUT(void);
  48. void TM1650_Set(unsigned char add,unsigned char dat);//数码管显示
  49. void LCD_Display(unsigned char state,unsigned int NUM);
  50. #endif
复制代码




回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表