STC12C5A60S2-定时器+数码管

系列文章目录

第2-3章 定时器+74HC573显示8位数码管


文章目录

  • 系列文章目录
  • 前言
  • 一、TIMER0
  • 二、74HC573
    • 1.原理图
    • 2.显示结果
    • 大功告成
  • 总结


前言

两章合并,主要运用定时器0和开发板上的74HC573点亮8位数码管。计划做一个8位计时器,每秒加1.


一、TIMER0

增强型的51说明书看着头大,主要是功能啰里啰嗦的,一大堆用不到的东西。定时器注意,12C5A向下兼容,所以定时器默认是12T的,若要改为1T,需配置定时器
AUTX|=0X80

另外计算定时器TH0,TL0的值,直接找STC-ISP上有直接计算的。
自己算的话,就是

#define TIMER0_COUNT (24*1000) //24Mhz,1000us
void Timer0_Init(void)
{
    AUXR|=0X80;
    TH0=(65536-TIMER0_COUNT)/256;
    TL0=(65536-TIMER0_COUNT)%256;
    TMOD|=0X01;
    TR0=1;
    ET0=1;
    EA=1;

}

上述即为1T时,24Mhz晶振定时1ms的值。
另外测试定时器发现个问题,折腾了好久:

#define WEILA   P0^0
#define DULA    P0^1

WEILA=1;

上面这么写一直报错,说语法错误,少个分号啥的,没整明白为啥,必须要改成P00才行,不能用P0^0赋值。
另外还有个要注意的点,

sbit WEILA P00;
这么写也是错的,要写成sbit WEILA=P00;

二、74HC573

点亮这玩意又耗费我好长时间,一个是因为开发板不熟,所有数码管要单独供电,跳线帽没插,2是原理图上脚位标的不清楚,脚位搞反了。

1.原理图

STC12C5A60S2-定时器+数码管_第1张图片
直接P2口做573输入,P00,P01分别做位选段选锁存使能。

代码如下(示例):

#define WEILA   P00
#define DULA    P01
#define LEDS    P2
const uchar num_table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
const uchar wei_table[]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};

void Timer0_isr(void) interrupt 1
{
 
    TH0=(65536-TIMER0_COUNT)/256;
    TL0=(65536-TIMER0_COUNT)%256;
    P0^=0X04;
    tms_1s++;
    if(tms_1s==1000)
    {
        tms_1s=0;
        f_1s=1;
    }
        
    disp_cnt%=8;
    if(disp_cnt==0)
    {
        disp_num=disp_count;
    }

    WEILA=1;
    LEDS=wei_table[disp_cnt];
    WEILA=0;

    DULA=1;
    LEDS=num_table[disp_num%10];
    DULA=0;  
    disp_num/=10;
    disp_cnt++;
}

void main()
{


    Timer0_Init();
   
    while(1)
    {
        
        if(f_1s)
        {
            f_1s=0;
            disp_count++;                    
        }
         
    }

    return;
}

disp_cnt用来切换8个数码管显示哪一位,分时8次动态显示
disp_count是要显示的计数值,每秒加1
disp_num为当前位选要显示的数字,程序中通过不断除10取余得到这个数,靓!

2.显示结果

效果如下:
STC12C5A60S2-定时器+数码管_第2张图片
显示正常,但是有鬼影,应该是段选位选切换的一瞬间WEILA=1;DULA=1时造成的,在置1前将所有IO口重新设置一次。

代码如下(示例):

void Timer0_isr(void) interrupt 1
{
 
    TH0=(65536-TIMER0_COUNT)/256;
    TL0=(65536-TIMER0_COUNT)%256;
    P0^=0X04;
    tms_1s++;
    if(tms_1s==1000)
    {
        tms_1s=0;
        f_1s=1;
    }
        
    disp_cnt%=8;
    if(disp_cnt==0)
    {
        disp_num=disp_count;
    }

    LEDS=0XFF;//消除鬼影
    WEILA=1;
    LEDS=wei_table[disp_cnt];
    WEILA=0;
    LEDS=0X00;//消除鬼影
    DULA=1;
    LEDS=num_table[disp_num%10];
    DULA=0;  
    disp_num/=10;
    disp_cnt++;
}

再次看下结果:
STC12C5A60S2-定时器+数码管_第3张图片

大功告成

总结

写了七八年单片机汇编,写程序思路没啥问题,关键是对51的C编译器不太熟,我又喜欢钻牛角尖,影响效率。另外后续再写类似的前先搞个简单的,比如这个点亮8位数码管,我一次程序直接写完,结果调试不好找问题,应该先尝试下只点亮一个的。

今天就整这么多吧,后续整个模板出来。

你可能感兴趣的:(单片机练级,51单片机)