初级会员

- 积分
- 67
- 金钱
- 67
- 注册时间
- 2019-5-14
- 在线时间
- 19 小时
|
5金钱
使用的是F407最小系统板,基于HAL库。发现在用模拟IIC接口接收数据的时候,触发串口接收中断会程序卡死。
简化后的测试程序是这样的:通过PB6(SDA), PB7(SCL)模拟IIC,连接红外传感器(MLX90640)读取数据。同时开启串口1的接收中断,直接printf接收到的数据。这样子触发接收中断(发送了“123\r\n”)就会卡死
后面有程序代码。没有修改串口1的驱动程序。
尝试了几种操作,结果如下:
1.在串口中断触发前(while循环外)读取了一次IIC数据,见程序,但是还是会卡死,感觉不像是IIC与串口中断同时发生造成的问题
2.程序卡死后,LED停止闪烁,拔掉串口线(当时串口用的串口2)后,LED恢复闪烁
3.注释掉IIC相关的代码(一次都不读取IIC),程序恢复正常
4.不修改程序,拔掉传感器,发现程序还是会卡死……
百度了一下,有关于串口接收中断异常的:【大致原因为开启了RXNE中断之后 ORE也开启了,但是使用USART_GetITStatus却无法读取到ORE的标志位(未使能ERR时),这样也无法消除中断申请,自然一直进入串口中断,如果要消除ORE需要使用USART_GetFlagStatus(USART1, USART_FLAG_ORE) ;然后再读取DR:USART_ReceiveData(USART1);就可以消除该中断请求。】
https://blog.csdn.net/gongyuan073/article/details/79436705
不知道我这种现象会不会是这种原因,还是说是IIC和串口中断冲突了?但是百度没查到这方面的资料,所以很困惑……
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "sensor_iic.h"
#include "mlx90640_api.h"
#define slaveAddr 0x33
#define RefreshRate Rate8HZ
int main(void)
{
u16 temp;
u16 i;
u16 len;
HAL_Init();
Stm32_Clock_Init(336,8,2,7);
delay_init(168);
LED2_Init();
SENSOR_IIC_Init();
uart_init(115200);
//下面是IIC操作,其实就是读了一个寄存器*********
MLX90640_I2CRead (0x33, 0x240F, 1, &temp); //后面有函数定义
delay_ms(10);
printf("temp is %d\r\n",temp);
//******************************************
while(1)
{
LED1=0;
delay_ms(200);
LED1=1;
delay_ms(300);
//usart1 test
if(USART_RX_STA&0x8000)
{
len=USART_RX_STA&0x3fff;
printf("\r\n你接收到的是:\r\n");
HAL_UART_Transmit(&UART1_Handler,(uint8_t*)USART_RX_BUF,len,1000);
printf("\r\n\r\n");
USART_RX_STA=0;
}
}
}
//用到的IIC函数**********************************
int MLX90640_I2CRead(u8 slaveAddr, u16 startAddress,u16 nMemAddressRead, u16 *data)
{
u8 sa;
int ack = 0;
int cnt = 0;
int i = 0;
char cmd[2] = {0,0};
char i2cData[1664] = {0};
u16 *p;
p = data;
sa = (slaveAddr << 1);
cmd[0] = startAddress >> 8;
cmd[1] = startAddress & 0x00FF;
SENSOR_IIC_Stop();
delay_us(2);
SENSOR_IIC_Start();
delay_us(2);
ack = SENSOR_I2CSendByte(sa)!=0;
if(ack != 0)
{
return -1;
}
ack = SENSOR_I2CSendByte(cmd[0])!=0;
if(ack != 0)
{
return -1;
}
ack = SENSOR_I2CSendByte(cmd[1])!=0;
if(ack != 0)
{
return -1;
}
SENSOR_I2CRepeatStart();
sa = sa | 0x01;
ack = SENSOR_I2CSendByte(sa);
if(ack != 0)
{
return -1;
}
SENSOR_I2CReadBytes((nMemAddressRead << 1), i2cData);
SENSOR_IIC_Stop();
for(cnt=0; cnt < nMemAddressRead; cnt++)
{
i = cnt << 1;
*p++ = (int)i2cData*256 + (int)i2cData[i+1];
}
return 0;
}
|
最佳答案
查看完整内容[请看2#楼]
解决了,应该是栈区溢出造成的。因为iic里面定义了一个很大的数组 char i2cData[1664] = {0};
感觉好像是串口中断触发的时候和原来的栈区冲突了之类的,这方面我也不是很懂。不知道有没有谁能够专业的解释一下
|