8-bit PIC (請註明使用元件編號):: PIC18F46K22 I2C讀寫問題
各位前輩好,
最近在試著寫PIC的code,
在使用I2C和外接的RTC讀寫時出了問題,
用示波器量SDA會持續pull high,SCL會持續low,
但SDA和SCL在I2C讀寫時應該要產生波形,
還請各位前輩指正。
使用的PIC是PIC18F46K22,外接RTC是DS1339,
開發工具是MPLAB X IDE v3.30,燒錄器是ICD 3,
Compiler是C18 v3.47。
以PIC18F46K22的第2組MSSP作為I2C來使用,
PIC是Master,DS1339是Slave。
以下是程式內容
#include <stdio.h>
#include <p18f46k22.h>
#include <spi.h>
#include <delays.h>
#include <i2c.h>
#include <stdlib.h>
#pragma romdata CONFIG
const rom unsigned char CONFIG1L=0xff ;
const rom unsigned char CONFIG1H=0b00001000 ;
const rom unsigned char CONFIG2L=0b00010111 ;
const rom unsigned char CONFIG2H=0b00000000 ;
const rom unsigned char CONFIG3L=0xff ;
const rom unsigned char CONFIG3H=0b10001100 ;
const rom unsigned char CONFIG4L=0b10000001 ;
const rom unsigned char CONFIG4H=0xff ;
const rom unsigned char CONFIG5L=0b00001111 ;
const rom unsigned char CONFIG5H=0b11000000 ;
const rom unsigned char CONFIG6L=0b00001111 ;
const rom unsigned char CONFIG6H=0b11100000 ;
const rom unsigned char CONFIG7L=0b00001111 ;
const rom unsigned char CONFIG7H=0b01000000 ;
#pragma romdata
void main(void)
{
char TTT[7];
PORTA = 0x0;
PORTB = 0x0;
PORTC = 0x0;
PORTD = 0x0;
PORTE = 0x0;
LATA = 0x0;
LATB = 0x0;
LATC = 0x0;
LATD = 0x0;
LATE = 0x0;
ANSELA = 0x00;
ANSELB = 0x00;
ANSELC = 0x00;
ANSELD = 0x00;
ANSELE = 0x00;
TRISA = 0x1D;
TRISB = 0xFF;
TRISC = 0xD4;
TRISD = 0x66;
TRISE = 0x0;
WPUB = 0xFF;
// SCS INTOSC; IRCF 16MHz_HFINTOSC/4; IDLEN disabled;
OSCCON = 0x72;
// PRISD enabled; SOSCGO disabled; MFIOSEL disabled;
OSCCON2 = 0x04;
// INTSRC disabled; PLLEN disabled; TUN 0;
OSCTUNE = 0x00;
// Set the secondary oscillator
// SMP End; CKE Active to Idle;
SSP1STAT = 0xC0;
// SSPEN enabled; WCOL no_collision; CKP Idle:High, Active:Low; SSPM FOSC/64; SSPOV no_overflow;
SSP1CON1 = 0x32;
// SSP1ADD 0;
SSP1ADD = 0x00;
//I2C
SSP2STAT = 0xC0;
SSP2CON1 = 0x28;
SSP2CON2 = 0x00;
SSP2ADD = 0x19; //19:100kHz Baud clock
INTCON = 0;
PIE1 = 0;
IPR1 = 0;
PIR1 = 0;
PIE2 = 0;
IPR2 = 0;
PIR2 = 0;
RCONbits.IPEN = 1;
INTCONbits.PEIE = 1;
INTCONbits.GIE = 1;
while(1){
//Write Part
OpenI2C2(MASTER, SLEW_OFF); // PIC is master, SLEW_OFF for 100 kHz communication
IdleI2C2();
StartI2C2(); // Send START condition
IdleI2C2();
putcI2C2( 0xD0 ); // Send address with R/W cleared for write (11010000); 0xd0: 7-bit DS1339 address, which is 1101000
IdleI2C2();
putcI2C2( 0x00 ); // Write word address (00h is seconds)
IdleI2C2();
putcI2C2( 0x15 ); // Write second : 15 second
IdleI2C2();
putcI2C2( 0x21 ); // Write minute : 21 minute
IdleI2C2();
putcI2C2( 0x16 ); // Write hour : 16 hour
IdleI2C2();
putcI2C2( 0x02 ); // Write day : 2 day(Tuesday)
IdleI2C2();
putcI2C2( 0x31 ); // Write date : 31 date
IdleI2C2();
putcI2C2( 0x05 ); // Write month : 5 month
IdleI2C2();
putcI2C2( 0x16 ); // Write year : 2016 year
IdleI2C2();
StopI2C2();
//Read Part
StartI2C2(); // Send START condition
IdleI2C2();
putcI2C2( 0xD1 ); // Send address with R/W cleared for write (11010000); 0xd0: 7-bit DS1339 address, which is 1101000
IdleI2C2();
TTT[0] = getcI2C2(); // Read second (00h)
IdleI2C2();
TTT[1] = getcI2C2(); // Read minute (01h)
IdleI2C2();
TTT[2] = getcI2C2(); // Read hour (02h)
IdleI2C2();
TTT[3] = getcI2C2(); // Read day (03h)
IdleI2C2();
TTT[4] = getcI2C2(); // Read date (04h)
IdleI2C2();
TTT[5] = getcI2C2(); // Read month (05h)
IdleI2C2();
TTT[6] = getcI2C2(); // Read year (06h)
IdleI2C2();
NotAckI2C2();
IdleI2C2();
StopI2C2();
}
}