关于使用M16的PD5/6/7口与TM1638通信显示8位数码的程序疑问
TM1638通信显示8位数码模块 购买于 http://item.taobao.com/item.htm?id=9559804356 按键数码管模块LED显示模块(8位数码管+8个LED+8个按键) 示范程序中有些疑问,恳请解答:
以下是 文件TM1638.H的内容
#ifndef _TM1638_H
#define _TM1638_H
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#define DATA_COMMAND 0X40
#define DISP_COMMAND 0x80
#define ADDR_COMMAND 0XC0
#define SET_BIT(PORT,BIT) PORT|=(1<<BIT)
#define CLR_BIT(PORT,BIT) PORT&=~(1<<BIT)
#define BIT_IN(DDR,BIT) DDR&=~(1<<BIT)
#define BIT_OUT(DDR,BIT) DDR|=(1<<BIT)
#define READ_BIT(PIN,BIT) (PIN&(1<<BIT))
#define DIO PD7
#define CLK PD6
#define STB PD4
#define DIO_high SET_BIT(PORTD,DIO)
#define DIO_low CLR_BIT(PORTD,DIO)
#define CLK_high SET_BIT(PORTD,CLK)
#define CLK_low CLR_BIT(PORTD,CLK)
#define STB_high SET_BIT(PORTD,STB)
#define STB_low CLR_BIT(PORTD,STB)
#define DIO_IN BIT_IN(DDRD,DIO) //输入状态
#define DIO_OUT BIT_OUT(DDRD,DIO) //输出状态
#define DIO_READ READ_BIT(PIND,DIO) //读引脚电平
/*
#define DIO_IN DDRD&=~(1<<PD7) //输入状态
#define DIO_OUT DDRD|=(1<<PD7) //输出状态
#define DIO_READ PIND&(1<<PD7) //读引脚电平
//引脚定义???????????????????????????是否与上面重复了,只不过这里的定义更直接了些,类似的还出现在DIO_IN _READ _OUT
#define DIO_high PORTD|=(1<<PD7)
#define DIO_low PORTD&=~(1<<PD7)
#define CLK_high PORTD|=(1<<PD6)
#define CLK_low PORTD&=~(1<<PD6)
#define STB_high PORTD|=(1<<PD4)
#define STB_low PORTD&=~(1<<PD4)
*/
unsigned char tab[] PROGMEM={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
void TM1638_Write(unsigned char DATA) //写数据函数
{
unsigned char i;
DIO_OUT;
for(i=0;i<8;i++)
{
CLK_low;
if(DATA&0X01)
DIO_high;
else
DIO_low;
DATA>>=1;
CLK_high;
_delay_us(1);
}
}
unsigned char TM1638_Read(void) //读数据函数
{
unsigned char i;
unsigned char temp=0;
DIO_IN;
_delay_us(1);
for(i=0;i<8;i++)
{
temp>>=1;
CLK_low;
_delay_us(1);
if(DIO_READ) //????是否应该与 下面的CLK_high 交换位置 因为先置上升沿才能操作???
temp|=0x80;
CLK_high;
}
return temp;
}
void Write_COM(unsigned char cmd) //发送命令字
{
STB_low;
TM1638_Write(cmd);
STB_high;
_delay_us(1);
}
unsigned char Read_key(void)
{
unsigned char c,i,key_value=0;
STB_low;
TM1638_Write(0x42);
_delay_us(1);
for(i=0;i<4;i++)
c=TM1638_Read();
STB_high; //4个字节数据合成一个字节
for(i=0;i<4;i++)
key_value|=c<<i; ///???这个没有很清楚重组后的KS1KS2KS3KS4...的顺序
for(i=0;i<8;i++)
if((0x01<<i)==key_value)
break;
return i;
}
void Write_DATA(unsigned char add,unsigned char DATA) //指定地址写入数据
{
Write_COM(0x44);
STB_low;
TM1638_Write(0xc0|add);
TM1638_Write(DATA);
STB_high;
}
void Write_ALLDATA(unsigned char add,unsigned char *p,unsigned char cnt)
{
unsigned char i;
Write_COM(0x44);
for(i=0;i<cnt;i++)
{
Write_DATA(2*i,*(p+i));
}
}
void Write_oneLED(unsigned char num,unsigned char flag) //单独控制一个LED函数,num为需要控制的led序号,flag为0时熄灭,不为0时点亮
{
if(flag)
Write_DATA(2*num+1,1);
else
Write_DATA(2*num+1,0);
}
void Write_allLED(unsigned char LED_flag) //控制全部LED函数,LED_flag表示各个LED状态
{
unsigned char i;
for(i=0;i<8;i++)
{
if(LED_flag&(1<<i))
Write_DATA(2*i+1,3);
else
Write_DATA(2*i+1,0);
}
}
void init_TM1638(void)
{
unsigned char i;
Write_COM(0x8b);//亮度
Write_COM(0x40);
STB_low;
TM1638_Write(0xc0);
for(i=0;i<16;i++)
TM1638_Write(0x00);// 这里写的是0 还是全部消隐?
STB_high;
}
#endif
这是按键数码管模块LED显示模块的附送例程ourdev_671959LHMKKB.rar(文件大小:658K) (原文件名:TM1638+按键数码管模块.rar) 这个产品是抄袭我们店里面的,这个函数也是直接使用我写的,我们现在的模块已经是双色led的了,并且已经由工厂贴片去做了
前面接口定义的地方没有重复,下面的定义是注释掉的,TM1638_Read函数里面的语句不能交换位置,注意是读函数,数据在clk的下降沿以后改变,在上升沿读入,至于重新组合读取到的4个字节的按键数据纯粹是为了简单方便,因为只有8个按键因此用一个8位的数据即可表示,这个地方需要结合硬件和手册里面的按键读取地址映射来思考,很简单的。。。 谢谢little Monkey
,支持正品。
贵店的淘宝地址在哪里? little_Monkey 发表于 2011-8-28 22:21 static/image/common/back.gif
这个产品是抄袭我们店里面的,这个函数也是直接使用我写的,我们现在的模块已经是双色led的了,并且已经由 ...
不知道 大侠 能不能共享下 程序。
或者提供下店铺地址
YaphetS 发表于 2012-4-17 13:15 static/image/common/back.gif
不知道 大侠 能不能共享下 程序。
或者提供下店铺地址
头文件,直接调用即可
#ifndef _TM1638_H
#define _TM1638_H
#include <avr/io.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#define DATA_COMMAND 0X40
#define DISP_COMMAND 0x80
#define ADDR_COMMAND 0XC0
#define SET_BIT(PORT,BIT) PORT|=(1<<BIT)
#define CLR_BIT(PORT,BIT) PORT&=~(1<<BIT)
#define BIT_IN(DDR,BIT) DDR&=~(1<<BIT)
#define BIT_OUT(DDR,BIT) DDR|=(1<<BIT)
#define READ_BIT(PIN,BIT) (PIN&(1<<BIT))
#define DIO PD7
#define CLK PD6
#define STB PD4
#define DIO_high SET_BIT(PORTD,DIO)
#define DIO_low CLR_BIT(PORTD,DIO)
#define CLK_high SET_BIT(PORTD,CLK)
#define CLK_low CLR_BIT(PORTD,CLK)
#define STB_high SET_BIT(PORTD,STB)
#define STB_low CLR_BIT(PORTD,STB)
#define DIO_IN BIT_IN(DDRD,DIO) //输入状态
#define DIO_OUT BIT_OUT(DDRD,DIO) //输出状态
#define DIO_READ READ_BIT(PIND,DIO) //读引脚电平
/*
#define DIO_IN DDRD&=~(1<<PD7) //输入状态
#define DIO_OUT DDRD|=(1<<PD7) //输出状态
#define DIO_READ PIND&(1<<PD7) //读引脚电平
//引脚定义
#define DIO_high PORTD|=(1<<PD7)
#define DIO_low PORTD&=~(1<<PD7)
#define CLK_high PORTD|=(1<<PD6)
#define CLK_low PORTD&=~(1<<PD6)
#define STB_high PORTD|=(1<<PD4)
#define STB_low PORTD&=~(1<<PD4)
*/
unsigned char tab[] PROGMEM={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
void TM1638_Write(unsigned char DATA) //写数据函数
{
unsigned char i;
DIO_OUT;
for(i=0;i<8;i++)
{
CLK_low;
if(DATA&0X01)
DIO_high;
else
DIO_low;
DATA>>=1;
CLK_high;
_delay_us(1);
}
}
unsigned char TM1638_Read(void) //读数据函数
{
unsigned char i;
unsigned char temp=0;
DIO_IN;
_delay_us(1);
for(i=0;i<8;i++)
{
temp>>=1;
CLK_low;
_delay_us(1);
if(DIO_READ)
temp|=0x80;
CLK_high;
}
return temp;
}
void Write_COM(unsigned char cmd) //发送命令字
{
STB_low;
TM1638_Write(cmd);
STB_high;
_delay_us(1);
}
unsigned char Read_key(void)
{
unsigned char c,i,key_value=0;
STB_low;
TM1638_Write(0x42);
_delay_us(1);
for(i=0;i<4;i++)
c=TM1638_Read();
STB_high; //4个字节数据合成一个字节
for(i=0;i<4;i++)
key_value|=c<<i;
for(i=0;i<8;i++)
if((0x01<<i)==key_value)
break;
return i;
}
void Write_DATA(unsigned char add,unsigned char DATA) //指定地址写入数据
{
Write_COM(0x44);
STB_low;
TM1638_Write(0xc0|add);
TM1638_Write(DATA);
STB_high;
}
void Write_ALLDATA(unsigned char add,unsigned char *p,unsigned char cnt)
{
unsigned char i;
Write_COM(0x44);
for(i=0;i<cnt;i++)
{
Write_DATA(2*i,*(p+i));
}
}
void Write_oneLED(unsigned char num,unsigned char flag) //单独控制一个LED函数,并且不影响其他的led状态,num为需要控制的led序号,
{ //flag为0时熄灭,为1时红灯亮,为2时绿灯亮,为3时亮橙色
Write_DATA(2*num+1,flag&0x03);
}
void Write_allLED(unsigned char flag) //控制全部LED函数,flag表示LED状态
{
unsigned char i;
for(i=0;i<8;i++)
Write_DATA(2*i+1,flag&0x03);
}
void init_TM1638(void)
{
unsigned char i;
Write_COM(0x88);//亮度
Write_COM(0x40);
STB_low;
TM1638_Write(0xc0);
for(i=0;i<16;i++)
TM1638_Write(0x00);
STB_high;
}
#endif
little_Monkey 发表于 2012-4-17 16:56 static/image/common/back.gif
头文件,直接调用即可
#ifndef _TM1638_H
谢谢楼主的共享精神! 谢谢,刚好在用这个片子,不用自己调了
页:
[1]