一个51的可编程快门线程序
leida_wt2016/03/01电子技术 IP:山东
这是当时我的第一个51练手作品,现在看来有不少地方写的很繁琐,发着玩,求轻喷[s::)] IMG_20160225_000840_AO_HDR-2.jpg


快门线,输入间隔时间和拍摄张数就可以控制单反间隔拍摄了,详情见某宝,一搜一大把[s::)]


硬件连接很简单,单片机12c2052ad,液晶是1602a


#include<stc12c2052ad.h>
#define uchar unsigned char
#define uint  unsigned int
#define lcd P1//lcd数据


void busytest();
void lcd_com(uchar com);
void lcd_data(uchar date);
void lcdinit();
void timeset();
void times();
void delay(uint t);
void interrupt_init();
void shooting();
void beef();//蜂鸣器,io口不够用,没加。。。


sbit lcdrs   = P3 ^ 4;
sbit lcdrw   = P3 ^ 3;
sbit lcden   = P3 ^ 7;
sbit lcdbusy = P1 ^ 7;      //busy test port,same as D7
sbit key1=P3^0;//百位输入
sbit key2=P3^1;//十位输入
sbit key4=P3^2;//ok键,可中断
sbit key3=P3^5;//个位输入
sbit focus=P3^0;//对焦继电器
sbit shoot=P3^1;//拍摄继电器
sbit beefer=P3^5;


uint ctime;
uchar bai;
uchar shi;
uchar ge;
uint input_time;
uint input_shoots;
bit  key4press;
uint tnum;//时间计数
uint snum;//次数计数
bit  timefull;
uchar printnum1;
uchar printnum2;
uchar printnum3;
uchar printnum4;
uchar printnum5;
uchar printnum6;
uchar printnum7;
uchar code table[]="PLEASE SET TIME"; //15
uchar code table1[]="time(s):"; //8
uchar code table2[]="01234567890";
uchar code table3[]="SET SHOOT TIMES"; //15
uchar code table4[]="PRESS OK TO"; //11
uchar code table5[]="START";   //5
uchar code table6[]="REST TIME:";//10
uchar code table7[]="REST SHOOTS:"; //12
/***************************************************************************/
#define CMD_clear 0x01             // 清除屏幕
#define CMD_back 0x02             // DDRAM回零位
#define CMD_dec1 0x04             // 读入后AC(指针)减1,向左写
#define CMD_add1 0x06             // 读入后AC(指针)加1,向右写
#define CMD_dis_gb1 0x0f             // 开显示_开光标_开光标闪烁
#define CMD_dis_gb2 0x0e             // 开显示_开光标_关光标闪烁
#define CMD_dis_gb3 0x0c             // 开显示_关光标_关光标闪烁
#define CMD_OFF_dis 0x08             // 关显示_关光标_关光标闪烁
#define CMD_set82 0x38             // 8位总线_2行显示
#define CMD_set81 0x30             // 8位总线_1行显示(上边行)
#define CMD_set42 0x28             // 4位总线_2行显示
#define CMD_set41 0x20             // 4位总线_1行显示(上边行)
#define lin_1 0x80             // 4位总线_1行显示(上边行)
#define lin_2 0xc0             // 4位总线_1行显示(上边行)
/***************************************************************************/
void main()
{
    lcdinit();                        
interrupt_init();
focus=1;
shoot=1;
for(printnum1=0;printnum1<15;printnum1++)
lcd_data(table[printnum1]);
lcd_com(0x80+0x40); //换行
for(printnum2=0;printnum2<8;printnum2++)
lcd_data(table1[printnum2]);
timeset();
key4press=0;
lcd_com(CMD_clear);
input_time=(bai*100+shi*10+ge)*2;//单位50ms
ctime=(bai*100+shi*10+ge)/10;
bai=0;
shi=0;
ge=0;
for(printnum3=0;printnum3<15;printnum3++)
lcd_data(table3[printnum3]);
lcd_com(0x80+0x40);
times();
input_shoots=bai*100+shi*10+ge;//拍摄次数
lcd_com(CMD_clear);
key4press=0;
for(printnum4=0;printnum4<11;printnum4++)
lcd_data(table4[printnum4]);
lcd_com(0x80+0x40);
for(printnum5=0;printnum5<5;printnum5++)
lcd_data(table5[printnum5]);
while(key4press==0);//等待ok按下
lcd_com(CMD_clear);
shooting();
lcd_com(CMD_clear);
lcd_data('F');
lcd_data('I');
lcd_data('N');
lcd_data('I');
lcd_data('S');
lcd_data('H');
lcd_data('!');
//beef();//未实现
while(1);

}
void busytest()
{
    lcd = 0xff;      //测忙函数
    lcdrs = 0;
    lcdrw = 1;
    lcden = 1;
    while(lcdbusy);
    lcden = 0;
}
void lcd_com(uchar com)  //写命令
{
   busytest();
   lcd = com;
   lcdrs = 0;
   lcdrw = 0;
   lcden = 1;
   lcden = 0;
}
void lcd_data(uchar date) //写数据
{
    busytest();
lcd = date;
   lcdrs = 1;
   lcdrw = 0;
   lcden = 1;
   lcden = 0;
}
void lcdinit()
{    
   lcd_com(CMD_set82);     //  显示模式设置:显示2行,每个字符为5*7个像素
   lcd_com(CMD_clear);    //  显示清屏
   lcd_com(CMD_back); //  数据指针指向第1行第1个字符位置
   lcd_com(CMD_add1); //  显示光标移动设置:文字不动,光标右移
   lcd_com(CMD_dis_gb3);  //  显示开及光标设置:显示开,光标开,闪烁开
}
void delay(uint t)
{
uint b,c;
for(b=0;b<t;b++)
for(c=0;c<355;c++);

}
void timeset()
{
while(key4press==0)
{
if(key1==0)
{
delay(10);
if(key1==0)
{
bai++;
}
while(key1==0);

}
if(key2==0)
{
delay(10);
if(key2==0)
{
shi++;
}
while(key2==0);

}
if(key3==0)
{
delay(10);
if(key3==0)
{
ge++;
}
while(key3==0);

}

if(bai==10)
bai=0;
if(shi==10)
shi=0;
if(ge==10)
ge=0;
lcd_com(0x80+0x40+0x08);//指针控制
lcd_data(table2[bai]);
lcd_data(table2[shi]);
lcd_data('.');
lcd_data(table2[ge]);


}
}
void times()
{
while(key4press==0)
{
if(key1==0)
{
delay(10);
if(key1==0)
{
bai++;
}
while(key1==0);

}
if(key2==0)
{
delay(10);
if(key2==0)
{
shi++;
}
while(key2==0);

}
if(key3==0)
{
delay(10);
if(key3==0)
{
ge++;
}
while(key3==0);

}

if(bai==10)
bai=0;
if(shi==10)
shi=0;
if(ge==10)
ge=0;
lcd_com(0x80+0x40);//指针控制
lcd_data(table2[bai]);
lcd_data(table2[shi]);
lcd_data(table2[ge]);
lcd_data(' ');
lcd_data('s');
lcd_data('h');
lcd_data('o');
lcd_data('o');
lcd_data('t');
lcd_data('s');



}
}
void timer0() interrupt 1
{
TH0=0x3c;//初装,50ms  
TL0=0xb0;
tnum++;
if(tnum==input_time/2)
{
timefull=1;
tnum=0;
}
}


