Actualmente estoy probando el MCP23017 (dispositivo esclavo) Expansor de E / S de 16 bits usando un PIC18F45K20 con el compilador C18 para transmitir datos al MCP23017. Los pines de dirección (A0, A1 y A2) del MCP23017 están conectados a tierra. El reloj serie (SCL) se ejecuta a 100kHz.
Verifiqué el código de mi programa de pies a cabeza y no pude encontrar ningún problema en mi código a pesar de que se compiló sin error.
Los problemas que enfrenté son:
-
El MCP23017 no genera los datos transmitidos desde el PIC18F45K20 (el código del programa se muestra a continuación).
-
La forma de onda SCL de PIC18F45K20 no es una onda cuadrada. Se midió utilizando un osciloscopio
#include <stdio.h> #include <stdlib.h> #include <delays.h> #include <i2c.h> #include <p18f45k20.h> #include <sw_i2c.h> #define MCP_IODIR_A 0x00 #define MCP_IPOL_A 0x02 #define MCP_OLAT_A 0x14 #define MCP_GPIO_A 0x12 #define MCP_IOCON_A 0x0A #define MCP_GPINTEN_A 0x04 /* * */ //----------------------------Global variable---------------------------- // PIC18F45K20 Configuration Bit Settings // CONFIG1H #pragma config FOSC = INTIO67 // Oscillator Selection bits (Internal oscillator block, port function on RA6 and RA7) #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled) #pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled) // CONFIG2L #pragma config PWRT = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config BOREN = SBORDIS // Brown-out Reset Enable bits (Brown-out Reset enabled in hardware only (SBOREN is disabled)) #pragma config BORV = 30 // Brown Out Reset Voltage bits (VBOR set to 3.0 V nominal) // CONFIG2H #pragma config WDTEN = OFF // Watchdog Timer Enable bit (WDT is controlled by SWDTEN bit of the WDTCON register) #pragma config WDTPS = 32768 // Watchdog Timer Postscale Select bits (1:32768) // CONFIG3H #pragma config CCP2MX = PORTC // CCP2 MUX bit (CCP2 input/output is multiplexed with RC1) #pragma config PBADEN = ON // PORTB A/D Enable bit (PORTB<4:0> pins are configured as analog input channels on Reset) #pragma config LPT1OSC = OFF // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation) #pragma config HFOFST = ON // HFINTOSC Fast Start-up (HFINTOSC starts clocking the CPU without waiting for the oscillator to stablize.) #pragma config MCLRE = OFF // MCLR Pin Enable bit (RE3 input pin enabled; MCLR disabled) // CONFIG4L #pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset) #pragma config LVP = OFF // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled) #pragma config XINST = OFF // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode)) // CONFIG5L #pragma config CP0 = OFF // Code Protection Block 0 (Block 0 (000800-001FFFh) not code-protected) #pragma config CP1 = OFF // Code Protection Block 1 (Block 1 (002000-003FFFh) not code-protected) #pragma config CP2 = OFF // Code Protection Block 2 (Block 2 (004000-005FFFh) not code-protected) #pragma config CP3 = OFF // Code Protection Block 3 (Block 3 (006000-007FFFh) not code-protected) // CONFIG5H #pragma config CPB = OFF // Boot Block Code Protection bit (Boot block (000000-0007FFh) not code-protected) #pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected) // CONFIG6L #pragma config WRT0 = OFF // Write Protection Block 0 (Block 0 (000800-001FFFh) not write-protected) #pragma config WRT1 = OFF // Write Protection Block 1 (Block 1 (002000-003FFFh) not write-protected) #pragma config WRT2 = OFF // Write Protection Block 2 (Block 2 (004000-005FFFh) not write-protected) #pragma config WRT3 = OFF // Write Protection Block 3 (Block 3 (006000-007FFFh) not write-protected) // CONFIG6H #pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected) #pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block (000000-0007FFh) not write-protected) #pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected) // CONFIG7L #pragma config EBTR0 = OFF // Table Read Protection Block 0 (Block 0(000800-001FFFh) not protected from table reads executed in other blocks) #pragma config EBTR1 = OFF // Table Read Protection Block 1 (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks) #pragma config EBTR2 = OFF // Table Read Protection Block 2 (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks) #pragma config EBTR3 = OFF // Table Read Protection Block 3 (Block 3 (006000-007FFFh) not protected from table reads executed in other blocks) // CONFIG7H #pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot Block (000000-0007FFh) not protected from table reads executed in other blocks) void init_I2C() { DDRCbits.RC3 = 1; //Configure SCL as input DDRCbits.RC4 = 1; //Configure SDA as input // SSPSTAT Configuration (0x80) SSPSTATbits.SMP = 1; //Slew rate control disabled SSPSTATbits.CKE = 0; //SMBus disabled SSPSTATbits.D_A = 0; //Reserved in master mode SSPSTATbits.P = 0; //Stop bit was not detected last SSPSTATbits.S = 0; //Start bit was not detected last SSPSTATbits.R_W = 0; SSPSTATbits.UA = 0; //Address doesnot need to be updated SSPSTATbits.BF = 0; // SSPCON1 Configuration (0x28) SSPCON1bits.WCOL = 0; SSPCON1bits.SSPOV = 0; SSPCON1bits.SSPEN = 1; //Serial port enabled SSPCON1bits.CKP = 0; //Holds clock low SSPCON1bits.SSPM3 = 1; //1000 = I2C Master mode SSPCON1bits.SSPM2 = 0; //BitRate = FOSC/(4*(SPPADD+1)) SSPCON1bits.SSPM1 = 0; SSPCON1bits.SSPM0 = 0; // SSPADD Configuration SSPADD = 0x27; //should be 0x27 for 100kHz //SSPADD = [(FOSC/BitRate)/4]-1 // SSPCON2 Configuration (0x00) SSPCON2bits.GCEN = 0; //General call address disabled SSPCON2bits.ACKSTAT = 0; //Acknowledge was received from slave SSPCON2bits.ACKDT = 0; //Acknowledge SSPCON2bits.ACKEN = 0; //Acknowledge sequence idle SSPCON2bits.RCEN = 0; //Receive idle SSPCON2bits.PEN = 0; //Stop condition idle SSPCON2bits.RSEN = 0; //Repeated start condition idle SSPCON2bits.SEN = 0; } void MCP_write() { WriteI2C(0x40); } void MCP_read() { WriteI2C(0x41); } void MCP_addr() { StartI2C(); MCP_write(); } void init_MCP() { //IODIR A configuration MCP_addr(); AckI2C(); WriteI2C(MCP_IODIR_A); AckI2C(); WriteI2C(0x00); StopI2C(); //IPOL A configuration MCP_addr(); AckI2C(); WriteI2C(MCP_IPOL_A); AckI2C(); WriteI2C(0x00); StopI2C(); //OLAT A configuration MCP_addr(); AckI2C(); WriteI2C(MCP_OLAT_A); AckI2C(); WriteI2C(0xFF); StopI2C(); //IOCON A configuration MCP_addr(); AckI2C(); WriteI2C(MCP_IOCON_A); AckI2C(); WriteI2C(0x00); StopI2C(); //GPINTEN A configuration MCP_addr(); AckI2C(); WriteI2C(MCP_GPINTEN_A); AckI2C(); WriteI2C(0x00); StopI2C(); } //----------------------------Main program---------------------------- void main(void) { OSCCON = 0x70; //Set internal oscillation to 16 MHz TRISD=0; init_I2C(); //I2C initialization init_MCP(); //MCP23017 initialization while(1) { MCP_addr(); AckI2C(); WriteI2C(MCP_GPIO_A); AckI2C(); WriteI2C(0x11); StopI2C(); } }