打印
[应用方案]

单片机跑马灯

[复制链接]
1011|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
capturesthe|  楼主 | 2016-4-21 22:29 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我用的板子是一个电机驱动版,上面有四个LED,接在P1.0,P1.1,P1.2,P1.3脚上,拉低就点亮。
用定时器1ms触发一次,1000次就是1秒,每个灯亮一秒,形成跑马灯。
/*----------------------------------------------------
        名称:用定时器控制led亮灭
        单片机:stc12c2052
        晶振:12M
        说明:四个led,一个亮一秒,跑马灯。
------------------------------------------------------*/
#include<reg52.h>                //头文件
sbit LED1=P1^0;
sbit LED2=P1^1;
sbit LED3=P1^2;
sbit LED4=P1^3;
#define LED1_ON        {LED1 = 0;}
#define LED2_ON        {LED2 = 0;}
#define LED3_ON        {LED3 = 0;}
#define LED4_ON        {LED4 = 0;}
#define ALL_OFF {LED1 = 1;LED2 = 1;LED3 = 1;LED4 = 1;}
void Init_Timer0(void)        //初始化定时器0
{
        TMOD=0x01;                                //定时器0,使用模式1,16位定时器
        TH0=(65536-1000)/256;        //给定初值
        TL0=(65536-1000)%256;
        EA=1;                //打开总中断
        ET0=1;        //打开定时器中断
        TR0=1;        //开定时器
}
void main()        //主函数
{
        Init_Timer0();
        LED1 = 0;
        while(1)
        {
        }
}
void Timer0_isr(void) interrupt 1
{
        static unsigned short int count = 0;
        static char index = 0;
        TH0=(65536-1000)/256;//重新赋值 1ms
        TL0=(65536-1000)%256;
        EA = 0;
        ++count;
        if(count == 1000)
        {
                ++index;
                index &= 0x03;
                ALL_OFF;
                switch(index){
                        case 0:
                                LED1_ON;
                                break;
                        case 1:
                                LED2_ON;
                                break;
                        case 2:
                                LED3_ON;
                                break;
                        case 3:
                                LED4_ON;
                                break;
                        default:
                                break;
                }
                count = 0;
        }
        EA = 1;
}
stc_01_1.c
觉得switch语句太丑了,想改成根据序号,点亮不同的灯,但点灯的变量是sbit ,C51不支持sbit数组。
想了想,把点灯动作写成函数,四个灯四个函数,函数指针数组,这个支持。

/*----------------------------------------------------
        名称:用定时器控制led亮灭
        单片机:stc12c2052
        晶振:12M
        说明:四个led,一个亮一秒,跑马灯。
------------------------------------------------------*/
#include<reg52.h>                //头文件
typedef void (*pFun)(void);
sbit LED1=P1^0;
sbit LED2=P1^1;
sbit LED3=P1^2;
sbit LED4=P1^3;

#define LED1_ON        {LED1 = 0;}
#define LED2_ON        {LED2 = 0;}
#define LED3_ON        {LED3 = 0;}
#define LED4_ON        {LED4 = 0;}
#define ALL_OFF {LED1 = 1;LED2 = 1;LED3 = 1;LED4 = 1;}

void set_led1_on(void)
{
        LED1_ON;
}
void set_led2_on(void)
{
        LED2_ON;
}
void set_led3_on(void)
{
        LED3_ON;
}
void set_led4_on(void)
{
        LED4_ON;
}

const pFun led_on[4] = {set_led1_on,set_led2_on,set_led3_on,set_led4_on};
//const void (*led_on[4])(void) = {set_led1_on,set_led2_on,set_led3_on,set_led4_on};

void Init_Timer0(void)        //初始化定时器0
{
        TMOD=0x01;                                //定时器0,使用模式1,16位定时器
        TH0=(65536-1000)/256;        //给定初值
        TL0=(65536-1000)%256;
        EA=1;                //打开总中断
        ET0=1;        //打开定时器中断
        TR0=1;        //开定时器
}

void main()        //主函数
{
        Init_Timer0();//初始化定时器0
        LED1 = 0;                //开第一个灯
        while(1)
        {
        }
}

//定时器中断函数,1ms 定时。
void Timer0_isr(void) interrupt 1
{
        static unsigned short int count = 0;
        static char index = 0;
        TH0=(65536-1000)/256;//重新赋值 1ms
        TL0=(65536-1000)%256;
        EA = 0;
        ++count;
        if(count == 1000)        //到 1 秒了
        {
                ++index;                //点灯序号
                index &= 0x03;        //四个灯,序号0~3
                ALL_OFF;                //全关灯
                (*led_on[index])();                //打开序号对应灯
                count = 0;                                // 1秒计数开始。1s = 1000ms。
        }
        EA = 1;
}
stc_01_2.c
后来想到虽然sbit数组不支持,但是我可以不单个控制灯,而是四个灯一起控制,P1口可以用char赋值,char数组是支持的,改成下面这样:
/*----------------------------------------------------
        名称:用定时器控制led亮灭
        单片机:stc12c2052
        晶振:12M
        说明:四个led,一个亮一秒,跑马灯。
------------------------------------------------------*/
#include<reg52.h>                //头文件
typedef void (*pFun)(void);
const unsigned char led_port[4] = {0xFE,0xFD,0xFB,0xF7};
void Init_Timer0(void)        //初始化定时器0
{
        TMOD=0x01;                                //定时器0,使用模式1,16位定时器
        TH0=(65536-1000)/256;        //给定初值
        TL0=(65536-1000)%256;
        EA=1;                //打开总中断
        ET0=1;        //打开定时器中断
        TR0=1;        //开定时器
}
void main()        //主函数
{
        Init_Timer0();//初始化定时器0
        P1 = 0xFE;                //开第一个灯
        while(1)
        {
        }
}
//定时器中断函数,1ms 定时。
void Timer0_isr(void) interrupt 1
{
        static unsigned short int count = 0;
        static char index = 0;
        TH0=(65536-1000)/256;//重新赋值 1ms
        TL0=(65536-1000)%256;
        EA = 0;
        ++count;
        if(count == 1000)        //到 1 秒了
        {
                ++index;                //点灯序号
                index &= 0x03;        //四个灯,序号0~3
                P1 = led_port[index];
                count = 0;                                // 1秒计数开始。1s = 1000ms。
        }
        EA = 1;
}


沙发
xuanhuanzi| | 2018-8-15 12:37 | 只看该作者
多谢分享

使用特权

评论回复
板凳
zhuotuzi| | 2018-8-15 20:55 | 只看该作者
这个用法新奇。

使用特权

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

本版积分规则

22

主题

136

帖子

1

粉丝