void interrupt_init()
{
TMOD=0x01;//定时器模式设置
//AUXR &= 0x7F;//定时器时钟12T模式
TH0=0x3c;//初装,50ms  
TL0=0xb0;
ET0=1;//开定时器中断
EA=1; //开总中断
//TR0=1;//开定时器
//P2M1=0;
//P2M0=0xFF;
EX0=1;//开外部中断0
IT0=1;//外部中断0设为下降沿触发
}
void shooting()
{
TR0=1;
while(snum<input_shoots)
{
for(printnum6=0;printnum6<10;printnum6++)
lcd_data(table6[printnum6]);
lcd_data(table2[(input_shoots-snum)*ctime /60 / 100]);
lcd_data(table2[(input_shoots-snum)*ctime /60 % 100 / 10]);
lcd_data(table2[(input_shoots-snum)*ctime /60 % 10]);
lcd_data('m');
lcd_data('i');
lcd_data('n');
lcd_com(0x80+0x40);
for(printnum7=0;printnum7<12;printnum7++)
lcd_data(table7[printnum7]);
lcd_data(table2[(input_shoots-snum)/100]);
lcd_data(table2[((input_shoots-snum)%100)/10]);
lcd_data(table2[(input_shoots-snum)%10]);


focus=0;
while(timefull==0);//等待定时器满
timefull=0;
shoot=0;
delay(50);
focus=1;
shoot=1;
while(timefull==0);//等待定时器满
timefull=0;
snum++;
lcd_com(CMD_clear);
}
}
void beef()
{
unsigned int c,d,e;
while(e<20)
{
while(d<3000)
{
beefer=~beefer;
for(c=0;c<100;c++);
d++;
}
d=0;
delay(500);
e++;
}
}
void key4scan()   interrupt 0
{
if(key4==0)
{
delay(10);
if(key4==0)
key4press=1;
while(key4==0);
}
}
来自:电子信息 / 电子技术
5
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
ne555
8年11个月前 IP:山东
811071
1602的偏置电压脚没有接可调电阻?拍摄方向问题?怎么感觉偏置电压不对呢
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
leida_wt作者
8年11个月前 IP:山东
811753
是有点黑
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
amo
8年11个月前 IP:浙江
811787
轻喷一下,对焦和快门用NMOS控制就好了,基本没有额外功耗(继电器功耗很高的);
如果只喜欢51可以考虑C8051F93X或一些新的低功耗单片机,程序精心设计,一节7号干电池就能用个一两年
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
leida_wt作者
8年10个月前 IP:山东
811842
[s::)]有道理
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
所属分类
上级专业
同级专业
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}