基于STM32f103的TM1640驱动共阴极LED数码管程序(地址自动加1 和 固定地址)

  • TM1640的个人理解

首先需要知道TM1640是什么,其功能如何,TM1640 是一种LED(发光二极管显示器)驱动控制专用电路,内部集成有MCU 数字接口、数据锁存器、LED 驱动等电路。本产品性能优良,质量可靠。主要应用于电子产品LED显示屏驱动。采用SOP28的封装形式。

管脚定义:在这就自行省略了,下面要说的才是重点,后面会将在网上下载的中文手册贴到下面。
数据传输:其采用的是两线串行接口SCLKDIN,微处理器的数据通过两线总线接口和 TM1640 通信,在输入数据时当 CLK 是高电平时,DIN 上的信号必须保持不变,只有 CLK 上的时钟信号为低电平时,DIN 上的信号才能改变(可以理解为一个时钟周期发送一个高/低电平)。数据的输入总是低位在前,高位在后传输。在这里加个个人理解,当你想发送一个0x44的指令时,其对应的二进制为0100 0100,那么数据输入的顺序是0010 0010。数据输入的开始条件是 CLK 为高电平时,DIN 由高变低;结束条件是 CLK 为高时,DIN 由低电平变为高电平。开始上图(就是截图过来的),指令数据传输格式:(水印不会去掉,将就着看吧)

由上图可见,当开始一个指令时,CLKDIN都是由高电平转换为低电平的,而且DIN的转换要在CLK之前,结束时CLK先于DIN转换为高电平。由此就可以写出数据传输的起始结束指令了:

void TM1640Start(void)  //起始指令
{   TM1640SLK_HING;delay_us(2);TM1640DAT_HING;    delay_us(2) ;  TM1640DAT_LOW;delay_us(2);
}
void TM1640Stop(void)  //结束指令
{      TM1640SLK_LOW;  delay_us(2);TM1640DAT_LOW;  delay_us(2); TM1640SLK_HING;  delay_us(2);TM1640DAT_HING;
}


如上表所示:这是一个数据命令设置表,在这里只提地址自加和固定地址的模式;如下图所示,
地址自动加1
Command1是设置数据的,就是通过传输上表中的数据来设置芯片工作模式;即 0x40 为地址自动加1模式,0x44 为固定地址模式。(下图为数据地址自动加1模式)


Command2是设置地址,也就是我们平时调试数码管的位选值,这里可以根据个人所使用的原理图来进行选择。后面的就是所要显示的数据传输了,以及Command3的控制显示,就是控制LED的亮度。

上图是每个地址所对应的数据,自动地址加1模式,只需要设置起始地址即可,根据个人的电路需求进行选择起始地址。下面是显示数据与芯片管脚以及显示地址之间的对应关系表:

这些都是根据个人的电路需求来设置的,本次是以驱动共阴极为例的,不建议使用共阳极,个人认为很麻烦。


此为共阴极数码管,由此为例,若选择GRID1为起始地址并显示"7",其指令的先后顺序是:
1.先传输工作状态指令:0x40
2.继续传输起始地址指令:0xc0
3.发送显示“7”的数据:0x07(0000 0111)(dp g f e d c b a)
4.发送亮度指令:0x8D。
如果要显示更多继续在第三步后面加要显示的数值对应的数据即可。

固定地址显示
下图为固定地址的时序图:可以发现,在每一次传输完指令前后都会有起始结束的标志。

细心的人可以发现,在Command2data1之间与地址自动加1的一样并没有结束和起始的标识,但是在data1后面出现了结束标识,CommandN前面出现了开始标识符,由此可见每发送一个地址+显示数据 都要加上 起始结束标识,其它的和上述的地址自动加1一样。
好了下面直接上代码。

  • 代码

先准备头文件 .h

#ifndef __TM1640_H__
#define __TM1640_H__
#include "stm32f10x.h"
#include "sys.h"
/*
控制显示:
0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f 0x0X(这里X代表十六进制的任意值)
1/16,  2/16,  4/16,  10/16, 11/16, 12/16, 13/16, 14/16, 关灯  0x40,0x44  分别对应  地址自动加1 和 固定地址
*/
#define SCLK_GPIO_PORT      GPIOB
#define SCLK_GPIO_CLK       RCC_APB2Periph_GPIOB
#define SCLK_GPIO_PIN       GPIO_Pin_6              #define DIN_GPIO_PORT       GPIOB
#define DIN_GPIO_CLK        RCC_APB2Periph_GPIOB
#define DIN_GPIO_PIN        GPIO_Pin_7#define TM1640SLK_LOW      GPIO_WriteBit( SCLK_GPIO_PORT, SCLK_GPIO_PIN,0)
#define TM1640SLK_HING     GPIO_WriteBit( SCLK_GPIO_PORT, SCLK_GPIO_PIN,1)
#define TM1640DAT_LOW      GPIO_WriteBit( DIN_GPIO_PORT, DIN_GPIO_PIN,0)
#define TM1640DAT_HING     GPIO_WriteBit( DIN_GPIO_PORT, DIN_GPIO_PIN,1)void TM1640_Init(void);
void TM1640Start(void);
void TM1640Stop(void);
void TM1640WriteByte(u8 date);
void TM1640_Config(u8 InValue);
void TM1640_SendData(u8 Addr1640,u8 *a,u8 DataLong);

