找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1317|回复: 26
收起左侧

stc8g1k17的三位数码管显示问题

[复制链接]
ID:1135888 发表于 2024-12-24 17:56 | 显示全部楼层 |阅读模式
三位数码管的显示问题,因为之前的扫描方式亮度不均匀,换了下面这种扫描方式,但更换后发现数值显示有问题 如我输入值为 1.1  数码管三位 应为 1  .   1     0  ; 实际显示我拍照了 请看大图        
调试了一下 disx 值 固定为 0 ,1  , 2 , 3时 对应的位选上显示的数值都是正常的 ,但是设为 disx++; 后就不正常了 。
小白技术不太行 寻求帮助,给我点思路 ,我自己修改就可以的 感谢
#include    "smg.h"
#include    "STC8H.H"
#include     "button.h"
#include    "eeprom.h"
extern void abc(int c);
// 数码管位选引脚定义
#define DIGIT1 P13
#define DIGIT2 P15
#define DIGIT3 P17
#define DIGIT4 P10
unsigned char segmentCodes[] = {
    0x3F, // 0
    0x06, // 1
    0x5b, // 2
    0x4F, // 3
    0x66, // 4
    0x6D, // 5
    0x7D, // 6
    0x07, // 7
    0x7F, // 8
    0x6F, // 9
    0x80, // .

};

void smg_io_init()
{
    P1M0 |= 0xee;
    P1M1 &= ~0xee;
    P3M0 |= 0x31;
    P3M1 &= ~0x31;
    P5M0 |= 0x30;
    P5M1 &= ~0x30;

    SEG_A  = 0;
    SEG_B  = 0;
    SEG_C  = 0;
    SEG_D  = 0;
    SEG_E  = 0;
    SEG_F  = 0;
    SEG_G  = 0;
    SEG_DP = 0;  
}

char dppos = 0; // 默认小数点位置在最后一位(百分位)
char displayBuffer[4] = {0}; // 存储待显示的数字,包括整数、小数点和两位小数部分
char disx     =    0;
char AJ ;

void DisplayVoltage(double voltage) {
    unsigned int  sw,gw,x1, x2,number,xs;
    float abc;
    number   =   (int)voltage;
    abc = voltage - number;
    // 将电压值转换为整数和小数部分
    sw = number/10 ;
    gw = number%10 ;
    abc *= 100;
    x1 = (int)abc/10;
    x2 = (int)abc%10;
    xs = 10;

    // 设置显示缓冲区
    if (voltage >= 10.00) {

        displayBuffer[0] = sw ;  // 十位数
        displayBuffer[1] = gw ;
        displayBuffer[3] = xs ;
        displayBuffer[2] = x1;//

        dppos=2;
    } else {
        displayBuffer[0] = gw ; // 个位数
        displayBuffer[3] = xs; // 个位数
        displayBuffer[1] = x1; // 个位数
        displayBuffer[2] = x2; // 小数点后一位

        dppos=1;
    }
}
int f;
extern x1;
unsigned int  digit  ;
void DisplayVoltage1() {

    unsigned char mask = 0x01;
     f++;  
    DIGIT1 = 1;
    DIGIT2 = 1;
    DIGIT3 = 1;

    // 根据digitIndex选中对应的数码管
    switch (disx) {
    case 0:
        DIGIT1 = 0;
        DIGIT2 = 1;
        DIGIT3 = 1;
        break;
    case 1:
        DIGIT1 = 1;
        DIGIT2 = 0;
        DIGIT3 = 1;
        break;
    case 2:
        DIGIT1 = 1;
        DIGIT2 = 1;
        DIGIT3 = 0;
        break;
    case 3:
        if(dppos ==  1) {
            DIGIT1 = 0;
            DIGIT2 = 1;
            DIGIT3 = 1;
        }
        else if(dppos ==  2) {
            DIGIT1 = 1;
            DIGIT2 = 0;
            DIGIT3 = 1;
        }  
        break;
    }
            digit =  displayBuffer[disx];

        switch (f-1) {

          case 0: SEG_A = (segmentCodes[digit] &   mask) ?      1 : 0; break;
          case 1: SEG_B = (segmentCodes[digit] & (mask << 1)) ? 1 : 0; break;
          case 2: SEG_C = (segmentCodes[digit] & (mask << 2)) ? 1 : 0; break;
          case 3: SEG_D = (segmentCodes[digit] & (mask << 3)) ? 1 : 0; break;
          case 4: SEG_E = (segmentCodes[digit] & (mask << 4)) ? 1 : 0; break;
          case 5: SEG_F = (segmentCodes[digit] & (mask << 5)) ? 1 : 0; break;
          case 6: SEG_G = (segmentCodes[digit] & (mask << 6)) ? 1 : 0; break;
          case 7: SEG_DP =(segmentCodes[digit] & (mask << 7)) ? 1 : 0; break;
        }

    if (f == 9) {
        disx++;
        if(disx > 3)           
           disx=0;      
    }

else if(f  >  9 )   f = 0;



}------------------------------------------------------------------------------
void Timer0_Init()                //100微秒@11.0592MHz
{   
    //定时器时钟12T模式
    TMOD &= 0xf0;                        //设置定时器模式
    TMOD |= 0x01;
    TL0 = 0xCD;                                //设置定时初始值
    TH0 = 0xD4;                                                        //设置定时初始值
    TF0 = 0;                                //清除TF0标志
    TR0 = 1;                                //定时器0开始计时
    ET0 = 1;
    EA  = 1;
}
void TM0_Isr() interrupt 1 //每隔两毫秒
{      
    DisplayVoltage1();

    TL0 = 0xCD;                                //设置定时初始值
    TH0 = 0xD4;                                                //设置定时初始值
}
51hei图片_20241224174546.jpg
回复

