class="markdown_views prism-kimbie-light">
前言
这篇文章用来记录呼吸灯实验的设计思路并进行经验的归纳总结
源代码
- main.h文件
#ifndef __main_h
#define __main_h
#define P_led1 P2_0
#define P_led2 P2_1
#define F_led1On() P_led1 = 0
#define F_led1Off() P_led1 = 1
#define F_led2On() P_led2 = 0
#define F_led2Off() P_led2 = 1
// 定义基准时间
//基准时间 4ms
#define D_4ms 1
#define D_250ms 70
#define D_1s 250
//基准时间 1s
#define D_1m 60
//基准时间 1m
#define D_1h 60
#ifdef MAIN_C
bit b4ms;
uint8_t timer1Click, timer4ms, timer250ms, timer1s, timer1m, timer1h;
#else
extern bit b4ms;
extern uint8_t timer1Click, timer4ms, timer250ms, timer1s, timer1m, timer1h; ;
#endif
void InitSys();
void DisplayProcess();
void UserSettingProcess();
void TimeProcess();
void TaskProcess();
void Delay(int time);
#endif
- main.c文件
#define __main_c
#include "includeAll.h"
int test = 0; // 定义一个test变量用于表示LedOn时的延时时间
int flag = 1; // flag = 1 代表led从暗逐渐变到亮
//============================================
void main() {
F_turOnWDT(); // 看门狗寄存器
InitSys();
TH2 = (65536 - 900) / 256; // 0.25ms==4khz timer2 interrupt
RCP2H = TH2;
TL2 = (65536 - 900) % 256;
RCP2L = TL2;
EA = 1; // 开总中断
ET2 = 1; // timer2 interrupt enable
TR2 = 1; // timer2 running
while (1) {
TimeProcess();
}
}
//============================================
void InitSys() {
// system clock
CLKCON = 0x03; // Clock div 1
STPPCK = 0;
STPFCK = 0;
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
SELFCK = 1;
// I/O init
P2MOD = 0xa;
}
//============================================
void DisplayProcess() {}
//============================================
void UserSettingProcess() {}
//============================================
void TaskProcess() {}
//============================================
void TimeProcess() {
if (b4ms == 1) {
b4ms = 0;
timer4ms++;
timer250ms++;
timer1s++;
}
if ((timer4ms >= D_4ms)) {
timer4ms = 0;
// do something
if(test > 300){
test = 300;
flag = 0; // flag = 0 代表led从亮逐渐变到暗
}
if(test < 0){
test = 0;
flag = 1; // flag = 1 代表led从暗逐渐变到亮
}
F_led1On();
Delay(test);
F_led1Off();
Delay(3000);
if(test <= 300 && flag == 1){
test += 1;
}
if(test <= 300 && flag == 0){
test -= 1;
}
}
if (timer250ms >= D_250ms) {
timer250ms = 0;
// do something
}
if (timer1s >= D_1s) {
// 1s
timer1s = 0;
// do something
timer1m++;
if (timer1m >= D_1m) {
// 1m
timer1m = 0;
// do something
timer1h++;
if (timer1h >= D_1h) {
timer1h = 0;
// do something
}
}
}
}
//=============================================================================
// Function: void TIMER2_int(void)
// Purpose: TIMER2 interrupt vector
// Input: none
// OutPut: none
// Author:
//=============================================================================
void TIMER2_int(void) interrupt 5 { // 4Khz == 0.25ms
TF2 = 0; // clear interrupt flag
TR2 = 1;
TH2 = (65536 - 900) / 256; // 重新给定时器赋初值
RCP2H = TH2;
TL2 = (65536 - 900) % 256;
RCP2L = TL2;
timer1Click++;
if (timer1Click > 16) { // 16=4ms@0.25ms
b4ms = 1;
timer1Click = 0;
}
}
// 用于LED灯的延时
void Delay(int time) {
int i;
for (i = 0; i < time; i++)
CLRWDT = 1;
}
设计思路
- 该呼吸灯实验是通过控制每一个瞬间LED亮和灭的延时时间比来控制LED灯的亮度,然后通过中断调用子程序和单片机的定时器功能来实现持续不断的改变LED灯的亮度从而实现呼吸灯的实验。
- 代码片段如下,其中test为一个变量。每来一次定时时将实现test自增1或自减1:
F_led1On();
Delay(test);
F_led1Off();
Delay(3000);
// 用于LED灯的延时
void Delay(int time) {
int i;
for (i = 0; i < time; i++)
CLRWDT = 1;
}
- 在main.c文件中,如下代码片段是根据你本次实验想要定时计数器计数的时间片段计算出来的:
TH2 = (65536 - 900) / 256; // 0.25ms==4khz timer2 interrupt
RCP2H = TH2;
TL2 = (65536 - 900) % 256;
RCP2L = TL2;
- main.c文件中的
EA = 1;
为使得每个中断通过其各个中断控制位使能或禁止;ET2 = 1;
为允许Timer2中断;TR2 = 1;
为Timer2运行。你也可以直接对特殊功能寄存器“IE”、特殊功能寄存器“T2CON”进行赋值来实现中断控制,详细说明如下如所示:
实验结果
Ps
有关学习单片机的经验总结到这里就先告一段落了,不管你是有意还是无意点击并看到我写这几篇文章,我都在此向屏幕前的你表示感谢。此外,由于时间仓促,如果文章中有出现什么错误欢迎留言指正,我们争取共同进步!