5、数码管驱动使用

一、判断现在手里头买的是共阴还是共阳数码管

我们可使用万用表进行最简单判断,将万用表调到二极管档,

(1)万用表笔随便一脚,假设红笔, 搭在数码管上任一脚 。黑笔在其它脚上扫过,如果不亮,有可能此管为共阴,可用2法再试。如有一段点亮。黑笔不动, 移动红笔,在其它脚测。如果其它脚 分别都 能点亮,则可以说明黑笔接的是公共脚 ,此管共阳。(指针 表的黑表笔是正电源)

(2)表笔更换一下,黑笔先搭一脚,扫红笔。如有一段点亮,红笔不动,扫黑笔。如各段分别点亮,则红笔所接为公共 ,此管共阴

二、段选与位选

多位一体数码管,内部的公告端是独立的,我们把公共端叫做位选线

负责显示什么数字的线全部都是连接在一起,我们把这个叫做段选线

三、现在使用大部分都直接使用驱动芯片了,所以我们重点来讲驱动芯片的使用

网上搜一搜 ,比如tm1650就是一个8*4驱动,可以驱动4位数码管,采用的IIC通讯

当时开发用的中微的芯片,所以在此我就拿中微的CMS1650来写,其实他跟TM1650都是一样的,数码管驱动芯片大同小异,掌握一款其他就都会了。

三、CMS1650

1、概述

方便使用,电路设计便捷,工作电压又低,堪称完美

2、管脚

管脚分布图DIG就是位选,其他就是段选

3、通讯协议

通讯协议采用的是IIC通讯协议。我们可以看看规格书,规格书我上传了。

(1)先来看看规格书写的协议的开始的信号与停止信号

启始信号,在SCL为高电平期间,SDA出现下降沿现象;

考虑代码整洁性,我们可以先进行宏定义

#define CLS_CMS_SCL   P0_4 = 0   //时钟拉低
#define SET_CMS_SCL   P0_4 = 1   //时钟拉高 
#define SET_CMS_SDA   P0_5 = 1   //数据拉低
#define CLS_CMS_SDA   P0_5 = 0   //数据拉高

#define CLK           P0_4  
#define SDA           P0_5  

#define SDA_OUT()     {P0TRIS |= 0x20;P0 |= 0x20; } 
#define SDA_INT()     {P0TRIS &= 0xDF;P0UP |=0x20;}

void LED_Init(void)
{
  P0TRIS |= 0x10; //设置P04输出 SCL
    P0 |= 0x10;     //输出高    
 
    P0TRIS |= 0x20; //设置P05输出 SDA
    P0 |= 0x20;     //输出高
}

void CMS1650_Start(void) //SCL 为“1”,SDA 从“1”跳“0”,认为是开始信号

    SDA_OUT();//设置/SCL、SDA 为输出脚
    SET_CMS_SCL;
    SET_CMS_SDA;
    delay_us(5);
    CLS_CMS_SDA;
    delay_us(5);
    CLS_CMS_SCL;//钳住I2C总线,准备发送或接收数据,(IIC规定只有在SCL为低电平期间,数据线上才允许高低变化,所以开始信号启动后,拉低SCL)
}

void CMS1650_Stop(void) // SCL 为“1”电平,SDA 从“0”跳“1”,认为是结束信号

    SDA_OUT();
    SET_CMS_SCL;
    CLS_CMS_SDA;
    delay_us(5);
    SET_CMS_SDA;
    delay_us(5);//停止信号,就不用把SCL拉低
}

(2)应答信号

应答信号由接收设备产生,在SCL为高电平期间,接收设备将SDA拉低说明数据传输正确,产生应答。

所以我们代码应该这样写,传输完数据后,得先释放数据线;再将SCL拉高,判断低电平是否到来。

//等待从机应答信号到来
//返回值:1,接收应答失败
//              0,接收应答成功
u8 CMS1650_Wait_Ack(void)
{
    u16 time = 0;
     SDA_INT();//将SDA设置为上拉输入 ,主机释放数据总线(总线在空闲状态为高电平)等待从机产生应答信号       

    delay_us(5);  
    SET_CMS_SCL;//   SCL拉高
    while(SDA == 1)//在while循环延时这段时间内,看丛机是否有产生应答信号,有的话SDA就=0,跳出循环
    {
        time++;
        if(time>255)//从机没应答,传输失败
        {
            CMS1650_Stop();
            return 1; //有必要的话显示或者产生个中断说明传输失败,跳出循环。注:return可以可以跳出while循环

                                                                      continue:不跳出当前循环,结束本次循环(结束当前循环),执行下一轮循环
                                                                      break:跳出当前循环,结束该循环执行
        }
    }
    CLS_CMS_SCL;
    return 0;  
}

(3)写入数据