使用道具 举报

ID:1141252 发表于 2024-12-24 21:09 | 显示全部楼层
连接数码管的IO口设置为强推模式了吗
回复

使用道具 举报

ID:1141252 发表于 2024-12-24 21:11 | 显示全部楼层
连接数码管的IO口设置为强推模式了么
回复

使用道具 举报

ID:1133081 发表于 2024-12-24 21:13 | 显示全部楼层
把原理图发上来
回复

使用道具 举报

ID:1109793 发表于 2024-12-25 07:48 | 显示全部楼层
一个8位机,float,double都用上了。还用了乘
mask<<这里直角用0x01<<不行吗?弄个变量会更快吗?后面的?运算有意义吗?
SEG是段码,设计时不在同一组IO里面吗?这么费劲。
白色阻焊不好,透明度不行。还是绿色好看。
回复

使用道具 举报

ID:1135888 发表于 2024-12-25 09:21 | 显示全部楼层
power-man 发表于 2024-12-24 21:09
连接数码管的IO口设置为强推模式了吗

设置了 推挽了
回复

使用道具 举报

ID:1135888 发表于 2024-12-25 09:33 | 显示全部楼层
WL0123 发表于 2024-12-24 21:13
把原理图发上来

板子不是自己设计的 是给的测试   他的板子  有一个IO口 P12 跟数码管 按键 还有一个灯同时复用了,有点没想明白怎么做
回复

使用道具 举报

ID:1135888 发表于 2024-12-25 09:37 | 显示全部楼层
xiaobendan001 发表于 2024-12-25 07:48
一个8位机,float,double都用上了。还用了乘
mask

,刚开始做这个好多地方不会,您说的这个 我后面都会注意 去改的,刚开始打 的是绿色的,测试的时候不小心烧了 ,后面打板的时候看见有白色的阻焊,就像试一下,打出来发现,好看是挺好看的,但是透明度不行,线路不如绿色的清楚
回复

使用道具 举报

