基于STC32的四位TM1637程序

该程序使用的开发板为STC公司的屠龙刀,代码风格接近51,微调后51也可以使用!

这个程序中的定时是用软延时做的,所以对单片机频率要求高,该代码用的24Mhz,如有其他频率需求,只需在延时接口更改即可;

程序比较适合新手入门,写的很详细,代码量比较多。有现成的亮度,各位数码管控制等。

该控制非常简单,只需直接输入数字即可显示数字,无需理会段码。

PS:起初我随意看了看芯片文档,看着和iic协议很像,想都没想就用了硬件iic,但万万没想到,这个芯片协议看似iic,实则只是相似,我也因此调试了半天没调出来,还是后来仔细观摩使用手册才发现猫腻。

这个是主函数

#include <STC32G.H>
#include <tm1637.H>


void main()
{
  P2M0 = 0x00; P2M1 = 0x00; //配置io口
	Smg_ctrl_all(1,2,3,4,1,8);
	while(1);
}

这个是Tm1637.c函数

#include <tm1637.H>
#include <intrins.h> 

static unsigned char data t_display[]={                       //标准字库
//   0    1    2    3    4    5    6    7    8    9   black 
    0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x00};
unsigned char xdata smg_hc[4];                                  //数码管缓存
unsigned char luminance=0;                                      //亮度存储
bit dot_f=0;                                                    //小数点标志位

void Delay1us()		//@24.000MHz
{
	unsigned long edata i;

	_nop_();
	_nop_();
	_nop_();
	i = 4UL;
	while (i) i--;
}

