为需要的小伙伴提供个控制多个数码管tm1640的驱动,测试有效,有错的地方感谢指正!
以下是基于标准库的 .h 和.c文件。
#ifndef __TM1640_H
#define __TM1640_H
#include "stm32f4xx.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, 关灯
*/
#define DEL 2 //宏定义 通信速率(默认为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 //宏定义 亮度 关
/************************** TM1640 连接引脚定义****************************/
#define SCLK_GPIO_PORT GPIOC
#define SCLK_GPIO_CLK RCC_AHB1Periph_GPIOC
#define SCLK_GPIO_PIN GPIO_Pin_9
#define DIN_GPIO_PORT GPIOC
#define DIN_GPIO_CLK RCC_AHB1Periph_GPIOC
#define DIN_GPIO_PIN GPIO_Pin_7
/*********************** 直接操作寄存器的方法控制IO ***********************/
#define digitalHi(p,i) {p->BSRRL=i;} //输出为高电平
#define digitalLo(p,i) {p->BSRRH=i;} //输出低电平
#define digitalTOGGLE(p,i) {p->ODR^=i;} //输出反转状态
#define TM1640_SCLK_LOW digitalLo( SCLK_GPIO_PORT, SCLK_GPIO_PIN)
#define TM1640_SCLK_HIGH digitalHi( SCLK_GPIO_PORT, SCLK_GPIO_PIN)
#define TM1640_DIN_LOW digitalLo( DIN_GPIO_PORT, DIN_GPIO_PIN)
#define TM1640_DIN_HIGH digitalHi( DIN_GPIO_PORT, DIN_GPIO_PIN)
void TM1640_Init(void);
void TM1640_Start(void);
void TM1640_Stop(void);
void TM1640_WriteByte(uint8_t date);
void TM1640_Config(uint8_t InValue);
void TM1640_SendData(uint8_t Addr1640,uint8_t *a,uint8_t DataLong);
void TM1640_SendData_FixedMode(uint8_t location,uint8_t Value) ;
#endif /* __TM1640_H */
/*******************************************************************************************/
#include "./tm1640/bsp_tm1640.h"
#include "./systick/bsp_SysTick.h"
#define delay_us(us) SysTick_Delay_us(us)
//--------------- 0 1 2 3 4 5 6 7 8 9 A B C D E F - 无 无 无
const uint8_t buff[31]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x40,0x00,0x00,0x00,
0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0x00,};//数字0~F及0~9加点显示段码表
//--------------- 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. 无
uint8_t INIT_DATE[16]={20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20}; // 清0.
/**
* 函数名:TM1640_Init
* 描述 :初始化控制tm1640的IO
*/
void TM1640_Init(void)
{
/*定义一个GPIO_InitTypeDef类型的结构体*/
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd ( SCLK_GPIO_CLK|DIN_GPIO_CLK , ENABLE);
/*GPIO_InitTypeDef类型的结构体配置*/
GPIO_InitStructure.GPIO_Pin = SCLK_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(SCLK_GPIO_PORT, &GPIO_InitStructure); // 初始化 SCLK 引脚
GPIO_InitStructure.GPIO_Pin = DIN_GPIO_PIN;
GPIO_Init(DIN_GPIO_PORT, &GPIO_InitStructure); // 初始化 DIN 引脚
/*引脚初始状态为高,便于产生下降沿*/
GPIO_SetBits(SCLK_GPIO_PORT, SCLK_GPIO_PIN); //SCLK
GPIO_SetBits(DIN_GPIO_PORT, DIN_GPIO_PIN); //DIN
/*初始数码管状态为 空 */
TM1640_SendData(0,INIT_DATE,16); //自动加一模式
}
/*
* 函数名:TM1640Start
* 描述 :起始函数
*/
void TM1640_Start(void)
{
TM1640_SCLK_HIGH; delay_us(DEL);
TM1640_DIN_HIGH; delay_us(DEL) ;
TM1640_DIN_LOW; delay_us(DEL);
}
/*
* 函数名:TM1640Stop
* 描述 :结束函数
*/
void TM1640_Stop(void)
{
TM1640_SCLK_LOW; delay_us(DEL);
TM1640_DIN_LOW; delay_us(DEL);
TM1640_SCLK_HIGH; delay_us(DEL);
TM1640_DIN_HIGH; delay_us(DEL);
}
/*
* 函数名:TM1640WriteByte
* 描述 :写一字节数据
* 输入 :date :所要写的数据
* 输出 :无
*/
void TM1640_WriteByte(uint8_t date)
{
uint8_t i;
for(i=0;i<8;i++)
{
TM1640_SCLK_LOW;
delay_us(DEL);
if(date & 0x01) //先低位后高位
{
TM1640_DIN_HIGH;
}
else
{
TM1640_DIN_LOW;
}
delay_us(DEL);
date = date>>1;
TM1640_SCLK_HIGH;
delay_us(DEL);
}
}
/*
* 函数名:TM1640_SendData
* 描述 :发送数组---适用于地址自加1模式
* 输入 :Addr1640:起始地址值 0-15
* DisplayValue: 所要发送的数组,数组内为要显示的数值,带小数点的 数值+20
* len:想要发送的数据长度 1-16
* 输出 :无
*/
void TM1640_SendData(uint8_t Addr1640,uint8_t *DisplayValue,uint8_t len)
{
uint8_t i,num;
TM1640_Start();
TM1640_WriteByte(TM1640MEDO_ADD);//自动加一模式,Command1
TM1640_Stop();
TM1640_Start();
TM1640_WriteByte(0XC0+Addr1640); //设置地址,Command2
for(i=0;i<len;i++)
{
num = DisplayValue[i];
TM1640_WriteByte(buff[num]);
}
TM1640_Stop();
TM1640_Start();
TM1640_WriteByte(TM1640MEDO_DISPLAY);//亮度控制,Command3
TM1640_Stop();
}
/*
* 函数名:TM1640_SendData_FixedMode
* 描述 :点亮一个数码管---适用于地址自固定模式
* 输入 :location:数码管位置号1-16
* Value: 显示的数值,0-9直接写,0.-9. 对应数值+20 (9.=9+10=19)
* 输出 :无
*/
void TM1640_SendData_FixedMode(uint8_t location,uint8_t Value)
{
TM1640_Start();
TM1640_WriteByte(0x44);//固定模式,Command1
TM1640_Stop();
switch(location)
{
case 1:TM1640_Start(); TM1640_WriteByte(0XC0); TM1640_WriteByte(buff[Value]); TM1640_Stop();break;//设置地址(Command2)和发送数据
case 2:TM1640_Start(); TM1640_WriteByte(0XC1); TM1640_WriteByte(buff[Value]); TM1640_Stop();break;
case 3:TM1640_Start(); TM1640_WriteByte(0XC2); TM1640_WriteByte(buff[Value]); TM1640_Stop();break;
case 4:TM1640_Start(); TM1640_WriteByte(0XC3); TM1640_WriteByte(buff[Value]); TM1640_Stop();break;
case 5:TM1640_Start(); TM1640_WriteByte(0XC4); TM1640_WriteByte(buff[Value]); TM1640_Stop();break;
case 6:TM1640_Start(); TM1640_WriteByte(0XC5); TM1640_WriteByte(buff[Value]); TM1640_Stop();break;
case 7:TM1640_Start(); TM1640_WriteByte(0XC6); TM1640_WriteByte(buff[Value]); TM1640_Stop();break;
case 8:TM1640_Start(); TM1640_WriteByte(0XC7); TM1640_WriteByte(buff[Value]); TM1640_Stop();break;
case 9:TM1640_Start(); TM1640_WriteByte(0XC8); TM1640_WriteByte(buff[Value]); TM1640_Stop();break;
case 10:TM1640_Start();TM1640_WriteByte(0XC9); TM1640_WriteByte(buff[Value]); TM1640_Stop();break;
case 11:TM1640_Start();TM1640_WriteByte(0XCA); TM1640_WriteByte(buff[Value]); TM1640_Stop();break;
case 12:TM1640_Start();TM1640_WriteByte(0XCB); TM1640_WriteByte(buff[Value]); TM1640_Stop();break;
case 13:TM1640_Start();TM1640_WriteByte(0XCC); TM1640_WriteByte(buff[Value]); TM1640_Stop();break;
case 14:TM1640_Start();TM1640_WriteByte(0XCD); TM1640_WriteByte(buff[Value]); TM1640_Stop();break;
case 15:TM1640_Start();TM1640_WriteByte(0XCE); TM1640_WriteByte(buff[Value]); TM1640_Stop();break;
case 16:TM1640_Start();TM1640_WriteByte(0XCF); TM1640_WriteByte(buff[Value]); TM1640_Stop();break;
}
TM1640_Start();
TM1640_WriteByte(TM1640MEDO_DISPLAY);//亮度控制,Command3
TM1640_Stop();
}