📄 main.c
字号:
//相机控制器程序
//使用89C51线路板
//
//2005-09-12支持995和20D
//2005-11-2加入地方恒星时计算
#include <AT89X51.H>
//=======================
//定义I/O资源
//=======================
//4X4键盘扫描,P1
sbit SCAN1=P1^4;
sbit SCAN2=P1^5;
sbit SCAN3=P1^6;
sbit SCAN4=P1^7;
sfr KEYPORT=0x90; //P1
//LCD,P0,P2
sbit BACKLIGHT1=P2^0;//背光
sbit BACKLIGHT2=P2^1;//背光
sbit VO=P2^4; //负压
sbit REGSEL=P2^5; //显示寄存器选择输出
sbit RDWR=P2^6; //显示模式输出
sbit ENABLE=P2^7 ; //显示使能输出
sfr DISPDATA=0x80; //P0,显示8 位数据总线
//995/串口,P3^0,P3^1
//3线通信,P3
sbit TRICTRL=P3^2; //INT0
sbit TRICLK=P3^4;
sbit TRIDATA=P3^5;
//20D输出,P3
sbit FOCUS=P3^6;
sbit SHUTTER=P3^7;
//空闲IO:P2^3,P3^3
//=======================
//定义常数
//=======================
//键盘定义
#define KEY1 0x0008
#define KEY2 0x0080
#define KEY3 0x0800
#define KEY4 0x8000
#define KEY5 0x0004
#define KEY6 0x0040
#define KEY7 0x0400
#define KEY8 0x4000
#define KEY9 0x0002
#define KEY0 0x0020
#define KEYA 0x0200
#define KEYB 0x2000
#define KEYC 0x0001
#define KEYD 0x0010
#define KEYE 0x0100
#define KEYF 0x1000
//显示命令
#define DISP_CLEAR 0x01
#define DISP_POS 0x80
#define DISP_LINE2 0xC0 //=DISP_LINE2 0x40|DISP_POS 0x80
#define DISP_CGRAM 0x40
#define DISP_BUSY 0x80
#define DISP_FUNC 0x38
#define DISP_ENTRY 0x06
#define DISP_CNTL 0x08
#define DISP_ON 0x04
#define DISP_HOME 0x02
#define LINE2_8 (DISP_LINE2|8)
#define LINE2_11 (DISP_LINE2|11)
#define LINE2_14 (DISP_LINE2|14)
//时基 640Hz
#define RELOAD_HIGH 250
#define RELOAD_LOW 118
//=======================
//定义常数变量
//=======================
//菜单
unsigned char code welc1[16]= {" DIGITAL CAMERA"};
unsigned char code welc2[16]= {" CONTROLLER "};
unsigned char code menu_mode1[16]= {"1.COOLPIX 995 "};
unsigned char code menu_mode2[16]= {"2.EOS 20D 3.COM "};
unsigned char code menu_995[16]= {"cp995/4500 "};
unsigned char code menu_prg[16]= {"PRG:000+000x000s"};
unsigned char code menu_20d[16]= {"eos 20d "};
unsigned char code menu_com1[16]= {"LCD&POLAR "};
unsigned char code menu_com2[16]= {"E contrast C ha "};
unsigned char code menu_setcam[16]= {"SETUP "};
unsigned char code menu_mirror1[16]={"mirror lock:OFF "};
unsigned char code menu_mirror2[16]={"DELAY:00sec "};
unsigned char code menu_polar1[16]= {"20 - - - : "};
unsigned char code menu_polar2[16]= {"1 d m: h m "};
//显示
char code bcdmap[10]={'0','1','2','3','4','5','6','7','8','9'};
//按键组合
unsigned int code keys[16]={KEY0,KEY1,KEY2,KEY3,KEY4,KEY5,KEY6,KEY7,KEY8,KEY9,KEYA,KEYB,KEYC,KEYD,KEYE,KEYF};
#define KEY_NUM_F_ENABLE KEY0|KEY1|KEY2|KEY3|KEY4|KEY5|KEY6|KEY7|KEY8|KEY9|KEYF //number key and esc enabled
#define KEY_13_ENABLE KEY1|KEY2|KEY3
#define KEY_NUM_CF_ENABLE KEY0|KEY1|KEY2|KEY3|KEY4|KEY5|KEY6|KEY7|KEY8|KEY9|KEYF|KEYC //number key and C,esc enabled
#define KEY_NUM_ENABLE KEY0|KEY1|KEY2|KEY3|KEY4|KEY5|KEY6|KEY7|KEY8|KEY9 //number key enabled
//曝光时间
unsigned int code expo[10]={1,60,120,180,240,1,1,1,1,999};
//字符串
unsigned char code str_off[3]={"OFF"};
unsigned char code str_on[3]={"ON "};
//=======================
//定义全局变量
//=======================
//键盘
bit flag_keyscan_en; //enable keyscan
unsigned int nk; //键盘状态,pressed key set that bit
unsigned char ikey; //last key id
//通信
unsigned char uartread,uartwrite;
unsigned char uartbuf[8]; //buffer of received byte
unsigned char tricomwrite,tricomsend;
unsigned char tricombuf[8]; //buffer of sending byte
bit flag_uart_busy,flag_tri_sending;
//相机
unsigned char mode; //1:995 2:20D 3:Misc
unsigned int camexpo,camwait,camrpt;//曝光时间,间隔时间,重复次数
bit flag_focus,flag_mirror;
unsigned char mirror;//预升延时
//时钟
unsigned char second_cnt=1; //second count(devider)
unsigned int secticker;
bit flag_newsec;
//=======================
//函数声明
//=======================
//显示
void disp_init(void);
void disp_cmd(unsigned char cmd);
void dismenu(unsigned char code *strmenu1,unsigned char code *strmenu2);
void disint(unsigned int v,unsigned char pos,unsigned char dig);
//键盘
void wait_for_release(void);
//相机
void setmode(void);
void setcamera(void);
void cp995(void);
void eos20d(void);
//通信
void trisend(unsigned char cmd);
//时角
void polar(void);
//=======================
//主函数
//=======================
void main (void){
FOCUS=0;
//lcd显示初始化
{unsigned int i;
for(i=0;i<10000;i++){ //delay
;
}
disp_init();
disp_cmd(DISP_CLEAR);
dismenu(welc1,welc2); //display welcome
for(i=0;i<30000;i++){ //delay
;
}
}
SHUTTER=0;
//中断设置
//timer0设置
TMOD|=0x01; //Timer0: 16-bit timer;
TH0=RELOAD_HIGH; //设定重装值
TL0=RELOAD_LOW;
//UART设置
SCON = 0x50; // SCON: mode 1, 8-bit UART, enable rcvr
TMOD|= 0x20; // TMOD: timer 1, mode 2, 8-bit reload
PCON|=0x80;// SMOD=1;speed double
TL1=0xFD; //19200 baud rate
TH1=0xFD; //19200 baud rate reload
TXD=1;
RXD=1;
//INT0设置
IT0=1;//边沿触发
//interrupt configuration
EA=1;
ET0=1; //TIMER 0 enabled
ET1=0; //TIMER 1 disabled
ES=1; //UART enabled
EX0=1; //INT0 enabled
//interrupt priority
PT0=1; //T0 high
//pin initialization
TRICLK=1;
TRIDATA=1;
TRICTRL=1;
BACKLIGHT1=1; //背光开
BACKLIGHT2=1;
VO=1; //低反差
//开始定时
TR0=1;
TR1=1;
//启动键盘扫描
flag_tri_sending=0;
flag_keyscan_en=1;
//初始化通信缓冲参数
uartread=0;
uartwrite=0;
tricomwrite=0;
tricomsend=0;
//初始化
camexpo=1;
camwait=10;
camrpt=100;
mode=2;
flag_mirror=0;
mirror=2;
setmode();
while (1) {
while (flag_keyscan_en) { //等待键盘输入,只在此期间处理接收的数据和指令
if(mode==3){
if(uartread!=uartwrite){//uart cmd received
if(++uartread>7) uartread=0;
disint((unsigned int)(uartbuf[uartread]),DISP_LINE2,3);
}
}
}//end of while
if(nk){
ikey=0;
while (!(nk&keys[ikey])) ikey++;
if(nk&KEYF) setmode();
else if(nk&KEYD) {
BACKLIGHT1=~BACKLIGHT1;
BACKLIGHT2=~BACKLIGHT2;
}
else{
switch(mode){
case 1:
cp995();
break;
case 2:
eos20d();
break;
case 3:
if(ikey==14) VO=~VO;
else if(ikey==12) polar();
else trisend(ikey);
//SBUF=ikey;
break;
}
}
wait_for_release();
}
flag_keyscan_en=1; //重新扫描
} //end of while(1)
}
//========================================
//communication via triple line method
//3线串行通信
//========================================
/*****************************
send cmd via triple line
******************************/
void trisend(unsigned char cmd){
tricombuf[tricomwrite]=cmd;
if(++tricomwrite==8) tricomwrite=0;
flag_tri_sending=1; //start sending
}
/******************************
INT0 interrupt
receive cmd from triple line
*******************************/
void int0(void) interrupt 0 using 2{
static unsigned char trvcmd=0;
if(TRICLK==1) { //end of byte
if(++uartwrite>7) uartwrite=0;
uartbuf[uartwrite]=trvcmd;
trvcmd=0;
}
else{
trvcmd>>=1;
if(TRIDATA==1) trvcmd+=128;
}
}
//========================================
//communication via UART
//串行通信
//========================================
/*********************************
uart interrupt
**********************************/
void uart(void) interrupt 4 using 3{
if( TI){
TI=0;
}
if (RI){
if(++uartwrite>7) uartwrite=0;
uartbuf[uartwrite]=SBUF;
RI=0;
}
flag_uart_busy=0;
}
//========================================
//timing and key scan
//时钟维护与键盘扫描及三线发送
//========================================
/**********************************
timer0 interrupt
system tick;keyboard scan
***********************************/
void timer0(void) interrupt 1 using 1{
static unsigned char ttxcmd=0,ttxcmdbit=0;
static unsigned char mscnt=1; //50ms count
//Timer Reload
TR0=0; // stop T0
TH0=RELOAD_HIGH; //设定重装值
TL0=RELOAD_LOW;
TR0=1; //开始定时
if(flag_tri_sending){
if(ttxcmdbit){ //is sending
TRICLK=1;
ttxcmd>>=1;
if(ttxcmd&0x01) TRIDATA=1;
else TRIDATA=0;
if(++ttxcmdbit==9){ //last(MSB) bit+1
TRICTRL=1;
TRICLK=0;
ttxcmdbit=0;
if(++tricomsend==8) tricomsend=0;
if(tricomsend==tricomwrite){
EX0=1; //INT0 enabled
flag_tri_sending=0;
}
TRIDATA=1;
TRICLK=1;
}
else TRICLK=0;
}
else if(tricomsend!=tricomwrite){ //cmd to be sent, bit=0;
TRICLK=1;
if(TRICLK==1) {//is not receiving
EX0=0; //INT0 disabled
TRICTRL=0;
ttxcmd=tricombuf[tricomsend];
ttxcmdbit++;
if(ttxcmd&0x01) TRIDATA=1;
else TRIDATA=0;
TRICLK=0;
}
}
}
//Clock Maintenance
if(!(--mscnt)){ //如果经过50毫秒
mscnt=32;
if(!(--second_cnt)){
second_cnt=20; //设置计数值
secticker++;
flag_newsec=1; //发生秒跳变
}
//key scan every 50ms
if(flag_keyscan_en){
unsigned char temp;
nk=0;
KEYPORT|=0x0F; // all high
SCAN1=0;
temp=KEYPORT&0x0F;
nk=temp;
SCAN1=1;
SCAN2=0;
temp=KEYPORT&0x0F;
nk=nk*16+temp;
SCAN2=1;
SCAN3=0;
temp=KEYPORT&0x0F;
nk=nk*16+temp;
SCAN3=1;
SCAN4=0;
temp=KEYPORT&0x0F;
nk=nk*16+temp;
SCAN4=1;
nk=~nk; //key pressed=bit set to 1
flag_keyscan_en=0;
}//end of key scan
}
}
//========================================
//LCD Display
//LCD显示
//========================================
/**********************************
void wait_for_lcdready(void);
function:wait until lcd ready
input: none
return: none
global variables:none
call: none
***********************************/
void wait_for_lcdready(void){
unsigned char value;
do {
DISPDATA=0xFF;
REGSEL=0; //选择命令寄存器
RDWR=1 ; //选择读模式
ENABLE=1 ; //使能LCD 输出
value=DISPDATA; //读数据
ENABLE=0;
}
while((value&DISP_BUSY));
}
/**********************************
void disp_cmd(unsigned char);
function:send command to lcd and wait until lcd ready again
input: command
return: none
global variables:none
call: wait_for_lcdready
***********************************/
void disp_cmd(unsigned char cmd){
DISPDATA=cmd; //锁住命令
REGSEL=0;//选择命令寄存器
RDWR=0; //write
ENABLE=1 ;
ENABLE=0;
wait_for_lcdready(); //等待命令被执行
}
/**********************************
void disp_write(unsigned char);
function:send data to lcd and wait until lcd ready again
input: data
return: none
global variables:none
call: wait_for_lcdready
***********************************/
void disp_write(unsigned char value){
DISPDATA=value;
REGSEL=1 ;
RDWR=0;
ENABLE=1 ;
ENABLE=0;
wait_for_lcdready();
}
/**********************************
void disp_init(void);
function:lcd display initilization
input: none
return: none
global variables:none
call: wait_for_lcdready,disp_cmd
***********************************/
void disp_init(void){
wait_for_lcdready();
disp_cmd(DISP_FUNC); //设置显示格式
disp_cmd(DISP_ENTRY); //每输入一个字符,显示地址加1
/*disp_cmd(DISP_CGRAM); //向CGRAM内写入字模
{unsigned int i;
for (i=0;i<32;i++){
disp_write(cgram[i]);
};
};*/
disp_cmd(DISP_CNTL|DISP_ON); //打开显示,关闭光标
disp_cmd(DISP_CLEAR); //清除显示
}
/***********************************
void disint(unsigned int v,unsigned char pos,dig)
display dig-digs integer v at pos
************************************/
void disint(unsigned int v,unsigned char pos,unsigned char dig) {
//dig<=4;otherwise doing nothing
disp_cmd(DISP_HOME);
disp_cmd((pos));
switch(dig){
case 4:
disp_write(bcdmap[v/1000]);
case 3:
v%=1000;
disp_write(bcdmap[v/100]);
case 2:
v%=100;
disp_write(bcdmap[v/10]);
case 1:
v%=10;
disp_write(bcdmap[v]);
default:
break;
}
}
/***********************************
display n char string
************************************/
void disstr(unsigned char code *str,unsigned char pos,unsigned char n){
unsigned char i;
n%=17;
disp_cmd(DISP_HOME);
disp_cmd((pos));
for (i=0;i<n;i++) disp_write(*str++);
}
/***********************************
void dismenu(unsigned char code )
function:display pre-determined menu
input: pointer of menu string
return: none
global variables:none
call: disp_cmd,disp_write
************************************/
void dismenu(unsigned char code *strmenu1,unsigned char code *strmenu2){
disp_cmd(DISP_CLEAR); //清除显示
disstr(strmenu1,(DISP_POS),16);
disstr(strmenu2,(DISP_LINE2),16);
}
//========================================
//keyboard proc
//键盘操作
//========================================
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -