单片机学习小组
直播中

tulin

12年用户 1225经验值
私信 关注

如何利用CC2530和74HC595实现数码管动态显示数字的效果?

数码管的原理是什么?
如何利用CC2530和74HC595实现数码管动态显示数字的效果?

回帖(1)

黎桂珍

2022-1-25 10:34:09
本文章主要介绍了数码管的原理,结合CC2530单片机和74HC595驱动,实现数码管动态显示数字的效果。

































注意:
我们使用的是共阳极的数码管,低电平点亮对应的LED,比如我们要点亮数码管中的LED a,需要在Q0上输出低电平,即 让 Q0 = 0;
同学们自己完成上表。






























完整的源代码


#include
//定义控制灯的端口
#define LED1 P1_0 //定义LED1为P1_0口控制
#define LED2 P1_5 //定义LED2为P1_5口控制
#define LED3 P1_3 //定义LED3为P1_3口控制
#define LED4 P1_4 //定义LED4为P1_4口控制


#define SW1 P1_2        //定义SW1为P1_2端口
#define SW2 P0_1        //定义SW2为P0_1端口


#define SRCLK P0_4
#define RCLK  P0_5
#define SER   P0_6


#define LEDS0 P0_7
#define LEDS1 P1_7
#define LEDS2 P0_0


const unsigned char LED7Code[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
                              // 0     1   2    3     4   5    6    7    8    9  
/****************************
//延时
*****************************/
void Delay_mS(unsigned int n)
{
unsigned int tt,i = 0;
        for(i = 0; i < n; i ++)
   for(tt = 0; tt<1040; tt++);
}
void Delay_uS(unsigned int n)
{
  unsigned int i = 0;
  for(;i < n; i++);
}


/****************************
//初始化函数
*****************************/
void Initial(void)
{
        CLKCONCMD &= 0x80;//使用外部32MHz晶振
        
        P0DIR = 0xFF;
        P2DIR = 0xFF;
        P1DIR = 0xFB;//将P12设为输入,其他设为输出 (0xFB = 11111011)
        
        LED1 = 0;//关闭LED1
        LED2 = 0;//关闭LED2
        LED3 = 0;//关闭LED3
        LED4 = 0;//关闭LED4
        
        LEDS0 = 1;
        LEDS1 = 1;
        LEDS2 = 1;
}
/****************************
//数码管显示函数
*****************************/
void Hc595SendByte(unsigned char dat)
{
  unsigned char a = 8;
  SRCLK = 0;
  RCLK  = 0;
  for(a = 0; a < 8; a ++)
  {
    SER = dat >> 7;
    dat <<= 1;
    SRCLK = 1;
    Delay_uS(1);
    SRCLK = 0;
  }
  RCLK = 1;
  Delay_uS(1);
  RCLK = 0;
}
/*****************************************
//读键值
//单击返回1
//双击返回11
//长按返回111
*****************************************/
unsigned char KeyScan(void)
{
  if(SW1 == 0)       //低电平有效
  {
    Delay_mS(20);     //消除抖动
    if(SW1 == 0)
    {
        while(!SW1); //直到松开按键
        return(1);
    }
  }
  return(0);
}


unsigned char Keyvalue = 0 ; //用来记录按键的值
unsigned char i = 0;
/***************************
//主函数
***************************/
void main(void)
{
        int a = 0;
        int g,s,b,time = 0;   
        Initial();  //调用初始化函数
        Hc595SendByte(0xC0); //控制数码管显示数字0
        while(1)
        {
              g  = a %10;   //获得a的个位
              s  = (a/10)%10; //获得a的十位
              b  = (a/10)/10; //获得a的百位
              LEDS0 = 0; LEDS1 = 0; LEDS2 = 0;  //关闭所有数码管
              Hc595SendByte(LED7Code[g]); //个位
              LEDS0 = 1; LEDS1 = 0; LEDS2 = 0;//打开数码管1
              Delay_mS(1);
              LEDS0 = 0; LEDS1 = 0; LEDS2 = 0;//关闭所有数码管
              Hc595SendByte(LED7Code); //十位
              LEDS0 = 0; LEDS1 = 1; LEDS2 = 0;//打开数码管2
              Delay_mS(1);
              LEDS0 = 0; LEDS1 = 0; LEDS2 = 0;//关闭所有数码管
              Hc595SendByte(LED7Code); //百位
              LEDS0 = 0; LEDS1 = 0; LEDS2 = 1; //打开数码管3
              Delay_mS(1);
              time ++;
              if(time > 333) //扫描周期是 3 mS, 333个扫描周期刚好约等于 1S
              {
                time = 0;
                a ++;
                if(a >=1000)
                {
                  a = 0;
                }
              }
        }
}
改进空间

在上述代码中,我们是通过延时来实现给每个数码管分配显示时间的,如果在主函数中调用了其他延时函数就会影响数码管的时间分配,导致数码管颜色亮度不一。
如果学了定时器,我们可以在定时器中实现上述操作,可以节省CPU的资源,也可以防止时间被打乱导致数码管亮度不一致。
举报

更多回帖

×
20
完善资料,
赚取积分