下面开始配置驱动程序 .C 文件

#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "delay.h"
#include "TM1640.h"void TM1640_Init(void)
{       GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(SCLK_GPIO_CLK|DIN_GPIO_CLK, ENABLE);RCC_APB2PeriphClockCmd(EN_GPIO_CLK, ENABLE);GPIO_InitStructure.GPIO_Pin = SCLK_GPIO_PIN;    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(SCLK_GPIO_PORT, &GPIO_InitStructure);   GPIO_SetBits(SCLK_GPIO_PORT, SCLK_GPIO_PIN);  //  SCLKGPIO_InitStructure.GPIO_Pin = DIN_GPIO_PIN;  GPIO_Init(DIN_GPIO_PORT, &GPIO_InitStructure);     GPIO_SetBits(DIN_GPIO_PORT, DIN_GPIO_PIN); //DIN}/****************************************
起始函数
***************************************/
void TM1640Start(void)
{   TM1640SLK_HING;delay_us(2);TM1640DAT_HING;    delay_us(2) ;  TM1640DAT_LOW;delay_us(2);
}
/*************************************
结束函数
***************************************/
void TM1640Stop(void)
{       TM1640SLK_LOW;  delay_us(2);TM1640DAT_LOW;  delay_us(2); TM1640SLK_HING;  delay_us(2);TM1640DAT_HING;
}
/*************************************
TM1640WriteByte
写一字节数据  date 为所要写的数据
***************************************/
void TM1640WriteByte(u8 date)
{  u8 i;     for(i=0;i<8;i++)  {  TM1640SLK_LOW;  delay_us(2);  if(date & 0x01)  //先低位后高位{  TM1640DAT_HING;  delay_us(3);  }  else  {  TM1640DAT_LOW;  delay_us(3);  } date = date>>1;     //数据右移一位                        TM1640SLK_HING;delay_us(3);                }
}
/***************************************
发送数组
Addr1640:起始地址值
*a : 所要发送的数组
ValueLong:想要发送的数据长度
适用于地址自加1模式
**************************************/
void TM1640_SendData(u8 Addr1640,u8 *a,u8 ValueLong)
{  u8 i;       TM1640Start();  TM1640WriteByte(Addr1640);   for(i=0;i<ValueLong;i++)  {  TM1640WriteByte(a[i]);   }        TM1640Stop();
}

再加一个如何使用的MAIN.C函数吧,仅供参考:

#include "delay.h"
#include "sys.h"
#include "TM1640.h"
//共阴极,数码管正常排列数字对应表
u8 Test_data[8] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07};//0,1 2 3 4 5 6 7
void main()
{u8 flag = 1;delay_init();TM1640_Init();while(1){//地址自加  起始地址为00H 长度为8if(flag){TM1640Start();TM1640WriteByte(0x40);TM1640Stop();TM1640Start();TM1640_SendData(0xc0,Test_data,8);TM1640Stop();TM1640Start();TM1640WriteByte(0x8b);TM1640Stop();flag = 0;}else{TM1640Start();TM1640WriteByte(0x44);TM1640Stop();TM1640Start();TM1640WriteByte(0xC0);TM1640WriteByte(Test_data[6]);TM1640Stop();TM1640Start();TM1640WriteByte(0xC1);TM1640WriteByte(Test_data[0]);TM1640Stop();TM1640Start();TM1640WriteByte(0xC2);TM1640WriteByte(GRID1_8(Test_data[4]);TM1640Stop();flag = 0;}}}

小结

好了驱动程序写完了,地址自加1的模式比较呆板,但是省事;固定模式虽然要多些步骤但是可以想让哪里亮就哪里亮。

有哪些理解不正确的地方,欢迎指正。

尴尬,第一次发这个,没法导入文档,不过网上很多,大家可自行下载…

基于STM32f103的TM1640驱动程序(地址自动加1 和 固定地址)相关推荐

  1. 基于Stm32f103针对TM1640驱动数码管

    最近,在学习stm32f103芯片的使用,发现单片机很多东西,必须亲力亲为去写一遍才会明白里面的坑!第一次写,有问题请大佬指出. 之前学习了一下TM1640芯片,一直没有时间在开发板上实践,直到最近才 ...

  2. [STM32F1]基于STM32F103实现TM1640点亮16位共阴极数码管,显示“0~F”数字

    本节我们目标是实现TM1640点亮16位共阴极数码管,显示"0~F"数字: 1. 硬件设计 GPIO初始化配置 SCL(PB6)  SDA(PB7):开漏输出,通过IO模拟驱动TM ...

  3. 基于STM32F103的步进电机S型曲线加减速算法与实现

    步进电机是将电脉冲信号转变为角位移或线位移的开环控制电机,是现代数字程序控制系统中的主要执行元件,应用极为广泛.在非超载的情况下,电机的转速.停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的 ...

  4. c语言FRA地址自动加一,c – 如何使用c语言在framebuffer中绘制图形?

    在/ dev(例如/ dev / fb0)中的正确文件上使用 open(),然后使用 mmap()将其映射到内存中.如果您不知道如何使用这些系统调用,联机帮助页将帮助您. 然后,< linux ...

  5. 小程序智能识别快递收货地址,自动解析出省市区等信息,让地址标准化格式的实现(使用腾讯云api)

    源码直接使用,下载地址 1,下载源码后需要改两个editaddress.js中的参数即可使用. //云市场分配的密钥Id let appKey = "你自己的secretId"; ...

  6. JavaScript实现http地址自动检测并添加URL链接

    一.天生我材必有用 给http字符自动添加URL链接是比较常见的一项功能.举两个我最近常用到的自动检测http://地址并添加链接的例子吧,首先是QQ邮箱,在使用QQ邮箱时,如果输入了URL地址(ht ...

  7. ipv6笔记无状态地址自动配置及状态

    当配置一个新的ipv6地址时,会进入到tentative 阶段,会发送以自己IP地址为目的地址的请求报文,一秒后,如果没响应,就没有冲突,就可以用. 生命周期是针对动态获取的IP的,但是tentati ...

  8. 让Windows系统自动加载SATA驱动程序(转)

    以前在安装Windows的时候老是要借软驱插软盘,遇到软驱软盘坏了就麻烦了,一直都想把驱动做到光盘或者硬盘上并让Windows安装程序自动加载,经过查资料和摸索,得出下面的方法: 安装Windows ...

  9. 让Windows系统自动加载SATA驱动程序

    以前在安装Windows的时候老是要借软驱插软盘,遇到软驱软盘坏了就麻烦了,一直都想把驱动做到光盘或者硬盘上并让Windows安装程序自动加载,经过查资料和摸索,得出下面的方法: 安装Windows ...

  10. 基于JQuery实现滚动到页面底端时自动加载更多信息

    基于JQuery实现滚动到页面底端时自动加载更多信息关键代码:代码如下: var stop=true; $(window).scroll(function(){ totalheight = parse ...

最新文章

  1. opencv cuda使用笔记
  2. DataTables实现rowspan思路
  3. Anaconda快速安装pytorch几分钟离线快速安装一定可行 下载缓慢conda install offline pytorch cudatoolkit slowly
  4. 中小型工厂如何玩转ERP生产管理系统
  5. html打印多了空白页,为什么打印Word文档会多打印出一空白页
  6. python螺旋线-利用Python绘制一个正方形螺旋线
  7. RxJava学习 - 11. Switching, Throttling, Windowing, and Buffering
  8. Uconn DataMining Math5671 课程小记(1)
  9. sql面试题——手写sql练习案例(一)
  10. 十大python开发软件-介绍6款实用的python编程开发工具
  11. 为什么博客里的图片都显示不出来?
  12. hp-ux系统备份与恢复常用命令
  13. 粒子群算法(PSO)的Python实现(求解多元函数的极值)
  14. Spark数据分区(partitionBy分区、partitioner获取分区方式、自定义分区)
  15. 队友代码神注释,ORZ 留下两行泪
  16. 华为交换机配置接口安全
  17. 摩拜获巨额融资,为何还被曝拖欠底层员工薪水?
  18. sicily 1214
  19. 2020年软考数据库系统工程师--基础知识精讲视频-任铄-专题视频课程
  20. STM32外挂FLASH模拟U盘(基于HAL库)

热门文章

  1. java sdk 1.8 64位_java sdk 1.8 64
  2. M1 芯片Macbook pro连接支持AirPrint的佳能打印机
  3. logit回归模型假设_logistic回归模型分析
  4. 8 个经典的 HTML5 游戏及源码
  5. AWS环境搭建(六):Linux上部署wowza,并配置ssl证书
  6. M5000 全谱直读光谱仪
  7. matlab freqz2 逆变化,【matlab】freqz函数的使用(二)
  8. SmartSVN打分支与合并代码
  9. 【矩阵论】对称矩阵特征值的性质与直积
  10. C#实现个人理财软件小项目