|
答应给孙子做个红绿灯,说话要算数。
很多时候做还不如买划算,遗憾的是,没找到有带倒计时的红绿灯玩具。
这是第一次做的,单片机用的AT89C52,有一个电源开关。
可以实现倒计时及红绿灯转换,交给孙子玩后,马上就发现了问题,他开了就不关,直到电耗尽。
要他养成不玩关机的习惯恐怕还需要些时日,于是有了下面的改动。
单片机改用STC89C52RC,取消电源开关,最后一次按键操作后定时10分钟进入掉电模式,实现自动关机。
通过外部中断(黄灯键接口)唤醒。
AT89C52也有掉电模式,只是不能用外中断唤醒,需要把电池取下1分钟再装上,比较麻烦。
具体功能如下
一 红绿灯转换与倒计时
以下三步,不断循环。
1.红灯亮,9秒倒计时,小于3秒时红灯闪。
2.绿灯亮,9秒倒计时,小于3秒时绿灯闪。
3.黄灯亮,3秒倒计时,灯不闪。
二 按键有三个
黄灯键:按黄灯键开机(STC89C52),亮黄灯,长按转夜间模式,黄灯和数码管的小数点闪烁,数码管不显示数字。
红灯键:短按亮红灯,长按关机。
绿灯键:按绿灯键开机(STC15W204S),亮绿灯。
三 定时控制
如果没有按键操作,6分钟后转为夜间模式,10分钟后自动关机(实际上是进入掉电模式,耗电小于1微安)。
下面拆开看看
孙子三周岁,能说会道,拿到玩具很兴奋(新玩具都这样):跟真的一样。
这感觉是在夸爷爷,爷爷听了很高兴。
索性打板再做一个,把单片机(STC15W204S)及显示部分合在一起,减少连线。
按绿灯键开机,其余跟89C52的相同。
感谢嘉立创提供的免费打板。
新款送去, 孙子问:又做一个干嘛?
爷爷纳闷:咋不夸了呢?
STC89C52的代码奉上,本人不会英语,只能用拼音命名变量与函数。
#include "reg51.h" //STC89C52RC@12MHz
#include <intrins.h>
typedef unsigned char uchar;
typedef unsigned int uint;
//---开关
sbit S_hong = P3^0; //短按亮红灯,长按关
sbit S_lv = P3^1; //绿灯
sbit S_huang = P3^2; //短按亮黄灯,长按夜间模式,黄灯闪烁。
//----LED灯
sbit LED_hong = P1^2;
sbit LED_lv = P1^1;
sbit LED_huang = P1^0;
//---数码管
sbit SMG_dp =P0^0;
sbit SMG_c =P0^1;
sbit SMG_d =P0^2;
sbit SMG_e =P0^3;
sbit SMG_g =P0^4;
sbit SMG_f =P0^5;
sbit SMG_a =P0^6;
sbit SMG_b =P0^7;
//----
uint JS_1mS =0;
uchar JS_1S =9;
uint JS_1000mS=0;
uchar DengYanSe =1; //1:红色 3:黄色 2:绿色
bit BZ_hong =0;
bit BZ_huang = 0;
bit BZ_lv = 0;
uchar SJ_xianshi;
bit BZ_shanshuo =0;
bit BZ_ye =0; //夜间模式,黄灯闪
//共阳数码管段码
uchar code DuanMa_SMG[]={0XC0,0XF9,0XA4,0XB0,0X99,0X92,0X82,0XF8,0X80,0X90};
//
void chushihua_t0(void) //
{
TMOD=0x01;
TH0=0xfc; //(65536-1000)/256
TL0=0x18; //
TF0 =0;
ET0=1;
TR0=1; //
EA=1;
}
//==========================================
void DiaoDian()
{
P0 = 0xff;
P1 = 0xff;
P3 = 0xff;
P2 = 0xff;
EX0 =1;
PCON = 0x02;
_nop_();_nop_();_nop_();_nop_();
}
//=========按键及相关=============----
void anjian_shaumiao() //1mS
{
static uint JS_s=0;
static uchar SJ_s=0;
P3=0xff;
if(S_hong==0||S_lv==0||S_huang==0)
{
JS_s++;
JS_1000mS =0;
if(JS_s>=1000)
{
if(JS_s==1000)
{
if(S_huang==0)
{
DengYanSe = 3;
BZ_ye =1;
}
if(S_lv==0)
{
DengYanSe = 2;
JS_1S = 0;
BZ_ye = 0;
}
if(S_hong==0)
DiaoDian();
}
else
JS_s = 1200;
SJ_s =0;
}
else
{
if(JS_s>10)
{
if(S_lv==0) SJ_s=2;
if(S_huang==0) SJ_s=3;
if(S_hong==0) SJ_s=1;
}
}
}
else
{
JS_s =0;
if(SJ_s)
{
JS_1mS =0;
BZ_ye =0;
DengYanSe = SJ_s;
if(DengYanSe==3) //
JS_1S =3;
else
JS_1S = 9;
}
SJ_s =0;
}
}
//===================================================
void main()
{
uchar i =200;
while(i--);
P1 =0xff;
P0 =0xff;
DengYanSe =1;
JS_1S =9;
BZ_ye =0;
chushihua_t0();
while(1);
}
//==========================================
void timer0(void) interrupt 1 //
{
TR0 =0;
TF0 = 0;
TH0 = 0xfc;
TL0 = 0x18;
TR0 =1;
//--------------------------
JS_1mS++;
if(JS_1mS>=1000)
{
JS_1mS = 0;
if(!BZ_ye) //白天模式
{
JS_1S --;
if(JS_1S==0)
{
DengYanSe ++;
if(DengYanSe==4)
DengYanSe =1;
if(DengYanSe==3)
JS_1S = 3;
else
JS_1S =9;
}
}
JS_1000mS++;
if(JS_1000mS>=600)
{
DiaoDian(); //休眠模式
}
else
{
if(JS_1000mS>=480)//6分钟
BZ_ye =1; //夜间模式
}
}
if(JS_1mS>=500)
BZ_shanshuo = 1;
else
BZ_shanshuo = 0;
//---数码管显示部分-----LED驱动--------
if((JS_1mS&0x000f)==0) //16毫秒刷新一次
{
P0 = 0xff;
P1 = 0xff;
}
if((JS_1mS&0x000f)==1)
{
SJ_xianshi = DuanMa_SMG[JS_1S];
if(!BZ_ye) //白天模式 显示倒计时
{
SMG_a = SJ_xianshi&0x01;
SMG_b = SJ_xianshi&0x02;
SMG_c = SJ_xianshi&0x04;
SMG_d = SJ_xianshi&0x08;
SMG_e = SJ_xianshi&0x10;
SMG_f = SJ_xianshi&0x20;
SMG_g = SJ_xianshi&0x40;
}
else
if(!BZ_shanshuo)
SMG_dp = 0;
//-------------------
if(BZ_ye)
{
if(!BZ_shanshuo)
LED_huang = 0;
}
else
{
if(BZ_shanshuo&&JS_1S<4&&DengYanSe<3);
else
{
if(DengYanSe==1)
LED_hong = 0;
if(DengYanSe==2)
LED_lv = 0;
if(DengYanSe==3)
LED_huang = 0;
}
}
}
//------------------------------
anjian_shaumiao();
}
//===============================================
void INT0_HuanXing(void) interrupt 0 //
{
EX0 =0;
DengYanSe=3;
JS_1S = 3;
}
pcb文件有需要的吗 附件不会弄了
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
打赏
-
查看全部打赏
|