PAW3395传感器记录

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

paw3395

一、查看数据手册

首先,可以看到power on 需要做的步骤是7步

在这里插入图片描述

按照步骤区写寄存器即可。

可以让chatgpt帮忙写这些重复性的行为。

例如:

Write register Ox10 with value Ox20

Write register Ox20 with value Ox30

Write register Ox30 with value Ox40

帮忙 建立以下表格:

static PAW3395_REG_VALUE_T gst_additional_data[] = {

{0x10,0x20},

{0x20,0x30},

{0x30,0x40}

};

在这里插入图片描述

二、SPI通信

通过SPI接口读取鼠标的寄存器值

1.解析

函数接受三个参数:寄存器地址、数据缓冲区指针和要读取的数据长度。

在函数内部,首先将SPI的片选信号设置为低电平,以使得鼠标芯片能够与主控芯片进行通信。然后,使用spi_hw_s_write_byte函数向鼠标的寄存器地址发送数据,并使用spi_hw_s_read_byte函数读取寄存器的值,将其存储到数据缓冲区中。最后,延时5微秒,将SPI片选信号设置为高电平,完成一次寄存器读取操作。

2.上代码

spi_hw_read(0x6C,(k_uint8 *)&reg_value,1);
//向寄存器地址0x6c读,读到存储在变量reg_value里面

void spi_hw_read(k_uint8 uc_reg_addr,k_uint8 *puc_data, k_uint8 uc_data_len)
{
	//k_uint8 uc_read_register = uc_reg_addr;
	gpio_write(SPI_CS_PIN,0);	

	spi_hw_s_write_byte(uc_reg_addr);
	
	for (k_uint8 cnt = 0; cnt < uc_data_len; cnt++)
	{
	    *puc_data++ = spi_hw_s_read_byte();
	}
	time_delay_us(5);
	gpio_write(SPI_CS_PIN,1);	

}

三、运动判断

#define K_BIT_MASK(i) (1ul << (i))

#define PMW3325_MOTION_MASK (K_BIT_MASK(7)) 

if(!(uc_xy_motion & PMW3325_MOTION_MASK))

使用了位运算,K_BIT_MASK(i)表示将1左移i位得到的数,例如K_BIT_MASK(7)表示将1左移7位得到的数,即0x80。PMW3325_MOTION_MASK表示运算出来的结果,即1左移7位得到的数,表示掩码的位置在第7位。

!(uc_xy_motion & PMW3325_MOTION_MASK)的含义是判断uc_xy_motion的第7位是否为0,如果为0,说明没有运动;如果为1,说明有运动。

四、输出数组

Set X-axis Resolution:

0x0000: 50CPI

0x0001: 100CPI

0x0002: 150CPI

:

0x0063: 5000CPI (Default)

:

0x018F: 20000CPI

:

0x0207: 26000CPI (max)

#include <stdio.h>

int main() {
    const int MAX_CPI = 26000;
    const int CPI_STEP = 50;

printf("{");
for (int i = 0; i <= MAX_CPI / CPI_STEP; i++) {
    printf("{0x%04X, %d},", i, i * CPI_STEP + 50);
    if (i % 5 == 4) {
        printf("\n ");
    }
}
printf("}\n");
return 0;

}
	
static PAW3395_CPI_VALUE_T gst_cpi_value[] =
{
 {0x0000, 50},{0x0001, 100},{0x0002, 150},{0x0003, 200},{0x0004, 250},
 {0x0005, 300},{0x0006, 350},{0x0007, 400},{0x0008, 450},{0x0009, 500},

}
gus_loop_set_dpi_value = (us_cpi / 50) * 50;	
	guc_dpi_reg = ((us_cpi / 50) - 1);		

有规律的不需要建表,直接除50乘50获取整数,,再除50再-1就得到要写入的值。

五、步骤

power_on、

power_down

read_xy_data

set_cpi

如:power on

