OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2625|回复: 2

STM23F407最小系统i2c与串口接收中断冲突

[复制链接]

2

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2019-5-14
在线时间
19 小时
发表于 2020-1-8 00:45:40 | 显示全部楼层 |阅读模式
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}; 感觉好像是串口中断触发的时候和原来的栈区冲突了之类的,这方面我也不是很懂。不知道有没有谁能够专业的解释一下
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

4

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2019-5-14
在线时间
19 小时
 楼主| 发表于 2020-1-8 00:45:41 | 显示全部楼层
解决了,应该是栈区溢出造成的。因为iic里面定义了一个很大的数组 char i2cData[1664] = {0};
感觉好像是串口中断触发的时候和原来的栈区冲突了之类的,这方面我也不是很懂。不知道有没有谁能够专业的解释一下
回复

使用道具 举报

31

主题

2183

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
14407
金钱
14407
注册时间
2018-8-3
在线时间
1156 小时
发表于 2020-1-8 12:21:07 | 显示全部楼层
iic 的读写是有时序要求的 如果被中断打断 肯定会有异常的  所以你在操作IIC读写操作的时候 不能有中断这些打断它
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-11 15:43

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表