> 文章列表 > 【洋桃一号板】STM32F103CBT6标准库函数驱动TM1640点亮数码管

【洋桃一号板】STM32F103CBT6标准库函数驱动TM1640点亮数码管

【洋桃一号板】STM32F103CBT6标准库函数驱动TM1640点亮数码管

一、今天介绍如何使用STM32F103CBT6驱动TM1640点亮数码管,硬件用的洋桃开发板,点亮后效果如下,六个数码管依次显示0.1.2.3.4.5.6.7
【洋桃一号板】STM32F103CBT6标准库函数驱动TM1640点亮数码管
硬件原理图如下,只用到了单片机的两个IO口即可实现上图的效果,该开发板上用的是PA11和PA12两个IO口,用来模拟IIC通信,其中PA11接SCLK,PA12接DIN。另外可以看到TM1640的VDD接的是5V,规格书里面也是说需要接5V电压,但实际我试过了,接3.3V也是可以驱动的。【洋桃一号板】STM32F103CBT6标准库函数驱动TM1640点亮数码管

二、TM1640介绍
TM1640通信方式其实就是常用的的IIC通信,这点可以在规格书里面看到相关介绍
【洋桃一号板】STM32F103CBT6标准库函数驱动TM1640点亮数码管
【洋桃一号板】STM32F103CBT6标准库函数驱动TM1640点亮数码管

【洋桃一号板】STM32F103CBT6标准库函数驱动TM1640点亮数码管

三、写程序
1、先将重要的一些参数进行宏定义
a.固定地址模式上面分析过了,是0x44,后面进行配置会用到
b.设置亮度,上面也分析过了
c.通过上面的数据通信的过程我们知道需要用到SCLK和DIN两个信号,我们在硬件上接的是PA11和PA12两个脚,所以用TM1640_DIN_HTM1640_DIN_HTM1640_SCLK_LTM1640_SCLK_H来表示DIN和SCLK为高低电平。

#include "TM1640.h"
#include "delay.h"
#define DEL  1   //宏定义 通信速率(默认为1,如不能通信可加大数值)
//地址模式的设置
//#define TM1640MEDO_ADD  0x40   //宏定义	自动加一模式
#define TM1640MEDO_ADD  0x44   //宏定义 固定地址模式(推荐)//显示亮度的设置
//#define TM1640MEDO_DISPLAY  0x88   //宏定义 亮度  最小
//#define TM1640MEDO_DISPLAY  0x89   //宏定义 亮度
//#define TM1640MEDO_DISPLAY  0x8a   //宏定义 亮度
//#define TM1640MEDO_DISPLAY  0x8b   //宏定义 亮度
#define TM1640MEDO_DISPLAY  0x8c   //宏定义 亮度(推荐)
//#define TM1640MEDO_DISPLAY  0x8d   //宏定义 亮度
//#define TM1640MEDO_DISPLAY  0x8f   //宏定义 亮度 最大
#define TM1640MEDO_DISPLAY_OFF  0x80   //宏定义 亮度 关#define TM1640_DIN_H    GPIO_WriteBit(TM1640_GPIOPORT,TM1640_DIN,(BitAction)(1))
#define TM1640_DIN_L    GPIO_WriteBit(TM1640_GPIOPORT,TM1640_DIN,(BitAction)(0))#define TM1640_SCLK_H 	GPIO_WriteBit(TM1640_GPIOPORT,TM1640_SCLK,(BitAction)(1))
#define TM1640_SCLK_L 	GPIO_WriteBit(TM1640_GPIOPORT,TM1640_SCLK,(BitAction)(0))

2、通信的开启和结束代码
【洋桃一号板】STM32F103CBT6标准库函数驱动TM1640点亮数码管

