PIC24FJ256GA108. I2C2. @#$%$#@!! @#$!!! @$#@$#@$!!! Устанавливает BCL в регистре статуса на первом start condition (который сам же и формирует). Если такое случилось (зависит от фазы луны и погоды на марсе, чаще не случается при первом включении питания) -- перестанет работать до длительного сброса или же длительного отключения питания (короткое -- не помогает). Зависит от наличия осциллографа и чёрт знает чего ещё. На microchip.com/forum много разного шаманства. Предлагаю свой метод лечения, если вкратце: вначале включить I2C2 модуль (в регистр I2C2CON), потом сделать софтрезет (старт, 9 клоков, стоп). А не наоборот. Помогает. Выделено цветным:
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();
[ZX]
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;КЛЮЧЕВОЙ МОМЕНТ:
if (!i2c_fail) return 0; else return -1; }
-
- Ё! И как быть с серийным изделием? - Make_Pic(04.10.2011 07:45)