问答

汇集网友智慧,解决技术难题

villivateur

TA的家园币:10  

  • 【请教】关于 PCA9555 芯片 I2C 通讯挂死的奇怪问题

    最近的项目正在使用STM32F103RC和PCA9555芯片。PCA9555芯片的port0用于监控一个4x4的矩阵键盘(故GPIO低四位是输出模式,高四位是输入模式);port1用于向外接并口显示屏写数据(故GPIO八位均为输出模式)。STM32(使用FreeRTOS)通过I2C与9555通讯(使用了STM32的I2C控制器,非GPIO模拟),400kbps速率。键盘监听和写显示屏是两个线程,通过信号量保证I2C读写不冲突。问题出现了:程序运行后,I2C必现SDA被拉低挂死,必须重置PCA9555才能恢复,但下次启动又会被挂死。奇怪的现象是,如果我把PCA9555port1的最高位初始化为输入模式,同样的代码,就不会出现任何问题。同样的,删掉键盘监听线程(或者删掉监听线程里面读I2C的部分),也不会挂死;单独删掉显示屏线程,仍然会挂死。我的代码:1.初始化键盘相关:复制voidkeyboard_gpio_init(){PCA9555_WriteByte(PCA9555_OUTPUT_PORT0,0x00);PCA9555_WriteByte(PCA9555_CONF_PORT0,0xF0);//port0iskeyboard}2.初始化显示屏相关:复制voidtmf_lcd_gpio_init(){GPIO_InitTypeDefLCD_InitStructure;RCC_APB2PeriphClockCmd(LCD_CLK,ENABLE);LCD_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;LCD_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;LCD_InitStructure.GPIO_Pin=LCD_RS|LCD_RW|LCD_E|LCD_PSB|LCD_RST;GPIO_Init(LCD_PORT,&LCD_InitStructure);PCA9555_WriteByte(PCA9555_OUTPUT_PORT1,0x00);PCA9555_WriteByte(PCA9555_CONF_PORT1,0x00);//port1islcd}注意,此处如果把最后一行的0x00改成0x80或者0xF0等等,故障均会消失。3.键盘监听的部分代码:复制staticinlineuint8_tkeyboard_get_col(void){uint8_tdata=0xff;if(PCA9555_ReadByte(PCA9555_INPUT_PORT0,&data)!=0){return0xff;}if(data&KEYBOARD_COL0){return0x00;}if(data&KEYBOARD_COL1){return0x01;}if(data&KEYBOARD_COL2){return0x02;}if(data&KEYBOARD_COL3){return0

    STM32 芯片 通讯 pc I2c LCD

    2021-07-10 0