void TM1640_start()
{ //通信时序 启始TM1640_DIN_H; //DIN输出高电平1	TM1640_SCLK_H; //SCLK输出高电平1	delay_us(DEL);//延时一段时间TM1640_DIN_L; //DIN输出低电平0	delay_us(DEL);//延时一段时间TM1640_SCLK_L; //SCLK输出低电平0	delay_us(DEL);//延时一端时间
}
void TM1640_stop()
{ //通信时序 结束TM1640_DIN_L; //DIN输出低电平0	TM1640_SCLK_L; //SCLK输出低电平0	delay_us(DEL);//延时一段时间TM1640_SCLK_H; //SCLK输出高电平1	delay_us(DEL);TM1640_DIN_H; //DIN输出高电平1	delay_us(DEL);
}

3、底层函数,信号传输,写8位数据

void TM1640_write(u8 date){	//写数据(低层)u8 i;u8 aa;aa=date;TM1640_DIN_L; //DIN输出0	TM1640_SCLK_L; //SCLK输出0	for(i=0;i<8;i++){TM1640_SCLK_L; //SCLK输出0		delay_us(DEL);if(aa&0x01){TM1640_DIN_H; //DIN输出1delay_us(DEL);}else{TM1640_DIN_L; //DIN输出0delay_us(DEL);}TM1640_SCLK_H; //SCLK输出1delay_us(DEL);aa=aa>>1;//右移一位}TM1640_DIN_L; //DIN输出0TM1640_SCLK_L; //SCLK输出0}

安装上面的代码传输二进制10110001的时序图如下,左边为高位,右边为低位。所以实际是从低位开始传输数据。
【洋桃一号板】STM32F103CBT6标准库函数驱动TM1640点亮数码管
4、TM1640驱动函数
a、GPIO初始化、配置固定地址,设置亮度

void TM1640_Init(void){ //TM1640接口初始化GPIO_InitTypeDef  GPIO_InitStructure; 	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);       GPIO_InitStructure.GPIO_Pin = TM1640_DIN | TM1640_SCLK; //选择端口号(0~15或all)                        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //选择IO接口工作方式       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置IO接口速度(2/10/50MHz)    GPIO_Init(TM1640_GPIOPORT, &GPIO_InitStructure);GPIO_WriteBit(TM1640_GPIOPORT,TM1640_DIN,(BitAction)(1)); //接口输出高电平1	GPIO_WriteBit(TM1640_GPIOPORT,TM1640_SCLK,(BitAction)(1)); //接口输出高电平1	TM1640_start();TM1640_write(TM1640MEDO_ADD); //设置数据,0x40,0x44分别对应地址自动加一和固定地址模式TM1640_stop();TM1640_start();TM1640_write(TM1640MEDO_DISPLAY); //设置亮度//控制显示,开显示,0x88,  0x89,  0x8a,  0x8b,  0x8c,  0x8d,  0x8e,  0x8f分别对应脉冲宽度为://------------------1/16,  2/16,  4/16,  10/16, 11/16, 12/16, 13/16, 14/16	 //0x80关显示TM1640_stop();					
}

b、TM1638显示函数
【洋桃一号板】STM32F103CBT6标准库函数驱动TM1640点亮数码管

void TM1640_display(u8 address,u8 date){ //固定地址模式的显示输出const u8 buff[21]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0x00};//数字0~9及0~9加点显示段码表//---------------   0    1    2    3    4    5    6    7    8    9    0.   1.   2.   3.   4.   5.   6.   7.   8.   9.   无   TM1640_start();TM1640_write(0xC0+address);//传显示数据对应的地址TM1640_write(buff[date]);//传1BYTE显示数据TM1640_stop();
}

5、主函数
有了上面的铺垫,主函数就很简单了,只需要初始化TM1640,然后调用显示函数即可

int main ()
{TM1640_Init(); //TM1640初始化while(1){TM1640_display(0,0);	TM1640_display(1,1);TM1640_display(2,2); TM1640_display(3,3);TM1640_display(4,4);	TM1640_display(5,5);TM1640_display(6,6);TM1640_display(7,7);}
}