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

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

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-04-23 14:03:23

13

主题

27

回帖

454

积分

中级会员

积分
454
发表于 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功能。




回复

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:61
  • 最近打卡:2025-05-12 09:50:54

73

主题

5922

回帖

1万

积分

超级版主

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

TH0 = (u8)((65536-FOSC/12/100)/256);     //设置定时初值, 12T, 100Hz(10ms)
TL0 = (u8)((65536-FOSC/12/100)%256);
  • 打卡等级:初来乍到
  • 打卡总天数:5
  • 最近打卡:2025-04-23 14:03:23

13

主题

27

回帖

454

积分

中级会员

积分
454
发表于 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, 2025-5-13 15:14 , Processed in 0.147392 second(s), 63 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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