标题:
关于单片机呼吸灯的新想法设计
[打印本页]
作者:
邓文雄ABC
时间:
2018-9-10 16:59
标题:
关于单片机呼吸灯的新想法设计
看过一些用单片机做的呼吸灯,很多都是利于延时做的。如果用延时做,会有大量的延时处理。这是非常落后的程序,再想扩展别的功能就可能得不到正确的响应。我想到一个方法来做,并且已实现同时多路LED 的呼吸灯;
原理图见附件。
利用一个定时器产生20US的中断。每500个中断时间就是10ms,利用500个中断控制这10ms的高低电平(占空比),如250个中断高,250个中断低,就是50%的占空比。10MS的周期刚好是100HZ,LED 100HZ刷新足够了。利用另一个定时器来控制占空比的时间,这样就产生的呼吸效果。而且可以同时控制多路。
单片机源码:
#ifndef _CONFIG_H
#define _CONFIG_H
#include "STC15W40XXX.H"
#include <intrins.h>
//定义主时钟
#define FOSC 24000000UL //20MHZ
#define T1000Hz (FOSC / 12 / 1000)
#define CCP_S0 0x10 //P_SW1.4
#define CCP_S1 0x20 //P_SW1.5
/* 数据类型定义 */
typedef signed char uchar; // 8位有符号整型数
typedef signed int uint; //16位有符号整型数
typedef signed long ulong; //32位有符号整型数
//定时器T0用作脉冲发生器,定时20us
void Timer0Init(void) //20微秒@24.000MHz
{
AUXR &= 0x7F; //定时器时钟12T模式
TMOD &= 0xF0; //设置定时器模式
TL0 = 0xD8; //设置定时初值
TH0 = 0xFF; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
ET0=1;
}
#endif
#include "main.h"
sbit LEDAll = P3^5;
sbit LEDA = P3^2;
sbit LEDB = P3^3;
sbit LEDC = P5^5;
sbit LEDD = P5^4;
sbit KEY_On=P3^4;
bit Power_on=0;
uchar KeySta = 1; //全部按键的当前状态
uchar backup = 1; //按键值备份,保存前一次的值
uint cnt;
uint value;
uint PWM_Cont=0;
//--------------------
void UartInit(); [url=]//9600bps@33.1776MHz[/url]
void Timer0Init(); //Timer0 set
void PCATimerInit(); //Timer0 set
void Key_scan(); //按键扫描函数
void Key_Function(); //按键功能函数
void Delay500ms() [url=]//@33.1776MHz[/url]
{
unsigned char i, j, k;
_nop_();
_nop_();
i = 64;
j = 9;
k = 179;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
/**********************************************/
void main()
{
PCATimerInit(); //PCA定时器初始化
Timer0Init(); //定时器0初始化
UartInit(); //串口初始化
EA = 1; //打开总中断
Delay500ms();
SBUF=0XFF;
LEDAll=0;
LEDA=0;
LEDB=0;
LEDC=0;
LEDD=0;
P1=0X00;
while(1)
{
if(Power_on )
{
// LEDAll=0;
}
else
{
//LEDAll=1;
}
}
}
/********************** Timer0 20us中断函数 ************************/
//定义20us的中断,因为10ms的周期信号100hz控制LED频频, 在10MS内分成500分占空比。每20US一次。
void timer0 (void) interrupt 1
{
static uint P_20us=0;
EA=0;
P_20us++;
if(P_20us>=500)
{
LEDAll=1;
P_20us=0;
}
else
{
if(P_20us==PWM_Cont)
LEDAll=0;
}
EA=1;
}
//PCA定时器中断 1ms的中断时间
void PCA_isr() interrupt 7 using 1
{
static bit i=0;
static uchar j=0;
j++;
CCF0 = 0; //清中断标志
CCAP0L = value;
CCAP0H = value >> 8; //更新比较值
value += T1000Hz;
Key_scan();
Key_Function();
if(j>=5)
{
j=0;
if(i==0)
{
PWM_Cont++;
if(PWM_Cont==500)
{
i=1;
}
}
else
{
PWM_Cont--;
if(PWM_Cont==20)
{
i=0;
}
}
}
}
复制代码
电路原理图如下:
0.png
(141.07 KB, 下载次数: 38)
下载附件
2018-9-10 17:49 上传
下载:
直径105MM的三色呼吸灯.pdf
(104.15 KB, 下载次数: 16)
2018-9-10 16:50 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
邓文雄ABC
时间:
2018-9-10 17:00
按键部份已删除
作者:
z905188015
时间:
2018-9-11 14:38
学习学习,不错不错
作者:
z905188015
时间:
2018-9-11 14:38
学习学习,看看看看,见过大佬
作者:
leeder_a
时间:
2018-9-11 20:02
延时做的太占资源,芯片就干不了其它事了;用中断来做,所占的资源很少,芯片可处理其它事情。
作者:
bhjyqjs
时间:
2018-9-12 08:37
专业呼吸灯可以,要是在其他应用中,20uS中断一次,单片机什么也干不了
作者:
邓文雄ABC
时间:
2019-1-25 10:15
单片机的频率可以尽量设置最高的,比较24M或 以上,20US还是可以的,中断里面不要做过多的事就可以
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1