9#
无效楼层,该帖已经被删除
ID:1109793 发表于 2024-12-25 12:51 | 显示全部楼层
实在看不太懂,你这意思是每2MS调用一次显示,每次显示F++,然后只更新8段的一段,8个段更新完成后再更新一个位。为啥要这样呢?八个段一次更新完了直接显示不好吗?为何要搞这么复杂?你是觉得2ms更新太快了?芯片大概是SSOP20的,应该有一个完整的口给你用的啊。
况且在F==9的时候更新了位,此时直接F = 0;不行吗?还要再等下一次才能F = 0;
回复

使用道具 举报

ID:1135888 发表于 2024-12-25 14:16 | 显示全部楼层
不是自己设计的板子 ,布置的% 这个P12 同时与 按键 数码管 灯三方连接复用  按键与数码管 用定时器分时复用解决了 但灯实在解决不来哦
回复

使用道具 举报

ID:1109793 发表于 2024-12-25 15:56 | 显示全部楼层
左语杰 发表于 2024-12-25 14:16
不是自己设计的板子 ,布置的% 这个P12 同时与 按键 数码管 灯三方连接复用  按键与数码管 用定时器分时复 ...

还是先把原理图弄出来吧
回复

使用道具 举报

ID:1135888 发表于 2024-12-25 16:00 | 显示全部楼层
xiaobendan001 发表于 2024-12-25 12:51
实在看不太懂,你这意思是每2MS调用一次显示,每次显示F++,然后只更新8段的一段,8个段更新完成后再更新一 ...

嗯呐,  注释上是两毫秒是之前的没改 实际是 50us 进一次中断  ,就想设计每一段的扫描时间相同 保证 亮度一样  , 最早的一版是 一次更新八个段 ,即一个段码 ,但是亮度显示不均匀   
回复

使用道具 举报

ID:1135888 发表于 2024-12-25 16:22 | 显示全部楼层
我上午发了原理图 不知道 为什么 没发出来      C:\Users\JS16\Desktop
回复

使用道具 举报

ID:1135888 发表于 2024-12-25 16:24 | 显示全部楼层
原理图来了
51hei截图_20241225092700.png
回复

使用道具 举报

ID:1133081 发表于 2024-12-25 17:02 | 显示全部楼层
左语杰 发表于 2024-12-25 09:33
板子不是自己设计的 是给的测试   他的板子  有一个IO口 P12 跟数码管 按键 还有一个灯同时复用了,有点 ...

板子不是你自己设计的,原理图也还原不了,那你还写什么程序?所有软件都是基于硬件条件编写的。stc8g1k17-20做个三位数码管显示的电压表是轻而易举的事。你那数码管动态显示代码写得实在不敢恭维。数码管、按键、还有一个灯同时复用,没有原理图谁能搞得清你怎么接线的。
回复

使用道具 举报

ID:1109793 发表于 2024-12-25 18:28 | 显示全部楼层
左语杰 发表于 2024-12-25 16:00
嗯呐,  注释上是两毫秒是之前的没改 实际是 50us 进一次中断  ,就想设计每一段的扫描时间相同 保证 亮 ...

你这样才亮度不均匀吧,在更新段码前要先消隐的。
回复

使用道具 举报

ID:1109793 发表于 2024-12-25 18:47 | 显示全部楼层
左语杰 发表于 2024-12-25 16:00
嗯呐,  注释上是两毫秒是之前的没改 实际是 50us 进一次中断  ,就想设计每一段的扫描时间相同 保证 亮 ...

事实上只要时序弄对了,50US和2MS的关系不大,显示效果也几乎一样的
回复

使用道具 举报

ID:1109793 发表于 2024-12-25 18:57 | 显示全部楼层

居然可以这样搞,限流接在COM上面,目前的数码管这样其实亮度均匀性也还好,即便要分时均衡亮度,在每次更新段数据前要关闭所有段再打开应该亮的吧。那个板子上大面积的空闲,不至于省这5颗电阻吧。板子看起来好像没有什么大的耗电,还用一颗类似2575这么大的零件。我实际用一颗限流电阻驱动8个LED灯,同时点亮居然亮度都一样的,基本上看不到亮度不一样的。
回复

