搜索
bottom↓
回复: 4

TM1639 驱动8 位共阳数码管测试成功(可用于TM1629A)

[复制链接]

出0入0汤圆

发表于 2012-5-5 22:46:34 | 显示全部楼层 |阅读模式
今天测试下用TM1639来驱动 共阳数码管(因为家中只有4位共阳的数码管)
接线方式跟据官方手册说的接的 GRID接段选  SEG接位选  共阳的驱动起来比较麻烦的就是我做一下数据转换  共阴的就好用了直接写数据就好了

哎,看了看 数据手册的电路图 悲哀了这怎么能错呢?还好没按着那个接(难道我下载的是旧版本的??)






DIO接PD5
CLK接PD6
STB接PD7
数码管取模还是取共阴的码!
上测试程序
#include <avr/io.h>
#define F_CPU 7372800
#include <util/delay.h>

#define uchar unsigned char
#define uint  unsigned int
#define BIT(X) (1<<X)
#define delayms(x) _delay_ms(x)
#define delayus(x) _delay_us(x)

#define dio1 PORTD|=BIT(5)
#define dio0 PORTD&=~BIT(5)
#define clk1 PORTD|=BIT(6)
#define clk0 PORTD&=~BIT(6)
#define stb1 PORTD|=BIT(7)
#define stb0 PORTD&=~BIT(7)

