- 打卡等级:初来乍到
- 打卡总天数:5
- 最近打卡:2025-04-23 14:03:23
中级会员
- 积分
- 454
|
本帖最后由 sbk100 于 2023-2-28 14:06 编辑
先上电路
流水灯电路为共阳接法,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;//设置定时初值
0xF0 与 0xD8 的由来为(65536-1000)分别取整 256 和取余 256 得到,因为定时器采用的事 12T 的计数模式所以采用老51的算法。65536为16位的定时计数器最大计数值,1000为计数器记到最大值产生中断,
所以设置底线值的时候减掉需要计数的时间,256 是定时计数器的初值寄存器是 8 位的所以分为两个计数器。12T计数方式大概一个机械周期为1us。
“if(++i>=50)”定时中断里面这句用于计数50次,每次10ms,50次就是500ms,到了500ms实现对应LED功能。
|
|