共陽極數位管舉例
#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