📄 main.c
字号:
/****************************************Copyright (c)**************************************************
** Guangzou ZLG-MCU Development Co.,LTD.
** graduate school
** http://www.zlgmcu.com
**
**--------------File Info-------------------------------------------------------------------------------
** File name: main.c
** Last modified Date: 2004-09-16
** Last Version: 1.0
** Descriptions: The main() function example template
**
**------------------------------------------------------------------------------------------------------
** Created by: Chenmingji
** Created date: 2004-09-16
** Version: 1.0
** Descriptions: The original version
**
**------------------------------------------------------------------------------------------------------
** Modified by:
** Modified date:
** Version:
** Descriptions:
**
********************************************************************************************************/
#include "main.h"
//uint8 pic_camer[120][40];//[60][160];
uint8 camer0[120][160];//[60][320];
uint8 samp_start_flag;
uint8 samp_end_flag;
uint8 end_flag;
uint8 permit_read;
uint8 X_line;
uint8 Y_line;
uint8 LR_move_flag;
uint8 UD_move_flag;
uint8 motorUD_end_flag=3;
#define DELAY_TIME 50
#define SDA 1<<9
#define SCL 1<<8
/***------延时-----***/
void DELAY(uint16 t) /*延时函数*/
{ uint8 i;
while(t!=0)
{ for(i=0;i<10;i++);
t--;
}
}
/***-----I2C启动-----***/
void I2C_Start(void)
{
/*启动I2C总线的函数,当SCL为高电平时使SDA产生一个负跳变*/
IO0SET = SDA;//SDA=1;
IO0SET = SCL;//SCL=1;
DELAY(DELAY_TIME/2);
IO0CLR = SDA;//SDA=0;
DELAY(DELAY_TIME/25);
IO0CLR = SCL;//SCL=0;
DELAY(DELAY_TIME/20);
}
/***-----I2C停止-----***/
void I2C_Stop(void)
{
/*终止I2C总线,当SCL为高电平时使SDA产生一个正跳变*/
IO0CLR = SCL;//SCL=0;
IO0CLR = SDA;//SDA=0;
DELAY(DELAY_TIME/2);
IO0SET = SCL;//SCL=1;
DELAY(DELAY_TIME);
IO0SET = SDA;//SDA=1;
DELAY(DELAY_TIME);
}
/***-----发送1bit:0-----***/
void SEND_0(void) /* SEND ACK */
{
/*发送0,在SCL为高电平时使SDA信号为低*/
IO0CLR = SDA;//SDA=0;
DELAY(DELAY_TIME/25);
IO0SET = SCL;//SCL=1;
DELAY(DELAY_TIME/25);
IO0CLR = SCL;//SCL=0;
DELAY(DELAY_TIME/25);
}
/***-----发送1bit:1-----***/
void SEND_1(void)
{
/*发送1,在SCL为高电平时使SDA信号为高*/
IO0SET = SDA;//SDA=1;
DELAY(DELAY_TIME/25);
IO0SET = SCL;//SCL=1;
DELAY(DELAY_TIME/25);
IO0CLR = SCL;//SCL=0;
DELAY(DELAY_TIME/25);
}
/***-----发送1bit:等待-----***/
// write don't care bit
void Check_Acknowledge(uint8 sendbit)//void
{ //发送完一个字节后检验设备的应答信号
if(sendbit & 0x01)
IO0SET = SDA; //SDA=1
else
IO0CLR = SDA; //SDA=0
DELAY(DELAY_TIME/25);
IO0SET = SCL; //SCL=1
DELAY(DELAY_TIME/25);
IO0CLR = SCL; //SCL=0
DELAY(DELAY_TIME/25);
}
/***-----发送1 byte-----***/
void WriteI2CByte(uint8 b)//reentrant
{
/*向I2C总线写一个字节*/
uint8 i;
for(i=0;i<8;i++)
{ if((b<<i)&0x80)
SEND_1();
else
SEND_0();
}
}
/***-----读取1 byte-----***/
uint8 ReadI2CByte(void)//reentrant
{ /*从I2C总线读一个字节*/
uint8 recevise_dt=0,i;
uint8 BCY=0;
IO0DIR &= 0xfffffdff;
for(i=0;i<8;i++)
{
IO0CLR = SCL;
DELAY(DELAY_TIME/25);
IO0SET = SCL;
recevise_dt <<= 1;
DELAY(DELAY_TIME/25);
BCY = (IO0PIN>>8) & 0x02;
if(BCY!=0)
recevise_dt += 1;
IO0CLR = SCL;
DELAY(DELAY_TIME/25);
}
IO0DIR |= 0x00000200;
return recevise_dt;
}
/**********以下为读写24c02的函数**********/
void Write_One_Byte(uint8 addr,uint8 thedata)
{ I2C_Start();
WriteI2CByte(0x42);
Check_Acknowledge(0x00);
WriteI2CByte(addr);
Check_Acknowledge(0x00);
WriteI2CByte(thedata);
Check_Acknowledge(0x00);
I2C_Stop();
}
uint8 Read_One_Byte(uint8 addr,uint8 addrr)
{ uint8 recevise_data;
I2C_Start();
WriteI2CByte(0x42);
Check_Acknowledge(0x00);
WriteI2CByte(addrr);
Check_Acknowledge(0x00);
I2C_Stop();
DELAY(DELAY_TIME/25);
I2C_Start();
WriteI2CByte(0x43);
Check_Acknowledge(0x01);
recevise_data = ReadI2CByte();
Check_Acknowledge(0x01);
I2C_Stop();
return recevise_data;
}
//#define XY_use
/*
*******************************************************************************
** 函数名称:INT0_IRQ()
** 函数功能:camer0场中断
** 入口参数:中断口电平发生改变
** 出口参数:处理中断服务程序
*******************************************************************************
*/uint8 gap;
uint16 gbn;
uint16 dno;
void __irq IRQ_Eint0(void)
{ //IO0SET = RR;
if(samp_end_flag ==1) // 采样结束
{ end_flag =1; VICIntEnClr = 1<<0x0f; // 置采样结束标志,同时关闭行信号中断
}
else if(samp_start_flag ==0) // 没有结束
{ gap = 0;gbn =0; // 清空纵坐标
samp_start_flag = 1; // 置开始采样标志
VICIntEnable = 1<<0x0f; // 开行中断
}
EXTINT |= 0x01;
VICVectAddr = 0x00; // 中断处理结束
//IO0CLR = RR;
}
/*
*******************************************************************************
** 函数名称:INT1_IRQ()
** 函数功能:camer0行中断// VSYNC 信号
** 入口参数:中断口电平发生改变
** 出口参数:处理中断服务程序
*******************************************************************************
*/
void __irq IRQ_Eint1(void)
{ static uint8 start_samp=0; // 是否允许采样互锁
if(samp_start_flag ==1) // 检测到可以开始采样标志
{ //if(((IO0PIN>>8)&0x04) !=0) //HREF
{ if(gbn<239) // 采样240行
{ if(gbn%2 ==0) // 2行采集一次
{ gap++; dno =0;
}
gbn++; // 调整采样参数
}
else // 已经采完
{ samp_end_flag =1; // 置采样结束标志
samp_start_flag=0; // 清开始采样标志
start_samp = 0; //
VICIntEnClr = 1<<0x10; // 关闭采样clk中断
}
if(samp_end_flag==0 && start_samp==0)//判断是不是第一次开始采样
{ start_samp =1; //互锁
VICIntEnable = 1<<0x10; //开采样clk脉冲中断
}
}
}
EXTINT |= 0x02;
VICVectAddr = 0x00; // 中断处理结束
}
/*
*******************************************************************************
** 函数名称:INT2_IRQ()
** 函数功能:camer0行中断// VSYNC 信号
** 入口参数:中断口电平发生改变
** 出口参数:处理中断服务程序
*******************************************************************************
*/
void __irq IRQ_Eint2(void)
{ uint8 i;
if(samp_start_flag ==1) // 开始采样标志
{ if(((IO0PIN>>8)&0x04) !=0) // 判断HREF是否有效
{ if(dno%2 ==0) // 每格4点采样一点
{ i = (IO1PIN>>16)&0xff; // 得到数据
camer0[gap-1][dno/2]=i; // 放到缓冲期终
}
dno++; // 调整到下一个像素点
}
}
EXTINT |= 0x04;
VICVectAddr = 0x00; // 中断处理结束
}
/*******************************************************************************************
**函数名称:camerINT_Init()
**函数功能:camer照相的行与场的中断。
**入口参数:行与场电平变法
**返 回 值:相应各自的中断
**说 明:进入各自的中断服务处理程序
*******************************************************************************************/
void camerINT_Init()
{
EXTMODE = 0x07; // 使用边沿触发外部中断
EXTPOLAR = 0x04; // 开0、1、2、3中断,下降沿
}
/*
*******************************************************************************
** 函数名称:void LR_UD_move(uint8 x,uint8 y)
** 函数功能:步进电机要动作的方向
** 入口参数:当前camera采集到的像素点位置
** 出口参数:给出动作标志
*******************************************************************************
*/
void LR_UD_judge(uint8 x,uint8 y)
{ /*if(x>90) LR_move_flag =1; // 像素点在右边,摄像头右转
else if(x>1&&x<70) LR_move_flag =2; // 像素点在左边,摄像头左转
else if((x>70 && x<90) || x==0)
LR_move_flag =0; // 像素点在水平方向的中间位置、摄像头不动
if(y>70) UD_move_flag =1; // 像素点在下边,摄像头向下转
else if(y>1&&y<50) UD_move_flag =2; // 像素点在上方,摄像头向上转
else if((y>50&&y<70) || y==0)
UD_move_flag =0; // 像素点在垂直方向的中间位置、摄像头不动*/
if(x>90) LR_move_flag =1;
else if(x>70) LR_move_flag =0;
else if(x>1) LR_move_flag =2;
else LR_move_flag =0;
/*if(y>70) UD_move_flag =1;
else if(y>50) UD_move_flag =0;
else if(y>1) UD_move_flag =2;
else UD_move_flag =0;*/
}
/*
*******************************************************************************
** 函数名称:void LR_UD_move(uint8 x,uint8 y)
** 函数功能:步进电机要动作的方向
** 入口参数:当前camera采集到的像素点位置
** 出口参数:给出动作标志
*******************************************************************************
*/uint8 motor_end_flag=3;
void motor_move(void)
{ /*if(LR_move_flag ==0) // 水平方向在中间,不需要转动
{ //IO0CLR |= 0x00000080; // 关使能
//VICIntEnClr = 1 << 0x05;
motor_end_flag = 1;
}
else // 水平方向不在中间,需要转动
{ //IO0CLR |= 0x00000080; // 开使能
if(LR_move_flag ==1) // 在右边
IO0CLR = DIR;
else if(LR_move_flag ==2) // 在左边
IO0SET = DIR;
} */
switch(LR_move_flag)
{ case 0:motor_end_flag = 1;break;
case 1:IO0CLR = DIR;break;
case 2:IO0SET = DIR;break;
}
}
/*
*********************************************************************************************************
** 函数名称 :IRQ_T1()
** 函数功能 :T1定时器中断服务程序
** 入口参数 :无
** 出口参数 :匹配输出脉冲
*********************************************************************************************************
*/
void __irq IRQ_T1 (void)
{ //static uint8 re_p;
LR_UD_judge(X_line,Y_line);
motor_move();
T1IR = 0x01;
VICVectAddr = 0x00; // 中断处理结束
}
/*
*********************************************************************************************************
** 函数名称 :T1_Init()
** 函数功能 :T1定时器初始化,设置工作模式。
** 入口参数 :
*********************************************************************************************************
*/
void T1_Init ()
{ T1TC = 0; // 定时器初值设置为0
T1PR = 0; // 时钟不分频,(1秒计数Fpclk个脉冲)
T1MCR = 0x03; // 设置T1MR0匹配后复位T1TC,并产生中断标志
T1EMR = 0x30; // T1MR0匹配否MAT1.0输出翻转
T1MR0 = Fpclk / 128; // 匹配寄存器MR0等于1/3的计数频率,通过改变来改变
T1TCR = 0x01; // 定时器启动
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -