I am trying to get a PIC16LF15313 to read a high on either RA1 or RA2 however it does not seem to recognize that the pins are high. I am using the PIC as a slave on an I2C bus and the Master is sending a high to the PIC for it to set up itself for I2C communication. The I2C communication is working fine, however even though the pin has a voltage of 3.15V it is not recognizing that either RA1 or RA2 is high in the code. Please see my code below. In the code I have RA2 as the input, I did this after trying to set RA1 as the input and saw that it was not working, therefore I tired RA2 and got the same problem. Both pins work fine as outputs.
Please feel free to ask anymore questions and I apologize if my mistake is trivial. I am not very experienced with Micro-controllers (I am a engineering student working on a project). Thank you so much for your time, I really do appreciate any help that you can give. Also please feel free to critique my work in any way that you see fit.
- Code: Select all
/*
* File: newmain.c
* Author: Christopher
*
* Created on January 30, 2019, 1:00 PM
*/
// CONFIG1
#pragma config FEXTOSC = OFF // External Oscillator mode selection bits (Oscillator not enabled)
#pragma config RSTOSC = HFINT32 // Power-up default value for COSC bits (HFINTOSC with OSCFRQ= 32 MHz and CDIV = 1:1)
#pragma config CLKOUTEN = OFF // Clock Out Enable bit (CLKOUT function is disabled; i/o or oscillator function on OSC2)
#pragma config CSWEN = OFF // Clock Switch Enable bit (The NOSC and NDIV bits cannot be changed by user software)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (FSCM timer enabled)
// CONFIG2
#pragma config MCLRE = ON // Master Clear Enable bit (MCLR pin is Master Clear function)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config LPBOREN = OFF // Low-Power BOR enable bit (ULPBOR disabled)
#pragma config BOREN = OFF // Brown-out reset enable bits (Brown-out reset disabled)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (VBOR) set to 1.9V on LF, and 2.45V on F Devices)
#pragma config ZCD = OFF // Zero-cross detect disable (Zero-cross detect circuit is disabled at POR.)
#pragma config PPS1WAY = OFF // Peripheral Pin Select one-way control (The PPSLOCK bit can be set and cleared repeatedly by software)
#pragma config STVREN = OFF // Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will not cause a reset)
// CONFIG3
#pragma config WDTCPS = WDTCPS_31// WDT Period Select bits (Divider ratio 1:65536; software control of WDTPS)
#pragma config WDTE = OFF // WDT operating mode (WDT Disabled, SWDTEN is ignored)
#pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)
#pragma config WDTCCS = SC // WDT input clock selector (Software Control)
// CONFIG4
#pragma config BBSIZE = BB512 // Boot Block Size Selection bits (512 words boot block size)
#pragma config BBEN = OFF // Boot Block Enable bit (Boot Block disabled)
#pragma config SAFEN = OFF // SAF Enable bit (SAF disabled)
#pragma config WRTAPP = OFF // Application Block Write Protection bit (Application Block not write protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block not write protected)
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration Register not write protected)
#pragma config WRTSAF = OFF // Storage Area Flash Write Protection bit (SAF not write protected)
#pragma config LVP = OFF // Low Voltage Programming Enable bit (High Voltage on MCLR/Vpp must be used for programming)
// CONFIG5
#pragma config CP = OFF // UserNVM Program memory code protection bit (UserNVM code protection disabled)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#define _XTAL_FREQ 4000000
#include <xc.h>
#include <pic16lf15313.h>
#include <stdio.h>
#include <stdlib.h>
short z;
void __interrupt() ISR(void)
{
if(SSP1IF == 1){
SSP1CON1bits.CKP = 0; //holds clock low
if ((!SSP1STATbits.D_nA)&&(!SSP1STATbits.R_nW)){ //If last byte was Address plus write
z = SSP1BUF; //read SSPBUF to clear BF
}
else if(SSP1STATbits.D_nA){ //If last byte received was data
z = SSP1BUF; //read SSPBUF to clear it
SSPOV = 0; //clears overflow bit
if(z == 0xFF){
PORTAbits.RA0 = 1;
}
else{
if(z == 0x00){
PORTAbits.RA0 = 0;
}
else{ //If data sent is not 0x00 or 0xFF then data being sent is the new device ID
SSP1ADD = z;
PORTAbits.RA1 = 0; //turn on enable for next device in chain
}
}
}
SSP1CON1bits.CKP = 1; //releases clock
SSPOV = 0; //clears overflow bit
SSP1IF = 0; //sets the interrupt flag back to zero
}
return;
}
void I2C_Slave_Init(short address){
TRISAbits.TRISA4 = 1; //sets clock pin (SCL) RA4 as an input
TRISAbits.TRISA5 = 1; //sets data pin (SDA) RA5 as an input
SSP1STAT = 0X00;
SSP1BUF = 0x00; //clears buffer register
SSP1ADD = address;
SSP1CON1 = 0b00110110; //Enables serial port (bit 6) and Releases clock (bit 5) and I2C save mode (bits 3 - 0)
SSP1CON2 = 0b00000000;
SSP1CON3 = 0b00000000;
GIE = 1; //enables global interrupts
PEIE = 1; //enable peripheral interrupts
SSP1IF = 0; // sets the interrupt flag for I2C is low
SSP1IE = 1; //enables I2C interrupts
return;
}
void I2C_Pin_Init(){
PPSLOCK = 0x55;
PPSLOCK = 0xAA;
PPSLOCK = 0x00; //unlock the peripheral select module
RA4PPS = 0x15; //Changes the RA4 output to SCL
RA5PPS = 0x16; //Changes the RA5 output to SDA
SSP1CLKPPS = 0x04; //Changes the SCL input pin to RA4
SSP1DATPPS = 0x05; //Changes the SDA input pin to RA5
PPSLOCK = 0x55;
PPSLOCK = 0xAA;
PPSLOCK = 0x01; //locks the peripheral select module
ANSELA = 0;
}
void main(void) {
OSCFRQ = 0x04; //sets internal oscillator to 4MHz
TRISAbits.TRISA0 = 0; //LED pin as an output
PORTAbits.RA0 = 0; //ensures LED is off
TRISAbits.TRISA1 = 0; //output for initialization
TRISAbits.TRISA2 = 1; //input for initialization
PORTAbits.RA1 = 0; //ensures that output for initialization is low
while(PORTAbits.RA2 == 0){ //wait for initialization signal
}
PORTAbits.RA1 = 1;
I2C_Pin_Init();
I2C_Slave_Init(0xFC);
while(1);
return;
}