源代码

如上图将7个文放在Keli5 中即可,然后烧录在单片机中就行了

烧录软件用的是STC-ISP,不知道怎么安装的可以去看江科大的视频:
【51单片机入门教程-2020版 程序全程纯手打 从零开始入门】https://www.bilibili.com/video/BV1Mb411e7re?p=2\&vd_source=ada7b122ae16cc583b4add52ad89fd5e
源代码:
++头文件要记得宏定义和重定义,避免重复调用:++
cpp
#ifndef _Timer0_h_//名字根据文件名定义即可
#define _Timer0_h_
//声明函数......
#endif
main.c
cpp
#include <STC89C5xRC.H>
#include <INTRINS.H>
#include "Timer0.h"
#include "Key.h"//调用头文件
unsigned char KeyNum,LEDMode;//定义全局变量KeyNum(获取按键的值),LEDMode(切换流水灯流向)
void main()
{
P2=0xFE;//初始化灯P20=0,1111 1110(就是让01灯亮)
Timer0_Init();//初始化定时器/计时器
while(1)
{
KeyNum=Key();//获取按键值
if(KeyNum){
if(KeyNum==1){
LEDMode++;//切换流水灯模式
if(LEDMode>=2)LEDMode=0;
}
}
}
}
//中断程序函数
void Timer0_Routine() interrupt 1
{
static unsigned int T0Count;//局部静态变量
TL0 = 0x66; //设置定时初值
TH0 = 0xFC; //设置定时初值
T0Count++;
if(T0Count>=1000){
T0Count=0;
if(LEDMode==0)P2=_crol_(P2,1);//左移函数,P2每秒左移动一次
if(LEDMode==1)P2=_cror_(P2,1);//右移函数,P2每秒右移动一次
}
}
Timer0.c
cpp
#include <STC89C5xRC.H>
//void Timer0_Init()
//{
// TF0=0;TR0=1;//TCON,寄存器
// //TMOD=0x01;//0000 0001,寄存器
// TMOD=TMOD&0xF0;//把TMOD的低四位清零,高四位不变,方便使用两个定时器
// TMOD=TMOD&0x01;//把TMOD的最低位置1,高四位不变,方便使用两个定时器
// TH0=64535/256;//高电位,寄存器,1毫秒
// TL0=64535%256;//低电位,寄存器,1毫秒
// ET0=1;EA=1;PT0=0;//打开中断开关
//
//}
//定时器0初始化函数
void Timer0_Init() //1毫秒@11.0592MHz
{
// AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
TL0 = 0x66; //设置定时初值
TH0 = 0xFC; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;//允许中断
EA=1;//允许总中断
PT0=0;//低优先级
}
中断程序函数
//中断函数模版
//void Timer0_Routine() interrupt 1
//{
// static unsigned int T0Count;
// TL0 = 0x66; //设置定时初值
// TH0 = 0xFC; //设置定时初值
// T0Count++;
// if(T0Count>=1000){
// T0Count=0;
// P20=~P20;
// }
//}
Timer0.h
cpp
#ifndef _Timer0_h_
#define _Timer0_h_
void Timer0_Init();
#endif
Key.c
cpp
#include <STC89C5xRC.H>
#include "Delay.h"
unsigned char Key()//获取独立按键
{
unsigned char KeyNumber=0;
//进行判断是否摁下按键和防抖操作
if(P31==0){Delay(20);while(P31==0);Delay(20);KeyNumber=1;}
if(P30==0){Delay(20);while(P30==0);Delay(20);KeyNumber=2;}
if(P32==0){Delay(20);while(P32==0);Delay(20);KeyNumber=3;}
if(P33==0){Delay(20);while(P33==0);Delay(20);KeyNumber=4;}
return KeyNumber;
}
Key.h
cpp
#ifndef _Key_h_
#define _Key_h_
unsigned char Key();
#endif
Delay.c
cpp
//Delay.c
#include <STC89C5xRC.H>
#include <INTRINS.H>
//延时函数
void Delay(unsigned int xms) //@11.0592MHz
{
unsigned char i, j;
while(xms){
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
xms--;
}
}
Delay.h
cpp
//Delay.h
#ifndef __Delay_H__
#define __Delay_H__
//延时函数头文件
void Delay(unsigned int xms);
#endif
代码解析与教程:
main.c
- 注释解释很清楚,重点来讲解一下中断函数中的左移右移函数
他们哥俩是依赖头文件**<INTRINS.H>的库函数** :
会用即可,这是char类型的,里面也有其他类型的,参数一是要移动的数,参数二是移动的位数。
例如:0000 0001使用左移函数_crol_左移一位就是0000 0010,其他同理,因此,加上中断函数,灯就会每秒移动一次Dealy模块
- 包含源代码与头文件,不需要知道怎么实现的会用即可,后续使用,直接将头文件和源代码拿过来用即可;
xms是定义的毫秒,1000毫秒就是1秒;模版生成的是1毫秒的,因此xms等于1000Timer0模块
- 包含源代码与头文件,需要知道怎么实现,会用
- 51单片机的定时器和计数器十分重要,要理解怎么用,要知道原理是什么,要结合原理图来分析怎么做,先看代码
cpp#include <STC89C5xRC.H> //void Timer0_Init() //{ // TF0=0;TR0=1;//TCON,寄存器 // //TMOD=0x01;//0000 0001,寄存器 // TMOD=TMOD&0xF0;//把TMOD的低四位清零,高四位不变,方便使用两个定时器 // TMOD=TMOD&0x01;//把TMOD的最低位置1,高四位不变,方便使用两个定时器 // TH0=64535/256;//高电位,寄存器,1毫秒 // TL0=64535%256;//低电位,寄存器,1毫秒 // ET0=1;EA=1;PT0=0;//打开中断开关 // //} //定时器0初始化函数 void Timer0_Init() //1毫秒@11.0592MHz { // AUXR &= 0x7F; //定时器时钟12T模式 TMOD &= 0xF0; //设置定时器模式 TMOD |= 0x01; //设置定时器模式 TL0 = 0x66; //设置定时初值 TH0 = 0xFC; //设置定时初值 TF0 = 0; //清除TF0标志 TR0 = 1; //定时器0开始计时 ET0=1;//允许中断 EA=1;//允许总中断 PT0=0;//低优先级 } 中断程序函数 //中断函数模版 //void Timer0_Routine() interrupt 1 //{ // static unsigned int T0Count; // TL0 = 0x66; //设置定时初值 // TH0 = 0xFC; //设置定时初值 // T0Count++; // if(T0Count>=1000){ // T0Count=0; // //下面是代码区 // } //}
- 最上面注释掉的代码是要求理解的;中间的代码是STC-ISP软件生成的;最下面的代码是中断函数模版,拿到main.c中可直接使用,但是也要了解原理:
大家可以这个博客深度理解定时器计数器和中断,这个是教程博客:(51单片机)计时器时钟(C语言代码编撰)(定时器/中断器、计数器教程)(51单片机重点)-CSDN博客
Key模块
- 包含源代码与头文件,不需要知道怎么实现的会用即可,后续使用,直接将头文件和源代码拿过来用即可;
序号1是按键的防抖操作,不需要理解,有按键的地方直接用即可
序号2是独立按键控制变量。
KeyNumber就是返回值,按键K1就返回1,其他同理独立按键教程、LED教程
由于单片机系列版本不一样,单片机核心控制可能会有不同,例如:有些单片机的LED的L1是P21,有些就是P2_1,需要看单片机核心,或者头文件:

++可以看到我的STC89C52RC是P21;++
独立按键
先看原理图:
可以看到控制K1的是P31,同理K2是P30,按键都是高电位 ,因此只要将P31设置成0,就是按键通电,相当于激活LED教程
先看原理图:
LED是高电位,设定为0就是通电
P2就是16进制的LED灯总控制,如:0xFF=1111 1111,就是全关,例如代码中的:
P2=0xFE,就是1111 1110,就是L1亮,左移一位就是1111 1101,就是L2亮,其他同理,配合中断函数 ,就可以每秒移动一次
效果视频:
(51单片机)按键控制流水灯移位
注:该代码是本人自己所写,可能不够好,不够简便,欢迎大家指出我的不足之处。如果遇见看不懂的地方,可以在评论区打出来,进行讨论,或者联系我。上述内容全是我自己理解的,如果你有别的想法,或者认为我的理解不对,欢迎指出!!!如果可以,可以点一个免费的赞支持一下吗?谢谢各位彦祖亦菲!!!!!