Estoy tratando de usar una pantalla OLED con I2C, pero no pasa nada (literalmente), así que vengo aquí para ver si alguien puede arrojar algo de luz sobre lo que he hecho mal.
Mi primer enfoque fue escribir un software I2C-driver, después de leer sobre el protocolo en una aplicación de Texas Instruments, pero de alguna manera mis señales de SDA y SCL ocurrieron completamente separadas (el pulso del reloj vino después de datos). 4h de búsqueda de errores Descubrí que había 2 de 5 pines GPIO en mi PIC12F683 que estaban dañados.
En ese momento estaba harto, así que agarré un PIC16F886 con hardware-I2C, porque mi principal objetivo era usar la pantalla OLED en lugar de escribir un controlador de protocolo.
Sin embargo, ni siquiera eso funciona. En el bucle principal, enciendo / paro un LED solo para ver si el bucle se está ejecutando, y está en efecto. Esto significa, creo, que el propio I2C está funcionando (ya que tengo un bucle mientras espera el ACK, y ya está), pero la pantalla de alguna manera permanece apagada.
La pantalla es completamente nueva y no se usa, por lo que debería funcionar, pero, por supuesto, existe la posibilidad de que esté rota. El principal sospechoso aquí es mi código, sin embargo, es muy probable que yo haya olvidado algo.
Entonces, aquí está, escrito para el PIC16F886 usando el compilador XC8:
#include <xc.h>
// CONFIG1
#pragma config FOSC = INTRC_NOCLKOUT// Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF // Brown Out Reset Selection bits (BOR disabled)
#pragma config IESO = OFF // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config LVP = OFF // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)
// CONFIG2
#pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF // Flash Program Memory Self Write Enable bits (Write protection off)
#define OLED_CONTRAST 0x81
#define OLED_DISPLAY_ALL_ON_RESUME 0xa5
#define OLED_NORMAL_DISPLAY 0xa6
#define OLED_DISPLAY_ON 0xaf
#define OLED_DISPLAY_OFF 0xAE
#define OLED_ADDRESS 0b01111000
#define OLED_WRITE 0b01111000
#define OLED_READ 0b01111001
#define LED RC7
void delay() {
volatile unsigned long korv;
for (korv = 0; korv < 2*65535; korv++) {
NOP();
}
}
void init_mcu() {
OSCCON = 0b01110001; // 8MHz intosc
ANSEL = 0; // Digital I/O
ANSELH = 0;
CM1CON0 = 0; // Disable comparators
CM2CON0 = 0;
TRISA = 0;
TRISB = 0;
TRISC = 0b00011000; // SDA/SCL - inputs
SSPCONbits.SSPEN = 1; // Enable serial module
SSPCONbits.SSPM = 0b1000; // I2C-master
SSPCON2bits.RCEN = 0; // Disable receive mode
SSPADD = 4; // 8MHz Fosc -> 400kbps I2C
SSPSTATbits.SMP = 0; // Enable slew rate control for 400kHz
}
void i2c_wait() {
while (!SSPIF) {}
SSPIF = 0;
}
void i2c_start() {
SSPCON2bits.SEN = 1;
i2c_wait();
}
void i2c_stop() {
SSPCON2bits.PEN = 1;
i2c_wait();
}
void i2c_write_byte(unsigned char b) {
SSPBUF = b;
i2c_wait();
}
void oled_command(unsigned char c) {
i2c_start();
i2c_write_byte(OLED_WRITE);
i2c_write_byte(0x00); // D/C
i2c_write_byte(c);
i2c_stop();
}
void main() {
init_mcu();
while (1) {
oled_command(OLED_DISPLAY_ON);
LED = 1;
delay();
oled_command(OLED_DISPLAY_OFF);
LED = 0;
delay();
}
}
¿Hay algún error obvio con respecto al uso de I2C, lo he hecho?
ACTUALIZAR
Esquemas, foto de osciloscopio y tablero de prueba de la siguiente manera.
El alcance SDA / SCL produce 5V más o menos constante, sin pulsos en absoluto. Suponiendo que se rompió el chip, lo reemplacé con uno nuevo, uno nuevo de fábrica. Mismo error.
Estoy completamente perdido aquí.