今天中午开始调TM1640(一种扫描16个8段数码管的IC)
检查了很多次.终于发现是芯片问题.
1.全亮时死机
2.第三级亮时正常。第四级亮时不正常
还好没批量打板.论坛哪位朋友用过这个芯片?质量如何?
------------------------------------------------------
对于这类数码管/按键扫描其实之前我想用STM8自己做一个来用的.只是觉得太耗时
IIC。从机实现思想:
1.初始化--->main()。状态机=空闲
2.开SDA下降沿中断.(在中断中检测SCL=1---------状态机=开始. 关SDA中断允许,开SCL上升沿中断。然后等待传输数据)
-----------------------------
SCL中断程序中检测SDA状态.并移位.8次中断后接收完一个数据.等开SDA上升沿中断----------检测停止.让状态机进入空闲
以STM8这类内部16M RC的速度一定能采集到数据
其实TM1640也是个带内部振荡器的单片机.模拟IIC从机罢了
-----------------------------------------------------
程序如下:(以下程序已经验证正确)大家使用时只要改头文件中前4行#define即可
-------------------------------------------头文件---------------------------------------------
#define TM1640DelayTicks() asm("nop"); asm("nop");
#define TM1640Port (GPIOD->ODR)
#define TMSda 0x04
#define TMScl 0x08
#define TM1640_DIS_MODE1 0x88
#define TM1640_DIS_MODE2 0x89
#define TM1640_DIS_MODE3 0x8A
#define TM1640_DIS_MODE4 0x8B
#define TM1640_DIS_MODE5 0x8C
#define TM1640_DIS_MODE6 0x8D
#define TM1640_DIS_MODE7 0x8E
#define TM1640_DIS_MODE8 0x8F
#define TM1640_DIS_MODE_ON 0x8f
#define TM1640_DIS_MODE_OFF 0x80
#define TM1640_BUFF_SIZE 16
extern void TM1640_SetDisAddress(unsigned char Address);
extern void TM1640_SetDisplayMode(unsigned char DisMode);
extern void TM1640_SetAutoAddressMode(void);
extern void TM1640Init(void);
-------------------------------------------C文件---------------------------------------------
#include "gobal.h"
void TM1640_Start(void)
{
TM1640Port |= TMScl;//scl=1
TM1640DelayTicks();
TM1640Port |= TMSda;//sda=1
TM1640DelayTicks();
TM1640Port &= ~TMSda;//sda=0
TM1640DelayTicks();
TM1640Port &= ~TMScl;//scl=0
TM1640DelayTicks();
}
void TM1640_Stop(void)
{
TM1640Port &= ~TMSda;//sda=0
TM1640DelayTicks();
TM1640Port &= ~TMScl;//scl=0
TM1640DelayTicks();
TM1640Port |= TMScl;//scl=1
TM1640DelayTicks();
TM1640Port |= TMSda;//sda=1
TM1640DelayTicks();
}
void TM1640_SendByte(unsigned char c)
{
unsigned char i;
for(i=0;i!=8;i++)
{
TM1640Port &= ~TMScl;//scl=0
TM1640DelayTicks();
if( ((c&0x01)==0) )
{
TM1640Port &= ~TMSda;//sda=0
}
else
{
TM1640Port |= TMSda;//sda=1
}
TM1640DelayTicks();
TM1640Port |= TMScl;//scl=1
TM1640DelayTicks();
c>>=1;
}
}
/*------------API for main---------------------*/
/*------------API for main---------------------*/
/*------------API for main---------------------*/
/*------------API for main---------------------*/
/*------------API for main---------------------*/
//Address=0..0x0F
void TM1640_SetDisAddress(unsigned char Address)
{
Address&=0x0F;
Address+=0xC0;
TM1640_Start();
TM1640_SendByte(Address);
TM1640_Stop();
}
/////////////////
//设置显示模式.亮度DisMode=0---7
void TM1640_SetDisplayMode(unsigned char DisMode)
{
TM1640_Start();
TM1640_SendByte(DisMode);
TM1640_Stop();
}
//设置地址自动加1
void TM1640_SetAutoAddressMode(void)
{
TM1640_Start();
TM1640_SendByte(0x40);
TM1640_Stop();
}
void TM1640_SendData(unsigned char Address,unsigned char *p,unsigned char Len)
{
//TM1640_SetAutoAddressMode();
Address&=0x0F;
Address+=0xC0;
TM1640_Start();
TM1640_SendByte(Address);
for( ;Len!=0;Len--)
{
TM1640_SendByte(*p++);
}
TM1640_Stop();
}
/*
unsigned char TM1640_Buff[16]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}
*/
unsigned char const Tab[]={0xED,0x60,0xCE,0xEA,0x63,0xAB,0xAF,0xE0,
0xEF,0xEB,0xE7,0x2F,0x8D,0x6E,0x8F,0x87};
unsigned char TM1640_Buff[TM1640_BUFF_SIZE];//={Tab[0],Tab[1],Tab[2],Tab[3],Tab[4],Tab[5],Tab[6],Tab[7],Tab[0],Tab[1],Tab[2],Tab[3],Tab[4],Tab[5],Tab[6],Tab[7],};
void TM1640_BuffInit(void)
{
unsigned char i;
for(i=0;i!=TM1640_BUFF_SIZE;i++)
{
TM1640_Buff=Tab[i%8];
}
}
void TM1640Init(void)
{
TM1640_Stop();
TM1640_Stop();
TM1640_BuffInit();
//TM1640_SetDisplayMode(TM1640_DIS_MODE3);
TM1640_SetAutoAddressMode();
TM1640_SendData(0,TM1640_Buff,TM1640_BUFF_SIZE);
TM1640_SetDisplayMode(TM1640_DIS_MODE1);
}
调节到第四级亮度还可以。再到第五级就关显示.
图上这个亮度的时候,芯片发热,不烫手。
能用,就是没长期测试。华强北新亚洲2期拿货0.85元。。。拿了1管
大哥问一下,TM1640让数码管秒闪是怎么实现的
TM1640只负责将你送过去的128个点的LED数码管数据(16字节)自动帮你扫描刷新,其它的一概不管。
你要实现秒闪,就要用MCU控制送显的数据,0.5秒显示,另外0.5秒把秒闪的笔段数据清零,分别别正常和部分清零后的数据以最低0.5秒的间隔发给TM1640就可以实现秒闪了
一周热门 更多>