?? cam.c
字號:
#include <SST89x5xxRD2.h>
#define uchar unsigned char
#define uint unsigned int
#define Width 10 //圖像的寬80(8*10)個像素
#define Height 32 //圖像的高
uchar lcd_x;//lcd的x坐標
uchar lcd_y;//lcd的y坐標
sbit cs=P3^3; //定義LCD的D/#C控制口
sbit std=P3^5; //定義LCD的串行數據端口
sbit sclk=P3^7; //定義LCD的串行時鐘端口
sbit rst=P3^6;
sbit key=P2^0;
uchar code SYNC_ID[]= {0xaa,0x0d,0x00,0x00,0x00,0x00};
uchar code INITAL_ID[]= {0xaa,0x01,0x00,0x01,0x01,0x01}; //2位灰度圖160*120,4800B
uchar code BAUDRATE_ID[]= {0xaa,0x07,0xbf,0x01,0x00,0x00}; //baudrate=9600
uchar code SNAPSHOT_ID[]= {0xaa,0x05,0x01,0x00,0x00,0x00};
uchar code GETPICTURE_ID[]= {0xaa,0x04,0x01,0x00,0x00,0x00};
uchar code RESET1_ID[]= {0xaa,0x08,0x01,0x00,0x00,0x00};//狀態寄存器復位
uchar code RESET2_ID[]= {0xaa,0x08,0x00,0x00,0x00,0x00};//完全復位
uchar code SLEEP_ID[]= {0xaa,0x09,0x00,0x00,0x00,0x00};
uchar code ACK1_ID[]= {0xaa,0x0e,0x0d,0x00,0x00,0x00};
uchar code ACK2_ID[]= {0xaa,0x0e,0x0a,0x00,0x00,0x00};
//定義兩個隊列用來緩存圖片數據
uchar xdata Picture_Dat1[256]; //內部擴展數據RAM(00H~2FFH)
uchar xdata Picture_Dat2[256];
uchar idata front=0,rear=0;//隊列的隊頭指針和隊尾指針
bit bank;//bank=0指向Picture_Dat1,否則指向Picture_Dat2
uint idata countr;//已接受的數據(byte)
bit error;//傳輸出錯
void delay(uchar mm)
{
uchar idata i;
for(i=0;i<mm;i++)
;
}
void delay_1ms()
{
uchar idata i;
for(i=0;i<255;i++)
;
for(i=0;i<42;i++)
;
}
void delay_ms(uchar t)
{
uchar idata i;
for(i=0;i<t;i++)
delay_1ms();
}
void wr_lcd (uchar dat_comm,uchar content)
{
uchar idata a,i,j;
delay(50);
a=content;
cs=1;
sclk=0;
std=1;
for(i=0;i<5;i++)
{
sclk=1;
sclk=0;
}
std=0;
sclk=1;
sclk=0;
if(dat_comm)
std=1;//data
else
std=0;//command
sclk=1;
sclk=0;
std=0;
sclk=1;
sclk=0;
for(j=0;j<2;j++)
{
for(i=0;i<4;i++)
{
a=a<<1;
std=CY;
sclk=1;
sclk=0;
}
std=0;
for(i=0;i<4;i++)
{
sclk=1;
sclk=0;
}
}
}
void init_lcd (void)
{
rst=0;
delay(100);
rst=1;
wr_lcd(0,0x30); //30---基本指令動作
wr_lcd(0,0x01); //清屏,地址指針指向00H
delay(100);
wr_lcd(0,0x06); //光標的移動方向
wr_lcd(0,0x0c); //開顯示,關游標
}
//1、換晶振,用22.1184M晶振,在TH1=0xff時,剛好可以產生115200波特率。
//2、采用6個時鐘周期的單片機(換單片機啊。。。)
//3、增強型51單片機有定時器2!(幸好偶用的是增強型。。。)
//就用第三種方法啦!這時的公式如下:
//波特率=11059200/(32×[65536-(RCAP2H,RCAP2L)])
//其中的RCAP2H,RCAP2L為自動重裝值,由上式得:
//RCAP2H,RCAP2L=65536-11059200/(32×波特率)
void init_UART()
{
SCON=0x50; //串口工作方式1,8位UART,波特率可變
TH2=0xFF;
TL2=0xDC; //波特率:9600 晶振=11.0592MHz
RCAP2H=0xFF;
RCAP2L=0xDC; //16位自動再裝入值
//*****************
TCLK=1;
RCLK=1;
C_T2=0;
EXEN2=0; //波特率發生器工作方式
//*****************
ES=0;//關閉串口中斷
EA=1;//開全局中斷
TR2=1 ; //定時器2開始
}
void Read_Picture() interrupt 4 using 1
{
uchar dat;
if(RI)
{
dat=SBUF;
RI=0;
if(front==rear+1)//隊列已滿
{
ES=0;
error=1;
}
if(bank)
{
Picture_Dat2[rear]=dat;
bank=!bank;
rear++;
}
else
{
Picture_Dat2[rear]=dat;
bank=!bank;
countr++;
countr++;
}
}
}
void Send_Cmd(uchar *cmd)
{
uchar idata i;
for(i=0;i<6;i++)
{
SBUF=cmd[i];
while(TI==0)
;
TI=0;
delay(1);
}
}
void Wait_ACK(uchar *cmd)
{
uchar idata i;
for(i=0;i<6;i++)
{
while(RI==0)
;
cmd[i]=SBUF;
RI=0;
}
//if(cmd[0]==0xAA&&cmd[1]>=0x01&&cmd[1]<=0x0F)
// return 1;
//return 0;
}
bit CAM_Cmd(uchar *cmd)
{
uchar idata temp_cmd[6];
Send_Cmd(cmd);
Wait_ACK(temp_cmd);
if(temp_cmd[0]==0xAA&&temp_cmd[1]==0x0E&&temp_cmd[2]==cmd[1])
{
delay_ms(50);
return 1;
}
return 0;
}
bit Send_SYNC_Cmd()
{
uchar idata OldTH2,OldTL2;//保存原先的波特率
uchar idata cmd1[6];
uchar idata cmd2[6];
uchar idata i,j,k;
//*****************
//將波特率調整為115200
TR2=0 ; //定時器2停止
OldTH2=RCAP2H;
OldTL2=RCAP2L;
TH2=0xFF;
TL2=0xFD; //波特率:115200 晶振=11.0592MHz
RCAP2H=0xFF;
RCAP2L=0xFD; //16位自動再裝入值
TR2=1 ; //定時器2開始
//*****************
for(i=0;i<60;i++)
{
Send_Cmd(SYNC_ID);
for(j=0;j<255;j++)
{
for(k=0;k<255;k++)
{
if(RI!=0)
{
Wait_ACK(cmd1);
Wait_ACK(cmd2);
break;
}
}
}
if(j==255&&k==255)//350ms內沒有獲得應答
continue;
if(cmd1[0]!=0xAA||cmd1[1]!=0x0E||cmd1[2]!=0x0D)
continue;
if(cmd2[0]!=0xAA||cmd2[1]!=0x0D)
continue;
Send_Cmd(ACK1_ID);
delay_ms(50);
break;
}
if(i==60)
return 0;
//將CAM的波特率設置為9600
CAM_Cmd(BAUDRATE_ID);
//*****************
//恢復原先波特率9600
TR2=0 ; //定時器2停止
TH2=OldTH2;
TL2=OldTL2;
RCAP2H=OldTH2;
RCAP2L=OldTL2; //16位自動再裝入值
TR2=1 ; //定時器2開始
//*****************
return 1;
}
bit Get_Picture()
{
uchar idata temp_cmd[6];
uchar temp1,temp2,tempdat;
uchar i;
bank=0;
error=0;
countr=0;
lcd_x=0;
lcd_y=0;
wr_lcd (0,0x34);//8-BIT 控制接口的擴充指令集動作
wr_lcd(0,0x80); //設定GDRAM 地址到地址計數器
wr_lcd(0,0x81);
Send_Cmd(GETPICTURE_ID);
Wait_ACK(temp_cmd);
if(temp_cmd[2]==GETPICTURE_ID[1])
{
Wait_ACK(temp_cmd);
ES=1;
while(countr<1200&&(lcd_x<Width&&lcd_y<Height))
{
if(front!=rear)
{
temp1=Picture_Dat1[front];
temp2=Picture_Dat2[front];
front++;
tempdat=0;
for(i=0;i<4;i++)
{
tempdat<<=1;
if(temp1&0x80)
tempdat|=0x01;
temp1<<=2;
}
for(i=0;i<4;i++)
{
tempdat<<=1;
if(temp2&0x80)
tempdat|=0x01;
temp2<<=2;
}
wr_lcd(1,tempdat);
lcd_x++;
if(lcd_x==Width)//換行
{
lcd_y++;
wr_lcd (0,0x34);//8-BIT 控制接口的擴充指令集動作
wr_lcd(0,0x80+lcd_y); //設定GDRAM 地址到地址計數器
wr_lcd(0,0x81);
lcd_x=0;
}
}
else
{
if(error)
{
CAM_Cmd(RESET1_ID);
wr_lcd (0,0x36);
return 0;
}
}
}
ES=0;
if(countr<1200)
CAM_Cmd(RESET1_ID);
Send_Cmd(ACK2_ID);
wr_lcd (0,0x36);
delay_ms(50);
return 1;
}
return 0;
}
void main()
{
init_lcd();
init_UART();
wr_lcd (0,0x30);
wr_lcd (0,0x80);
wr_lcd (1,'S');
wr_lcd (1,'Y');
wr_lcd (1,'N');
wr_lcd (1,'C');
wr_lcd (1,' ');
if(Send_SYNC_Cmd())
{
wr_lcd (1,'O');
wr_lcd (1,'K');
}
else
{
wr_lcd (1,'E');
wr_lcd (1,'R');
goto ERROR;
}
wr_lcd (0,0x30);
wr_lcd (0,0x80);
wr_lcd (1,'I');
wr_lcd (1,'N');
wr_lcd (1,'I');
wr_lcd (1,'T');
wr_lcd (1,' ');
if(CAM_Cmd(INITAL_ID))
{
wr_lcd (1,'O');
wr_lcd (1,'K');
}
else
{
wr_lcd (1,'E');
wr_lcd (1,'R');
goto ERROR;
}
while(1)
{
if(!key)
{
delay_ms(10);
if(!key)
{
wr_lcd (0,0x30);
wr_lcd (0,0x85);
wr_lcd (1,'S');
wr_lcd (1,'N');
wr_lcd (1,'A');
wr_lcd (1,'P');
wr_lcd (1,' ');
wr_lcd (0,0x30);
wr_lcd (0,0x96);
if(CAM_Cmd(SNAPSHOT_ID))
{
wr_lcd (1,'O');
wr_lcd (1,'K');
}
else
{
wr_lcd (1,'E');
wr_lcd (1,'R');
goto ERROR;
}
Get_Picture();
while(!key)
;
}
}
}
ERROR:;
CAM_Cmd(RESET2_ID);
while(1)
;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -