找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2393|回复: 8
打印 上一主题 下一主题
收起左侧

关于单片机IO口直接驱动数码管程序调试

[复制链接]
跳转到指定楼层
楼主
利用STC单片机IO口推挽输出方式直接驱动4位数码管,最大限度地节省外围电路,电路原理图如下所示。P3.2 - P3.5推挽输出,每位驱动1位数码管;P1口每个时序驱动1段数码管,降低单片机的输出负载。如果需要降低显示亮度,还可以对P3.2 - P3.5增加软件PWM。源代码中Digits_Buf[4]是显示缓冲区,设置好显示内容以后,只要以固定间隔调用Digits_Refresh()就能正常显示。调用Digits_Refresh()的间隔时间不稳定时,会数码管各字符显示亮度不均匀并伴随闪烁。
#define DIGITS_DP   20

extern unsigned char Digits_Buf[4];

void Digits_Refresh();
Digits.c代码
#include "Hardware.h"

/*

sbit Digits_K1 = ...;
sbit Digits_K2 = ...;
sbit Digits_K3 = ...;
sbit Digits_K4 = ...;

*/

unsigned char code DIGITS_SEG_TAB[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0xee,0x3e,0x1a,0x7a,0x9e,0x8e,0x00,0xee,0x1c,0x02,
                                   //0    1    2    3    4    5    6    7    8    9    a    b    c    d    e    f    <sp> A    L    -
                                     0xfd,0x61,0xdb,0xf3,0x67,0xb7,0xbf,0xe1,0xff,0xf7,0xef,0x3f,0x1b,0x7b,0x9f,0x8f,0x01,0xef,0x1d,0x03};
                                   //0.   1.   2.   3.   4.   5.   6.   7.   8.   9.   a.   b.   c.   d.   e.   f.   <sp>.A.   L.   -.

unsigned char Digits_Buf[4];        //显存4字节,4个数码管

unsigned char Digits_SendBuff;
unsigned char Digits_BufPos;
unsigned char Digits_BitPos;

void Digits_Refresh()
{
    if (Digits_BitPos == 0)
    {
        if (Digits_BufPos == 3)
            Digits_BufPos = 0;
        else
            Digits_BufPos ++;

        Digits_SendBuff = DIGITS_SEG_TAB[Digits_Buf[Digits_BufPos]];

        Digits_BitPos = 0x80;

        P1 = 0xFF;
        P3 &= 0xC3;
        if (Digits_BufPos == 0)
            Digits_K1 = 1;
        else if (Digits_BufPos == 1)
            Digits_K2 = 1;
        else if (Digits_BufPos == 2)
            Digits_K3 = 1;
        else
            Digits_K4 = 1;
    }

    P1 = ~(Digits_SendBuff & Digits_BitPos);
    Digits_BitPos >>= 1;
}
请教一下,最后为什么&0x80?显示小点???不是^
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:123289 发表于 2021-6-21 10:58 | 只看该作者
这个硬件设计是欠妥的。应该考虑一下,IO口所能输出与吸入的电流,与LED的电流、亮度是否有冲突。
另外必要的限流是需要的,否则CPU会受到意外伤害。
回复

使用道具 举报

板凳
ID:734017 发表于 2021-6-21 12:44 | 只看该作者
yzwzfyz 发表于 2021-6-21 10:58
这个硬件设计是欠妥的。应该考虑一下,IO口所能输出与吸入的电流,与LED的电流、亮度是否有冲突。
另外必 ...

感谢,这是网上的的例程,最后说的那两句程序好像不对,发出来请教一下。实际中每路IO口肯定会加电阻,谢谢
回复

使用道具 举报

地板
ID:824490 发表于 2021-6-21 13:44 | 只看该作者
。亮度不均!没有限流,当显示8与显示1时,亮度就能看出差别了
回复

使用道具 举报

