找回密码
 立即注册
查看: 1828|回复: 2

新手学STC单片机 实验一 流水灯

[复制链接]
  • TA的每日心情

    2024-1-8 16:35
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    10

    主题

    18

    回帖

    350

    积分

    中级会员

    积分
    350
    发表于 2023-2-28 14:03:27 | 显示全部楼层 |阅读模式
    本帖最后由 sbk100 于 2023-2-28 14:06 编辑

    先上电路

    新手学STC单片机 实验一 流水灯-1.png

    流水灯电路为共阳接法,RP14 是一个排阻连接到VCC。JP78 给低电平时LED灯点亮。轮流点亮8个LED灯,就能看到流水灯的效果。


    流水灯程序使用了一个定时器进行延时,每 500ms 更新一次当前的状态,即当前 LED 灯灭,下一个 LED 灯亮。下面是程序



    /*******************************************************
    *
    程序功能:流水灯
    *******************************************************/
    #include "hal.h"


    #ifndef FOSC              //晶振频率
    #define FOSC 12000000L
    #endif
    #define DATA P0
    uchar num;
    /*******************************************************
    //函数名称:Timer0Init()
    //函数功能:定时器0初始化函数 10毫秒@12MHz
    //入口参数:无
    //返回参数:无
    ********************************************************/
    void Timer0Init(void)
    {
        TIMER_CLK_DIV(0,12);//定时器时钟12T模式  
        TIMER_TIME(0);//设置定时器0定时模式
        TIMER_MODE(0,0);//设置定时器0模式0
        TL0 = 0xF0;//设置定时初值
        TH0 = 0xD8;//设置定时初值  
        CLR_TIMER_FLAG(0);//清除TF0标志   
    }
    /*******************************************************
    //函数名称:main()
    //函数功能:程序主函数
    ********************************************************/
    void main()
    {

        num=0xfe;
        Timer0Init();//初试化定时器
        TIMER_RUN(0,START);//定时器0开始计时
        TIMER_INT_EN(0,ON);//开启定时器0中断
        INT_GLOBAL_ENABLE(ON); //开启全局中断
        while(1);
    }



    /*******************************************************
    //函数名称:Timer0_ISR()
    //函数功能:定时器0中断服务程序
    //入口参数:无
    //返回参数:无
    ********************************************************/

    void Timer0_ISR() interrupt 1 using 1
    {
           static unsigned char i;
           if( ++i>=50) //如果到500ms,更新一次状态
           {
                  i=0;
                  DATA=num;
                   if(num==0x7f)//检测是否移到最左端
                  {
                       num=0xfe;
                  }
                   else {
                       num<<=1;//左移一位
                       num|=0x01;//最后一位补1
                  }
            }
    }

    定时器定时初值10ms
    TL0 = 0xF0;//设置定时初值
    TH0 = 0xD8;//设置定时初值


    0xF00xD8 的由来为(65536-1000)分别取整 256 和取余 256 得到,因为定时器采用的事 12T 的计数模式所以采用老51的算法。65536为16位的定时计数器最大计数值,1000为计数器记到最大值产生中断,
    所以设置底线值的时候减掉需要计数的时间,256 是定时计数器的初值寄存器是 8 位的所以分为两个计数器。12T计数方式大概一个机械周期为1us。


    “if(++i>=50)”定时中断里面这句用于计数50次,每次10ms,50次就是500ms,到了500ms实现对应LED功能。




    回复 送花

    使用道具 举报

    该用户从未签到

    45

    主题

    2902

    回帖

    6522

    积分

    超级版主

    积分
    6522
    发表于 2023-2-28 15:35:46 | 显示全部楼层
    建议初值赋值:

    TH0 = (u8)((65536-FOSC/12/100)/256);     //设置定时初值, 12T, 100Hz(10ms)
    TL0 = (u8)((65536-FOSC/12/100)%256);
  • TA的每日心情

    2024-1-8 16:35
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    10

    主题

    18

    回帖

    350

    积分

    中级会员

    积分
    350
     楼主| 发表于 2023-2-28 16:32:46 | 显示全部楼层
    梁工 发表于 2023-2-28 15:35
    建议初值赋值:

    TH0 = (u8)((65536-FOSC/12/100)/256);     //设置定时初值, 12T, 100Hz(10ms)

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

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-4-25 13:38 , Processed in 0.057513 second(s), 39 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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