uchar table[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
uchar temp[16]={0};
uchar temp2[16]={0};

uint a;

void init_tm1639()
{
        DDRD|=BIT(5)|BIT(6)|BIT(7);
        dio0;
        clk0;
        stb1;
}
void write_byte(uchar dat)
{
        uchar i;
        stb0;
        for(i=0;i<8;i++)
        {
                if(dat&1)
                {
                        dio1;
                }       
                else
                {
                        dio0;
                }
                clk1;
                clk0;
                dat>>=1;
        }
}
void L_to_H()  //用于共阴码转换为共阳管显示 即 SEG接位选 GRID接段选 16位通用
{
        uchar i,j;
        for(i=0;i<16;i++)
        {
                for(j=0;j<8;j++)
                {
                        if(i<8)   //处理SEG1-8排列顺序
                        {
                                temp2[j*2]>>=1;                        //移空最高位等待数据
                                if((temp&(1<<j)))        //取阴码数据某一位判断是否为“1”
                                {
                                        temp2[j*2]|=0x80;        //为“1”则最高位存入1 否则跳过。
                                }
                        }
                        else         //处理SEG9-16排列顺序
                        {
                                temp2[j*2+1]>>=1;
                                if((temp&(1<<j)))
                                {
                                        temp2[j*2+1]|=0x80;
                                }
                        }
                }
        }
}
void write_tm1639()
{
        uchar i=0;
        L_to_H();
        stb1;
        write_byte(0x40);
        stb1;
        write_byte(0xc0);
        for(i=0;i<16;i++)
        {
                write_byte(temp2);
        }
        stb1;
        write_byte(0x8f);
        stb1;
}
int main(void)
{
        init_tm1639();
        while(1)
        {
                a++;
                temp[8]=table[a/10000];
                temp[3]=table[a%10000/1000];
                temp[2]=table[a%1000/100];
                temp[1]=table[a%100/10];
                temp[0]=table[a%10];
                write_tm1639();
                delayms(1000);
        }
}
  

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2012-5-7 13:48:32 | 显示全部楼层
你用的是51单片机吗?

出0入0汤圆

发表于 2012-5-7 15:54:34 | 显示全部楼层
我这个是52单片机驱动8 位共阴数码管的程序,请教下怎么改成驱动8 位共阳极数码管???


#include<reg52.h>
#include<intrins.h>
#define nop _nop_();
#define uchar unsigned char
#define uint  unsigned int
sbit stb =P1^0;        //定义片选通讯口
sbit clk =P1^1;        //定义时钟通讯口
sbit dio =P1^3;        //定义数据输入/输出通讯口

bdata uchar y=0;//定义可以位寻址全局变量y
sbit y7 =y^7;
uchar show[16] = {0x07,0x06,0x07,0x0b,0x03,0x08,0x03,0x08,0x03,0x0f};//初始化显示“HELLO”字符代码
uchar CODE[20] = {0x03,0x0f,0x00,0x06,0x05,0x0b,0x04,0x0f,0x06,0x06,0x06,0x0d,0x07,0x0d,0x00,0x07,0x07,0x0f,0x06,0x0f}; //0~9显示代码,相邻两个数之间
                                                                                                                        //代码组合显示一个数字
uchar TIME_seconds,seconds_2,sub_1,sub_2,shi_1,shi_2; //时间寄存器,依次从秒个位至小时十位
uchar TIME_count; //定时中断控制制位
uchar T_count;   //时钟小数点闪
/*********************************   
功能: TM1639写数据
**********************************/
void write(uchar wr_data)
{
     uchar i;
         stb =0;           //给有效的片选信号(片选信号是低电平有效)
         nop;
         nop;                 
         for(i=0;i<8;i++)//开始传送8位数据,每循环一次传送一位数据
         {
             clk =0;
                 nop;
                 nop;
             wr_data >>= 1;//移位数据,低位在前!
             nop;
             dio = CY;
             nop;
             nop;
             clk =1;
             nop;
           }
}
/*********************************  
功能:读按键子程序 由y 返回1BIT按键数据
**********************************/
unsigned char read()
{
  uchar d;
  stb = 0;          //给有效的片选信号(片选信号是低电平有效)
  dio = 1;          //将DIO置高,因为没有按键按下时,键值默认为00H,此时为了与键值有区别
  for(d=0;d<8;d++)
   {
     clk = 0;
         nop;
         nop;
         nop;
         nop;
         clk = 1;                   //上升沿读按键值
         nop;
         nop;
         nop;
         nop;

   if(dio==1)
     {
     y7 = 1;
         }
  else
     {
         y7 = 0;
         }

         if(d!=7){y=(y>>1);}   
         nop;
         nop;
        }
        return(y);
}                    
/*********************************
    TM1639控制指令
功能: 驱动LED屏做相应的显示
**********************************/
void xianshi(uchar show_led[16])
{
  uchar h;
  stb = 1;
  clk = 1;
  dio = 1;
  write(0x40);//写数据到显示寄存器,采用地址自动加一
  stb = 1;
  write(0xc0);//显示寄存器的00H单元开始
  for(h=0;h<16;h++)
  {   
   write(show_led[h]);//给显示寄存器送数据,
   }
   stb=1;
   write(0x8b);//显示控制参数,点亮数码屏幕,亮度可以通过改变低三位调节
   stb = 1;
}

//-------读按键以及相应的显示处理-------
void panjian()
{
   P3=0xf0
   uchar count3,key[4];
   stb = 1;
   write(0x42);//送读按键命令(42H),
     TR0 = 1;
         shi_2 = 0;
         shi_1 = 0;
         sub_2 = 0;
         sub_1 = 0;
         seconds_2 = 0;
         TIME_seconds = 0;
        }  
}
/**********************************
     定时中断函数入口
功能: 每50MS中断一次
**********************************/  
void time0(void) interrupt 1 using 2
{
  TH0=0x3c;
  TL0=0xb0;
  TIME_count++;
  if(TIME_count==21)
  {
    TIME_count = 0;
    TIME_seconds++;        // 秒寄存器加1
        T_count ^= 0x08;
   }
}
/*********************************
     时钟函数
功能: 处理时钟显示
**********************************/
void TIME_show()
{
  show[0] = CODE[TIME_seconds*2];
  show[1] = CODE[TIME_seconds*2+1];        // 数码屏上最后一个“8”字,依次下去
  show[2] = CODE[seconds_2*2];   //数码屏倒数第二个“8”字,
  show[3] = CODE[seconds_2*+1];
  show[4] = CODE[sub_1*2];
  show[5] = CODE[sub_1*2+1]|T_count;
  show[6] = CODE[sub_2*2];
  show[7] = CODE[sub_2*2+1];
  show[8] = CODE[shi_1*2];
  show[9] = CODE[shi_1*2+1]|T_count;
  show[10] = CODE[shi_2*2];
  show[11] = CODE[shi_2*2];
  if(TIME_seconds == 10)          //对时间数据进行处理,以免溢出。
   {
     TIME_seconds = 0;
         seconds_2+=1;
        }
  if(seconds_2 == 6)
   {
     seconds_2 = 0;
         sub_1 +=1;
        }
  if(sub_1 == 10)
   {
     sub_1 = 0;
         sub_2 +=1;
        }
  if(sub_2 == 6)                                                                                       
   {
     sub_2 = 0;
         shi_1 +=1;
    }
  if(shi_1 == 10)
   {
     shi_1 = 0;
         shi_2 +=1;
        }
  if(shi_2 == 6)          //时钟每60小时自动清0
   {
     shi_2 = 0;
         shi_1 = 0;
         sub_2 = 0;
         sub_1 = 0;
         seconds_2 = 0;
         TIME_seconds = 0;
        }
}      
/*********************************
    延时函数
功能: 1ms延时
**********************************/
void delay_ms(uchar cyc)
{
        //当cyc=1的时候,延时1ms
        uchar ii,jj;
        for(jj=1;jj<=cyc;jj++)
        {
                for(ii=0;ii<200;ii++)
                {
                        nop;
                }
        }
}         
/*********************************
    主函数
**********************************/
void main()
{
P0=0xff;
P1=0xff;
P2=0xff;
P3=0xff;//初始化单片机I/O口
TMOD=0x01;  //定时器设置
TH0=0x3c;
TL0=0xb0;
IE=0x82;
TF0=1;
xianshi(show);//初始化显示“HELLO”字符
delay_ms(230);
delay_ms(230);
delay_ms(230);   
delay_ms(230);
delay_ms(230);    //共延时1s
while(1)//循环
{
stb = 1;
dio = 1;
clk = 1;
TIME_show();   //控制做时钟显示
panjian();     //判断按键值
xianshi(show); //根据按键值,给显示寄存器送相应的显示数据
}
}
     

