⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 我看了一个外国的朋友关于相机的程序.试着编个程序看看.
💻 C
📖 第 1 页 / 共 2 页
字号:
//相机控制器程序
//使用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 + -