使用道具 举报

ID:1133081 发表于 2024-12-25 21:29 | 显示全部楼层

单就这个硬件设计就决定了数码管笔段亮度不容易搞均匀。此电路如不是高手炫技就是初学者的习作。单片机引脚使用混乱无序,还搞些复用,18个I/O口不够用?
回复

使用道具 举报

ID:161164 发表于 2024-12-25 23:11 | 显示全部楼层
你的代码段位只有点亮,没有熄灭啊
回复

使用道具 举报

ID:1135888 发表于 2024-12-26 09:50 | 显示全部楼层
WL0123 发表于 2024-12-25 21:29
单就这个硬件设计就决定了数码管笔段亮度不容易搞均匀。此电路如不是高手炫技就是初学者的习作。单片机引 ...

他给的io口确实是不够用的  4个独立按键  11个数码管   2个2ADC检测  1个PCA 的pwm 还有一个io口用于某个元器件的使能脚
回复

使用道具 举报

ID:1135888 发表于 2024-12-26 09:54 | 显示全部楼层
lkc8210 发表于 2024-12-25 23:11
你的代码段位只有点亮,没有熄灭啊

是这个吗   有熄灭位选 啊  case 0:
        DIGIT1 = 0;
        DIGIT2 = 1;
        DIGIT3 = 1;
        break;
    case 1:
        DIGIT1 = 1;
        DIGIT2 = 0;
        DIGIT3 = 1;
        break;
    case 2:
        DIGIT1 = 1;
        DIGIT2 = 1;
        DIGIT3 = 0;
        break;    只有选中的位选是亮的
回复

使用道具 举报

ID:1135888 发表于 2024-12-26 09:57 | 显示全部楼层
lkc8210 发表于 2024-12-25 23:11
你的代码段位只有点亮,没有熄灭啊

抱歉 我上一句理解错了       是段选点亮了 到下一位的时候没有熄灭
回复

使用道具 举报

ID:1109793 发表于 2024-12-26 11:24 | 显示全部楼层
左语杰 发表于 2024-12-26 09:54
是这个吗   有熄灭位选 啊  case 0:
        DIGIT1 = 0;
        DIGIT2 = 1;

不是CASE0的问题。是每次更新段之前都先熄灭,更新完了再打开。
回复

使用道具 举报

ID:1133081 发表于 2024-12-26 11:32 | 显示全部楼层
左语杰 发表于 2024-12-26 09:50
他给的io口确实是不够用的  4个独立按键  11个数码管   2个2ADC检测  1个PCA 的pwm 还有一个io口用于某个 ...

IO口不够用可以通过合理规划IO口复用。比如驱动数码管的8个段,3个位只有第一位有小数点,另两位的小数点空闲,可以分时复用驱动两个LED。4个按键可以与两路ADC检测分时复用(只要被检模拟量动态范围大于0小于VCC,按键分别接地和VCC即可准确识别),也可以另开一路ADC同时检测4个按键。这样可以轻松节省4-5个IO口,既不影响数码管和ADC功能,编程也不复杂。
回复

使用道具 举报

ID:1135888 发表于 2024-12-26 17:37 | 显示全部楼层
WL0123 发表于 2024-12-26 11:32
IO口不够用可以通过合理规划IO口复用。比如驱动数码管的8个段,3个位只有第一位有小数点,另两位的小数点 ...

好的 ,感谢 我重打一个板试一试 老师目前还没有要求完全跟原版一样 ,我试试您这个方案,这个板我也不放,继续试一试 ,感谢
回复

使用道具 举报

ID:1109793 发表于 2024-12-26 19:25 | 显示全部楼层
左语杰 发表于 2024-12-26 17:37
好的 ,感谢 我重打一个板试一试 老师目前还没有要求完全跟原版一样 ,我试试您这个方案,这个板我也不放 ...

我觉得不如使用数码管芯片比如TM1650这样的,电路更简洁,还能调整亮度,电阻也省了。还支持按键,省很多IO
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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