标题:
基于STC12C2520AD单片机的50W-LED可调光灯盘控制器程序
[打印本页]
作者:
das
时间:
2015-4-5 00:35
标题:
基于STC12C2520AD单片机的50W-LED可调光灯盘控制器程序
本帖最后由 das 于 2015-4-5 00:36 编辑
//*************************************************************************************//
//--P3.4口采样过零信号,每10ms采样到一个过零高电平,用于PWM0的时钟信号--//
//--P1.2口采样电位器的输出调光电压,并进行8bit的A/D转换--//
/*P3.7口输出PWM信号,PWM信号的频率和相位角应该自动能根据P1.6口的过零信号和P1.2口的模拟信号,
进行计算分析,输出时实的控制信号,以控制可控硅的导通时间,达到调光的目的; */
/*P3.2口利用外部中断功能,实现红外线遥控器的解码,以实现遥控功能. */
//P1.6是AT24C01的数据端;P1.7是AT24C01的时钟端,用于存储红外摇器的解码值,达到记忆亮度的效果//
//P1.0接LED指示灯//
// 2013-9-13 /杨旭
//*************************************************************************************//
#include <stc12c2052ad.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit LED=P1^0;
sbit IR_RE=P3^2;
sbit SDA=P1^6; //AT24C01数据端
sbit SCL=P1^7; //AT24C01时钟端
//--------------------------------红外线解码用变量
static uchar date[]={0,0,0,0};
static uchar qinlong;
//--------------------------------AD转换用变量
static uchar AD_dat_over0,AD_dat_over1;
static uchar j=0; //AD中断计数器
//--------------------------------------------------------------------------/
void delayms(uint a)
{
uint b;
for(b=0;b<a;b++);
}
//--------------------------------------------------------------------------//
void delay882()
{
uchar i,j;
i=35;
do{j=68;
do{j--;}
while(j);
i--;
}while(i);
}
//-------------------------
void delay1000()
{
uchar i,j;
i=39;
do{j=70;
do{j--;}
while(j);
i--;
}while(i);
}
//-------------------------
void delay2400()
{
uchar i,j;
i=93;
do{j=70;
do{j--;}
while(j);
i--;
}while(i);
}
//--------------------------------------------------------------------------//
/*名称:初始化端口程序
功能:系统初始化,检测芯片运行
*/
/*********************初始化LED程序******************************************/
void int_LED(void) //LED闪烁3次表示初始化正常
{
uchar a;
for(a=0;a<3;a++)
{
LED=0;
delayms(1000);
LED=1;
}
}
//--------------------初始化端口程序-----------------------------------------/
void int_cushi(void)
{
P1=1;
P3=1;
int_LED();
}
//--------------------------------------------------------------------------//
/*名称:EEROM通信程序
功能:完成摸拟I2C功能,完成AT24C01的读和写操作
*/
//----------
void delay()
{ ; ; }
//----------
void start()//启始信号
{
SDA=1;
delay();
SCL=1;
delay();
SDA=0;
delay();
}
//----------
void stop()//终止信号
{
SDA=0;
delay();
SCL=1;
delay();
SDA=1;
delay();
}
//----------
void respons() //应答信号,等待或者发送一个应答信号
{
uchar i;
SCL=1;
delay();
while((SDA==1)&&(i<250))i++;
SCL=0;
delay();
}
//----------
void I2C_init()//初始化
{
SDA=1;
SCL=1;
}
//----------
void write_byte(uchar date)//写一字节
{
uchar i;
SCL=0;
for(i=0;i<8;i++)
{
date=date<<1;
SDA=CY;
SCL=1;
delay();
SCL=0;
delay();
}
}
//----------
uchar read_byte() //读数据(也就是接收从器件传来的数据)
{
uchar i,k;
for(i=0;i<8;i++)
{
SCL=1;
delay();
k=(k<<1)|SDA;
SCL=0;
delay();
}
return k;
}
//----------
void delay1(uchar x)
{
uchar a,b;
for(a=x;a>0;a--)
for(b=100;b>0;b--);
}
//----------
void write_add(uchar address,uchar date) //写数据_调用层
{
start();
write_byte(0xa0); //写器件地址
respons(); //应答
write_byte(address); //写器件内部存储地址
respons();
write_byte(date); //写入数据
respons();
stop(); //停止
}
//----------
read_add(uchar address) //读数据_调用层
{
uchar date;
start();
write_byte(0xa0);
respons();
write_byte(address);
respons();
//------------------
start();
write_byte(0xa1);
respons();
date=read_byte();
stop();
return date;
}
//----------
uchar I2C_data() //主函数初始化后读EEROM中的亮度值
{
uchar a;
I2C_init();
delay1(250);
a=read_add(23);
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
return a;
}
//--------------------------------------------------------------------------/
/*名称:系统程序设置
功能:PWM0设置,外部中断0设置,AD中断设置
*/
void lcall_sezhi()
{
//-----------------------------------PWM设置
CMOD=0x86; //------PCA模块PWM设置
CCON=0x00; //CMOD=0X84为T0为信号源,这时将T0设置段落打开//0X80时则用12分频时钟信号
CL=0x00; //CMOD=0X86使用外部脉冲信号,从P3.4脚加入信号
CH=0x00;
CCAPM1=0x42; //0X42=01000010B 允许比较器功能位P1.4脚输出PWM脉宽信号
PCA_PWM1=0x00;//EPC1L和EPC1H在PWM模式下的值是0X00.
CR=1; //启动计数器
//====================================外部中断0设置
EX0=1; //允许外部中断0
IT0=1; //下降沿触发
//====================================AD
EADC_SPI=1; //允许ADC中断标志位
AUXR|=0x10; //允许ADC中断
P1M0=0x20;
P1M1=0x00; //设置P1.2为AD输入
ADC_CONTR=0xe2;
_nop_();
_nop_();
_nop_();
_nop_();
//-----------------------------------------------------------------------//
EA=1; //开总中断
}
//===============================lcall_AD====================================//
void lcall_AD(void)
{
ADC_CONTR=0xea; //启动AD转换
}
//---------------------------------------------------------------------------//
/*名称:红外线解码数据计算处理
功能:开/并功能,键值档位计算,EEROM存储功能,给CCAP0H和CCAP0L送值
*/
void IR_jiema_data(void)
{
if(qinlong==0x00) //0档位
{//向CCAP0H,CCAP0L输入比较器的初值,以和CL CH计数器的值进行比较实现PWM调宽
I2C_init();
delay1(250);
write_add(23,256-250);//写入EEROM地址23H,存储数据256-250
CCAP0H=(256-250);
CCAP0L=(256-250); //给PWM0传送脉宽值
qinlong=0xff;
}
else if(qinlong==0x01) //1档位
{
I2C_init();
delay1(250);
write_add(23,256-240);
CCAP0H=(256-240);
CCAP0L=(256-240);
qinlong=0xff;
}
else if(qinlong==0x02) //2档位
{
I2C_init();
delay1(250);
write_add(23,256-220);
CCAP0H=(256-220);
CCAP0L=(256-220);
qinlong=0xff;
}
else if(qinlong==0x03) //3档位
{
I2C_init();
delay1(250);
write_add(23,256-200);
CCAP0H=(256-200);
CCAP0L=(256-200);
qinlong=0xff;
}
else if(qinlong==0x04) //4档位
{
I2C_init();
delay1(250);
write_add(23,256-180);
CCAP0H=(256-180);
CCAP0L=(256-180);
qinlong=0xff;
}
else if(qinlong==0x05) //5档位
{
I2C_init();
delay1(250);
write_add(23,256-160);
CCAP0H=(256-160);
CCAP0L=(256-160);
qinlong=0xff;
}
else if(qinlong==0x06) //6档位
{
I2C_init();
delay1(250);
write_add(23,256-150);
CCAP0H=(256-150);
CCAP0L=(256-150);
qinlong=0xff;
}
else if(qinlong==0x07) //7档位
{
I2C_init();
delay1(250);
write_add(23,256-100);
CCAP0H=(256-100);
CCAP0L=(256-100);
qinlong=0xff;
}
else if(qinlong==0x08) //8档位
{
I2C_init();
delay1(250);
write_add(23,256-50);
CCAP0H=(256-50);
CCAP0L=(256-50);
qinlong=0xff;
}
else if(qinlong==0x09) //9档位
{
I2C_init();
delay1(250);
write_add(23,256-10);
CCAP0H=(256-10);
CCAP0L=(256-10);
qinlong=0xff;
}
}
//---------------------------------------------------------------------------//
/*名称:AD数码转换
功能:将电位器信号转换成8位数据,并用于EEROM存储和送入CCAP0H和CCAP0L中,从而
调节PWM0的输出
*/
//---------------------------------------------------------------------------//
void AD_jiema_data(void)
{ //AD转换后的数据处理
if((AD_dat_over0<(AD_dat_over1+5))&&(AD_dat_over0>(AD_dat_over1-5)))
{ //如果在范围内(+5/-5)说明没调电位器,应使用存储值
//给出+-5的范围是防止输入电压稍有变动,引起的判断错误
I2C_init();
delay1(250);
CCAP0H=read_add(23);
}
else
{
CCAP0H=(256-AD_dat_over0); //有调动电位器,应使用电位器AD值
I2C_init();
delay1(250);
write_add(23,AD_dat_over0); //刷新EEROM中的值
}
}
//**********************************************************************************//
/*名称:主函数
功能:完成系统的初始化和红外解码数据处理;AD转换数据处理;最终达到存储数据和调节PWM0.
*/
//******************************主函数**********************************************//
void main()
{
uchar a;
lcall_sezhi(); //调用系统设置
int_cushi(); //初始化系统检查
lcall_AD(); //启动AD
a=I2C_data(); //读I2C的数据
while(1)
{
CCAP0H=(256-a);
IR_jiema_data(); //红外解码数据处理
AD_jiema_data(); //AD数据处理
}
}
//***************************************************************************//
/*名称:红外解码_外部中断0
功能:完成红外线的数据解码功能,解码后的数据处理由主程序中的子程序处理.
*/
//---------------------------------------------------------------------------//
void int0_hongwai() interrupt 0 using 0
{
uchar i,j,k,n;
EX0=0;
for(n=0;n<10;n++)
{
delay882();
if(IR_RE==1)break;
}
while(IR_RE==0){};
//------------------------
//当遥控器持续按下则接收到一个9ms的低电平引导脉冲
//以及一个2.2ms的高电平脉冲,和一个0.7ms的低电平脉冲,和一个96ms的高电平脉冲
//以下是连续码的检测判断程序和4.5ms高电平判断
//------------------------
for(j=0;j<2;j++)
{
delay2400();
if(IR_RE==0)break;
}
//-------------------------读取数字信号----------
for(i=0;i<4;i++)
{
for(k=0;k<8;k++)
{
while(IR_RE==0){};
delay882();
if(IR_RE==0)
{
date[i]>>=1;
date[i]=date[i]|0x00;
}
else if(IR_RE==1)
{
delay1000();
date[i]>>=1;
date[i]=date[i]|0x80;//0x80=10000000b
}
}
}
//-----------------------------------------------
if(date[0]=~date[1]) //用户码和数据码判断
{
if(date[2]=~date[3])
qinlong=date[2];
}
EX0=1;
}
//**********************************************************//
/*名称:AD转换_AD中断程序
功能:完成AD转换数据传输,并同时清零AD中断标志位
*/
//==========================================================//
void AD_DAT12() interrupt 5 using 1
{
EADC_SPI=0; //允许ADC中断标志位
j++;
if(j==1)AD_dat_over0=ADC_DATA; //读数据
else if(j==2)
{
AD_dat_over1=ADC_DATA; //
j=0; //计数器归零
}
ADC_CONTR=0xea; //AD中断标志清零
EADC_SPI=1;
}
//-----------------------END File---------------------------//
复制代码
作者:
htzsz
时间:
2016-12-15 17:14
有仿制成功的吗?
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1