/**
************************************************************************************************************
* [url=home.php?mod=space&uid=288409]@file[/url] : main.c
* [url=home.php?mod=space&uid=187600]@author[/url] : xr
* [url=home.php?mod=space&uid=212281]@date[/url] : 2014年4月15日20:34:05 - 2014年4月15日22:28:08
* @version: V1.2.3
* [url=home.php?mod=space&uid=247401]@brief[/url] : PWM技术实现呼吸灯和KTV等娱乐场所的灯光闪烁效果 单片机STC89C52RC MCU 晶振 11.0592MHZ
************************************************************************************************************
*/
#include <reg52.h>
//74HC138
sbit ADDR0 = P1^0;
sbit ADDR1 = P1^1;
sbit ADDR2 = P1^2;
sbit ADDR3 = P1^3;
sbit ENLED = P1^4;
//sbit PWMOUT = P0^0;//PWM输出
#define PWMOUT P0 //8个LED小灯同时呼吸
//灯光控制编码(调整PWM的占空比)
unsigned char code PWM_Table[] = {
1, 3, 8, 11, 14, 17, 20, 23, 26, 29, 32, 35, 38, 41, 44, 47, 50,
53, 56, 59, 62, 65, 68, 71, 74, 77, 80, 83, 86, 89, 92, 95, 98, 99
}; //34个占空比
unsigned char heighHR0, heighLR0;//PWM高电平计数初值的高字节和低字节
unsigned char lowHR0, lowLR0; //PWM低电平计数初值的高字节和低字节
unsigned char thr1, tlr1; //T1计数初值高字节和低字节
unsigned long PWMCounter = 0; //PWM设定频率后的对应的所需计数值 UL型
void Initial();
void ConfigPWM(unsigned int fr, unsigned char dc);
void ConfigTimer1(unsigned int xms);
void main(void)
{
Initial();
/**********呼吸灯效果***************/
ConfigPWM(100, 5);//设定PWM的脉冲宽度为100hz,即10ms,占空比为5%,当PWM的脉冲宽度小于100HZ时,形成的是闪烁的灯光效果
ConfigTimer1(50); //定时50ms调整PWM占空比
/*PWM技术实现KTV等娱乐场所的灯光闪烁效果*/
/***************灯光闪烁****************/
/*
ConfigPWM(10, 5); //PWM脉冲宽度为10HZ,即1ms, 占空比5%
ConfigTimer1(50); //定时20ms调整PWM占空比
*/
while (1);
}
/*初始化*/
void Initial()
{
ADDR3 = 1;
ENLED = 0;//选择LED
ADDR2 = 1;
ADDR1 = 1;
ADDR0 = 0;//选择LEDS6,即流水灯
}
/*使用定时器T0配置PWM*/
void ConfigPWM(unsigned int fr, unsigned char dc) //参数:fr PWM配置的频率,当是100时,即是100HZ,周期是10ms,dc为占空比
{
unsigned long tmp;
unsigned int heigh, low;//分别存放高电平计数值和低电平计数值
tmp = 11059200/12;//一个机器周期的计数频率
PWMCounter = tmp / fr;//一个机器周期计数频率是多少个fr计数频率,即fr频率需要的计数值
heigh = (PWMCounter * dc) / 100;//高电平所需计数值 1/fr周期内高电平计数值
low = PWMCounter - heigh;//低电平所需计数值 1/fr周期内低电平计数值
heigh = 65536-heigh; //高电平时定时器需要装入的初值
low = 65536-low; //低电平时定时器需要装入的初值
heighHR0 = (unsigned char)(heigh >> 8);
heighLR0 = (unsigned char)heigh;
lowHR0 = (unsigned char)(low >> 8);
lowLR0 = (unsigned char)low;
TMOD &= 0xF0;//清零T0控制位
TMOD |= 0x01;//Timer0方式1,16位可设定定时模式
TH0 = heighHR0;
TL0 = heighLR0;//装入高电平时的初值
PWMOUT = 0xFF;//开始PWM输出高电平
TR0 = 1;//启动定时器T0
ET0 = 1;//开启T0中断
EA = 1;//开总中断
}
/*配置定时器Timer1,用于定时xms调整PWM的占空比*/
void ConfigTimer1(unsigned int xms)
{
unsigned long tmp;
tmp = 11059200/12;//一个机器周期的计数频率
tmp = (tmp * xms) /1000;//定时xms需要的计数频率(即计数次数)
tmp = 65536-tmp;//定时xms需要装入的计数初值
thr1 = (unsigned char)(tmp >> 8);//取高八位
tlr1 = (unsigned char)tmp;
TMOD &= 0x0F;//清零T1控制位
TMOD |= 0x10;//定时器T1方式1,16位可设定时器
TH1 = thr1;
TL1 = tlr1;
TR1 = 1;//启动timer1
ET1 = 1;//开启定时器T1中断
EA = 1;//开启总中断
}