Application - MPR121, capacitive touch sensor controller
於 2018年8月22日 (三) 23:24 由 Tommy (對話 | 貢獻) 所做的修訂 (已建立頁面,內容為 "thumb|400px|STM32F4+MPR121+LEDs == Library pinouts == <pre> PINS PACK 1 PINS PACK 2 PINS PACK 3 PINS PACK 4 I2Cx SCL SDA SCL SDA…")
目錄
Library pinouts
PINS PACK 1 PINS PACK 2 PINS PACK 3 PINS PACK 4 I2Cx SCL SDA SCL SDA SCL SDA SCL SDA I2C1 PB6 PB7 PB8 PB9 PB6 PB9 I2C2 PB10 PB11 PF1 PF0 PH4 PH5 I2C3 PA8 PC9 PH7 PH8 I2C4 PD12 PD13 PF1 PF0 PF14 PF15 PH11 PH12
HW connection
STM32F4 -- MPR121 VCC -- VCC(3.3V) GND -- GND IRQ -- IRQ(selected) PB7 -- SDA PB8 -- SCL
I²C Slave Address Pin Selects
- Connect to VSS, VDD, SDA, SCL to choose address 0x5A, 0x5B, 0x5C, 0x5D respectively
- Default was connected to VSS (0x5A)
Timing
- I2C reg read, 0x5D = 0x24 (Default)
- IRQ, negative edge interrupt
library hacking
- The API HAL_I2C_Master_Transmit() always generate stop bit
/* Generate Stop */ //hi2c->Instance->CR1 |= I2C_CR1_STOP;
- Control stop bit and start bit in main function
I2cHandle.Instance->CR1 &= ~I2C_CR1_STOP; I2cHandle.Instance->CR1 |= I2C_CR1_START;
- The API HAL_I2C_Master_Receive() wait for busy flag until timeout
#if 0 /* Wait until BUSY flag is reset */ if(I2C_WaitOnFlagUntilTimeout(hi2c, I2C_FLAG_BUSY, SET, I2C_TIMEOUT_BUSY_FLAG) != HAL_OK) { return HAL_BUSY; } #endif
mpr121 read/write API
uint8_t mpr121Read(uint8_t reg) { uint8_t data; if(HAL_I2C_Master_Transmit(&I2cHandle,(uint16_t)I2C_ADDRESS<<1 , ®, 1, 10000) != HAL_OK) { //Todo } I2cHandle.Instance->CR1 &= ~I2C_CR1_STOP; I2cHandle.Instance->CR1 |= I2C_CR1_START; /* Receive multiple byte */ if(HAL_I2C_Master_Receive(&I2cHandle, (uint16_t)I2C_ADDRESS<<1, data, 1, 10000) != HAL_OK) { //Todo } return data; } void mpr121Write(uint8_t register_address, uint8_t data) { uint8_t d[2]; /* Format array to send */ d[0] = register_address; d[1] = data; /* Try to transmit via I2C */ if (HAL_I2C_Master_Transmit(&I2cHandle,(uint16_t)I2C_ADDRESS<<1, (uint8_t *)d, 2, 1000) != HAL_OK) { Error_Handler(); } I2cHandle.Instance->CR1 |= I2C_CR1_STOP; }
mpr121 interrupt API
Note that, the IRQ would be triggered in both pressed and released!! void EXTI3_IRQHandler(void) { uint16_t touchstatus=0; touchstatus = mpr121Read(0x01) << 8; touchstatus |= mpr121Read(0x00); if(touchstatus & 0x0001) BSP_LED_On(LED4); else BSP_LED_Off(LED4); if(touchstatus & 0x0002) BSP_LED_On(LED5); else BSP_LED_Off(LED5); if(touchstatus & 0x0004) BSP_LED_On(LED6); else BSP_LED_Off(LED6); EXTI->PR = 0x0008; //clear interrupt flag for EXTI3 GPIOE->ODR |= 0x0100; //added to show the execution of IRQ function GPIOE->ODR &= 0x0100; //end of execution, about 300ns later }