概述
在使用单片机的过程中发现某些IO口不够用或者单片机的IO口比较少,比如如果IO口直驱数码管的话会用去很多IO口造成不必要的资源浪费
方案
使用TM1637模块,使用的是I2c的IC,只占用2个IO口便可以驱动6位数码管跟16个按键
效果图
代码效果演示视频
b站演示视频
代码
main函数
#include"reg52.h"
#include"tm1637.h"
unsigned char code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void delay(unsigned int i)
{
while(i--);
}
void main()
{
unsigned char i;
while(1)
{
for(i=0;i<17;i++)
{
Display(smgduan[i]);
delay(50000);
Display(0x00);
delay(20000);
}
}
}
TM1637 的头文件
#ifndef __TM1637_H__
#define __TM1637_H__
#include"reg52.h"
#include"intrins.h"
sbit CLK = P1^1;
sbit SDA = P1^0;
typedef unsigned char Byte;
typedef unsigned int Word;
void Display(Byte dat);
Byte Keysacn();
void TM1637_Init();
#endif
TM1637 的c文件
#include"tm1637.h"
void delay_6us()
{
_nop_();
}
void IIC_start(void)
{
CLK = 1;
_nop_();
SDA = 1;
delay_6us();
SDA = 0;
_nop_();
CLK = 0;
}
void IIC_stop(void)
{
CLK = 0;
_nop_();
SDA = 0;
_nop_();
CLK = 1;
delay_6us();
SDA = 1;
}
void IIC_ack(void)
{
CLK = 0;
delay_6us();
while(SDA);
CLK = 1;
_nop_();
}
void IIC_Write_cmd(Byte cmd)
{
Byte n;
IIC_start();
for(n=0;n<8;n++)
{
CLK = 0;
delay_6us();
SDA = cmd&0x01;
cmd>>=1;
CLK = 1;
delay_6us();
}
}
Byte Keysacn()
{
Byte n,key_value;
IIC_start();
IIC_Write_cmd(0x42);
IIC_ack();
SDA = 1;
for(n=0;n<8;n++)
{
CLK = 0;
delay_6us();
key_value = key_value>>1;
CLK = 1;
if(SDA)
{
key_value = key_value|0x80;
}
else
{
key_value = key_value|0x00;
}
delay_6us();
delay_6us();
delay_6us();
}
IIC_ack();
IIC_stop();
return (key_value);
}
void Display(Byte dat)
{
Byte n;
IIC_start();
IIC_Write_cmd(0x40);
IIC_ack();
IIC_stop();
IIC_start();
IIC_Write_cmd(0xc1);
IIC_ack();
for(n=0;n<6;n++)
{
IIC_Write_cmd(dat);
IIC_ack();
}
IIC_stop();
IIC_start();
IIC_Write_cmd(0x8f);
IIC_ack();
IIC_stop();
}
void TM1637_Init()
{
IIC_start();
IIC_Write_cmd(0x8f);
IIC_ack();
IIC_stop;
}
虽然说是52的程序,但是稍作改动可以适应所有stc单片机。