void CMS1650_SendByte(u8 txd)
{
  u8 t = 0;   
//   SDA_OUT();
//  CLS_CMS_SCL;//拉低时钟开始数据传输    ,开始信号已经拉低SCL了,这里可以不用写了
   for(t=0;t<8;t++)
   {   
            if((txd&0x80)>>7)
                SET_CMS_SDA;
            else
                CLS_CMS_SDA;
            txd<<=1; 
            delay_us(5); 
            SET_CMS_SCL;//数据发送完,拉高时钟
            delay_us(5); 
            CLS_CMS_SCL;//拉低时钟开始数据传输    
            delay_us(5);
     }
}

对于数据的写入为啥要SCL 从“0”跳到“1”,再从“1”跳到“0”这么写,我们来看看接收方是怎么接收就一目了然了;

从设备收数据:主设备发送了开始位后,把clk拉低,只有clk拉低,sda才可以做高低变化; 当clk被拉高时,(0->1)从设备就会去读取sda的高低电平值;clk再次被拉低时,(1->0)从设备认为此位已读取完毕,认为是有效位,等待clk再次拉高,读取下一位。

(4)一个完整的写显示时序

首先得先写入数据命令,然后开显示确定显示的亮度

8段显示的话就是小数点也显示出来

再来确定显存地址(确定位选地址)

最后

void main()
{

  u8 t = 0;

    LED_Init(); //SCL SDA 设置为输出

   delay_ms(300);    //延时一段时间,否则开显示无响应

   CMS1650_SendByte(0x48);

   CMS1650_Wait_Ack();//等待应答

 //这里应答处理,看大家要做什么处理,这里应答处理我就先不作处理

   CMS1650_SendByte(0x30);//开显示:3级亮度

    CMS1650_Wait_Ack();//等待应答    
    CMS1650_Stop();

    CMS1650_WriteByte(0x6E,0x7f);
    CMS1650_WriteByte(0x6C,0x7f);
    CMS1650_WriteByte(0x6A,0x7f);
    CMS1650_WriteByte(0x68,0x7f);//开机8888

 //单片机上电数码管显示8.8.8.8.

}

全部代码

void LED_Init(void)
{
  P0TRIS |= 0x10; //设置P04输出 SCL
    P0 |= 0x10;     //输出高    
 
    P0TRIS |= 0x20; //设置P05输出 SDA
    P0 |= 0x20;     //输出高
}
void CMS1650_Start(void) //SCL 为“1”,SDA 从“1”跳“0”,认为是开始信号

    SDA_OUT();
    SET_CMS_SCL;
    SET_CMS_SDA;
    delay_us(5);
    CLS_CMS_SDA;
    delay_us(5);
    CLS_CMS_SCL;//钳住I2C总线,准备发送或接收数据
}
void CMS1650_Stop(void) // SCL 为“1”电平,SDA 从“0”跳“1”,认为是结束信号

    SDA_OUT();
    SET_CMS_SCL;
    CLS_CMS_SDA;
    delay_us(5);
    SET_CMS_SDA;
    delay_us(5);
}

//等待从机应答信号到来
//返回值:1,接收应答失败
//        0,接收应答成功
u8 CMS1650_Wait_Ack(void)
{
    u16 time = 0;
    SDA_OUT();
    SET_CMS_SDA;delay_us(1);//主机释放数据总线,(总线在空闲状态为高电平)等待从机产生应答信号       
    SET_CMS_SCL;delay_us(1);     
    SDA_INT();//将SDA设置为上拉输入
    while(SDA == 1)//在while循环延时这段时间内,看丛机是否有产生应答信号,有的话SDA就=0,跳出循环
    {
        time++;
        if(time>255)//从机没应答,传输失败
        {
            CMS1650_Stop();
            return 1; //有必要的话显示或者产生个中断说明传输失败
        }
    }
    CLS_CMS_SCL;
    return 0;  
}

void CMS1650_SendByte(u8 txd)
{
  u8 t = 0;   
//    SDA_OUT();
//  CLS_CMS_SCL;//拉低时钟开始数据传输    ,开始信号已经拉低SCL了,这里可以不用写了
   for(t=0;t<8;t++)
   {   
            if((txd&0x80)>>7)
                SET_CMS_SDA;
            else
                CLS_CMS_SDA;
            txd<<=1; 
            delay_us(5); 
            SET_CMS_SCL;//数据发送完,拉高时钟
            delay_us(5); 
           CLS_CMS_SCL;//拉低时钟开始数据传输    
            delay_us(5);
     }
}

void CMS1650_WriteByte(u8 Addr,u8 Data)
{
    CMS1650_Start();
    CMS1650_SendByte(Addr);
    CMS1650_Wait_Ack();//等待应答
    CMS1650_SendByte(Data);
    CMS1650_Wait_Ack();//等待应答    
    CMS1650_Stop();
}

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值