段式数码管扫描程序如何减少代码量(采用扫描段码方式)
最近弄LED段式数码管程序(采用扫描段码方式),但是编写后发现代码多,不知如何可以减少代码量。//====================================================================
//=== 显示扫描函数 ===//
void display_scan(void)
{
unsigned char i;
P1 &= Bin(11111110);
P1 |= Bin(11111000);
P2 &= Bin(00000000);
P3 &= Bin(01100111);
P3 |= Bin(01100110);//关闭段码和位码,如共阳数码管(公共脚置低,段码置高)
//======================================//
for(i = 0;i < 4;i ++)
{
r_dis_data = table_seg]; //查LED段码表
}
switch (r_dig_bit) //在公共端接限流电阻,在数码管位数少时布线时有优势
{
case 1:
p_seg_a = 0; //扫描a段
if(r_dis_data & 0x01) p_dig_1 = 1;//如果r_dis_data第0位为高,则需要点亮,反之则不点亮
if(r_dis_data & 0x01) p_dig_2 = 1;
if(r_dis_data & 0x01) p_dig_3 = 1;
if(r_dis_data & 0x01) p_dig_4 = 1;
if(r_dis_buff & 0x01) p_dig_5 = 1;
if(r_dis_buff & 0x01) p_dig_6 = 1;
break;
case 2:
p_seg_b = 0;
if(r_dis_data & 0x02) p_dig_1 = 1;
if(r_dis_data & 0x02) p_dig_2 = 1;
if(r_dis_data & 0x02) p_dig_3 = 1;
if(r_dis_data & 0x02) p_dig_4 = 1;
if(r_dis_buff & 0x02) p_dig_5 = 1;
if(r_dis_buff & 0x02) p_dig_6 = 1;
break;
case 3:
p_seg_c = 0;
if(r_dis_data & 0x04) p_dig_1 = 1;
if(r_dis_data & 0x04) p_dig_2 = 1;
if(r_dis_data & 0x04) p_dig_3 = 1;
if(r_dis_data & 0x04) p_dig_4 = 1;
if(r_dis_buff & 0x04) p_dig_5 = 1;
if(r_dis_buff & 0x04) p_dig_6 = 1;
break;
case 4:
p_seg_d = 0;
if(r_dis_data & 0x08) p_dig_1 = 1;
if(r_dis_data & 0x08) p_dig_2 = 1;
if(r_dis_data & 0x08) p_dig_3 = 1;
if(r_dis_data & 0x08) p_dig_4 = 1;
if(r_dis_buff & 0x08) p_dig_5 = 1;
if(r_dis_buff & 0x08) p_dig_6 = 1;
break;
case 5:
p_seg_e = 0;
if(r_dis_data & 0x10) p_dig_1 = 1;
if(r_dis_data & 0x10) p_dig_2 = 1;
if(r_dis_data & 0x10) p_dig_3 = 1;
if(r_dis_data & 0x10) p_dig_4 = 1;
if(r_dis_buff & 0x10) p_dig_5 = 1;
if(r_dis_buff & 0x10) p_dig_6 = 1;
break;
case 6:
p_seg_f = 0;
if(r_dis_data & 0x20) p_dig_1 = 1;
if(r_dis_data & 0x20) p_dig_2 = 1;
if(r_dis_data & 0x20) p_dig_3 = 1;
if(r_dis_data & 0x20) p_dig_4 = 1;
if(r_dis_buff & 0x20) p_dig_5 = 1;
if(r_dis_buff & 0x20) p_dig_6 = 1;
break;
case 7:
p_seg_g = 0;
if(r_dis_data & 0x40) p_dig_1 = 1;
if(r_dis_data & 0x40) p_dig_2 = 1;
if(r_dis_data & 0x40) p_dig_3 = 1;
if(r_dis_data & 0x40) p_dig_4 = 1;
if(r_dis_buff & 0x40) p_dig_5 = 1;
if(r_dis_buff & 0x40) p_dig_6 = 1;
break;
case 8:
p_seg_h = 0;
if(r_dis_data & 0x80) p_dig_1 = 1;
if(r_dis_data & 0x80) p_dig_2 = 1;
if(r_dis_data & 0x80) p_dig_3 = 1;
if(r_dis_data & 0x80) p_dig_4 = 1;
if(r_dis_buff & 0x80) p_dig_5 = 1;
if(r_dis_buff & 0x80) p_dig_6 = 1;
break;
default:
keyscan_process(); //按键扫描
break;
}
r_dig_bit ++;
if(r_dig_bit >= 9) //扫描时基
r_dig_bit = 0;
} switch (r_dig_bit)
{
case 0:
p_seg_a = 0;
break;
case 1:
p_seg_b = 0;
break;
......
}
if(r_dis_data & (1<<r_dig_bit)) p_dig_1 = 1;
if(r_dis_data & (1<<r_dig_bit)) p_dig_2 = 1;
......
r_dig_bit ++;
if(r_dig_bit >= 8) //扫描时基
r_dig_bit = 0;
(1<<r_dig_bit)可以用数组代替。
这个switch 语句也可以用数组代替。
例如:
P1|=table_p1set;//置高某些位
P1&=table_p1clr;//置低某些位 本帖最后由 yilin411 于 2014-4-14 13:05 编辑
/*****************************************************************************
显示表格
*****************************************************************************/
const u8 LedDisplay_B = {0x1b,0x08,0x1d,0x1c,0x0e,0x16,0x17,0x18,0x1f,0x1e};
const u8 LedDisplay_C = {0x03,0x01,0x02,0x03,0x01,0x03,0x03,0x01,0x03,0x03};//数字0~9
#define Dispaly_Off() _pb = 0x20;_pc = 0x04
/*****************************************************************************
函 数 名: F_Display
功能描述: 数码管分时扫描(2位7段数码管)
输入参数: R_Display_Dat
输出参数: 无
返 回 值: 无
调用函数: 无
被调函数: 无
*****************************************************************************/
void F_Display(u8 R_Display_Dat)
{
R_Display_Dat_shi = R_Display_Dat / 10;
R_Display_Dat_ge= R_Display_Dat % 10;
if(0 == R_Display_cnt)
{
Dispaly_Off();
_pb |= LedDisplay_B;
_pc |= LedDisplay_C;
}
else if(1 == R_Display_cnt)
{
Dispaly_Off();
_pb |= LedDisplay_B;
_pc |= LedDisplay_C;
}
R_Display_cnt++;
if(R_Display_cnt >= 2)
{
R_Display_cnt = 0;
}
} yilin411 发表于 2014-4-14 13:00
/*****************************************************************************
显示表格
********* ...
我程序就是用这种方式,感觉挺省的。
1位 6段,大侠给瞅瞅。
/*********** 显示子程序 *************/
void Disp()//显示
{
Disp_Num++;
Disp_F_Num++;
if(Disp_F_Num == 100)
{
Disp_F_Num = 0;
if(Disp_1_F)//数码闪烁
Dis1 = ~Dis1;
else//数码不闪烁
Dis1 = Duan_Liang;
if(Disp_2_F)//数码闪烁
Dis2 = ~Dis2;
else//数码不闪烁
Dis2 = Duan_Liang;
if(Disp_3_F)//数码闪烁
Dis3 = ~Dis3;
else//数码不闪烁
Dis3 = Duan_Liang;
if(Disp_4_F)//数码闪烁
Dis4 = ~Dis4;
else//数码不闪烁
Dis4 = Duan_Liang;
if(Disp_5_F)//数码闪烁
Dis5 = ~Dis5;
else//数码不闪烁
Dis5 = Duan_Liang;
if(Disp_6_F)//数码闪烁
Dis6 = ~Dis6;
else//数码不闪烁
Dis6 = Duan_Liang;
}
Disp_1 = Disp_2 = Disp_3 = Disp_4 = Disp_5 = Disp_6 = Duan_Mie;//先都熄灭
switch(Disp_Num)
{//第 1 数码管显示 20MS后,显示第 2 数码管
case 1:
//显示 第 1 个 8 字
if(Dis1 == Duan_Liang)
{
P2 = Display_Buf;// 百位
if(Disp_N1)//如果 Disp_N1 为 1,表示显示小数点
{
P2 = P2 ^ Number;
}
Disp_1 = Duan_Liang;
}
break;
case 2:
//显示 第 2 个 8 字
if(Dis2 == Duan_Liang)
{
P2 = Display_Buf;// 十位
if(Disp_N2)//如果 Disp_N1 为 1,表示显示小数点
{
P2 = P2 ^ Number;
}
Disp_2 = Duan_Liang;
}
break;
case 3:
//显示 第 3 个 8 字
if(Dis3 == Duan_Liang)
{
P2 = Display_Buf;// 个位
if(Disp_N3)//如果 Disp_N1 为 1,表示显示小数点
{
P2 = P2 ^ Number;
}
Disp_3 = Duan_Liang;
}
// Disp_Num = 0;
break;
case 4:
//显示 第 1 个 8 字
if(Dis4 == Duan_Liang)
{
P2 = Display_Buf;// 百位
if(Disp_N4)//如果 Disp_N1 为 1,表示显示小数点
{
P2 = P2 ^ Number;
}
Disp_4 = Duan_Liang;
}
break;
case 5:
//显示 第 2 个 8 字
if(Dis5 == Duan_Liang)
{
P2 = Display_Buf;// 十位
if(Disp_N5)//如果 Disp_N1 为 1,表示显示小数点
{
P2 = P2 ^ Number;
}
Disp_5 = Duan_Liang;
}
break;
case 6:
//显示 第 3 个 8 字
if(Dis6 == Duan_Liang)
{
P2 = Display_Buf;// 个位
if(Disp_N6)//如果 Disp_N1 为 1,表示显示小数点
{
P2 = P2 ^ Number;
}
Disp_6 = Duan_Liang;
}
Disp_Num = 0;
break;
}
}
{:smile:}{:smile:}长见识 yilin411 发表于 2014-4-14 13:00
/*****************************************************************************
显示表格
********* ...
您这个是段码,位码分别在同一组IO口。如果在不同IO口怎么办呢? lcw_swust 发表于 2014-4-14 09:22
switch (r_dig_bit)
{
case 0:
试过了这个程序,比之前代码少了1/4左右,虽然有点少,不过能减少代码还是很不错的。。。。多谢您提供方法。 lyhfdz 发表于 2014-4-14 20:25
1位 6段,大侠给瞅瞅。
/*********** 显示子程序 *************/
void Disp()//显示
您这个代码量比我的应该不会少吧? lmt50211 发表于 2014-4-16 09:06
您这个是段码,位码分别在同一组IO口。如果在不同IO口怎么办呢?
只是给你参考,不在同一口这样的问题应该难不倒你吧。同一个口多的做成表格,少的直接控制,很简单的事 {:lol:}用3维数组做段码液晶表的路过(这是我第一次接触段码液晶) 以前有做个二维的 cmheia 发表于 2014-4-16 09:33
用3维数组做段码液晶表的路过(这是我第一次接触段码液晶)
以前有做个二维的 是不是这个意思?
unsigned char segment;//扫描段数
void TransmitDisplayByte(unsigned char code){
}
void segmentScan(unsigned char *bufferAddress, unsigned char amount){
unsigend char i;
unsigend char buffer = 0;
for (i = 0; i < amount; i++){//位码转换末位 ---> 首位
buffer <<= 1;
if (*(bufferAddress + i) & (1 << segment)){
buffer++;
}
if ((i + 1) % 8 == 0){//发送位码
TransmitDisplayByte(buffer);
}
}
if (i % 8 != 0){//发送最后几位位码
TransmitDisplayByte(buffer);
}
//发送段码
TransmitDisplayByte();
if (segment < 7){//8段数码管 一个完整显示周期扫描8次
segment++;
}else{
segment = 0;
}
}
上面的代码没试过,只是个思路。 学习一下{:lol:} 楼上的扫描代码测试通过
static void SegmentSan(unsigned char *bufferAddress, unsigned char com)
{
static unsigned char segment = 0;//扫描段数
unsigned char i;
unsigned char buffer =0;
//消隐,关闭段码&位码 如共阴(COM 置高,段码置低)
WriteOneByte(0xFF);//发送位码
WriteOneByte(0x00);//发送段码
HC595_LATCH(0);
HC595_LATCH(1);
//一个循环周期16ms 65.2HZ8段 每段 16/8=2ms
//限流电阻放置在公共端,在数码管位数少时布线时有优势适合段示扫描
for (i = 0; i < com; i++) //位码转换末位 ---> 首位
{
buffer <<= 1;
if(*(bufferAddress + i) & (1 <<segment))
{
buffer|=0x1;
}
if ((i + 1) % 8 == 0) //超出8位,满8位发送位码
{
WriteOneByte(~buffer); //位码, buf第0位为高,则需要点亮,反之则不点亮 共阴L共阳H
}
}
if (i % 8 != 0) //不满8位或超出8位的位码
{
WriteOneByte(~buffer); //发送位码
}
WriteOneByte(*(const unsigned char*)(bitDispDef+segment));//发送段码
HC595_LATCH(0);
HC595_LATCH(1);
if(++segment > 8) segment = 0; //8段数码管一个完整显示周期扫描8次
} 我看到有产品上使用4 位数码管做 4~20mA ,看上去效果也不错。
仔细想了一下,每个数码管的大概2mA 左右,提高扫描速度,每次只点亮一个灯。这样数码管的平均电流也差不多在2mA.
实例代码如下,已经测试通过。
static void DotSegment_Scan(unsigned char *bufferAddress, unsigned char com)
{
static unsigned char segment = 0;//扫描段数
static unsigned char ComScan = 0;
unsigned char i;
unsigned char buffer =0;
//消隐,关闭段码&位码 如共阴(COM 置高,段码置低)
//限流电阻不要放在被扫描的一端
WriteOneByte(0xFF);//发送位码
WriteOneByte(0x00);//发送段码
HC595_LATCH(0);
HC595_LATCH(1);
//COM*8 个灯,适合位数比较少的情况下,平均电流2.5mA
switch(segment)
{
case 0:
if(*(bufferAddress + ComScan) & (1 <<segment))
buffer|=0x1;
WriteOneByte(~(buffer<<ComScan));
WriteOneByte(*(const unsigned char*)(bitDispDef+segment));//发送段码
HC595_LATCH(0);
HC595_LATCH(1);
if(++ComScan > com)
{
ComScan = 0;
segment++;
}
break;
case 1:
if(*(bufferAddress + ComScan) & (1 <<segment))
buffer|=0x1;
WriteOneByte(~(buffer<<ComScan));
WriteOneByte(*(const unsigned char*)(bitDispDef+segment));//发送段码
HC595_LATCH(0);
HC595_LATCH(1);
if(++ComScan > com)
{ComScan = 0;
segment++;
}
break;
case 2:
if(*(bufferAddress + ComScan) & (1 <<segment))
buffer|=0x1;
WriteOneByte(~(buffer<<ComScan));
WriteOneByte(*(const unsigned char*)(bitDispDef+segment));//发送段码
HC595_LATCH(0);
HC595_LATCH(1);
if(++ComScan > com)
{
ComScan = 0;
segment++;
}
break;
case 3:
if(*(bufferAddress + ComScan) & (1 <<segment))
buffer|=0x1;
WriteOneByte(~(buffer<<ComScan));
WriteOneByte(*(const unsigned char*)(bitDispDef+segment));//发送段码
HC595_LATCH(0);
HC595_LATCH(1);
if(++ComScan > com)
{
ComScan = 0;
segment++;
}
break;
case 4:
if(*(bufferAddress + ComScan) & (1 <<segment))
buffer|=0x1;
WriteOneByte(~(buffer<<ComScan));
WriteOneByte(*(const unsigned char*)(bitDispDef+segment));//发送段码
HC595_LATCH(0);
HC595_LATCH(1);
if(++ComScan > com)
{
ComScan = 0;
segment++;
}
break;
case 5:
if(*(bufferAddress + ComScan) & (1 <<segment))
buffer|=0x1;
WriteOneByte(~(buffer<<ComScan));
WriteOneByte(*(const unsigned char*)(bitDispDef+segment));//发送段码
HC595_LATCH(0);
HC595_LATCH(1);
if(++ComScan > com)
{
ComScan = 0;
segment++;
}
break;
case 6:
if(*(bufferAddress + ComScan) & (1 <<segment))
buffer|=0x1;
WriteOneByte(~(buffer<<ComScan));
WriteOneByte(*(const unsigned char*)(bitDispDef+segment));//发送段码
HC595_LATCH(0);
HC595_LATCH(1);
if(++ComScan > com)
{
ComScan = 0;
segment++;
}
break;
case 7:
if(*(bufferAddress + ComScan) & (1 <<segment))
buffer|=0x1;
WriteOneByte(~(buffer<<ComScan));
WriteOneByte(*(const unsigned char*)(bitDispDef+segment));//发送段码
HC595_LATCH(0);
HC595_LATCH(1);
if(++ComScan > com)
{
ComScan = 0;
segment =0;
}
break;
default: segment =0; break;
}
} void LEDsFlash_Update()
{
static uchar data loop;
LEDs_OFF();
loop++;
if(loop>=250) { loop=0; }
switch(loop%5)
{
case 0:
P0 = LEDs_display];
LED1_pin = LED_LIGHT;
break;
case 1:
P0 = LEDs_display];
LED2_pin = LED_LIGHT;
break;
case 2:
P0 = LEDs_display];
LED3_pin = LED_LIGHT;
break;
case 3:
P0 = LEDs_display];
LED4_pin = LED_LIGHT;
break;
case 4:
P0 = LEDs_display];
LED5_pin = LED_LIGHT;
break;
}
}
好多代码啊,慢慢看,学习学习 直接上专用片子就行。 jacky_yhy 发表于 2014-5-12 14:35
直接上专用片子就行。
我们是说如何能减少代码,不是要更改硬件方面的的东西。。。。 xiaoguo_nihao 发表于 2014-5-12 14:18
好多代码啊,慢慢看,学习学习
大家一起学习,一起进步。。。。 为用专用的芯片省事. iwqt1983 发表于 2014-5-31 11:09
为用专用的芯片省事.
专用的芯片贵啊。 看看代码学习一下。。。。。。。。。。 本帖最后由 dz20062008 于 2014-6-12 12:29 编辑
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DISPLAY:
MOV R0,#10H ;逐位把显示缓存的LED代码显示出来
MOV R1,#00H ;清零刷新位数计数值
MOV A,#01111111B
SETB CY ;控制逐位显示刷新的刷新方向
LEDLOOP:MOV LED_DATA,@R0 ;LED段码送LED屏
SETB LED_DUAN ;送LED段码值到74HC373-A缓存
CLR LED_DUAN ;缓存LED段码
MOV LED_DATA,A ;LED位码送LED屏
SETB LED_WEI ;送LED位码值到74HC373-B缓存
CLR LED_WEI ;缓存LED位码
LCALL LED_DELAY ;位与位显示之间的显示延时
MOV LED_DATA,#00H
SETB LED_DUAN
CLRLED_DUAN
MOV LED_DATA,#0FFH
SETB LED_WEI
CLRLED_WEI
RR A ;更新LED位码值
INC R0 ;LED段码指针增一
INC R1 ;LED显示位数计数
CJNE R1,#8D,LEDLOOP ;显示完了吗?
RET ;显示完了,返回主程序
LED_DELAY:PUSH ACC
MOV R7,#4D ;装入显示延时循环的外圈值
D1:MOV R6,#100D ;装入显示延时循环的内圈值
D2:DJNZ R6,D2 ;内圈循环
DJNZ R7,D1 ;外圈循环
POP ACC
RET
本帖最后由 gotofly100 于 2014-6-12 14:12 编辑
void display_scan(void)
{
unsigned char i;
P1 &= Bin(11111110);
P1 |= Bin(11111000);
P2 &= Bin(00000000);
P3 &= Bin(01100111);
P3 |= Bin(01100110);//关闭段码和位码,如共阳数码管(公共脚置低,段码置高)
//======================================//
for(i = 0;i < 4;i ++)
{
r_dis_data = table_seg]; //查LED段码表
}
switch (r_dig_bit) //在公共端接限流电阻,在数码管位数少时布线时有优势
{
case 1:
p_seg_a = 0; //扫描a段
// if(r_dis_data & 0x01) p_dig_1 = 1;//如果r_dis_data第0位为高,则需要点亮,反之则不点亮
// if(r_dis_data & 0x01) p_dig_2 = 1;
// if(r_dis_data & 0x01) p_dig_3 = 1;
// if(r_dis_data & 0x01) p_dig_4 = 1;
// if(r_dis_buff & 0x01) p_dig_5 = 1;
// if(r_dis_buff & 0x01) p_dig_6 = 1;
//i=0x01;
break;
case 2:
p_seg_b = 0;
// if(r_dis_data & 0x02) p_dig_1 = 1;
// if(r_dis_data & 0x02) p_dig_2 = 1;
// if(r_dis_data & 0x02) p_dig_3 = 1;
// if(r_dis_data & 0x02) p_dig_4 = 1;
// if(r_dis_buff & 0x02) p_dig_5 = 1;
// if(r_dis_buff & 0x02) p_dig_6 = 1;
//i=0x02;
break;
case 3:
p_seg_c = 0;
// if(r_dis_data & 0x04) p_dig_1 = 1;
// if(r_dis_data & 0x04) p_dig_2 = 1;
// if(r_dis_data & 0x04) p_dig_3 = 1;
// if(r_dis_data & 0x04) p_dig_4 = 1;
// if(r_dis_buff & 0x04) p_dig_5 = 1;
// if(r_dis_buff & 0x04) p_dig_6 = 1;
break;
case 4:
p_seg_d = 0;
// if(r_dis_data & 0x08) p_dig_1 = 1;
// if(r_dis_data & 0x08) p_dig_2 = 1;
// if(r_dis_data & 0x08) p_dig_3 = 1;
// if(r_dis_data & 0x08) p_dig_4 = 1;
// if(r_dis_buff & 0x08) p_dig_5 = 1;
// if(r_dis_buff & 0x08) p_dig_6 = 1;
break;
case 5:
p_seg_e = 0;
// if(r_dis_data & 0x10) p_dig_1 = 1;
// if(r_dis_data & 0x10) p_dig_2 = 1;
// if(r_dis_data & 0x10) p_dig_3 = 1;
// if(r_dis_data & 0x10) p_dig_4 = 1;
// if(r_dis_buff & 0x10) p_dig_5 = 1;
// if(r_dis_buff & 0x10) p_dig_6 = 1;
break;
case 6:
p_seg_f = 0;
// if(r_dis_data & 0x20) p_dig_1 = 1;
// if(r_dis_data & 0x20) p_dig_2 = 1;
// if(r_dis_data & 0x20) p_dig_3 = 1;
// if(r_dis_data & 0x20) p_dig_4 = 1;
// if(r_dis_buff & 0x20) p_dig_5 = 1;
// if(r_dis_buff & 0x20) p_dig_6 = 1;
break;
case 7:
p_seg_g = 0;
// if(r_dis_data & 0x40) p_dig_1 = 1;
// if(r_dis_data & 0x40) p_dig_2 = 1;
// if(r_dis_data & 0x40) p_dig_3 = 1;
// if(r_dis_data & 0x40) p_dig_4 = 1;
// if(r_dis_buff & 0x40) p_dig_5 = 1;
// if(r_dis_buff & 0x40) p_dig_6 = 1;
break;
case 8:
p_seg_h = 0;
// if(r_dis_data & 0x80) p_dig_1 = 1;
// if(r_dis_data & 0x80) p_dig_2 = 1;
// if(r_dis_data & 0x80) p_dig_3 = 1;
// if(r_dis_data & 0x80) p_dig_4 = 1;
// if(r_dis_buff & 0x80) p_dig_5 = 1;
// if(r_dis_buff & 0x80) p_dig_6 = 1;
break;
default:
keyscan_process(); //按键扫描
break;
}
if((r_dig_bit<9)&&(r_dig_bit))
{
i=0x01<<(r_dig_bit-1);
if(r_dis_data & i) p_dig_1 = 1;
if(r_dis_data & i) p_dig_2 = 1;
if(r_dis_data & i) p_dig_3 = 1;
if(r_dis_data & i) p_dig_4 = 1;
if(r_dis_buff & i) p_dig_5 = 1;
if(r_dis_buff & i) p_dig_6 = 1;
}
r_dig_bit ++;
if(r_dig_bit >= 9) //扫描时基
r_dig_bit = 0;
}
楼上代码看的脑袋歪了, 重新给你编辑一下
void display_scan(void)
{
unsigned char i;
P1 &= Bin(11111110);
P1 |= Bin(11111000);
P2 &= Bin(00000000);
P3 &= Bin(01100111);
P3 |= Bin(01100110);//关闭段码和位码,如共阳数码管(公共脚置低,段码置高)
//======================================//
for(i = 0;i < 4;i ++)
{
r_dis_data = table_seg; //查LED段码表
}
switch (r_dig_bit) //在公共端接限流电阻,在数码管位数少时布线时有优势
{
case 1:
p_seg_a = 0; //扫描a段
// if(r_dis_data & 0x01) p_dig_1 = 1;//如果r_dis_data第0位为高,则需要点亮,反之则不点亮
// if(r_dis_data & 0x01) p_dig_2 = 1;
// if(r_dis_data & 0x01) p_dig_3 = 1;
// if(r_dis_data & 0x01) p_dig_4 = 1;
// if(r_dis_buff & 0x01) p_dig_5 = 1;
// if(r_dis_buff & 0x01) p_dig_6 = 1;
//i=0x01;
break;
case 2:
p_seg_b = 0;
// if(r_dis_data & 0x02) p_dig_1 = 1;
// if(r_dis_data & 0x02) p_dig_2 = 1;
// if(r_dis_data & 0x02) p_dig_3 = 1;
// if(r_dis_data & 0x02) p_dig_4 = 1;
// if(r_dis_buff & 0x02) p_dig_5 = 1;
// if(r_dis_buff & 0x02) p_dig_6 = 1;
//i=0x02;
break;
case 3:
p_seg_c = 0;
// if(r_dis_data & 0x04) p_dig_1 = 1;
// if(r_dis_data & 0x04) p_dig_2 = 1;
// if(r_dis_data & 0x04) p_dig_3 = 1;
// if(r_dis_data & 0x04) p_dig_4 = 1;
// if(r_dis_buff & 0x04) p_dig_5 = 1;
// if(r_dis_buff & 0x04) p_dig_6 = 1;
break;
case 4:
p_seg_d = 0;
// if(r_dis_data & 0x08) p_dig_1 = 1;
// if(r_dis_data & 0x08) p_dig_2 = 1;
// if(r_dis_data & 0x08) p_dig_3 = 1;
// if(r_dis_data & 0x08) p_dig_4 = 1;
// if(r_dis_buff & 0x08) p_dig_5 = 1;
// if(r_dis_buff & 0x08) p_dig_6 = 1;
break;
case 5:
p_seg_e = 0;
// if(r_dis_data & 0x10) p_dig_1 = 1;
// if(r_dis_data & 0x10) p_dig_2 = 1;
// if(r_dis_data & 0x10) p_dig_3 = 1;
// if(r_dis_data & 0x10) p_dig_4 = 1;
// if(r_dis_buff & 0x10) p_dig_5 = 1;
// if(r_dis_buff & 0x10) p_dig_6 = 1;
break;
case 6:
p_seg_f = 0;
// if(r_dis_data & 0x20) p_dig_1 = 1;
// if(r_dis_data & 0x20) p_dig_2 = 1;
// if(r_dis_data & 0x20) p_dig_3 = 1;
// if(r_dis_data & 0x20) p_dig_4 = 1;
// if(r_dis_buff & 0x20) p_dig_5 = 1;
// if(r_dis_buff & 0x20) p_dig_6 = 1;
break;
case 7:
p_seg_g = 0;
// if(r_dis_data & 0x40) p_dig_1 = 1;
// if(r_dis_data & 0x40) p_dig_2 = 1;
// if(r_dis_data & 0x40) p_dig_3 = 1;
// if(r_dis_data & 0x40) p_dig_4 = 1;
// if(r_dis_buff & 0x40) p_dig_5 = 1;
// if(r_dis_buff & 0x40) p_dig_6 = 1;
break;
case 8:
p_seg_h = 0;
// if(r_dis_data & 0x80) p_dig_1 = 1;
// if(r_dis_data & 0x80) p_dig_2 = 1;
// if(r_dis_data & 0x80) p_dig_3 = 1;
// if(r_dis_data & 0x80) p_dig_4 = 1;
// if(r_dis_buff & 0x80) p_dig_5 = 1;
// if(r_dis_buff & 0x80) p_dig_6 = 1;
break;
default:
keyscan_process(); //按键扫描
break;
}
if((r_dig_bit<9)&&(r_dig_bit))
{
i=0x01<<(r_dig_bit-1);
if(r_dis_data & i) p_dig_1 = 1;
if(r_dis_data & i) p_dig_2 = 1;
if(r_dis_data & i) p_dig_3 = 1;
if(r_dis_data & i) p_dig_4 = 1;
if(r_dis_buff & i) p_dig_5 = 1;
if(r_dis_buff & i) p_dig_6 = 1;
}
r_dig_bit ++;
if(r_dig_bit >= 9) //扫描时基
r_dig_bit = 0;
} 学习学习 我来学习 放定时器中断里面,代码量最小,且效果最好。 学习各位大侠的方法。 这个好,收藏了 本帖最后由 zhan_li 于 2014-10-5 11:59 编辑
我也发一段我的不用锁存器单片机直接驱动数码管的显示程序,用定时器延迟,时间大概2MS。且是按键和数码管共用I/O的。学名为数码管和按键分时复用程序,希望对大家有帮助。 mark, 支持一下 最近项目正用上了。 mark下,到公司研究研究能不能改进下我的方法 正好用的,好好学习一下。数码管和按键公用 IO kebaojun305 发表于 2014-5-31 12:15
专用的芯片贵啊。
专用芯片很贵吗?我用的aip1628才四毛多,10 段×7 位或13段×4 位,按键10×2 ,除非单片机IO口直接驱动数码管,否则真没有比用专用芯片更省钱的方案了。 LM1876 发表于 2014-5-11 12:21
void LEDsFlash_Update()
{
static uchar data loop;
这个代码 显示有闪烁感吗? zhcj66 发表于 2020-3-16 16:24
这个代码 显示有闪烁感吗?
这要看主程序结构,我用的是分时中断系统,放在1mS里。5位以内(含5位)就没闪烁感,5位以上就有 LM1876 发表于 2020-3-17 08:37
这要看主程序结构,我用的是分时中断系统,放在1mS里。5位以内(含5位)就没闪烁感,5位以上就有 ...
他们搞的10几个不闪烁不知道用mcu怎么实现的? zhcj66 发表于 2020-3-17 09:26
他们搞的10几个不闪烁不知道用mcu怎么实现的?
10来段的得用专用芯片了吧?不然光靠单片机的话,占太多资源了 LM1876 发表于 2020-3-17 09:55
10来段的得用专用芯片了吧?不然光靠单片机的话,占太多资源了
他们广告屏不都是用的164芯片做出来,没有用专用芯片 学习学习,谢谢提供 学习,参考
页:
[1]