5#
ID:374653 发表于 2022-12-6 22:32 | 只看该作者
名字不是重点 发表于 2021-6-21 13:44
。亮度不均!没有限流,当显示8与显示1时,亮度就能看出差别了

在公共段加限流电阻的电路,有没有办法软件去平均亮度?
回复

使用道具 举报

6#
ID:308903 发表于 2022-12-7 08:55 | 只看该作者
从问题倒推问题
数码管各字符显示亮度不均匀并伴随闪烁

闪烁:
说明导通时间大于人眼分辨时间--->间隔不稳定
亮度不均匀:
说明电流大小不一致。--->间隔不稳定

但是,为啥要使其间隔不稳定? 没明白

回复

使用道具 举报

7#
ID:213173 发表于 2022-12-7 09:26 | 只看该作者
给你一个硬件略图和修改后的代码,解释并解决你的问题。适用于IO口可设置推挽模式的MCU。
  1. #include <reg51.H>
  2. sfr P1M1    =   0x91;
  3. sfr P1M0    =   0x92;
  4. sfr P3M1    =   0xb1;
  5. sfr P3M0    =   0xb2;

  6. //反序共阴极数码管段码表,段码a-h顺序接PX7-PX0
  7. unsigned char code DIGITS_SEG_TAB[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0xee,0x3e,0x1a,0x7a,0x9e,0x8e,0x00,0xee,0x1c,0x02,
  8.                                    //0    1    2    3    4    5    6    7    8    9    a    b    c    d    e    f    <sp>  A    L    -
  9.                                      0xfd,0x61,0xdb,0xf3,0x67,0xb7,0xbf,0xe1,0xff,0xf7,0xef,0x3f,0x1b,0x7b,0x9f,0x8f,0x01,0xef,0x1d,0x03};
  10.                                    //0.   1.   2.   3.   4.   5.   6.   7.   8.   9.   a.   b.   c.   d.   e.   f.   <sp>. A.   L.   -.
  11. unsigned char Digits_Buf[4];        //显存4字节,4个数码管
  12. unsigned int num=1234;

  13. void main(void)
  14. {
  15.         unsigned char i;
  16.         unsigned int t;
  17.         P1M1=0x00;
  18.         P1M0=0xff;//P1推挽模式
  19.         P3M1=0x00;
  20.         P3M0=0x00;//P3准双向模式

  21.         while (1)
  22.         {
  23.                 switch(i)
  24.                 {
  25.                         case 0: Digits_Buf[0]=DIGITS_SEG_TAB[num/1000%10]; break;
  26.                         case 1: Digits_Buf[1]=DIGITS_SEG_TAB[num/100%10]|0x01; break;//加点
  27.                         case 2: Digits_Buf[2]=DIGITS_SEG_TAB[num/10%10]; break;
  28.                         case 3: Digits_Buf[3]=DIGITS_SEG_TAB[num%10]; break;
  29.                 }
  30.                 P1=0x00;
  31.                 P3&=0xc3;
  32.                 P3|=~(0x04<<i);
  33.                 P1=Digits_Buf[i];
  34.                 i=++i%4;
  35.                 t=1000;
  36.                 while(t--);//少许延时
  37.         }
  38. }
复制代码





回复

使用道具 举报

8#
ID:1034262 发表于 2022-12-7 11:16 | 只看该作者
段驱动要串联电阻(一般300欧姆或以上),避免过流烧IO。
回复

使用道具 举报

9#
ID:884147 发表于 2022-12-7 11:38 | 只看该作者
liangtiancong 发表于 2022-12-6 22:32
在公共段加限流电阻的电路,有没有办法软件去平均亮度?

虽然这种设计不合理,但是很多产品都在使用,比如有些焊台、即热水器等,可能为了控制成本。其实用软件是可以平均亮度的,根据亮的段数控制点亮时长,实际上就相当于控制占空比,显示1时间长点,显示8时间短点
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表