ST意法半导体
直播中

张伟

8年用户 1728经验值
私信 关注
[问答]

如何在内置电容式触摸面板FT5336上测试I2C驱动功能呢?

STM32F746-Disco
电容式触控面板 FT5336
STM32CubeIDE,Windows 10
仅限 CMSIS
我正在仅使用 CMSIS 为 STM32F746 开发我的第一个 I2C 驱动程序,我决定最好在内置电容式触摸面板 FT5336 上测试我的 I2C 技能。我使用 ST 提供的 ft5336.c/.h 来获取寄存器地址(因为 FT5336 数据表实际上没有它们)。所以显然我首先要尝试的是读取芯片 ID 寄存器。
最初,我已经为它开发了 DMA 驱动程序(是的,我可以做 DMA,但仍然没有尝试过 I2C),但是当我遇到问题时,我退后一步并采用完全阻塞的方式。有趣的是,结果是相同的。
我所做的:
我以写入模式(ACK)写入从地址,然后是 ID 寄存器(NACK)。
然后我稍微暂停一下(~30us,远高于数据表~10us 用于开始设置;尝试不同)。
然后我以读取模式(ACK)写入从地址,并收到 0x00(NACK)。
我已经用示波器和逻辑分析仪仔细检查了我的信号,确保时序正确无误。我可以随心所欲地写(主发送)(包括使用 DMA),但我似乎无法阅读。我不确定错误在哪一边。显然,如果我在上面运行 TouchGFX 项目,面板就可以工作。我查看了 TouchGFX 生成的代码,以防我在那里看到一些东西,但我没有发现任何让我印象深刻的东西。我手头没有任何其他 I2C 设备可以用来测试它。
I2C3 设置:
  • void i2c_setup(I2C_TypeDef *I2C) {
  •         I2C->CR1 &= ~I2C_CR1_PE; //make sure the peripheral is off
  •         /*
  •          * Analog filter enables, digital noise filter disabled
  •          * Interrupts disabled
  •          * */
  •         I2C->CR1 = 0x00; //reset
  •         I2C->CR1 |= (0x00 << I2C_CR1_ANFOFF_Pos) | (0x00 << I2C_CR1_DNF_Pos);
  •         /*
  •          * Set WRITE mode
  •          * 7-bit mode (ADD10=0)
  •          * Load 7-bit Slave Address
  •          */
  •         I2C->CR2 = 0x00; //reset
  •         I2C->CR2 |= (0x00 << I2C_CR2_RD_WRN_Pos) | (FT5336_I2C_SLAVE_ADDRESS << I2C_CR2_SADD_Pos);
  •         /*
  •          * tiMING
  •          * 100kHz I2C
  •          * */
  •         I2C->TIMINGR = 0x00; //reset
  •         I2C->TIMINGR |= (0x06 << I2C_TIMINGR_PRESC_Pos) | (0x02 << I2C_TIMINGR_SCLDEL_Pos) | (0x00 << I2C_TIMINGR_SDADEL_Pos) | (0x1E << I2C_TIMINGR_SCLH_Pos)
  •                         | (0x2A << I2C_TIMINGR_SCLL_Pos);
  •         I2C->CR1 |= I2C_CR1_PE; //activate peripheral
  • }
  • void i2c_sendByte(uint8_t data, I2C_TypeDef *I2C) {
  •         I2C->CR2 &= ~I2C_CR2_NBYTES; //make sure number of bytes to transmit is cleared
  •         I2C->CR2 |= (0x01 << I2C_CR2_NBYTES_Pos); //set number of bytes to send to 1
  •         I2C->CR2 |= I2C_CR2_AUTOEND; //stop bit after sent byte
  •         I2C->CR2 &= ~I2C_CR2_RD_WRN; //master requests write transfer
  •         while (!(I2C->ISR & I2C_ISR_TXE)); //wait while transmit data register is empty (just in case, whatever)
  •         //Slave address set in setup
  •         I2C->TXDR = data;
  •         I2C->CR2 |= I2C_CR2_START; //set start bit
  • }
  • void i2c_receiveByte(uint8_t *data, I2C_TypeDef *I2C) {
  •         I2C->CR2 &= ~I2C_CR2_NBYTES; //make sure number of bytes to transmit is cleared
  •         I2C->CR2 |= (0x01 << I2C_CR2_NBYTES_Pos); //set number of bytes to 1
  •         I2C->CR2 |= I2C_CR2_AUTOEND; //stop bit after sent byte
  •         I2C->CR2 |= I2C_CR2_RD_WRN; //master requests write transfer
  •         I2C->CR2 |= I2C_CR2_START; //set start bit
  •         while (!(I2C->ISR & I2C_ISR_RXNE)); //wait while receive data register is not empty
  •         *data = I2C->RXDR;
  • }
我实际上是如何在 main.c 中运行它的(删除了不相关的 UART 部分):
  • i2c_setup(I2C3);
  • uint8_t i2c3_id_register;
  • while (1) {
  •                 while (I2C3->ISR & I2C_ISR_BUSY);
  •                 for (uint32_t i = 0; i < 1000; i++); //lame pause
  •                 i2c_sendByte(0xA8, I2C3);
  •                 while (I2C3->ISR & I2C_ISR_BUSY);
  •                 for (uint32_t i = 0; i < 1000; i++); //lame pause
  •                 i2c_receiveByte(&i2c3_id_register, I2C3);
  •         }
截图如果来自逻辑分析器,所以我实际上看到了线上发生的物理情况,处理数据在这里不是问题。范围给出了相同的图片。我不确定我做错了什么。










回帖(1)

李海玮

2022-12-9 09:25:48
不幸的是,没有关于 FT5336 寄存器的文档,我可能可以推断出基本功能,例如如何读取一个数据点(读取寄存器 0x02 - 触摸次数),之后读取坐标寄存器,但我无法知道如何配置它 - 没有关于各种配置寄存器的作用和含义,哪些位改变什么的信息,至少不是所有的(有各种杂项寄存器)。几乎凭直觉。FT5336 的数据表在网上,但实际上除了寄存器地址本身和各个位的含义之外,它包含了所有内容。
令我惊讶的是,我在俄语论坛上找到了更多关于它的细节的信息(但还不是全部),这些论坛有时链接到晦涩的英语论坛(有时不链接)。将继续挖掘原始 ST 代码,不幸的是,它在文件之间拆分。
不过,FT5336 的数据表根本没有寄存器,这有点奇怪。
由于我非凡的谷歌搜索技能,我刚刚找到了这份文件,现在还不能全部阅读,但是有几个第一个寄存器匹配(它们的位也是如此)。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分