//	1. Apply power to VDD and VDDIO.

	//	2. Wait for 50ms.
	time_delay_ms(50);
	
	//	 3. Drive NCS high, and then low to reset the SPI port.
	
	paw3395_reset_spi();
	
	//	4. Write 0x5A to Power_Up_Reset register (or, alternatively toggle the NRESET pin).
	uc_w_value = 0x5a;
	
	//PMW_DEBUG("3.reg:0x%x data:0x%x \r\n",PMW3325_REG_Power_Up_Reset,uc_w_value);
	spi_hw_write(PMW3325_REG_Power_Up_Reset,&uc_w_value,1); //ba 
	
	//	5. Wait for 5ms.
	time_delay_ms(5);

// 6. Load power up initialization register setting:
for(i = 0;i < K_CALI_ARRAY_NUM(gst_power_on_data);i++) 
{
	spi_hw_write(gst_power_on_data[i].uc_req_adress,&(gst_power_on_data[i].uc_req_value),1);
	//PMW_DEBUG("[%d] reg:0x%x data:0x%x \r\n",i,gst_power_on_data[i].uc_req_adress,gst_power_on_data[i].uc_req_value);
	#if(WATCHDOG_EN)
	feed_watchdog();
	#endif		
}

time_delay_ms(1);
//Read register Ox6C at 1ms interval until value Ox80 is obtained or read up to 60 times, this register read interval
//must be carried out at 1ms interval with timing tolerance of ±1%If value of Ox80 is not obtained from registerOx6C after 60 times:

		int num_reads = 0;

		k_uint8 reg_value = 0;

	  while (num_reads < 60) {			
	  	spi_hw_read(0x6C,(k_uint8 *)&reg_value,1);
	  
		  // 如果读取到了目标值,输出提示并结束程序
		  if (reg_value == 0x80) {
			  PMW_DEBUG("Target value of Ox%x obtained after %d reads.\n", 0x80, num_reads + 1);
			  break;
		  }
		  time_delay_ms(1);
		  num_reads++;
	  }
	  // 循环完成后如果还没有读到目标值,输出提示并结束程序
	  PMW_DEBUG("Target value of Ox%x not obtained after %d reads.\n", 0x80, 60);
	  
	  	if (reg_value != 0x80) 		
{
	  	
			 // Target value not obtained after MAX_READS attempts
		 uc_w_value=0x14;
		 spi_hw_write(0x7F, &uc_w_value,1);
		 
		 uc_w_value=0x00;
	 	 spi_hw_write(0x6C, &uc_w_value,1);
		 
		 uc_w_value=0x14;
		 spi_hw_write(0x7F, &uc_w_value,1);
		 }

		uc_w_value=0x00;
		spi_hw_write(0x22, &uc_w_value,1);
		uc_w_value=0x00;
		spi_hw_write(0x55, &uc_w_value,1);
		uc_w_value=0x07;
		spi_hw_write(0x7f, &uc_w_value,1);
		uc_w_value=0x40;
		spi_hw_write(0x40, &uc_w_value,1);
		uc_w_value=0x00;
		spi_hw_write(0x7f, &uc_w_value,1);	



		// 7. Read from registers 0x02, 0x03, 0x04, 0x05 and 0x06 one time regardless of the motion pin state.??	
spi_hw_read(PAW3395_REG_Motion,(k_uint8*)&uc_w_value,1)	spi_hw_read(PAW3395_REG_Delta_X_L(k_uint8*)&uc_w_value,1);	spi_hw_read(PAW3395_REG_Delta_X_H(k_uint8*)&uc_w_value,1);	spi_hw_read(PAW3395_REG_Delta_Y_L(k_uint8*)&uc_w_value,1);	spi_hw_read(PAW3395_REG_Delta_Y_H(k_uint8*)&uc_w_value,1);	

spi_hw_write(PAW3395_REG_Resolution_x_low, (k_uint8*)&guc_dpi_reg, 2);
//low=0x48,high=0x49,together send

往连续的8位寄存器里写数据,可以直接写在低8位里写16位数据,溢出的会自动存的高8位里。(寄存器映射连续)

总结