/*******************************************************************************
* 函 数 名         : Delay_us
* 函数功能		     : 延时接口
* 输    入         : 微秒延时
* 输    出         : 无
*******************************************************************************/
void Delay_us(unsigned int i)
{ 
 unsigned long edata j;
 for(;i>0;i--) 
 {            //延时接口
	Delay1us();
 }
} 
/*******************************************************************************
* 函 数 名         : TM1637_Start
* 函数功能		     : 1637起始信号
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void TM1637_Start(void) 
{ 
  clk = 1; 
  dio = 1; 
  Delay_us(2); 
  dio = 0; 
} 
/*******************************************************************************
* 函 数 名         : TM1637_ask
* 函数功能		     : 1637 应答信号 
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void TM1637_ask(void)
{ 
  clk = 0; 
  Delay_us(5); //在第八个时钟下降沿之后延时 5us,开始判断 ACK 信号 
  while(dio); 
  clk = 1; 
  Delay_us(2); 
  clk=0; 
}
/*******************************************************************************
* 函 数 名         : TM1637_Stop
* 函数功能		     : 1637 停止信号
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void TM1637_Stop(void)
{ 
	 clk = 0; 
	 Delay_us(2); 
	 dio = 0; 
	 Delay_us(2); 
	 clk = 1; 
	 Delay_us(2); 
	 dio = 1; 
} 
/*******************************************************************************
* 函 数 名         : TM1637_WrByte
* 函数功能		     : 写一个字节
* 输    入         : char数据
* 输    出         : 无
*******************************************************************************/
void TM1637_WrByte(unsigned char oneByte) 
{ 
	 unsigned char i; 
	 for(i=0;i<8;i++) 
	 { clk = 0; 
	 if(oneByte&0x01) //低位在前 
	 { 
	 dio = 1; 
	 } 
	 else 
	 { 
	 dio = 0; 
	 } 
	 Delay_us(3); 
	 oneByte=oneByte>>1; 
	 clk=1; 
	 Delay_us(3); 
	 } 
} 
/*******************************************************************************
* 函 数 名         : SmgDisplay
* 函数功能		     : 写显示寄存器 
* 输    入         : *p:数码管段码 L:0-9亮度
* 输    出         : 无
*******************************************************************************/
void SmgDisplay(unsigned char *p,char L)
{ 
	 unsigned char i; 
	 TM1637_Start(); 
	 TM1637_WrByte(0x40); // 40H 地址自动加 1 模式,44H 固定地址模式,本程序采用自加 1 模式 
	 TM1637_ask(); 
	 TM1637_Stop(); 
	 TM1637_Start(); 
	 TM1637_WrByte(0xc0); //设置首地址, 
	 TM1637_ask(); 
	 
	 for(i=0;i<6;i++) //地址自加,不必每次都写地址 
	 { 
	   TM1637_WrByte(*p++); //送数据 
	   TM1637_ask(); 
	 } 
 
	 TM1637_Stop(); 
	 TM1637_Start(); 
	 if((L>0)&&(L<9)) TM1637_WrByte((unsigned char)(0x88+(L-1))); //开显示 ,最大亮度 
	 else TM1637_WrByte(0x80);
	 
	 TM1637_ask(); 
	 TM1637_Stop(); 
} 
/*******************************************************************************
* 函 数 名         : Smg_ctrl_dot
* 函数功能		     : 控制小数点亮灭
* 输    入         : 0:小数点熄灭   1:小数点亮起
* 输    出         : 无
*******************************************************************************/
void Smg_ctrl_dot(bit dot)
{
	if(dot) smg_hc[1]-=0x80;
	SmgDisplay(smg_hc,luminance);
}
/*******************************************************************************
* 函 数 名         : Smg_ctrl_bit
* 函数功能		     : 控制单独数码管
* 输    入         : i:要控制的数码管位 dat:要写入的数据:0~9; 10为熄灭该数码管
* 输    出         : 无
*******************************************************************************/
void Smg_ctrl_bit(unsigned char i,unsigned char dat)
{
	smg_hc[i+1]=t_display[dat];
	SmgDisplay(smg_hc,luminance);
}
/*******************************************************************************
* 函 数 名         : Smg_ctrl_lum
* 函数功能		     : 数码管亮度控制
* 输    入         : 亮度等级:1~8;  0为熄灭
* 输    出         : 无
*******************************************************************************/
void Smg_ctrl_lum(unsigned char R)
{
	luminance=R;
	SmgDisplay(smg_hc,luminance);
}
/*******************************************************************************
* 函 数 名         : Smg_ctrl_all
* 函数功能		     : 数码管全部资源控制
* 输    入         :  a:第一位数码管 0~9
											b:第二位数码管 0~9
											c:第三位数码管 0~9
                      d:第四位数码管 0~9
                      t:小数点       0|1
                      R:亮度         0~8
* 输    出         : 无
*******************************************************************************/
void Smg_ctrl_all(unsigned char a,unsigned char b,unsigned char c,unsigned char d,bit t,char R)
{

  smg_hc[0]=t_display[a];
	smg_hc[1]=t_display[b];
	dot_f=t;
	if(t) smg_hc[1]-=0x80;
	smg_hc[2]=t_display[c];
	smg_hc[3]=t_display[d];
	luminance=R;
	SmgDisplay(smg_hc,luminance);
}

这个是Tm1637.h函数,原件引脚在这个文件修改

#ifndef		__tm1637_H
#define		__tm1637_H

#include <STC32G.H>
//定义端口 
sbit clk = P2^4; 
sbit dio = P2^5; 


void SmgDisplay(unsigned char *p,char L);//*p:数码管段码 L:0-9亮度
void Smg_ctrl_dot(bit dot);//0:小数点熄灭   1:小数点亮起
void Smg_ctrl_bit(unsigned char i,unsigned char dat);//i:要控制的数码管位 dat:要写入的数据:0~9; 10为熄灭该数码管
void Smg_ctrl_lum(unsigned char R);//亮度等级:1~8;  0为熄灭
void Smg_ctrl_all(unsigned char a,unsigned char b,unsigned char c,unsigned char d,bit t,char R);

#endif

代码可以直接复制使用,实验现象如下