出0入0汤圆

 楼主| 发表于 2012-5-7 16:49:39 | 显示全部楼层
zzcseu 发表于 2012-5-7 15:54
我这个是52单片机驱动8 位共阴数码管的程序,请教下怎么改成驱动8 位共阳极数码管???

插入下面一段就好了 自己编的不知道能不能看得懂!我用的是M16测试的  我想51也是一样的!都只是数据的处理
把一个字节的数拆成8位 放到8个字节的同一位中(例如:0xff 拆了变成8个0x01)
void L_to_H()  //用于共阴码转换为共阳管显示 即 SEG接位选 GRID接段选 16位通用
{
        uchar i,j;
        for(i=0;i<16;i++)
        {
                for(j=0;j<8;j++)
                {
                        if(i<8)   //处理SEG1-8排列顺序
                        {
                                temp2[j*2]>>=1;                        //移空最高位等待数据
                                if((temp&(1<<j)))        //取阴码数据某一位判断是否为“1”
                                {
                                        temp2[j*2]|=0x80;        //为“1”则最高位存入1 否则跳过。
                                }
                        }
                        else         //处理SEG9-16排列顺序
                        {
                                temp2[j*2+1]>>=1;
                                if((temp&(1<<j)))
                                {
                                        temp2[j*2+1]|=0x80;
                                }
                        }
                }
        }
}

出0入0汤圆

发表于 2016-9-9 16:57:04 | 显示全部楼层
今天正好用到这个,先收藏了,感谢楼主
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-22 07:36

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表