- 积分
- 10608
- 在线时间
- 15508 小时
- 最后登录
- 2022-3-31
- 阅读权限
- 150
- 精华
- 6
 
- UID
- 13663
- 帖子
- 13726
- 精华
- 6
- 经验
- 10608 点
- 金钱
- 8449 ¥
- 注册时间
- 2006-10-21
|

楼主 |
发表于 2014-3-20 10:08
|
显示全部楼层
本帖最后由 ahao 于 2014-3-20 10:49 编辑
电路原理和程序部分
程序如下红字部分
#include "STC12C5A60S2.H"
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit gewei=P1^7;
sbit shiwei=P1^6;
sbit baiwei=P1^5;
sbit qianwei=P1^4;
sbit dian=P3^7;
sbit on=P0^0;
sbit key=P1^3;
sbit ir=P1^1;
uint tt_on,xyz,adc_p;
uchar tt_js,tt_off,tt01,tt02,tt11,tmp,m,zt1,zt2;
uchar code led[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; //定义led 0-9数组
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=100;y>0;y--);
}
uint get_ad_result(uchar channel) //AD转换函数
{
uchar ad_finished=0; //存储A/D转换标志
ADC_RES=0; //高8位清零
ADC_RESL=0; //低2位清零
channel&=0x07; //0000 0111 清零高5位
ADC_CONTR=0x60; //转换速率为70个时钟周期转换1次
_nop_();
ADC_CONTR|=channel; //选择A/D当前通道
_nop_();
ADC_CONTR|=0x80; //启动A/D电源
delay(1); //延时一下使输入电压达到稳定
ADC_CONTR|=0x08; //0000,1000 令 ADCS = 1, 启动A/D转换,
ad_finished=0;
while(ad_finished==0) //等待A/D转换结束
{
ad_finished=(ADC_CONTR&0x10); //0001,0000 测试A/D转换结束否
}
ADC_CONTR&=0xE7; //1111,0111 清 ADC_FLAG 位, 关闭A/D转换,
return(ADC_RES*256+ADC_RESL); //返回 A/D 高8位+低2位转换结果
}
void display(uint abc)
{
if(on==1) //开机状态时数码管显示功率
{
if(abc>15) //功耗大于15显示具体值
{
P3=led[abc%10];
gewei=0;
delay(20);
gewei=1;
P3=led[abc%100/10];
if(abc>=10)
shiwei=0;
delay(20);
shiwei=1;
P3=led[abc%1000/100];
if(abc>=100)
baiwei=0;
delay(20);
baiwei=1;
if(abc>=1000)
P3=led[abc/1000];
else
P3=0x73; //显示P 0111 0011 表示电视功耗
qianwei=0;
delay(20);
qianwei=1;
}
else //否则功耗小于15时
{
P3=0x40; //显示---- 0100 0000
gewei=0;
delay(20);
gewei=1;
shiwei=0;
delay(20);
shiwei=1;
baiwei=0;
delay(20);
baiwei=1;
qianwei=0;
delay(20);
qianwei=1;
}
}
else //关机状态时只显示百位上的点
{
P3=0x00;
dian=1;
baiwei=!baiwei;
delay(20);
}
}
void init()
{
TMOD=0x11; //设定定时器0工作方式
EA=1; //开总中断
ET0=1; //开定时器0
TR0=1; //启动定时器0
TH0=(65536-50000)/256; //高8位装初值 定时50ms
TL0=(65536-50000)%256; //低8位装初值
ET1=1; //开定时器1
TH1=(65536-1000)/256; //高8位装初值
TL1=(65536-1000)%256; //低8位装初值
}
void main()
{
P0M0=0x01; //0000 0001 设定P0/0口为强推挽输出模式
P3M0=0xff; //1111 1111 设定P3口为强推挽输出模式
P1ASF=0x01; //0000 0001 将P1.0置为模拟口
AUXR1|=0x04; //0000 0100 令ADRJ=1,10位A/D转换结果的最高2位放在ADC_RES寄存器,低8位放在ADC_RESL
ADC_CONTR|=0x80; //打开A/D转换电源启动A/D转换
init();
xyz=0;
on=0;
while(1)
{
if(on==0) //关机状态时遥控有效
{
if((ir==0)&&(m==1)) //有遥控信号产生同时变量m为1时
{
tmp++;
m=0; //变量置0,目的是只让进入此函数一次
tt_off=0;
if(tmp<15) //开启定时器1
{
TR1=1;
}
else //超过15个脉冲后判断变量值
{
if(tt11<40) //如果用时不超过40ms就开机
on=1;
TR1=0; //关闭定时器1,变量置0
tt11=0;
tmp=0;
}
}
if(ir==1)
{
m=1;
}
if(tt_off>20)
display(0);
tt_on=0;
}
else //开机状态下
{
if(xyz<20) //功耗小于20 延时后关机
{
tt_js=1; //计时变量置1,开始计时
if(tt_on>24000) //50ms*24000=1200s=20分钟
on=0;
}
else
{
tt_js=0;
tt_on=0;
}
if(tt02>5) //300msAD转换一次
{
adc_p=get_ad_result(0); //算出具体电压值模拟功率
if(adc_p>30)
xyz=adc_p*0.63+18;
else
xyz=adc_p*1.2;
tt02=0;
}
display(xyz);
}
if(key==0) //开关机按键按下
{
zt1=1;
if(tt01>=10) //延时500ms消抖
{
if(zt2==0)
{
on=~on; //执行开机或者关机动作
zt2=1;
}
}
}
else
{
zt1=0;
tt01=0;
zt2=0;
}
}
}
void timer0() interrupt 1 //定时器0中断程序 装初值50ms
{
TH0=0x3c; //TH0=(65536-50000)/256;
TL0=0xb0; //TL0=(65536-50000)%256;
if(zt1==1)
{
if(tt01<100)
tt01++;
}
if(tt02<100)
tt02++;
if(tt_off<100)
tt_off++;
if(tt_js==1)
{
if(tt_on<50000)
tt_on++;
}
}
void timer1() interrupt 3 //定时器1中断程序 装初值1ms
{
TH1=0xfc; //TH1=(65536-1000)/256;
TL1=0x18; //TL1=(65536-1000)%256;
if(tt11<100) //让变量tt11最大为100
tt11++;
}
|
评分
-
查看全部评分
|