[求助] 关于4位数码管的动态显示问题,新手虚心求教,有空的大兄弟进来看看

youyuchao   2015-2-12 19:25 楼主
以下是程序,下载到板子上不能实现一秒变化一次,大概8秒才一次
#include
typedef unsigned char uint8;
typedef unsigned int  uint16;
typedef unsigned long uint32;

code uint8 number[] = {0xc0,0xf9,0xa4,0xb0,
                                                              

                       0x99,0x92,0x82,0xf8,
                                                              

                       0x80,0x90,0x88,0x83,
                                                              

                       0xa7,0xa1,0x86,0x8e}; //【16进制数组】
uint8  i = 0;
uint16 counter = 0;

//sbit ENLED = P1^4;
sbit SMG1 = P3^4;
sbit SMG2 = P3^5;
sbit SMG3 = P3^6;
sbit SMG4 = P3^7;

void timer1_init()                //定时器初始化
{
        TMOD |= 0x01;
        TH1   = 0xfc;
        TL1   = 0x67;                //1ms
        TR1   = 1;
}

void int_init()                        //中断初始化
{
        ET1 = 1;
        EA  = 1;
}

main()
{
        P0 = 0xff;P3 = 0xff;
    timer1_init();
        int_init();
        while(1);
}

void refresh() //数码管动态扫描显示
{
        static uint8 j = 0;

        switch(j)
        {
                case 0: SMG1 = 0;P0 = number[i];break;
                case 1: SMG2 = 0;P0 = number[i];break;
                case 2: SMG3 = 0;P0 = number[i];break;
                case 3: SMG4 = 0;P0 = number[i];break;
                default: break;
        }
        if(3 == j++)
                j = 0;
}

void interrupt_timer1() interrupt 3
{
        TH1 = 0xfc;
        TL1 = 0x67;
        counter++;
        if(1000 == counter)
        {
                i++;
                if(15 == i)
                {
                        i = 0;
                }       
        }
        refresh();
}



附上原理图
在线等  谢谢各位了~~

回复评论 (11)

没人吗?有什么不清楚的可以说说  
点赞  2015-2-12 19:36
1,com口只开不关,估计数码管会飘一片红
2,屏变化慢,应该是定时器参数没调好,你再算算

另外说一点,数码管程序需要分层次写,将IO脚根据逻辑分组定义,这样你的上层程序会完全与硬件无关
要666
点赞  2015-2-12 19:42
晕眩,刚才第一点说错了

lz的代码逻辑就有问题,1秒的扫描间隔?
至少需要30Hz(或更好) * 4(com口数量)的扫描频率
要666
点赞  2015-2-12 19:49
引用: le062 发表于 2015-2-12 19:42
1,com口只开不关,估计数码管会飘一片红
2,屏变化慢,应该是定时器参数没调好,你再算算

另外说一点,数码管程序需要分层次写,将IO脚根据逻辑分组定义,这样你的上层程序会完全与硬件无关
1,数码管可以正常从0显示到F,只是不是1秒变化一次,没有出现飘红的情况,2.定时器参数应该没有算错  以前都是用这个,附上算法12*(65536-x)/1105926=0.001s  算出x,转化为16进制是 FC67
   数码管程序需要分层次写,将IO脚根据逻辑分组定义,这样你的上层程序会完全与硬件无关,,这句话没有理解到  能详细点吗?
  
谢谢细心解答~~THX!




点赞  2015-2-12 19:50
引用: le062 发表于 2015-2-12 19:49
晕眩,刚才第一点说错了

lz的代码逻辑就有问题,1秒的扫描间隔?
至少需要30Hz(或更好) * 4(com口数量)的扫描频率
我用的是1ms的扫描(定时器的fc67)。。1秒的是数组1秒变化一次达到秒表的效果



点赞  2015-2-12 19:52
引用: youyuchao 发表于 2015-2-12 19:50
1,数码管可以正常从0显示到F,只是不是1秒变化一次,没有出现飘红的情况,2.定时器参数应该没有算错  以前都是用这个,附上算法12*(65536-x)/1105926=0.001s  算出x,转化为16进制是 FC67
   数码管程序需要分层次写,将IO脚根据逻辑分组定义,这样你的上层程序会完全与硬件无关,,这句话没有理解到  能详细点吗?
  
谢谢细心解答~~THX!


是不会飘红,因为你设计的扫描频率是1Hz,而且不关com口这就变成同步1hz刷新了,
但又由于定时器配置错误,变成0.125Hz的同步刷新



要666
点赞  2015-2-12 19:55
1.晶振是多少?
2.一般在中断里不会再去处理其他东西,refresh();这个函数可以放到main()里。
3.在refresh();里定义的static uint8 j = 0;感觉总是怪怪的。
4.楼上所说的第一条是对的,你数码管估计重影会特别厉害。
5.有一点没看懂,就是你四位数码管显示的是同一个数字吧?是分四个路口吗?

你试着这样排查,把中断函数里的refresh函数注释掉,在i++后面直接控制LED闪烁,看一下闪烁频率是多少,如果正常的话,就是你refresh函数写的不对。
点赞  2015-2-12 19:55
引用: MrKingMCU 发表于 2015-2-12 19:55
1.晶振是多少?
2.一般在中断里不会再去处理其他东西,refresh();这个函数可以放到main()里。
3.在refresh();里定义的static uint8 j = 0;感觉总是怪怪的。
4.楼上所说的第一条是对的,你数码管估计重影会特别厉害。
5.有一点没看懂,就是你四位数码管显示的是同一个数字吧?是分四个路口吗?

你试着这样排查,把中断函数里的refresh函数注释掉,在i++后面直接控制LED闪烁,看一下闪烁频率是多少,如果正常的话,就是你refresh函数写的不对。



小灯的频率 不对  我再看看 谢谢大兄弟的帮忙的  解决问题的方法学习了!谢谢了
点赞  2015-2-12 20:10
从代码来讲,应该会重影,但lz又没看到重影
lz可以做个方波输出,看看中断频率是多少。

也可以通过仿真器单步调,看运行时间
要666
点赞  2015-2-12 20:11
下次再写就这样写吧,仅供参考
void timer1_init()                //定时器初始化
{
        //初始化
}

void display(void)
{
        //显示函数
}

main()
{
        P0 = 0xff;P3 = 0xff;
            timer1_init();
        while(1)
        {
                if(timer>=1)
                {
                        dispaly_time++;
                        check_time++;
                        timer=0;
                }
                if(display_time>=Display_Timer)
                {
                        dispaly_time=0;
                        display();
                }
                if(check_time>=Check_Timer)
                {
                        check_time=0;
                        //定时加1
                }
        }
}


void interrupt_timer1() interrupt 3
{
        TH1 = 0xfc;
        TL1 = 0x67;
        timer++;
}
点赞  2015-2-12 20:13
引用: le062 发表于 2015-2-12 20:11
从代码来讲,应该会重影,但lz又没看到重影
lz可以做个方波输出,看看中断频率是多少。

也可以通过仿真器单步调,看运行时间
恩恩 在用仿真看看时间,谢谢了 大兄弟 我再看看



点赞  2015-2-12 20:13
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复