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 *)®_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 *)®_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位里。(寄存器映射连续)