ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Среда
24 апреля
273971
fk0, легенда (22.09.2011 20:17 - 20:24, просмотров: 2335)
PIC24FJ256GA108. I2C2. @#$%$#@!! @#$!!! @$#@$#@$!!! Устанавливает BCL в регистре статуса на первом start condition (который сам же и формирует). Если такое случилось (зависит от фазы луны и погоды на марсе, чаще не случается при первом включении питания) -- перестанет работать до длительного сброса или же длительного отключения питания (короткое -- не помогает). Зависит от наличия осциллографа и чёрт знает чего ещё. На microchip.com/forum много разного шаманства. Предлагаю свой метод лечения, если вкратце: вначале включить I2C2 модуль (в регистр I2C2CON), потом сделать софтрезет (старт, 9 клоков, стоп). А не наоборот. Помогает. Выделено цветным:
static int_fast8_t i2c_wait(void)
{
ftime_t t;
        t=timer();
        do {
                if (I2C2STATbits.BCL) {
                        /* collision */
                        i2c_fail=I2C_FAIL_COLL;
                        return -1;
                }
        
                if ((I2C2CON & 0x1f)==0 && I2C2STATbits.TRSTAT==0)
                        /* finished ok */
                        return 0;
        
        } while (timer() - t < (ftime_t)(10L*FTIME_PER_SEC/1000));
        
        /* timeout! */
        i2c_fail=I2C_FAIL_TO;
        return -1;
}       


static inline int_fast8_t i2c_start(void)
{       
        I2C2CONbits.SEN=1;
        return i2c_wait();
}                       
        

static inline int_fast8_t i2c_stop(void)
{
        I2C2CONbits.PEN=1;
        return i2c_wait();
}


int i2c_init(void)
{
unsigned n;
        TRISAbits.TRISA15=1, TRISAbits.TRISA14=1;
        CNPU3bits.CN43PUE=1, CNPU3bits.CN44PUE=1;
КЛЮЧЕВОЙ МОМЕНТ: I2C2CON=0; /* 400KHz rate, enable I2C */ I2C2STAT=0; I2C2BRG=F_OSC/2/400000 - F_OSC/2/10000000 - 1; I2C2CON=1<<15; /* Bus reset -- start, 9 clocks, stop */ LATAbits.LATA15=0, LATAbits.LATA14=0; TRISAbits.TRISA15=0; /* START (SDA=0) */ i2c_delay(); TRISAbits.TRISA14=0; /* SCL=0 */ i2c_delay(); TRISAbits.TRISA15=1; /* SDA=1 */ n=9; do { i2c_delay(); TRISAbits.TRISA14=1; /* SCL=1 */ i2c_delay(); TRISAbits.TRISA14=0; /* SCL=0 */ } while(--n); i2c_delay(); TRISAbits.TRISA15=0; /* STOP (SDA=0) */ i2c_delay(); TRISAbits.TRISA14=1; /* SCL=1 */ i2c_delay(); TRISAbits.TRISA15=1; /* SDA=1 */ i2c_delay(); i2c_fail=0; i2c_start(); i2c_stop();
        if (!i2c_fail) return 0;
        else return -1;
}
[ZX]