打印

问个iic配置的问题(已解决)

[复制链接]
3827|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
iversonma|  楼主 | 2009-8-13 14:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 iversonma 于 2009-8-14 09:05 编辑

采用的是PIC18F65J10系列,使用MSSP1作为IIC主设备读取RTC的数据,但是目前存在的问题是无论做任何操作,IIC的SSP1IF中断位都没有置位,同时用示波器测量IIC总线,也找不到任何的变化,一直都是高电平~基本可以确认是配置的问题,但是IIC前配置就那么几个位,实在是找不到了,麻烦各位帮忙看看~第一次使用PIC的东东,有些东西不太了解。

IIC配置相关的几个地方

1. 相关引脚配置为输入“1”,
2.SSP1CON1配置为0x28(SSPEN为1,SSPM3--0为“1000”)
3. iic总线速度配置,外接时钟为8M,因此配置SSP1ADD为0x13,转为10进制为19,计算可得到IIC总线速度为100k

后续就可以直接发送start信号了~



附上程序:

void main(void)
{

    // configure USART
    keyboard_init();
    uart_232_init();
    LED_CLEAN();
   
    I2C1_Init();
   
    do
    {
        I2C1_Start();
        I2C1_SendByte(0xa3);
        
        for(n=0;n<19;n++)
        {
            arrayrd[n] = I2C1_GetByte();
        }
        I2C1_Stop();
        Delay100TCYx(10);
        
        for(n=0;n<19;n++)
        {
            Write1USART(n);
            Write1USART(arrayrd[n]);
            Delay10KTCYx(1);
            Write1USART(iic_value1);
            Delay10KTCYx(1);
            Write1USART(iic_value2);
            Delay10KTCYx(100);
        }
        Delay10KTCYx(10000);
    }
    while(1);
   
}

void I2C1_Init( void )
{

    TRISCbits.TRISC3 = 1;
    TRISCbits.TRISC4 = 1;
   
                 // Slew rate control enable for high speed mode(400kHz)
    SSP1CON1=0x28; //SSPEN=1 and SSPM3:SSPM0=1000
    SSP1ADD= 0x4f;                        //8Mhz cystall, 100khz
    Delay100TCYx(10);
}

void I2C1_Start( void )
{
    unsigned int i;

    SSP1CON2bits.SEN = 1;            // initiate bus start condition
    iic_value1 = SSP1CON2;
    iic_value2 = PIR1;
    for ( i=I2C_TIMEOUT; i; i-- ) {    // this is about 1ms timeout
        if ( PIR1bits.SSP1IF )
            break;
    }
   
    PIR1bits.SSP1IF = 0;  
}

void I2C1_Stop( void )
{
    unsigned int i;
   
    SSP1CON2bits.PEN = 1;

    for ( i=I2C_TIMEOUT; i; i-- ) {    // this is about 1ms timeout
        if (PIR1bits.SSP1IF)
            break;
    }
    PIR1bits.SSP1IF = 0;
}

unsigned char I2C1_ReadAck( void )
{
    unsigned int i;
   
    for ( i=I2C_TIMEOUT; i; i-- ) {    // this is about 1ms timeout
        if (!SSP1CON2bits.ACKSTAT) {
            return 1;
        }
    }
    return 0;
}

void I2C1_SendByte( unsigned char u8_data )
{
    unsigned int i;
   
    SSP1BUF = u8_data;

//    I2C2_ReadAck();
    for ( i=I2C_TIMEOUT; i; i-- ) {    // this is about 1ms timeout
        if (PIR1bits.SSP1IF) {
            break;
        }
    }
    PIR1bits.SSP1IF = 0;
    I2C1_ReadAck();
    PIR1bits.SSP1IF = 0;
}

unsigned char I2C1_GetByte( void )
{
    unsigned int i;
   
    SSP1CON2bits.RCEN = 1;
    for ( i=I2C_TIMEOUT; i; i-- ) {    // this is about 1ms timeout
        if ( SSP1STATbits.BF ) {
            break;
        }
    }
    PIR1bits.SSP1IF = 0;

    return SSP1BUF;
}

void I2C1_SendACK( void )
{
    unsigned int i;
   
    SSP1CON2bits.ACKEN = 1;
    for ( i=I2C_TIMEOUT; i; i-- ) {    // this is about 1ms timeout
        if ( SSP1CON2bits.ACKEN == 0 ) {
            break;
        }
    }
    PIR1bits.SSP1IF = 0;
}


void I2C1_SendNotACK( void )
{
    SSP1CON2bits.ACKDT = 1;
    I2C1_SendACK();
}

void Restart_I2C1( void )
{
    SSP1CON2bits.RSEN = 1;           // initiate bus restart condition
    while(!PIR1bits.SSP1IF);                // Completed the action when the SSPIF is Hi.
    PIR1bits.SSP1IF=0;  
}
沙发
iversonma|  楼主 | 2009-8-13 14:34 | 只看该作者
程序结构并不是很麻烦,熟悉pic结构的各位大侠帮忙看看,硬件配置上面应该是没有问题,外围接的是一个RTC的芯片,因为读写不对,所以才简单写了上面一个程序,只是想测试一个iic总线上面是否有跳变。

说说目前的状态,在start以后,按照资料上面的解释,应该在一个IIC总线周期以内SSPIF中断标志位置位,但是一直检测不到这个信号,所以才由此确定是配置的问题,但是实在找不到那里还需要再配置。打印相关的配置寄存器值也没有问题,可以确保配置值已经正确的写入。

使用特权

评论回复
板凳
iversonma|  楼主 | 2009-8-13 18:24 | 只看该作者
问题解决了~

两个原因~
1.timeout值太小,因为iic失踪比较低,在等待sspif的时候每次都是超时推出
2,示波器trigger设置触发条件过于严格,硬件板子上面信号不好,导致检测不到信号,修改阈值后解决。

谢谢各位了

使用特权

评论回复
地板
深渊叹息| | 2012-3-24 11:14 | 只看该作者
发送启动位的时候,我是通过查询SSPCON2的SEN位也就是启动条件使能位,来判断启动位是否发送完毕,停止位以及重复启动位也是采用同样的方法

使用特权

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

本版积分规则

17

主题

325

帖子

1

粉丝