STC15控制数码管 38译码器

共阳极数码管举例

#define 	MAIN_Fosc		27000000L	//定义主时钟

#include	"STC15Fxxxx.H"

#define uchar unsigned char

void enable_38(void);
void LED_OUT(uchar X);
void Led_test(char pos);

//数码管显示0-9值,全暗状态是0xFF
unsigned char code LED_0F[] =
{
   //0   1     2     3     4     5     6     7     8     9
   0x11, 0xD7, 0x32, 0x92, 0xD4, 0x98, 0x18, 0xD3, 0x10, 0x90,
};

//595控制数码管
sbit DIO = P2 ^ 7;			//串行数据输入
sbit RCK = P2 ^ 6;			//锁存
sbit SCK = P2 ^ 5;			//移位

//38译码器3个输入和1个使能
sbit _74HC238_A0 = P2 ^ 4;
sbit _74HC238_A1 = P2 ^ 3;
sbit _74HC238_A2 = P2 ^ 2;
sbit _74HC238_E1 = P2 ^ 1;	 //拉低有效

//用于控制38译码器输出不同值,来源于真值表
uchar _38[] = {0x0, 0x10, 0x8, 0x18}; //位选每个数码管

// 主程序
void main(void)
{
   P0M1 = 0;
   P0M0 = 0;	//设置为准双向口
   P1M1 = 0;
   P1M0 = 0;
   P2M1 = 0;
   P2M0 = 0;
   P3M1 = 0;
   P3M0 = 0;
   P4M1 = 0;
   P4M0 = 0;
   P5M1 = 0;
   P5M0 = 0;
   P6M1 = 0;
   P6M0 = 0;
   P7M1 = 0;
   P7M0 = 0;

   while(1)
   {
      enable_38();
   }
}

//========================================================================
// 函数: void  delay_ms(u8 ms)
// 描述: 延时函数。
// 参数: ms,要延时的ms数, 这里只支持1~255ms. 自动适应主时钟.
// 返回: none.
// 版本: VER1.0
// 日期: 2013-4-1
// 备注:
//========================================================================
void  delay_ms(u8 ms)
{
   u16 i;

   do
   {
      i = MAIN_Fosc / 13000;

      while(--i);
   }
   while(--ms);
}

//使能38译码器输出不同值,此函数很重要
//因为是共阳极数码管,所以必须先段选(先给电平)再位选(使能),不然有微弱重影
void enable_38(void)
{
   static char index = 0; //代表位选第n列

   Led_test(index); //显示第n列

   //位选
   P2 &= 0xE3;
   P2 |= _38[index];

   //38译码器使能
   _74HC238_E1 = 0;

   delay_ms(1);

   //38译码器去使能,必须要去使能以后再使能下一个数码管,不然有严重重影
   _74HC238_E1 = 1;

   index++; //循环点亮
   index %= 4; //一共4列
}

//点亮一个数码管
void LED_display(uchar X)
{
   LED_OUT(X); //段选
   RCK = 0; //锁存
   RCK = 1;
}

/*
	38译码器每次位选一列数码管,一列有四个数码管,分别用595控制
	pos: 第n列数码管
*/
void Led_test(char pos)
{
   switch(pos)
   {
      case 0:
         //位选一次,分别点亮4个数码管
         LED_display(LED_0F[0]);
         LED_display(LED_0F[1]);
         LED_display(LED_0F[2]);
         LED_display(LED_0F[3]);
         break;

      case 1:
         LED_display(LED_0F[3]);
         LED_display(LED_0F[2]);
         LED_display(LED_0F[1]);
         LED_display(LED_0F[0]);
         break;

      case 2:
         LED_display(LED_0F[5]);
         LED_display(LED_0F[6]);
         LED_display(LED_0F[7]);
         LED_display(LED_0F[8]);
         break;

      case 3:
         LED_display(LED_0F[8]);
         LED_display(LED_0F[7]);
         LED_display(LED_0F[6]);
         LED_display(LED_0F[5]);
         break;

      default:
         break;
   }
}

//单个数码管显示
void LED_OUT(uchar X)
{
   uchar i;

   for(i = 8; i >= 1; i--)
   {
      if(X & 0x80)
      {
         DIO = 1;
      }
      else
      {
         DIO = 0;
      }

      X <<= 1;

      SCK = 0; //移位
      SCK = 1;
   }
}

38译码器https://blog.csdn.net/zhangxuechao_/article/details/91566673

posted @ 2019-07-16 13:15  thomas_blog  阅读(479)  评论(0编辑  收藏  举报