Я новичок в микроконтроллерах и использую PIC18F4620 (ведущий) для связи с датчиком цвета TCS34725 (ведомый) и часами реального времени DS1307 (ведомый, на плате) через I2C. Прямо сейчас я испытываю какое-то вмешательство между этими двумя. Если я запускаю любой из них по отдельности, а другой не подключен к порту, то он работает нормально. Если другой подключен, даже не проинициализировавшись, то зависает в процессе чтения. Их подчиненные адреса не совпадают, поэтому я не понимаю, почему это происходит. Это код датчика цвета.
/* Initialize LCD. */
initLCD();
I2C_Master_Init(100000); //Initialize I2C Master with 100 kHz clock
while(1){
/*read the id */
I2C_Master_Start();
I2C_Master_Write(0b01010010);
I2C_Master_Write(0b10010010);
I2C_Master_RepeatedStart();
I2C_Master_Write(0b01010011);
id = I2C_Master_Read(NACK);
I2C_Master_Stop();
__delay_ms(200);
/* Configure the RGBC Time register */
I2C_Master_Start();
I2C_Master_Write(0b01010010);
I2C_Master_Write(0b10000001);
I2C_Master_Write(0);
I2C_Master_Stop();
__delay_ms(200);
/* Configure the Control register */
I2C_Master_Start();
I2C_Master_Write(0b01010010);
I2C_Master_Write(0b10001111);
I2C_Master_Write(0);
I2C_Master_Stop();
__delay_ms(200);
/* Configure the Control register */
I2C_Master_Start();
I2C_Master_Write(0b01010010);
I2C_Master_Write(0b10000000);
I2C_Master_Write(0b00001011);
I2C_Master_Stop();
__delay_ms(200);
/* Read red data */
I2C_Master_Start();
I2C_Master_Write(0b01010010);
I2C_Master_Write(0b10010110);
I2C_Master_RepeatedStart();
I2C_Master_Write(0b01010011);
tmp[0] = I2C_Master_Read(ACK);
tmp[1]= I2C_Master_Read(NACK);
I2C_Master_Stop();
__delay_ms(1000);
rC = (tmp[0])|(tmp[1]<<8);
/* Read green data */
I2C_Master_Start();
I2C_Master_Write(0b01010010);
I2C_Master_Write(0b10011000);
I2C_Master_RepeatedStart();
I2C_Master_Write(0b01010011);
tmp[0] = I2C_Master_Read(ACK);
tmp[1]= I2C_Master_Read(NACK);
I2C_Master_Stop();
__delay_ms(1000);
gC = (tmp[0])|(tmp[1]<<8);
/* Read blue data */
I2C_Master_Start();
I2C_Master_Write(0b01010010);
I2C_Master_Write(0b10011010);
I2C_Master_RepeatedStart();
I2C_Master_Write(0b01010011);
tmp[0] = I2C_Master_Read(ACK);
tmp[1]= I2C_Master_Read(NACK);
I2C_Master_Stop();
__delay_ms(1000);
bC = (tmp[0])|(tmp[1]<<8);
/* Display data on the LCD */
__lcd_home();
__lcd_clear();
printf("id: %d", id);
__delay_ms(500);
__lcd_clear();
printf("r:%u,b:%u", rC, bC);
__lcd_newline();
printf("g:%u", gC);
__delay_ms(1000);
id = 0;
rC = 0;
bC = 0;
gC = 0;
}
Это код для RTC
void main(void) {
/* Write outputs to LATx, read inputs from PORTx. Here, all latche (LATx)
* are being cleared (set low) to ensure a controlled start-up state. */
LATA = 0x00;
LATB = 0x00;
LATC = 0x00;
LATD = 0x00;
LATE = 0x00;
/* After the states of LATx are known, the data direction registers, TRISx
* are configured. 0 --> output; 1 --> input. Default is 1. */
TRISA = 0xFF; // All inputs (this is the default, but is explicated here for learning purposes)
TRISB = 0xFF;
TRISC = 0b10000000; /* RC3 is SCK/SCL (SPI/I2C),
* RC4 is SDA (I2C),
* RC5 is SDA (SPI),
* RC6 and RC7 are UART TX and RX, respectively. */
TRISD = 0x00; // All output mode on port D for the LCD
TRISE = 0x00;
/************************** A/D Converter Module **************************/
ADCON0 = 0x00; // Disable ADC
ADCON1 = 0b00001111; // Set all A/D ports to digital (pg. 222)
/* Initialize LCD. */
initLCD();
I2C_Master_Init(100000); //Initialize I2C Master with 100 kHz clock
/* Set the time in the RTC.
*
* To see the RTC keep time, comment this line out after programming the PIC
* directly before with this line included. */
RTC_setTime();
/* Declare local variables. */
unsigned char time[7]; // Create a byte array to hold time read from RTC
unsigned char i; // Loop counter
/* Main loop. */
while(1){
/* Reset RTC memory pointer. */
I2C_Master_Start(); // Start condition
I2C_Master_Write(0b11010000); // 7 bit RTC address + Write
I2C_Master_Write(0x00); // Set memory pointer to seconds
I2C_Master_RepeatedStart(); // Start condition
I2C_Master_Write(0b11010001); // 7 bit RTC address + Read
for(i = 0; i < 6; i++){
time[i] = I2C_Master_Read(ACK); // Read with ACK to continue reading
}
time[6] = I2C_Master_Read(NACK); // Final Read with NACK
I2C_Master_Stop(); // Stop condition
/* Print received data to LCD. */
__lcd_home();
printf("%02x/%02x/%02x", time[6],time[5],time[4]); // Print date in YY/MM/DD
__lcd_newline();
printf("%02x:%02x:%02x", time[2],time[1],time[0]); // HH:MM:SS
__delay_ms(1000);
}
}
void RTC_setTime(void){
/* Writes the happynewyear array to the RTC memory.*/
I2C_Master_Start(); // Start condition
I2C_Master_Write(0b11010000); //7 bit RTC address + Write
I2C_Master_Write(0x00); // Set memory pointer to seconds
/* Write array. */
for(char i=0; i<7; i++){
I2C_Master_Write(happynewyear[i]);
}
I2C_Master_Stop(); //Stop condition
}
Я не смотрел код, потому что, во-первых, это набор высокоуровневых вызовов, не показывающих, что на самом деле происходит на уровне шины.
Однако, скорее всего, это проблема с электрикой. Возможно, вторые слейвы загружают линии шины так, что что-то не работает. Вы ничего не сказали о битрейте или подтягиваниях. Это важно. Возможно, подтяжки имеют слишком высокий импеданс и/или вы пытаетесь использовать слишком высокую скорость передачи данных. Посмотрите на линии с прицелом и посмотрите, что происходит на самом деле. Удостоверьтесь, что когда каждая линия поднимается вверх, она попадает туда надежно в течение небольшого времени.
Крис Стрэттон
Жюль
софатак
софатак
Крис Стрэттон
Жюль
тусклый
Ник Алексеев
Ник Алексеев
софатак
софатак
Олин Латроп