| /***********************************************************************/ /*P1.4LED; P1.5  继电器; P2.3 中断输入;P2.1 红外触发方式:1 连续触发,0 非连续触发
 430 主频 8M,启用 32K 低频晶振。
 */
 #include    <msp430x14x.h>
 #include    "api.h"
 unsigned  char  sync_cmd[]={0xAA,0x0D,0x00,0x00,0x00,0x00}; //唤醒  &  同
 步模块命令
 unsigned  char  init_cmd[]={0xAA,0x01,0x00,0x07,0x05,0x03}; //模块初始化命
 令,分辨率 160*128
 // unsigned char COM_SetBaudRatio[]={0xAA,0x07,0x1F,0x01,0x00,0x00};      //设置波特率命
 令  57600
 // unsigned char  setpage_cmd[]={0xAA,0x06,0x08,0x00,0x02,0x00}; //设置下载包大小命令,
 512
 unsigned char setpage_cmd[]={0xAA,0x06,0x08,0x20,0x00,0x00}; //设置下载包大小命令,32
 unsigned char snap_cmd[]={0xAA,0x05,0x00,0x00,0x00,0x00};          //拍照命令
 unsigned char getdata_cmd[]={0xAA,0x04,0x01,0x00,0x00,0x00};    //抓图命令
 unsigned char sleep_cmd[]={0xAA,0x09,0x00,0x00,0x00,0x00}; //进入休眠命令
 unsigned char reset_cmd[]={0xAA,0x08,0x01,0x00,0x00,0x00};        //复位命令
 unsigned char dataend_cmd[]={0xAA,0x0E,0x00,0x00,0xf0,0xf0}; //上位机同步应答
 unsigned char data_cmd[]={0xAA,0x0E,0x00,0x00,0x00,0x00};//上位机同步应答
 unsigned char *Flash_ptr = (unsigned char *)0xd000;
 BYTE cmd_buf[32];
 BYTE flag_6;//标志 6 字应答
 BYTE flag_12;//标志 1 2 字应答
 BYTE flag_ack;//标志应答数据
 BYTE flag_sync;//标志同步
 BYTE flag_datastart;//标志数据开始
 BYTE flag_data;//标志数据
 BYTE flag_t;//标志时间
 BYTE flag_err;//标志错误
 unsigned int page_num;
 unsigned char seg_num;
 unsigned int count;基于 430 单片机的摄像头程序
 unsigned int all_data;
 unsigned int end_size;
 void InitSystemClock(void) //  初始化系统时钟
 {
 unsigned char i;
 BCSCTL1=0x00; //Set 430 clk  开启 XT2,DOC 的标称频率
 为最低  且不分频;XT1 为低速晶体(32.768K)
 BCSCTL2=SELM_2+SELS+DIVS_0+DIVS_1; //smclk 1M
 //    BCSCTL2=SELM_2+SELS; //选择 MCLK SCLK 的时钟源为
 高速时钟  不分频,均为 8M
 do
 {
 IFG1&=~OFIFG; //清除震荡器失效标志
 for(i=0xff;i>0;i--); //稳定时间
 }
 while ((IFG1&OFIFG)!=0);
 // BCSCTL2=SELM_2+SELS; //选择 MCLK SCLK 的时钟源为高速
 时钟  不分频,均为 8M
 BCSCTL2=SELM_2+SELS+DIVS_0+DIVS_1; //smclk 1M
 }
 void Delay5us(void) //延时 86 个时钟周期,5.3us
 {
 uchar x;
 uchar y;
 for(y=0;y<5;y++)
 for(x=0;x<2;x++);
 }
 void Usart0init(void) //串口初始化
 {
 P3SEL |= 0x30; //p3.4 p3.5 为外围模式
 P3DIR |= 0x10;
 U0CTL |=SWRST;
 U0CTL = CHAR; //设置  8 字节 UART 模式
 U0TCTL=SSEL0+SSEL1;    //UCLK=SMCLK
 U0BR0=0x8A;
 U0BR1=0x00;
 U0MCTL=0xEF; //设置  57600基于 430 单片机的摄像头程序
 ME1 |=UTXE0+URXE0;      //模块使能
 IE1 |=URXIE0; //  使能  USART0  接收和发送  中断
 U0CTL &=~SWRST; // UART 启动
 }
 void Init_Timer_A(void) //初始化定时器
 {
 TACTL = TASSEL_2 + TACLR +ID1+ID0; // SMCLK, upmode    8 分
 频
 TACCR0=65535; //定时 33ms
 }
 /******************************************************************************
 *****/
 void main(void)
 {
 unsigned char h;
 WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
 InitSystemClock(); //初始化系统时钟
 for(unsigned char k=0;k<100;k++) //延时等待电源稳定
 {
 Delay5us();
 }
 Init_Timer_A(); //初始化定时器
 Usart0init(); //初始串口
 _BIS_SR(GIE);
 _EINT(); //开启总中断
 h=init_carame(); //初始化摄像头
 /*
 if(h==1)
 {
 可加入初始化成功标志,如亮灯
 因为初始化不成功,下面不会成功
 }
 else
 {
 不成功处理基于 430 单片机的摄像头程序
 }*/
 h=get_image(); //拍照
 /*
 if(h==1)
 {同上}*/
 while(1)
 {
 LPM0; //进入低功耗
 _NOP();
 }
 }
 #pragma vector=UART0RX_VECTOR // UART0 接收中断子程序
 __interrupt void usart0_rx(void)
 {
 _DINT();
 unsigned char a;
 a=RXBUF0;
 cmd_buf[count++]=a;
 if(count==6)
 {
 if(cmd_buf[0]==0xaa&&cmd_buf[1]==0x0f)
 {
 flag_err=1;
 }
 else if(flag_6==1)
 {
 flag_6=0;
 flag_ack=1;
 count=0;
 }
 }
 else if(count==12&&flag_12==1)
 {基于 430 单片机的摄像头程序
 flag_12=0;
 if(cmd_buf[7]==0x0d)
 {
 flag_sync=1;
 }
 else if(cmd_buf[7]==0x0a)
 {
 flag_datastart=1;
 all_data=cmd_buf[9]+cmd_buf[10]*256;
 }
 count=0;
 }
 else if(count==32||(page_num==1&&count==end_size))
 {
 flag_data=1;
 count=0;
 }
 }
 #pragma vector=TIMERA0_VECTOR //定时器中断函数
 __interrupt void Timer0_a3(void)
 {
 _DINT();
 flag_t=0;
 }
 unsigned char send_sync(unsigned char*cmd)//建立同步,flag_sync==1
 {
 unsigned char i,j,result=0;
 for(j=0;j<3;j++)//无应答,重发,共 3 次
 {
 for(i=0;i<6;i++)
 {
 TXBUF0=cmd[i];
 while((U0TCTL&0X01)==0);
 }
 TACTL   |= MC_1 ; //开定时器
 TACCTL0    |= CCIE; // CCR0  中断使能
 flag_12=1; //响应为 12 个字节基于 430 单片机的摄像头程序
 flag_t=1;
 while(flag_t)//定时等待回应
 {
 if(flag_sync==1&&flag_err!=1)
 {
 flag_sync=0;
 result=1;
 break;
 }
 }
 TACTL = TASSEL_2 + TACLR +MC_0+ID1+ID0; //关闭定时器
 if(result==1)//有应答,退出重发
 {
 break;
 }
 }
 return result;
 }
 unsigned char send_cmd(unsigned char * cmd)//发送普通命令,需要应答 flag_ack==1
 {
 unsigned char i,j,result=0;
 for(j=0;j<3;j++)//无应答,重发,共 3 次
 {
 for(i=0;i<6;i++)
 {
 TXBUF0=cmd[i];
 while((U0TCTL&0X01)==0);
 }
 TACTL   |= MC_1 ; //开定时器
 TACCTL0    |= CCIE; // CCR0  中断使能
 flag_t=1;
 flag_6=1; //响应为 6 个字节
 while(flag_t)//定时等待回应
 {
 if(flag_ack==1&&flag_err!=1)
 {
 flag_ack=0;
 result=1;
 break;
 }基于 430 单片机的摄像头程序
 }
 TACTL = TASSEL_2 + TACLR +MC_0+ID1+ID0; //关闭定时器
 if(result==1)//有应答,退出重发
 {
 break;
 }
 }
 return result;
 }
 unsigned char send_getdata(unsigned char*cmd) //获取图像,flag_datastart==1
 {
 unsigned char i,j,result=0;
 for(j=0;j<3;j++)//无应答,重发,共 3 次
 {
 for(i=0;i<6;i++)
 {
 TXBUF0=cmd[i];
 while((U0TCTL&0X01)==0);
 }
 TACTL   |= MC_1 ; //开定时器
 TACCTL0    |= CCIE; // CCR0  中断使能
 flag_t=1;
 flag_12=1; //响应为 12 个字节
 while(flag_t) //定时等待回应
 {
 if(flag_datastart==1&&flag_err!=1)
 {
 page_num=count_page(all_data);
 end_size=(all_data+6*page_num)%32;
 seg_num=count_seg(all_data);
 for(i=0;i<seg_num;i++)
 {
 erase_Seg(Flash_ptr);
 Flash_ptr+=512;
 }
 Flash_ptr=(unsigned char *)0xd000;
 flag_datastart=0;
 result=1;
 break;
 }
 }
 TACTL = TASSEL_2 + TACLR +MC_0+ID1+ID0; //关闭定时器基于 430 单片机的摄像头程序
 if(result==1)//有应答,退出重发
 {
 break;
 }
 }
 return result;
 }
 unsigned char send_dataack(unsigned char * cmd)//请求数据包,flag_data==1
 {
 unsigned char result=0;
 int i;
 for(i=0;i<6;i++)
 {
 TXBUF0=cmd[i];
 while((U0TCTL&0X01)==0);
 }
 while(flag_data!=1);//一直等到收满 32 字节
 flag_data=0;
 if(flag_err!=1)
 {
 write_Seg(Flash_ptr,cmd_buf,32);//将正确数据写入 flash
 Flash_ptr+=32;
 result=1;
 }
 return result;
 }
 void send_noack(unsigned char * cmd)//发送不需应答的命令
 {
 unsigned char i;
 for(i=0;i<6;i++)
 {
 TXBUF0=cmd[i];
 while((U0TCTL&0X01)==0);
 }
 }
 unsigned char init_carame(void)
 {
 unsigned char ret;
 ret=send_sync(sync_cmd);//同步
 if(ret==1)
 {基于 430 单片机的摄像头程序
 ret=send_cmd(init_cmd);//初始化
 if(ret==1)
 {
 ret=send_cmd(setpage_cmd);//包大小
 if(ret==1)
 {
 ret=send_cmd(sleep_cmd);//休眠
 }
 }
 }
 return ret;
 }
 unsigned char get_image(void)
 {
 unsigned char ret;
 ret=send_sync(sync_cmd);//同步
 if(ret==1)
 {
 ret=send_cmd(snap_cmd);//快照
 if(ret==1)
 {
 ret=send_getdata(getdata_cmd);//获取图像
 if(ret==1)
 {
 do
 {
 ret=send_dataack(data_cmd);//请求数据包
 data_cmd[4]++;
 if(data_cmd[4]==0x00)
 {
 data_cmd[5]++;
 }
 page_num--;
 }while(ret&&page_num!=0);
 data_cmd[4]=0x00;
 data_cmd[5]=0x00;
 Flash_ptr = (unsigned char *)0xd000;
 if(ret==1)
 {
 send_noack(dataend_cmd);//结束
 ret=send_cmd(reset_cmd);//复位基于 430 单片机的摄像头程序
 if(ret==1)
 {
 ret=send_cmd(sleep_cmd); //休眠
 }
 }
 }
 }
 }
 return ret;
 }
 unsigned int count_page(int all_data)//计算需要多少包,用于摄像头发送结束信号
 {
 unsigned int num;
 num=all_data/26;
 if(all_data%26)
 {
 num++;
 }
 return num;
 }
 unsigned char count_seg(int all_data)//计算需要几段 FLash,用于擦除
 {
 unsigned char num;
 num=(all_data+6*page_num)/512;
 if(all_data+6*page_num%512)
 {
 num++;
 }
 return num;
 }
 void erase_Seg(unsigned char *seg)//擦除寄存器
 {
 while(FCTL3&0x01);
 FCTL2 = FWKEY + FSSEL1 + FN0; // SMCLK/2 for Flash Timing Generator
 FCTL3 = FWKEY; // Clear Lock bit
 FCTL1 = FWKEY + ERASE ; // Set Erase bit, allow interrupts
 *seg = 0;
 }基于 430 单片机的摄像头程序
 void write_Seg(unsigned char *seg,unsigned char *p,unsigned int    num)//写寄存器
 {
 unsigned int i;
 while(FCTL3&0x01);
 FCTL2 = FWKEY + FSSEL1 + FN0; // SMCLK/2 for Flash Timing Generator
 FCTL3 = FWKEY;
 FCTL1 = FWKEY + WRT; // Set WRT bit for write operation
 for (i = 0; i < num; i++)
 {
 *seg++ = *p++; // Write value to flash
 }
 FCTL1 = FWKEY; // Clear WRT bit
 FCTL3 = FWKEY + LOCK; // Set LOCK bit
 }
 void Flash_read(unsigned char * seg,unsigned char *p,unsigned char num)//读 flash
 {
 unsigned char i;
 for(i=0;i<num;i++)
 {
 p[i]=*seg++;
 }
 }
 /*****************************************************************************
 |