打印
[PIC®/AVR®/dsPIC®产品]

PIC16做从I2C时 SSP1STATbits.P==1走不到 怎么判断数据块写结束呢

[复制链接]
1387|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
本帖最后由 yhy08090 于 2019-4-4 14:17 编辑

PIC16 L18346作为从设备,需要连续的接收一个长度为N的数据块,希望传输结束的时候做一些操作,
中断处理函数if(1 == SSP1STATbits.P)判断,经过打印走不到,不清楚是否我的地方写错了,还是?我应该怎么判断整个数据块传输结束了呢?

粘贴中断处理代码:
void I2C1_ISR ( void )
{
    uint8_t     i2c_data                = 0x55;

    static uint8_t slaveWriteType   = SLAVE_NORMAL_DATA;


    PIR1bits.SSP1IF = 0;        // clear the slave interrupt flag
    i2c_data  = SSP1BUF;        // read SSPBUF to clear BF


    if(1 == SSP1STATbits.R_nW)
    {
        if((1 == SSP1STATbits.D_nA) && (1 == SSP1CON2bits.ACKSTAT))
        {
//            callback routine can perform any post-read processing
        }
        else
        {   
//            callback routine should write data into SSPBUF
        }
    }
    else if(0 == SSP1STATbits.D_nA)
    {
         slaveWriteType  = SLAVE_DATA_ADDRESS;
//        this is an I2C address
//        callback routine should prepare to receive data from the master
    }
    else if(1 == SSP1STATbits.P)
    {
    //经过打印走不到!!
    }
    else
    {
        I2C1_slaveWriteData   = i2c_data;
        switch(slaveWriteType)
        {
            case SLAVE_DATA_ADDRESS:
                eepromAddress    = I2C1_slaveWriteData;
                break;
            case SLAVE_NORMAL_DATA:
            default:
                // the master has written data to store in the eeprom
            break;
        } // end switch(slaveWriteType)
        slaveWriteType  = SLAVE_NORMAL_DATA;
//        callback routine should process I2C1_slaveWriteData from the master
    }

    SSP1CON1bits.CKP    = 1;    // release SCL
} // end I2C1_ISR()

关于SSP1STATbits相关的资料如下:
bit 7 SMP:SPI 数据输入采样位
SPI 主模式:
1 = 在数据输出时间的末尾采样输入数据
0 = 在数据输出时间的中间采样输入数据
SPI 从模式:
当SPI 工作在从模式时,必须将SMP 清零
在I2 C 主模式或从模式下:
1 = 标准速度模式下禁止压摆率控制(100 kHz 和1 MHz)
0 = 高速模式下使能压摆率控制(400 kHz)
bit 6 CKE:SPI 时钟边沿选择位(仅限SPI 模式) (1)
在SPI 主模式或从模式下:
1 = 时钟状态从有效转换到空闲时发送
0 = 时钟状态从空闲转换到有效时发送
仅在I2 C 模式下:
1 = 使能输入逻辑以使阈值符合SMBus 规范
0 = 禁止SMBus 特定输入
bit 5 D/A:数据/ 地址位(仅限I2C 模式)
1 = 指示上一个接收或发送的字节是数据
0 = 指示上一个接收或发送的字节是地址
bit 4 P:停止位(2)
(仅限I2C 模式。在MSSP 模块被禁止且SSPEN 被清零时,该位会被清零。)
1 = 指示上次检测到停止位(此位在复位时为0)
0 = 上次未检测到停止位
bit 3 S:启动位(2)
(仅限I2C 模式。在MSSP 模块被禁止且SSPEN 被清零时,该位会被清零。)
1 = 指示上次检测到启动位(此位在复位时为0)
0 = 上次未检测到启动位
bit 2 R/W:读/ 写位信息(仅限I2C 模式)
该位保存上一次地址匹配后的R/W 位信息。该位仅在从地址匹配到出现下一个启动位、停止位或非ACK 位之间有效。
在I2 C 从模式下:
1 = 读
0 = 写
在I2 C 主模式下:
1 = 正在进行发送
0 = 未进行发送
将该位与SEN、RSEN、PEN、RCEN 或ACKEN 进行逻辑或运算将指示MSSP 是否处于空闲模式。
bit 1 UA:更新地址位(仅10 位I2C 模式)
1 = 指示用户需要更新SSP1ADD 寄存器中的地址
0 = 不需要更新地址
bit 0 BF:缓冲区满状态位
接收(SPI 和I2 C 模式):
1 = 接收完成, SSP1BUF 已满
0 = 接收未完成, SSP1BUF 为空
发送(仅限I2 C 模式):
1 = 数据发送正在进行(不包括ACK 位和停止位), SSP1BUF 为满
0 = 数据发送完成(不包括ACK 位和停止位), SSP1BUF 为空
注1: 时钟状态的极性由SSP1CON 寄存器的CKP 位设置。
2: 当复位或SSPEN 被清零时,该位被清零。

STAT.png (36.08 KB )

STAT.png

使用特权

评论回复
评论
csyy 2019-7-23 15:51 回复TA
你好,我目前正在做这款单片机的I2C主模式通信,能否给点交流一下呢?刚入这行,不是很懂 
沙发
淘猫汤姆| | 2019-4-3 21:00 | 只看该作者
你太多else把判断的机会都葬送了

使用特权

评论回复
板凳
yhy08090|  楼主 | 2019-4-4 09:00 | 只看该作者
淘猫汤姆 发表于 2019-4-3 21:00
你太多else把判断的机会都葬送了

我放在最前面,也没有起效果。

使用特权

评论回复
地板
yhy08090|  楼主 | 2019-4-4 10:22 | 只看该作者
查出原因了是SSP1CON1设置的问题

使用特权

评论回复
5
oxygenzz| | 2019-4-4 11:15 | 只看该作者
yhy08090 发表于 2019-4-4 10:22
查出原因了是SSP1CON1设置的问题



了解了。
是下面的 SSPxCON1:SSPM<3:0>设置的问题吧?



使用特权

评论回复
6
yhy08090|  楼主 | 2019-4-4 13:38 | 只看该作者
本帖最后由 yhy08090 于 2019-4-8 09:24 编辑
oxygenzz 发表于 2019-4-4 11:15
了解了。
是下面的 SSPxCON1:SSPM设置的问题吧?

是的,但是我修改后还是有其他的问题:1.SSP1BUF不知道为什么总是从数据块的第二位才读,导致整体的数据块错位,而最后的一位默认到0去了。
2.不晓得是不是不应该修改SSPxCON1的设置。

使用特权

评论回复
7
dongnanxibei| | 2019-4-10 15:38 | 只看该作者
代码有点乱。

使用特权

评论回复
8
susceptibility| | 2019-4-10 16:27 | 只看该作者
中断里面尽量少放逻辑处理,最好只做标志的置位,在外面进行处理。

使用特权

评论回复
9
lcczg| | 2019-7-23 17:45 | 只看该作者
MPLAB X的MCC里看看例程

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

47

帖子

0

粉丝