/*
*函数名: ADNS_3080_GPIO_Configuration(void)
*描述 :ADNS3080的使能引脚PTC5-NCS 掉电PC6-NPD=0 复位引脚PC7-RST 的初始化
*输入 :无
*输出 :无
*调用 :内部调用
*/
void ADNS_3080_GPIO_Configuration(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC); //使能PTC
GPIOPinTypeGPIOOutput(GPIO_PORTC_BASE, GPIO_PIN_7|GPIO_PIN_6|GPIO_PIN_5); //PTC5-NCS芯片使能引脚 PC6-NPD=0 芯片掉电 PC7-RST 复位
}
/*
*函数名: ADNS3080_reset(void)
*描述 :ADNS3080 复位脉冲信号
*输入 :无
*输出 :无
*调用 :内部调用
*/
void ADNS3080_reset(void) //ADNS3080 复位(高)脉冲信号
{
GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_7, 0x00);
delayms(5);//5ms
GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_7, 0x80);
delayms(5);//5ms
GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_7, 0x00);
}
/*
*函数名: Write_srom(void)
*描述 :SROM下载函数 A3080的固件下载
*输入 :无
*输出 :无
*调用 :内部调用
*/
void Write_srom(void)
{
int i;
ON_CS();
writr_register(0x20,0x44); //0x20-0x3C是保留出来的寄存器
delayus(51 );
writr_register(0x23,0x07);
delayus(51);
writr_register(0x24,0x88);
delayus(51 );
OFF_CS(); //突发_写模式
delayus(340); //等待大于1帧时间
ON_CS();
writr_register(SROM_Enable,0x18); //下载SROM固件到SROM_Load寄存器之前要将0X18写入该寄存器
OFF_CS(); //突发_写模式
delayus(41); // >40us
ON_CS();
for(i=0;i<=1985;i++)
{
writr_register(0x60,SROM[i]); //0x60 下载静态只读存储器 寄存器 SROM_Load寄存器是被用于高速编程3080的一个外部SROM或单片机。
delayus(11);// >10us
}
OFF_CS();
delayus(105); //>104us
}
/*
*函数名: ADNS3080_Init(void)
*描述 :A3080的初始化
*输入 :无
*输出 :无
*调用 :主函数调用
*/
void ADNS3080_Init(void)
{
ADNS_3080_GPIO_Configuration();
SPI_TM4C123_init();
ADNS3080_reset(); //复位PC7
GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_6, 0x40); //拉高NPD,免睡眠
delayms(10);
Write_srom(); //写SROM_enable寄存器 下载固件
delayms(100);
ADNS_Configuration();
}
/*
*函数名: ADNS_Configuration(void)
*描述 :A3080的寄存器配置
*输入 :无
*输出 :无
*调用 :主函数调用
*/
void ADNS_Configuration(void)
{
ON_CS();
writr_register(Configuration_bits,0x10); //设置分辨率 1600 0x10 //若Bit 4为0 即0X00,则为400点每英寸
delayms(3);
writr_register(Extended_Config,0x01); //固定帧速率 由Frame_Period_Max_Bound 寄存器里的值决定
delayms(3);
if(read_busy()!=1) //帧率的判忙 Extended_Config寄存器最高位dusy ==1忙 ==0允许写
{ //设为3000帧每秒
OFF_CS(); //突发_写模式
delayms(2);
ON_CS();
SPI_SendReceive(Frame_Period_Max_Bound_Lower+0x80); //设置帧率 //先写低位再写高位
SPI_SendReceive(0x40); // 帧率=时钟频率/寄存器的值
SPI_SendReceive(Frame_Period_Max_Bound_Upper+0x80);
SPI_SendReceive(0x1f); // 0x1f40=8000
// writr_register(Frame_Period_Max_Bound_Lower,0x40); //设置帧率 //先写低位再写高位 帧率=时钟频率/寄存器的值
// writr_register(Frame_Period_Max_Bound_Upper,0x1f); //帧率=时钟频率/寄存器的值 =76000000/8000=9500Hz=0.1ms
}
clear_motion(); //运动寄存器清零 编写任何值这个寄存器将导致Delta_X,Delta_Y和内部运动寄存器被清除。
OFF_CS();
}
/*
*函数名: read_register(void)
*描述 :读寄存器函数 地址的最高位为0时-读寄存器
*输入 :要读的寄存器的地址
*输出 :寄存器中的数
*调用 :内部调用
*/
uint8_t read_register(uint8_t adress)
{
uint8_t temp;
ON_CS();
temp=SPI_SendReceive(adress+0x00);
delayus(75);
temp=SPI_SendReceive(0xff);
OFF_CS();
return temp;
}
/*
*函数名: writr_register(void)
*描述 :对寄存器进行写操作,第一个输入的最高位 为1 即写操作
*输入 :要写的寄存器的地址 寄存器数值
*输出 :无
*调用 :内部调用
*/
void writr_register(uint8_t adress,uint8_t vlue)
{
ON_CS();
SPI_SendReceive(adress+0x80);
SPI_SendReceive(vlue);
OFF_CS();
delayus(51);
}
/*
*函数名: read_busy(void)
*描述 :对寄存器Extended_Config进行写操作,最高位是1表示忙信号,不允许写,最高位是0时允许写寄存器Frame_Period_Max_Bound_Upper and Lower
* Frame_Period_Min_Bound_Upper and Lower Shutter_Max_Bound_Upper and Lower
*输入 :无
*输出 :0 表示允许写寄存器 1 忙信号不允许写
*调用 :内部调用
*/
uint8_t read_busy(void) //写帧率的判忙 ==1忙
{
uint8_t temp;
ON_CS();
temp=SPI_SendReceive(Extended_Config+0x00);
delayus(75);
temp=SPI_SendReceive(0xff);
temp&=0x80; //Extended_Config最高位与1相与 读dusy位 0时允许写
OFF_CS();
return temp;
}
/*
*函数名: clear_motion(void)
*描述 :对寄存器Motion_Clear进行写操作,使寄存器DX,DY 中的数据清除
*输入 :无
*输出 :无
*调用 :内部调用
*/
void clear_motion(void)
{
ON_CS();
SPI_SendReceive(Motion_Clear+0x80);
SPI_SendReceive(0xff); //清除X Y数据 编写任何值这个寄存器将导致Delta_X,Delta_Y和内部运动寄存器被清除。
OFF_CS();
}
/*
*函数名: read_zhenlv(void)
*描述 :对寄存器Frame_Period_Uppe,Frame_Period_Lower进行读操作
*输入 :无
*输出 :帧率
*调用 :内部调用
*/
uint16_t read_zhenlv(void) //读帧率
{
return read_register(Frame_Period_Uppe) << 8|read_register(Frame_Period_Lower);
}
/*
*函数名: Read_Data_burst(void)
*描述 :对寄存器Motion,DX,DY进行读操作 ,从而得到x,y的位移
*输入 :无
*输出 :无
*调用 :主函数调用
*/
void Read_Data_burst(void)
{
static int SumX;
static int SumY;
int sum_x,sum_y;
unsigned char move=0;
int x=0;
int y=0;
ON_CS();
SPI_SendReceive(0x50); //0x50 SQUAL寄存器 ???????????????
delayus(75);
move=SPI_SendReceive(0x02); //0xFF改为0x02 0xFF
x0=SPI_SendReceive(0x03); //0xFF改为0x03 0xFF
y0=SPI_SendReceive(0x04); //0xFF改为0x04 0xFF
//move=SPI_SendReceive(Motion);
UARTCharPut(UART1_BASE, move);
UARTCharPut(UART1_BASE, x0);
UARTCharPut(UART1_BASE, y0);
if(x&0x80) //保留x最高位 x最高位==1 x为负数 ==0 x为正数
{
//x的二补码转换
/* x -= 1;
x = ~x;
x=(-1)*x;
x-=256;*/
/*潘梦珠方法 该数是负,把左边最高位的符号位抛弃 把剩下的二进制每一位都取反 取反以后的数值+1,
得到的数就是此负的二进制补码的绝对值了 把此绝对值按照二进制转换为十进制,
在转换得到的十进制前面加一个负号 就得到了这负的二进制补码对应的十进制数。*/
x=x&0x7f; //去掉最高位
x=~x;
x=x+1;
x=(-1)*x-128;
}
if(y&0x80)
{
//y的二补码转换
y=y&0x7f;
y=~y;
y=y+1;
y=(-1)*y-128;
}
//printf("%d,%d\n",x,y);
SumX=SumX+x; //累加X读入的移动数据
SumY=SumY+y; //累加Y读入的移动数据
OFF_CS();
delayus(4);
OFF_CS();
sum_x=(25.4*(float)SumX *H)/(12*1600);//距离=d_x*(25.4/1600)*n 其中n=像高:物高=8毫米:物长
sum_y=(25.4*(float)SumY *H)/(12*1600);
// printf("%d,%d\n",sum_x,sum_y);
if((move&0x10)!=1) //Delta_Y和/或Delta_X缓冲区没有溢出
{
if(move&0x80) //运动发生,数据准备读Delta_X和Delta_Y寄存器
{
// printf("%d,%d\n",sum_x,0);
}
else
{
x=0;
y=0;
}
}
else
{
x=0;
y=0;
}
/**/
}
/*
*函数名: read_average_pixel(void)
*描述 :对寄存器Pixel_Sum进行读操作 ,从而得到平均像素
*输入 :无
*输出 :平均像素
*调用 :主函数调用
*/
float read_average_pixel(void) //读平均像素
{
float temp;
ON_CS();
temp=SPI_SendReceive(Pixel_Sum);
delayus(76);
temp=SPI_SendReceive(0xff);
temp=temp*0.2844;
OFF_CS();
return temp;
}
/*
*函数名: read_pixel(void)
*描述 :
*输入 :无
*输出 :无
*调用 :内部调用
*/
void read_pixel(void)
{
uint8_t i,j ,regValue, pixelValue,test=1;
writr_register(Frame_Capture,0x83);
delayus(1010); //等待3帧 (1/3000)*1000000*3+10 =1010us
//显示数据 30*30=900
for(i=0;i<30;i++)//列
{
for(j=0;j<30;j++) //行
{
regValue=read_register(Frame_Capture); //读像素
if( test && ((regValue&0x40)==0)) //找不到第一个像素
{
}
test=0;
pixelValue =(regValue<<2);
delayus(50);
}
}
ADNS3080_reset(); //重启运行
}
/*
*函数名: read_pixel_burst(void)
*描述 :
*输入 :无
*输出 :无
*调用 :内部调用
*/
void read_pixel_burst(void) //爆发读图像
{
int i,j;
writr_register(Frame_Capture,0x83);
delayus(1010); //等待3帧 (1/3000)*1000000*3+10 =1010us
//开始burst读
ON_CS();
SPI_SendReceive(0x40);
delayus(75);
for(i=0;i<30;i++)
{
for(j=0;j<30;j++)
{
delayus(10);
}
}
OFF_CS();
delayus(4);
OFF_CS();
}