怎么判断数据块写结束呢

[复制链接]
890|19
 楼主| chuxh 发表于 2020-11-16 20:26 | 显示全部楼层 |阅读模式
PIC16做从I2C时 SSP1STATbits.P==1走不到
tian111 发表于 2020-11-16 20:30 | 显示全部楼层

楼主详细说说怎么回事啊,这么说太笼统了
 楼主| chuxh 发表于 2020-11-16 20:33 | 显示全部楼层
PIC16 L18346作为从设备,需要连续的接收一个长度为N的数据块,希望传输结束的时候做一些操作,
中断处理函数if(1 == SSP1STATbits.P)判断,经过打印走不到,不清楚是否我的地方写错了,还是?我应该怎么判断整个数据块传输结束了呢?
zwll 发表于 2020-11-16 20:41 | 显示全部楼层

楼主程序可以公开吗?贴程序看下吧,这么说看不出什么原因
 楼主| chuxh 发表于 2020-11-16 20:44 | 显示全部楼层
中断处理代码:
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()
 楼主| chuxh 发表于 2020-11-16 20:48 | 显示全部楼层

关于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 被清零时,该位被清零。
pengf 发表于 2020-11-16 20:52 | 显示全部楼层

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
renyaq 发表于 2020-11-16 20:59 | 显示全部楼层
你太多else把判断的机会都葬送了
 楼主| chuxh 发表于 2020-11-16 21:02 | 显示全部楼层
我放在最前面,也没有起效果。
 楼主| chuxh 发表于 2020-11-16 21:05 | 显示全部楼层
查出原因了是SSP1CON1设置的问题
supernan 发表于 2020-11-16 21:09 | 显示全部楼层

了解了。
是下面的 SSPxCON1:SSPM<3:0>设置的问题吧?
liuzaiy 发表于 2020-11-16 21:12 | 显示全部楼层
 楼主| chuxh 发表于 2020-11-16 21:19 | 显示全部楼层
是的,但是我修改后还是有其他的问题
ousj 发表于 2020-11-16 21:22 | 显示全部楼层
什么问题
 楼主| chuxh 发表于 2020-11-16 21:25 | 显示全部楼层
SSP1BUF不知道为什么总是从数据块的第二位才读,导致整体的数据块错位,而最后的一位默认到0去了。
 楼主| chuxh 发表于 2020-11-16 21:29 | 显示全部楼层
不晓得是不是不应该修改SSPxCON1的设置。
hanwe 发表于 2020-11-16 21:32 | 显示全部楼层
代码有点乱。
llia 发表于 2020-11-16 21:39 | 显示全部楼层
中断里面尽量少放逻辑处理,最好只做标志的置位,在外面进行处理。
wangpe 发表于 2020-11-16 21:42 | 显示全部楼层
MPLAB X的MCC里看看例程
 楼主| chuxh 发表于 2020-11-16 21:46 | 显示全部楼层

其实还是不大明白,我再琢磨琢磨吧,多谢了哈先
您需要登录后才可以回帖 登录 | 注册

本版积分规则

936

主题

11296

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部