打印
[PIC®/AVR®/dsPIC®产品]

PIC16F877A秒表的设计问题?

[复制链接]
1685|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 冰封小肥牛 于 2016-6-2 20:06 编辑

打算用16F877A设计一个秒表,然后用数码管显示出来。最低两位数码管用来显示毫秒(0--100)变化范围,每隔10ms(使用的是定时器0的中断)计数加一次。但是现在显示的数码管有问题,如图(只有最低位数码管在变化,而且两个数码管非常暗)。求解应该如何编写程序才能正确显示。下面是在下的编写的程序


872943584.jpg (428.7 KB )

872943584.jpg
沙发
冰封小肥牛|  楼主 | 2016-6-2 20:06 | 只看该作者
#include <xc.h>
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF        // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF       // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF         // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; low-voltage programming enabled)
#pragma config CPD = OFF        // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF        // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

unsigned int i,ms;
const unsigned char table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};        //共阴极数码管显示编码

void display(unsigned int seg_num);
void delay(unsigned int x);
void time0_init();

void main()
{            
    PORTD = 0x00;               //数码管位选
    PORTA = 0x00;               //数码管段选
    TRISA = 0x00;
    TRISD = 0x00;              
    time0_init();
    while(1)
    {
        display(ms);
        if(ms == 99)            //毫秒加到100清0
        {
            ms = 0;
        }
    }
}

void interrupt time0(void)      //中断函数
{
    if(INTCONbits.T0IF == 1)   
    {
        INTCONbits.T0IF = 0;
        TMR0 = 0xD9;            //定时10MS
        ms++;                   //过10MS加1
    }
}

void delay(unsigned int x)      //延时函数
{
        unsigned int a,b;
        for(a=x;a>0;a--)
                for(b=110;b>0;b--);
}

void display(unsigned int seg_num)
{
      unsigned int ms_dec,ms_un;   
      ms_dec = seg_num/10;
      ms_un = seg_num%10;
      PORTAbits.RA0 = 1;            //段选最低位数码管(个位)
      PORTD = table[ms_un];         //毫秒个位显示
      PORTAbits.RA0 = 0;            //关段选
//      delay(1);
      PORTAbits.RA1 = 1;            //段选第二位数码管(十位)
      PORTD = table[ms_dec];        
      PORTAbits.RA1 = 0;
//      delay(1);
}

void time0_init()
{
    TMR0 = 0xD9;                    //定时器0的设置,采用64分频
    INTCONbits.GIE = 1;
    INTCONbits.T0IE = 1;
    INTCONbits.T0IF = 0;
    OPTION_REGbits.T0CS = 0;
    OPTION_REGbits.PSA = 0;
    OPTION_REGbits.PS0 = 1;
    OPTION_REGbits.PS1 = 0;
    OPTION_REGbits.PS2 = 1;
}

使用特权

评论回复
板凳
NE5532| | 2016-6-3 13:09 | 只看该作者
先送段数据,再选片选,片选以后要延时,让人看清楚,然后再换下一位。你第一个字显示以后马上片选就关了,然后显下一位,当然只有后面一个数咯,除非你反应能达到光速。楼主先画流程图再写程序,不然总是晕的。

使用特权

评论回复
地板
冰封小肥牛|  楼主 | 2016-6-4 09:18 | 只看该作者
NE5532 发表于 2016-6-3 13:09
先送段数据,再选片选,片选以后要延时,让人看清楚,然后再换下一位。你第一个字显示以后马上片选就关了, ...

搞定啦!不过最后一位还是不变化,应该是数码管变化刷新太快了

使用特权

评论回复
5
MOn51| | 2016-6-4 13:56 | 只看该作者
冰封小肥牛 发表于 2016-6-4 09:18
搞定啦!不过最后一位还是不变化,应该是数码管变化刷新太快了

100毫秒跳一次,LED刷新没有没有问题,请再检查程序。

使用特权

评论回复
6
冰封小肥牛|  楼主 | 2016-6-4 15:59 | 只看该作者
MOn51 发表于 2016-6-4 13:56
100毫秒跳一次,LED刷新没有没有问题,请再检查程序。

嗯!我定时的是10MS,太快了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

27

主题

198

帖子

1

粉丝