PIC18F4520 internal EEprom data is gone after power off and on - pic

I have some difficulty with EEprom. Any help is highly appreciated.
I am using MPLABX ide with XC8 v2.10 compiler. I wrote a simple code that gets some text message content (Up to 50 characters) via UART and write them to EEprom for later use. I am attaching the code below.
This is my main code.
#include <xc.h>
#include <string.h>
#include <pic18f4520.h>
#include <stdio.h>
#include <stdlib.h>
#include "config.h"
#include "uart.h"
#include "EEPROM_RW.h"
#define LED PORTDbits.RD0
#define Buzzer PORTBbits.RB0
#include <xc.h>
void Configuration();
void Timer_IE();
void Timer_ID();
void UART_Flush();
int ADC_Read(int Ch);
unsigned char UART_RX[100]='\r';
unsigned char UART_Dummy=0,loop_pointer=0,EE_Pointer=0,EE_Dummy;
int counter=0;
bit LED_Blink=0,Modem_Attached=0,UART_Data_Ready;
void main(void) {
Configuration();
Timer_IE();
LED=0;
Buzzer=0;
UART_Close();
UART_Open(9600);
UART_Flush();
while(1){
if(Modem_Attached==0){
LED_Blink=1;
if(UART_Data_Ready==1){
for(UART_Dummy=0;UART_Dummy<=99;UART_Dummy++){
if(UART_RX[UART_Dummy]=='O'){
if(UART_RX[UART_Dummy+1]=='K'){
Modem_Attached=1;
UART_Data_Ready=0;
UART_Flush();
}
}
if(UART_RX[UART_Dummy]=='A'){
if(UART_RX[UART_Dummy+1]=='T'){
if(UART_RX[UART_Dummy+2]=='+'){
loop_pointer=UART_Dummy+3;
EE_Pointer=205;
while(1){
if(UART_RX[loop_pointer]=='\0'){
EEPROM_WriteByte(EE_Pointer,UART_RX[loop_pointer]);
loop_pointer=0;
EE_Pointer=0;
UART_Write("Alarm Text Saved\r");
UART_Data_Ready=0;
UART_Flush();
break;
}
else{
EEPROM_WriteByte(EE_Pointer,UART_RX[loop_pointer]);
loop_pointer++;
EE_Pointer++;
}
if(EE_Pointer==255){
UART_Write("Alarm Text is too long\r");
EE_Pointer=0;
UART_Data_Ready=0;
UART_Flush();
break;
}
}
}
if(UART_RX[UART_Dummy+2]=='?'){
EE_Pointer=205;
UART_Write("Alarm Text = ");
while(1){
EE_Dummy=EEPROM_ReadByte(EE_Pointer);
if(EE_Dummy!='\0'){
UART_Write_Byte(EE_Dummy);
EE_Pointer++;
}
else{
EE_Pointer=0;
UART_Data_Ready=0;
UART_Flush();
break;
}
if(EE_Pointer==255){
UART_Data_Ready=0;
UART_Flush();
break;
}
}
UART_Write_Byte('\r');
}
}
}
}
}
}
if(Modem_Attached==1){
LED_Blink=0;
LED=0;
}
}
return;
}
void Configuration()
{
//setting the Oscillator Freq. 8MHz
OSCCONbits.IRCF0=1;
OSCCONbits.IRCF1=1;
OSCCONbits.IRCF2=1;
//ADC Module Settings
ADCON0=0x00;
ADCON1=0b00001010;
ADCON2=0b10010000;
//Timer 0 Interrupt Parameters
T0CONbits.T08BIT=1;
T0CONbits.T0CS=0;
T0CONbits.PSA=1;
TRISD=0x00;
TRISBbits.RB0=0;
}
void Timer_IE()
{
INTCONbits.GIE=1;
INTCONbits.TMR0IE=1;
T0CONbits.TMR0ON=1;
}
void Timer_ID()
{
INTCONbits.TMR0IE=0;
T0CONbits.TMR0ON=0;
}
void UART_Flush()
{
unsigned char dummy, i;
dummy=UART_RX[0];
i=0;
while(dummy!=0){
UART_RX[i]=0;
dummy=UART_RX[i+1];
i++;
}
UART_RX[i+1]=0;
i=0;
}
int ADC_Read(int Ch)
{
if(Ch==0)
ADCON0=0x03;
else if(Ch==1)
ADCON0=0x07;
else if(Ch==2)
ADCON0=0x0B;
else if(Ch==3)
ADCON0=0x0F;
else if(Ch==4)
ADCON0=0x13;
else
return 0;
while(GODONE);
ADON=0;
return ADRES;
}
__interrupt (low_priority) void tmr0(void)
{
if(INTCONbits.TMR0IF == 1){
INTCONbits.TMR0IF = 0;
if(Modem_Attached==0){
counter++;
}
else{
counter=0;
}
}
if(counter>=15000){
counter=0;
if(Modem_Attached==0){
UART_Write("ATZ\r");
}
if(LED_Blink==1){
if(LED==0)
LED=1;
else
LED=0;
}
}
if(UART_RX_Ready()==1){
Timer_ID();
UART_Read_kemal(&UART_RX);
UART_Data_Ready=1;
Timer_IE();
}
}
This is the EEPROM_RW.h
unsigned char EEPROM_ReadByte(unsigned char eepromAddress)
{
EECON1bits.CFGS=0;
while(EECON1bits.RD || EECON1bits.WR); // check the WR&RD bit to see if a RD/WR is in progress
EEADR=eepromAddress; // Write the address to EEADR.
EECON1bits.RD = 1; // Set the RD bit to trigger the eeprom read operation.
return(EEDATA); // Return the data read form eeprom.
}
void EEPROM_WriteByte(unsigned char eepromAddress, unsigned char eepromData)
{
signed char gie_Status;
while(EECON1bits.WR==1); // check the WR bit to see if a previous Write operation is in progress
EEADR=eepromAddress; // Write the address to EEADR.
EEDATA=eepromData; // load the 8-bit data value to be written in the EEDATA register.
EECON1bits.EEPGD = 0; // select "EEPROM"
EECON1bits.CFGS = 0; // not the config-registers
EECON1bits.WREN = 1;
gie_Status = GIE; // Copy the current Interrupt state
GIE = 0; // Disable the interrupts
EECON2=0x55; // Execute the special instruction sequence
EECON2=0xaa; // Refer the datasheet for more info
EECON1bits.WR=1; // Set the WR bit to trigger the eeprom write operation.
while(EECON1bits.WR==1);
PIR2.EEIF = 0;
EECON1bits.WREN = 0;
GIE = gie_Status; // Restore the interrupts
}
this is Configuration bits.
// PIC18F4520 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1H
#pragma config OSC = 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 = ON // Power-up Timer Enable bit (PWRT enabled)
#pragma config BOREN = ON // Brown-out Reset Enable bits (Brown-out Reset enabled and controlled by software (SBOREN is enabled))
#pragma config BORV = 3 // Brown Out Reset Voltage bits (Minimum setting)
// CONFIG2H
#pragma config WDT = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#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 = OFF // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config LPT1OSC = OFF // Low-Power Timer1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = OFF // MCLR Pin Enable bit (RE3 input pin enabled; MCLR disabled)
// CONFIG4L
#pragma config STVREN = OFF // Stack Full/Underflow Reset Enable bit (Stack full/underflow will not 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 bit (Block 0 (000800-001FFFh) not code-protected)
#pragma config CP1 = OFF // Code Protection bit (Block 1 (002000-003FFFh) not code-protected)
#pragma config CP2 = OFF // Code Protection bit (Block 2 (004000-005FFFh) not code-protected)
#pragma config CP3 = OFF // Code Protection bit (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 bit (Block 0 (000800-001FFFh) not write-protected)
#pragma config WRT1 = OFF // Write Protection bit (Block 1 (002000-003FFFh) not write-protected)
#pragma config WRT2 = OFF // Write Protection bit (Block 2 (004000-005FFFh) not write-protected)
#pragma config WRT3 = OFF // Write Protection bit (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 bit (Block 0 (000800-001FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (002000-003FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF // Table Read Protection bit (Block 2 (004000-005FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF // Table Read Protection bit (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)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>

Related

CAN transmission is working, but not the listening part

We are using Sparkfun CAN shield and Arduino Uno to build a CAN network. We are observing the data in CAN network using KVaser Canking. When we send a data to the CAN bus, we can see the data in KVaser window. But, when we try to read something from the CAN bus, it is showing garbage values. Note that 120 ohm is also there. Here is the code:
`
#include <Canbus.h>
#include <defaults.h>
#include <global.h>
#include <mcp2515.h>
#include <mcp2515_defs.h>
//********************************Setup Loop*********************************//
void setup() {
Serial.begin(115200);
Serial.println("CAN Write - Testing transmission of CAN Bus messages");
delay(1000);
if(Canbus.init(CANSPEED_250)) //Initialise MCP2515 CAN controller at the specified speed
Serial.println("CAN Init ok");
else
Serial.println("Can't init CAN");
delay(1000);
}
unsigned long now=0, prev=0;
void loop() {
mcp2515_bit_modify(CANCTRL, (1<<REQOP2)|(1<<REQOP1)|(1<<REQOP0), 0);
tCAN message; // message read from the bus
tCAN amessage;
// Attack message details
amessage.id = 0x631; //formatted in HEX
amessage.header.rtr = 0;
amessage.header.length = 8; //formatted in DEC
amessage.data[0] = 0x00;
amessage.data[1] = 0x00;
amessage.data[2] = 0x00;
amessage.data[3] = 0x00; //formatted in HEX
amessage.data[4] = 0x00;
amessage.data[5] = 0x00;
amessage.data[6] = 0x00;
amessage.data[7] = 0x00;
while(! mcp2515_check_message()){
}
if(mcp2515_get_message(&message) and message.id==0x630){ //wait for target message on the bus
amessage.id = 0x630;
mcp2515_send_message(&amessage);//this is not working
Serial.println("Sending attack message");//this is not working
}
auto error_tec = mcp2515_read_register(TEC);
Serial.print("TEC Count of adversary : "); //this is working
Serial.println(error_tec); //this is working
}
Can some one help how to resolve this?

I2c Slave data PIC MPLAB X

I am trying to migrate from PIC16F886 to PIC18F24K40 . NOw here I am trying to communicate PIC18F24K40 with DS1307 and Display it on 4 Segment Display. I have tested my code on PIC16F886 but not worked on PIC18F24K40 . SInce PIC18F24K40 uses MPLAB X ide and creates MCC code configuration based I2c c file and .h file . Can someone suggest what wrong done i have done in below code
I could not able to update time once written.
/**
Generated Main Source File
Company:
Microchip Technology Inc.
File Name:
main.c
Summary:
This is the main file generated using MPLAB(c) Code Configurator
Description:
This header file provides implementations for driver APIs for all modules selected in the GUI.
Generation Information :
Product Revision : MPLAB(c) Code Configurator - 4.15
Device : PIC18F24K40
Driver Version : 2.00
The generated drivers are tested against the following:
Compiler : XC8 1.35
MPLAB : MPLAB X 3.40
*/
/*
(c) 2016 Microchip Technology Inc. and its subsidiaries. You may use this
software and any derivatives exclusively with Microchip products.
THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
PARTICULAR PURPOSE, OR ITS INTERACTION WITH MICROCHIP PRODUCTS, COMBINATION
WITH ANY OTHER PRODUCTS, OR USE IN ANY APPLICATION.
IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN
ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF THESE
TERMS.
*/
#include "mcc_generated_files/mcc.h"
#include "mcc_generated_files/i2c1.h"
uint8_t status;
#define DS1307_RETRY_MAX 100 // define the retry count
#define Ds1307_ADDRESS 0xD0 // slave device address
#define RTC_addres 0x68 // RTC slave device address
//static unsigned char readI2C[10], writeI2C[4];
#define buffersize 20
static unsigned char writeBuffer[buffersize]; //Buffer for I2C writing.
static unsigned char readbuffer[buffersize]; // Buffer for I2C reading.
uint8_t second;
uint8_t start_addres;
uint8_t length;
//I2C1_MESSAGE_STATUS w_status;
uint8_t sourceData[] = {0x1A, 0x2A, 0x4A, 0x8A,0x1A, 0x2A, 0x4A, 0x8A,0x1A, 0x2A, 0x4A, 0x8A,0x1A, 0x2A, 0x4A, 0x8A};
uint8_t addressBuffer[] = {0xAB,0x10} ; //Put your address here
uint8_t readBuffer[16];
uint8_t readByte;
# define LED RC7
unsigned int i;
unsigned int count;
unsigned int x;
unsigned short sec;
unsigned short min;
unsigned short hour;
unsigned short date;
unsigned short month;
unsigned short year;
unsigned short day;
unsigned short int temp=0;
unsigned short r_data;
#define Seg1 0x01
#define Seg2 0x02
#define Seg3 0x04
#define Seg4 0x08
#define Seg5 0x10
#define Seg6 0x20
unsigned short int cnt, num,Dgt=0;;
unsigned short int temp1,temp2,temp3;
void Delay(int k)
{
for(i=0;i<=k;i++);
}
void Blink_LED()
{
LED=!LED;
Delay(10000);
}
void SetSeg(unsigned short data, unsigned short segno)
{
switch(data)
{
case 0: PORTB = 0x3F; break;
case 1: PORTB = 0x06; break;
case 2: PORTB = 0x5B; break;
case 3: PORTB = 0x4F; break;
case 4: PORTB = 0x66; break;
case 5: PORTB = 0x6D; break;
case 6: PORTB = 0x7D; break;
case 7: PORTB = 0x07; break;
case 8: PORTB = 0x7F; break;
case 9: PORTB = 0x6F; break;
default : PORTB = 0X00; break;
}
if(segno==1)
{
PORTA = Seg4;
}
if(segno==2)
{
PORTA = Seg3;
}
if(segno==3)
{
PORTA = Seg2;
}
if(segno==4)
{
PORTA = Seg1;
}
}
unsigned int bcdtodecimal(unsigned int bcd)
{
unsigned int decimal;
decimal = (((bcd & 0xF0) >> 4) * 10) + (bcd & 0x0F);
return decimal;
}
void wait_mssp(void)
{
while(!PIR3bits.SSP1IF);
PIR3bits.SSP1IF =0;
}
void ds1307_write(unsigned char addr ,unsigned char data)
{
SSP1CON2bits.SEN =1; //Start bit
//SSP1BUF = 0XD0; //slave address(address of ds1307) + write bit
SSP1BUF =0X68;
SSP1BUF =addr;
SSP1BUF = data;
SSP1CON2bits.PEN =1; //stop bit
}
unsigned int ds1307_read(unsigned char addr)
{
SSP1CON2bits.RSEN =1;
//SSP1BUF =0XD0; //slave address(address of ds1307) + write bit;
SSP1BUF =0X68;
SSP1BUF =addr;
SSP1CON2bits.RSEN =1;
//SSP1BUF =0XD1; //slave address(address of ds1307) + read bit;
SSP1BUF =0X69;
SSP1CON2bits.RCEN =1;
SSP1CON2bits.ACKDT=1;
SSP1CON2bits.ACKEN =1;
SSP1CON2bits.PEN=1;
x = SSP1BUF;
return (x);
}
void SetDateTime()
{
ds1307_write(0X00,0x03);
ds1307_write(0X01,0X07);
ds1307_write(0X02,0X00);
ds1307_write(0X3,0X01);
ds1307_write(0X04,0x07);
ds1307_write(0X5,0X08);
ds1307_write(0X6,0X08);
}
void GetDateTime()
{
sec = ds1307_read(0X00);
sec=bcdtodecimal(sec);
min = ds1307_read(0X01);
min = bcdtodecimal(min);
hour = ds1307_read(0X02);
hour=bcdtodecimal( hour);
day= ds1307_read(0X03);
day = bcdtodecimal(day);
date= ds1307_read(0X04);
date=bcdtodecimal(date);
month= ds1307_read(0X05);
month = bcdtodecimal( month);
year= ds1307_read(0X06);
year= bcdtodecimal(year);
}
void Blink_Count()
{
if(PIR0bits.TMR0IF == 1)
{
PIR0bits.TMR0IF =0;
count=count+1;
if(count>=15)
{
LED=!LED;
count=0;
// SetSeg(min/10,4);
// SetSeg(min%10,3);
// SetSeg(sec/ 10,2);
// SetSeg(sec%10,1);
}
}
}
void main(void)
{
// Initialize the device
SYSTEM_Initialize();
// If using interrupts in PIC18 High/Low Priority Mode you need to enable the Global High and Low Interrupts
// If using interrupts in PIC Mid-Range Compatibility Mode you need to enable the Global and Peripheral Interrupts
// Use the following macros to:
// Enable high priority global interrupts
//INTERRUPT_GlobalInterruptHighEnable();
// Enable low priority global interrupts.
//INTERRUPT_GlobalInterruptLowEnable();
// Disable high priority global interrupts
//INTERRUPT_GlobalInterruptHighDisable();
// Disable low priority global interrupts.
//INTERRUPT_GlobalInterruptLowDisable();
// Enable the Global Interrupts
//INTERRUPT_GlobalInterruptEnable();
// Enable the Peripheral Interrupts
//INTERRUPT_PeripheralInterruptEnable();
// Disable the Global Interrupts
//INTERRUPT_GlobalInterruptDisable();
// Disable the Peripheral Interrupts
//INTERRUPT_PeripheralInterruptDisable();
// I2C1_Initialize();
SSP1CLKPPS = 0x0E; //RB6->MSSP:SCL;
SSP1DATPPS = 0x0C; //RB4->MSSP:SDA;
RB6PPS = 0x10; //RB6->MSSP:SCL;
RB4PPS = 0x11; //RB4->MSSP:SDA;
SetDateTime();
while (1)
{
GetDateTime();
SetSeg(min/10,4);
SetSeg(min%10,3);
SetSeg(sec/ 10,2);
SetSeg(sec%10,1);
}
}
Based On MCC code configuration and used library below. But i could not see sec parameter updating after writing.
void main(void)
{
uint8_t second;
uint8_t start_addres;
uint8_t length;
I2C1_MESSAGE_STATUS w_status;
I2C1_MESSAGE_STATUS r_status;
// Initialize the device
SYSTEM_Initialize();
start_addres = 0;
length =12;
I2C1_MasterWriteTRBBuild( 0X00, length, RTC_addres, &w_status);
while (1)
{
I2C1_MasterReadTRBBuild( &second, length, RTC_addres, &r_status);
I2C1_MasterRead(&second, length, RTC_addres, &r_status);
sec=second;
}
}
THis is I2C1.c file created after MCC
typedef union
{
struct
{
uint8_t full:1;
uint8_t empty:1;
uint8_t reserved:6;
}s;
uint8_t status;
}I2C_TR_QUEUE_STATUS;
/**
I2C Driver Queue Entry Type
#Summary
Defines the object used for an entry in the i2c queue items.
#Description
This defines the object in the i2c queue. Each entry is a composed
of a list of TRBs, the number of the TRBs and the status of the
currently processed TRB.
*/
typedef struct
{
uint8_t count; // a count of trb's in the trb list
I2C1_TRANSACTION_REQUEST_BLOCK *ptrb_list; // pointer to the trb list
I2C1_MESSAGE_STATUS *pTrFlag; // set with the error of the last trb sent.
// if all trb's are sent successfully,
// then this is I2C1_MESSAGE_COMPLETE
} I2C_TR_QUEUE_ENTRY;
/**
I2C Master Driver Object Type
#Summary
Defines the object that manages the i2c master.
#Description
This defines the object that manages the sending and receiving of
i2c master transactions.
*/
typedef struct
{
/* Read/Write Queue */
I2C_TR_QUEUE_ENTRY *pTrTail; // tail of the queue
I2C_TR_QUEUE_ENTRY *pTrHead; // head of the queue
I2C_TR_QUEUE_STATUS trStatus; // status of the last transaction
uint8_t i2cDoneFlag; // flag to indicate the current
// transaction is done
uint8_t i2cErrors; // keeps track of errors
} I2C_OBJECT ;
/**
I2C Master Driver State Enumeration
#Summary
Defines the different states of the i2c master.
#Description
This defines the different states that the i2c master
used to process transactions on the i2c bus.
*/
typedef enum
{
S_MASTER_IDLE,
S_MASTER_RESTART,
S_MASTER_SEND_ADDR,
S_MASTER_SEND_DATA,
S_MASTER_SEND_STOP,
S_MASTER_ACK_ADDR,
S_MASTER_RCV_DATA,
S_MASTER_RCV_STOP,
S_MASTER_ACK_RCV_DATA,
S_MASTER_NOACK_STOP,
S_MASTER_SEND_ADDR_10BIT_LSB,
S_MASTER_10BIT_RESTART,
} I2C_MASTER_STATES;
/**
Section: Macro Definitions
*/
/* defined for I2C1 */
#ifndef I2C1_CONFIG_TR_QUEUE_LENGTH
#define I2C1_CONFIG_TR_QUEUE_LENGTH 1
#endif
#define I2C1_TRANSMIT_REG SSP1BUF // Defines the transmit register used to send data.
#define I2C1_RECEIVE_REG SSP1BUF // Defines the receive register used to receive data.
// The following control bits are used in the I2C state machine to manage
// the I2C module and determine next states.
#define I2C1_WRITE_COLLISION_STATUS_BIT SSP1CON1bits.WCOL // Defines the write collision status bit.
#define I2C1_MODE_SELECT_BITS SSP1CON1bits.SSPM // I2C Master Mode control bit.
#define I2C1_MASTER_ENABLE_CONTROL_BITS SSP1CON1bits.SSPEN // I2C port enable control bit.
#define I2C1_START_CONDITION_ENABLE_BIT SSP1CON2bits.SEN // I2C START control bit.
#define I2C1_REPEAT_START_CONDITION_ENABLE_BIT SSP1CON2bits.RSEN // I2C Repeated START control bit.
#define I2C1_RECEIVE_ENABLE_BIT SSP1CON2bits.RCEN // I2C Receive enable control bit.
#define I2C1_STOP_CONDITION_ENABLE_BIT SSP1CON2bits.PEN // I2C STOP control bit.
#define I2C1_ACKNOWLEDGE_ENABLE_BIT SSP1CON2bits.ACKEN // I2C ACK start control bit.
#define I2C1_ACKNOWLEDGE_DATA_BIT SSP1CON2bits.ACKDT // I2C ACK data control bit.
#define I2C1_ACKNOWLEDGE_STATUS_BIT SSP1CON2bits.ACKSTAT // I2C ACK status bit.
#define I2C1_7bit true
/**
Section: Local Functions
*/
void I2C1_FunctionComplete(void);
void I2C1_Stop(I2C1_MESSAGE_STATUS completion_code);
/**
Section: Local Variables
*/
static I2C_TR_QUEUE_ENTRY i2c1_tr_queue[I2C1_CONFIG_TR_QUEUE_LENGTH];
static I2C_OBJECT i2c1_object;
static I2C_MASTER_STATES i2c1_state = S_MASTER_IDLE;
static uint8_t i2c1_trb_count = 0;
static I2C1_TRANSACTION_REQUEST_BLOCK *p_i2c1_trb_current = NULL;
static I2C_TR_QUEUE_ENTRY *p_i2c1_current = NULL;
/**
Section: Driver Interface
*/
void I2C1_Initialize(void)
{
i2c1_object.pTrHead = i2c1_tr_queue;
i2c1_object.pTrTail = i2c1_tr_queue;
i2c1_object.trStatus.s.empty = true;
i2c1_object.trStatus.s.full = false;
i2c1_object.i2cErrors = 0;
// SMP Standard Speed; CKE enabled;
SSP1STAT = 0xC0;
// SSPEN enabled; CKP disabled; SSPM FOSC/4_SSPxADD_I2C;
SSP1CON1 = 0x28;
// SBCDE disabled; BOEN disabled; SCIE disabled; PCIE disabled; DHEN disabled; SDAHT 100ns; AHEN disabled;
SSP1CON3 = 0x00;
// Baud Rate Generator Value: SSPADD 2;
SSP1ADD = 0x02;
// clear the master interrupt flag
PIR3bits.SSP1IF = 0;
// enable the master interrupt
PIE3bits.SSP1IE = 1;
}
uint8_t I2C1_ErrorCountGet(void)
{
uint8_t ret;
ret = i2c1_object.i2cErrors;
return ret;
}
void I2C1_ISR ( void )
{
static uint8_t *pi2c_buf_ptr;
static uint16_t i2c_address = 0;
static uint8_t i2c_bytes_left = 0;
static uint8_t i2c_10bit_address_restart = 0;
PIR3bits.SSP1IF = 0;
// Check first if there was a collision.
// If we have a Write Collision, reset and go to idle state */
if(I2C1_WRITE_COLLISION_STATUS_BIT)
{
// clear the Write colision
I2C1_WRITE_COLLISION_STATUS_BIT = 0;
i2c1_state = S_MASTER_IDLE;
*(p_i2c1_current->pTrFlag) = I2C1_MESSAGE_FAIL;
// reset the buffer pointer
p_i2c1_current = NULL;
return;
}
/* Handle the correct i2c state */
switch(i2c1_state)
{
case S_MASTER_IDLE: /* In reset state, waiting for data to send */
if(i2c1_object.trStatus.s.empty != true)
{
// grab the item pointed by the head
p_i2c1_current = i2c1_object.pTrHead;
i2c1_trb_count = i2c1_object.pTrHead->count;
p_i2c1_trb_current = i2c1_object.pTrHead->ptrb_list;
i2c1_object.pTrHead++;
// check if the end of the array is reached
if(i2c1_object.pTrHead == (i2c1_tr_queue + I2C1_CONFIG_TR_QUEUE_LENGTH))
{
// adjust to restart at the beginning of the array
i2c1_object.pTrHead = i2c1_tr_queue;
}
// since we moved one item to be processed, we know
// it is not full, so set the full status to false
i2c1_object.trStatus.s.full = false;
// check if the queue is empty
if(i2c1_object.pTrHead == i2c1_object.pTrTail)
{
// it is empty so set the empty status to true
i2c1_object.trStatus.s.empty = true;
}
// send the start condition
I2C1_START_CONDITION_ENABLE_BIT = 1;
// start the i2c request
i2c1_state = S_MASTER_SEND_ADDR;
}
break;
case S_MASTER_RESTART:
/* check for pending i2c Request */
// ... trigger a REPEATED START
I2C1_REPEAT_START_CONDITION_ENABLE_BIT = 1;
// start the i2c request
i2c1_state = S_MASTER_SEND_ADDR;
break;
case S_MASTER_SEND_ADDR_10BIT_LSB:
if(I2C1_ACKNOWLEDGE_STATUS_BIT)
{
i2c1_object.i2cErrors++;
I2C1_Stop(I2C1_MESSAGE_ADDRESS_NO_ACK);
}
else
{
// Remove bit 0 as R/W is never sent here
I2C1_TRANSMIT_REG = (i2c_address >> 1) & 0x00FF;
// determine the next state, check R/W
if(i2c_address & 0x01)
{
// if this is a read we must repeat start
// the bus to perform a read
i2c1_state = S_MASTER_10BIT_RESTART;
}
else
{
// this is a write continue writing data
i2c1_state = S_MASTER_SEND_DATA;
}
}
break;
case S_MASTER_10BIT_RESTART:
if(I2C1_ACKNOWLEDGE_STATUS_BIT)
{
i2c1_object.i2cErrors++;
I2C1_Stop(I2C1_MESSAGE_ADDRESS_NO_ACK);
}
else
{
// ACK Status is good
// restart the bus
I2C1_REPEAT_START_CONDITION_ENABLE_BIT = 1;
// fudge the address so S_MASTER_SEND_ADDR works correctly
// we only do this on a 10-bit address resend
i2c_address = 0x00F0 | ((i2c_address >> 8) & 0x0006);
// set the R/W flag
i2c_address |= 0x0001;
// set the address restart flag so we do not change the address
i2c_10bit_address_restart = 1;
// Resend the address as a read
i2c1_state = S_MASTER_SEND_ADDR;
}
break;
case S_MASTER_SEND_ADDR:
/* Start has been sent, send the address byte */
/* Note:
On a 10-bit address resend (done only during a 10-bit
device read), the original i2c_address was modified in
S_MASTER_10BIT_RESTART state. So the check if this is
a 10-bit address will fail and a normal 7-bit address
is sent with the R/W bit set to read. The flag
i2c_10bit_address_restart prevents the address to
be re-written.
*/
if(i2c_10bit_address_restart != 1)
{
// extract the information for this message
i2c_address = p_i2c1_trb_current->address;
pi2c_buf_ptr = p_i2c1_trb_current->pbuffer;
i2c_bytes_left = p_i2c1_trb_current->length;
}
// check for 10-bit address
if(!I2C1_7bit && (0x0 != i2c_address))
{
if (0 == i2c_10bit_address_restart)
{
// we have a 10 bit address
// send bits<9:8>
// mask bit 0 as this is always a write
I2C1_TRANSMIT_REG = 0xF0 | ((i2c_address >> 8) & 0x0006);
i2c1_state = S_MASTER_SEND_ADDR_10BIT_LSB;
}
else
{
// resending address bits<9:8> to trigger read
I2C1_TRANSMIT_REG = i2c_address;
i2c1_state = S_MASTER_ACK_ADDR;
// reset the flag so the next access is ok
i2c_10bit_address_restart = 0;
}
}
else
{
// Transmit the address
I2C1_TRANSMIT_REG = i2c_address;
if(i2c_address & 0x01)
{
// Next state is to wait for address to be acked
i2c1_state = S_MASTER_ACK_ADDR;
}
else
{
// Next state is transmit
i2c1_state = S_MASTER_SEND_DATA;
}
}
break;
case S_MASTER_SEND_DATA:
// Make sure the previous byte was acknowledged
if(I2C1_ACKNOWLEDGE_STATUS_BIT)
{
// Transmission was not acknowledged
i2c1_object.i2cErrors++;
// Reset the Ack flag
I2C1_ACKNOWLEDGE_STATUS_BIT = 0;
// Send a stop flag and go back to idle
I2C1_Stop(I2C1_DATA_NO_ACK);
}
else
{
// Did we send them all ?
if(i2c_bytes_left-- == 0U)
{
// yup sent them all!
// update the trb pointer
p_i2c1_trb_current++;
// are we done with this string of requests?
if(--i2c1_trb_count == 0)
{
I2C1_Stop(I2C1_MESSAGE_COMPLETE);
}
else
{
// no!, there are more TRB to be sent.
//I2C1_START_CONDITION_ENABLE_BIT = 1;
// In some cases, the slave may require
// a restart instead of a start. So use this one
// instead.
I2C1_REPEAT_START_CONDITION_ENABLE_BIT = 1;
// start the i2c request
i2c1_state = S_MASTER_SEND_ADDR;
}
}
else
{
// Grab the next data to transmit
I2C1_TRANSMIT_REG = *pi2c_buf_ptr++;
}
}
break;
case S_MASTER_ACK_ADDR:
/* Make sure the previous byte was acknowledged */
if(I2C1_ACKNOWLEDGE_STATUS_BIT)
{
// Transmission was not acknowledged
i2c1_object.i2cErrors++;
// Send a stop flag and go back to idle
I2C1_Stop(I2C1_MESSAGE_ADDRESS_NO_ACK);
// Reset the Ack flag
I2C1_ACKNOWLEDGE_STATUS_BIT = 0;
}
else
{
I2C1_RECEIVE_ENABLE_BIT = 1;
i2c1_state = S_MASTER_ACK_RCV_DATA;
}
break;
case S_MASTER_RCV_DATA:
/* Acknowledge is completed. Time for more data */
// Next thing is to ack the data
i2c1_state = S_MASTER_ACK_RCV_DATA;
// Set up to receive a byte of data
I2C1_RECEIVE_ENABLE_BIT = 1;
break;
case S_MASTER_ACK_RCV_DATA:
// Grab the byte of data received and acknowledge it
*pi2c_buf_ptr++ = I2C1_RECEIVE_REG;
// Check if we received them all?
if(--i2c_bytes_left)
{
/* No, there's more to receive */
// No, bit 7 is clear. Data is ok
// Set the flag to acknowledge the data
I2C1_ACKNOWLEDGE_DATA_BIT = 0;
// Wait for the acknowledge to complete, then get more
i2c1_state = S_MASTER_RCV_DATA;
}
else
{
// Yes, it's the last byte. Don't ack it
// Flag that we will nak the data
I2C1_ACKNOWLEDGE_DATA_BIT = 1;
I2C1_FunctionComplete();
}
// Initiate the acknowledge
I2C1_ACKNOWLEDGE_ENABLE_BIT = 1;
break;
case S_MASTER_RCV_STOP:
case S_MASTER_SEND_STOP:
// Send the stop flag
I2C1_Stop(I2C1_MESSAGE_COMPLETE);
break;
default:
// This case should not happen, if it does then
// terminate the transfer
i2c1_object.i2cErrors++;
I2C1_Stop(I2C1_LOST_STATE);
break;
}
}
void I2C1_FunctionComplete(void)
{
// update the trb pointer
p_i2c1_trb_current++;
// are we done with this string of requests?
if(--i2c1_trb_count == 0)
{
i2c1_state = S_MASTER_SEND_STOP;
}
else
{
i2c1_state = S_MASTER_RESTART;
}
}
void I2C1_Stop(I2C1_MESSAGE_STATUS completion_code)
{
// then send a stop
I2C1_STOP_CONDITION_ENABLE_BIT = 1;
// make sure the flag pointer is not NULL
if (p_i2c1_current->pTrFlag != NULL)
{
// update the flag with the completion code
*(p_i2c1_current->pTrFlag) = completion_code;
}
// Done, back to idle
i2c1_state = S_MASTER_IDLE;
}
void I2C1_MasterWrite(
uint8_t *pdata,
uint8_t length,
uint16_t address,
I2C1_MESSAGE_STATUS *pflag)
{
static I2C1_TRANSACTION_REQUEST_BLOCK trBlock;
// check if there is space in the queue
if (i2c1_object.trStatus.s.full != true)
{
I2C1_MasterWriteTRBBuild(&trBlock, pdata, length, address);
I2C1_MasterTRBInsert(1, &trBlock, pflag);
}
else
{
*pflag = I2C1_MESSAGE_FAIL;
}
}
void I2C1_MasterRead(
uint8_t *pdata,
uint8_t length,
uint16_t address,
I2C1_MESSAGE_STATUS *pflag)
{
static I2C1_TRANSACTION_REQUEST_BLOCK trBlock;
// check if there is space in the queue
if (i2c1_object.trStatus.s.full != true)
{
I2C1_MasterReadTRBBuild(&trBlock, pdata, length, address);
I2C1_MasterTRBInsert(1, &trBlock, pflag);
}
else
{
*pflag = I2C1_MESSAGE_FAIL;
}
}
void I2C1_MasterTRBInsert(
uint8_t count,
I2C1_TRANSACTION_REQUEST_BLOCK *ptrb_list,
I2C1_MESSAGE_STATUS *pflag)
{
// check if there is space in the queue
if (i2c1_object.trStatus.s.full != true)
{
*pflag = I2C1_MESSAGE_PENDING;
i2c1_object.pTrTail->ptrb_list = ptrb_list;
i2c1_object.pTrTail->count = count;
i2c1_object.pTrTail->pTrFlag = pflag;
i2c1_object.pTrTail++;
// check if the end of the array is reached
if (i2c1_object.pTrTail == (i2c1_tr_queue + I2C1_CONFIG_TR_QUEUE_LENGTH))
{
// adjust to restart at the beginning of the array
i2c1_object.pTrTail = i2c1_tr_queue;
}
// since we added one item to be processed, we know
// it is not empty, so set the empty status to false
i2c1_object.trStatus.s.empty = false;
// check if full
if (i2c1_object.pTrHead == i2c1_object.pTrTail)
{
// it is full, set the full status to true
i2c1_object.trStatus.s.full = true;
}
}
else
{
*pflag = I2C1_MESSAGE_FAIL;
}
// for interrupt based
if (*pflag == I2C1_MESSAGE_PENDING)
{
while(i2c1_state != S_MASTER_IDLE);
{
// force the task to run since we know that the queue has
// something that needs to be sent
PIR3bits.SSP1IF = true;
}
} // block until request is complete
}
void I2C1_MasterReadTRBBuild(
I2C1_TRANSACTION_REQUEST_BLOCK *ptrb,
uint8_t *pdata,
uint8_t length,
uint16_t address)
{
ptrb->address = address << 1;
// make this a read
ptrb->address |= 0x01;
ptrb->length = length;
ptrb->pbuffer = pdata;
}
void I2C1_MasterWriteTRBBuild(
I2C1_TRANSACTION_REQUEST_BLOCK *ptrb,
uint8_t *pdata,
uint8_t length,
uint16_t address)
{
ptrb->address = address << 1;
ptrb->length = length;
ptrb->pbuffer = pdata;
}
bool I2C1_MasterQueueIsEmpty(void)
{
return(i2c1_object.trStatus.s.empty);
}
bool I2C1_MasterQueueIsFull(void)
{
return(i2c1_object.trStatus.s.full);
}
void I2C1_BusCollisionISR( void )
{
// enter bus collision handling code here
}
/**
End of File
*/

Shared Memory between Kernel and User

I am currently working on a kernel module for a RaspberryPi 3 and am new to this area. This should generate an interrupt on a rising or falling edge. In the corresponding ISR, a time stamp is set and a signal is generated to notify a user application.
I have taken the signaling for the sake of the code.
My goal is now to write the value of the time stamp into a shared memory and the user application can read it out after an incoming signal in order to measure the latency between the interrupt and the signal received in the user application. I have already researched but found no solution. How do I map the virtual kernel address of the allocated memory into the user application and what steps are necessary?
Thanks in advance.
Kernel Code:
/****************************************************************************/
/* Kernelmodul Shared Memory */
/****************************************************************************/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/types.h>
#include <linux/ioport.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
// kmalloc
#include <linux/slab.h>
// ioremap
#include <asm/io.h>
/****************************************************************************/
/* Define block */
/****************************************************************************/
#define DriverAuthor ""
#define DriverDescription "Shared Memory"
#define InterruptPin 26
#define GPIO_PIN_DEV_STR "PIN"
#define GPIO_PIN_STR "Timestamp"
unsigned int * timerAddr;
unsigned int time = 0;
unsigned int * SHMvirtual = 0;
/****************************************************************************/
/* Module params declaration block */
/****************************************************************************/
static short int gpio_pin = InterruptPin;
/****************************************************************************/
/* Interrupts variables block */
/****************************************************************************/
short int irq_gpio_pin = InterruptPin;
short int irq_enabled = 0; // this is only a flag
/****************************************************************************/
/* IRQ handler */
/****************************************************************************/
static irqreturn_t ISR(int irq, void *dev_id, struct pt_regs *regs) {
unsigned long flags;
// disable hard interrupts (remember them in flag 'flags')
local_irq_save(flags);
time = timerAddr[1];
*SHMvirtual = time;
// restore hard interrupts
local_irq_restore(flags);
return IRQ_HANDLED;
}
/****************************************************************************/
/* This function configures interrupts. */
/****************************************************************************/
void configInterrupts(void) {
if (gpio_request(gpio_pin, GPIO_PIN_STR))
{
printk(KERN_INFO "GPIO request faiure %d\n", gpio_pin);
return;
}
if ( (irq_gpio_pin = gpio_to_irq(gpio_pin)) < 0 )
{
printk(KERN_INFO "GPIO to IRQ mapping faiure %d\n", gpio_pin);
return;
}
printk(KERN_INFO "Mapped int %d\n", irq_gpio_pin);
if (request_irq(irq_gpio_pin, (irq_handler_t ) ISR, (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING), GPIO_PIN_STR,
GPIO_PIN_DEV_STR))
{
printk("Interrupt Request failure\n");
return;
}
return;
}
/****************************************************************************/
/* This function releases interrupts. */
/****************************************************************************/
void releaseInterrupt(void) {
free_irq(irq_gpio_pin, GPIO_PIN_DEV_STR);
gpio_free(gpio_pin);
return;
}
/****************************************************************************/
/* Module init / cleanup block. */
/****************************************************************************/
int initModule(void) {
printk(KERN_INFO "Hello\n");
configInterrupts();
timerAddr = ioremap(0x3F003000, 0x20);
SHMvirtual = (unsigned int *)kmalloc(sizeof(time),GFP_USER);
return 0;
}
void cleanupModule(void) {
printk(KERN_INFO "Goodbye\n");
releaseInterrupt();
kfree(SHMvirtual);
return;
}
module_init(initModule);
module_exit(cleanupModule);
/****************************************************************************/
/* Module licensing/description block. */
/****************************************************************************/
MODULE_LICENSE("GPL");
MODULE_AUTHOR(DriverAuthor);
MODULE_DESCRIPTION(DriverDescription);

PIC microcontroller I2C reads fail with MPLABX generated code

I am using MPLABX 3.10 and I have generated a I2C Master interface using the MSSPI2C master interrupt feature. I was able to generate a I2C write event that on an osciloscope looks okay to me. Reads however are failing. When I look at the scope output I can clearly see that start condition is generated, and device ID with the read bit set is generated and acked. Next I am expecting to see the register address go out, but instead I see all zeros. Am I using the generated code incorrectly? Do I need to do a device write followed by a device read? I tried reducing the code to following:
void I2C_Initialize(void) {
i2c_object.pTrHead = i2c_tr_queue;
i2c_object.pTrTail = i2c_tr_queue;
i2c_object.trStatus.s.empty = true;
i2c_object.trStatus.s.full = false;
i2c_object.i2cErrors = 0;
// BF RCinprocess_TXcomplete; UA dontupdate; SMP Sample At Middle; P stopbit_notdetected; S startbit_notdetected; R_nW write_noTX; CKE Idle to Active; D_nA lastbyte_address;
SSP1STAT = 0x00;
// SSPEN enabled; WCOL no_collision; SSPOV no_overflow; CKP Idle:Low, Active:High; SSPM FOSC/4_SSPxADD;
SSP1CON1 = 0x28;
// BOEN disabled; AHEN disabled; SBCDE disabled; SDAHT 100ns; DHEN disabled; ACKTIM ackseq; PCIE disabled; SCIE disabled;
SSP1CON3 = 0x00;
// Baud Rate Generator Value: SSPADD 3;
SSP1ADD = 0x03;
/* Byte sent or received */
// clear the master interrupt flag
PIR1bits.SSP1IF = 0;
// enable the master interrupt
PIE1bits.SSP1IE = 1;
}
void I2C_MasterRead(
uint8_t *pdata,
uint8_t length,
uint16_t address,
I2C_MESSAGE_STATUS *pflag) {
static I2C_TRANSACTION_REQUEST_BLOCK trBlock;
// check if there is space in the queue
if (i2c_object.trStatus.s.full != true) {
I2C_MasterReadTRBBuild(&trBlock, pdata, length, address);
I2C_MasterTRBInsert(1, &trBlock, pflag);
} else {
*pflag = I2C_MESSAGE_FAIL;
}
}
void I2C_MasterReadTRBBuild(
I2C_TRANSACTION_REQUEST_BLOCK *ptrb,
uint8_t *pdata,
uint8_t length,
uint16_t address) {
ptrb->address = address << 1;
// make this a read
ptrb->address |= 0x01;
ptrb->length = length;
ptrb->pbuffer = pdata;
}
void main(void) {
#define BMA222E_BASE_ADDRESS_DEV0 (0x18) // <BMA222E base address
uint8_t dummy[2];
I2C_MESSAGE_STATUS pflag;
/* Configure the oscillator for the device */
ConfigureOscillator();
I2C_Initialize();
dummy[0] = 0x0F; // I expect to see 0x0F go out as the register value
dummy[1] = 0x00;
I2C_MasterRead (&dummy, 2, BMA222E_BASE_ADDRESS_DEV0, &pflag);
}
Ok, so figured it out. I need to write the address and then read the data in two steps. I modified the main function as follows.
void main(void) {
#define BMA222E_BASE_ADDRESS_DEV0 (0x18) // <BMA222E base address
uint8_t dummy[2];
I2C_MESSAGE_STATUS pflag;
/* Configure the oscillator for the device */
ConfigureOscillator();
I2C_Initialize();
dummy[0] = 0x0F; // I expect to see 0x0F go out as the register value
dummy[1] = 0x00;
I2C_MasterWrite (&dummy, 1, BMA222E_BASE_ADDRESS_DEV0, &pflag);
I2C_MasterRead (&dummy, 1, BMA222E_BASE_ADDRESS_DEV0, &pflag);
// dummy[0] now contains the read data.
}

ADC value in pic 16f1827

I want to check the result of adc and when this condition is met i want my microcontroller to output a digital signal at RB5 pin.
Please check the code.is it correct.? Becoz when i run the simulation its not working properly in proteus.
Here's the code.
#define USE_OR_MASKS
#include <xc.h>
#include <stdlib.h>
// CONFIG1
#pragma config FOSC = INTOSC
// Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select (MCLR/VPP pin function is digital input)
#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
#pragma config IESO = OFF // Internal/External Switchover (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)
// CONFIG2
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config LVP = ON // Low-Voltage Programming Enable (Low-voltage programming enabled)
void InitSfr(void);
int ReadADC(unsigned char ch);
void InitADC(void);
void Delay_ms(unsigned long time);
//************ Global Variables ****************************
int value;
unsigned int result;
//************ I2C MASTER ****************************
void main(void)
{
InitSfr();
InitADC();
LATBbits.LATB3=0;
LATBbits.LATB5=0;
//checking for the ADC result
do
{
//value=ReadADC(0);
//LATB=value;
//unsigned long int max = (value/1023)*5;
ADCON0bits.CHS0 = 0;
ADCON0bits.CHS1 = 0;
ADCON0bits.CHS2 = 0;
ADCON0bits.CHS3 = 0;
ADCON0bits.CHS4 = 0;
ADCON0bits.ADON = 1; // enable A/D converter
// ADCON0 = 0b00000001 + (ch<<2); // set channel to read
Delay_ms(5);
GO_nDONE =1; // 16F1827 start conversion
while(GO_nDONE){}; // wait for conversion
result = (ADRESH << 8) + ADRESL;
if (result>512)
{
LATBbits.LATB5=1;
Delay_ms(10);
LATBbits.LATB5=!LATBbits.LATB5;
Delay_ms(10);
}
else
{
LATBbits.LATB3=1;
Delay_ms(10);
LATBbits.LATB3=!LATBbits.LATB3;
Delay_ms(10);
}
} while(1);
//PIC16 Register Initialization
}//end Main
void InitSfr(void)
{
ANSELA = 0b00000001; // RA0 analog input
TRISA = 0b00100001; // RA0, RA5 inputs
ANSELB = 0b00000000; // PORTB all digital outputs
TRISB = 0b11100111; // PORTB all outputs
// Configure FVR to 4.096 V
FVRCON = 0b11000011 ;
}
//initialise the ADC
void InitADC()
{
// Configure ADCON1=0b1000011
ADCON1bits.ADNREF = 0; // Vref- is connected to ground
ADCON1bits.ADPREF0 = 1; // Vref+ is 4.096 V
ADCON1bits.ADPREF1 = 1;
ADCON1bits.ADCS0 = 0; // Use conversion clock, Fosc/2
ADCON1bits.ADCS1 = 0; // Fosc = 500 KHz
ADCON1bits.ADCS2 = 0;
ADCON1bits.ADFM = 1; // result is right Justified
}
void Delay_ms(unsigned long time)
{
unsigned int j;
while(time--)
{
for(j = 0; j<260; j++)
{
int x=0;
}
}
}
Hi there is error in void InitSfr(void).
Error is You made TRISB Bit 5 as input by making that 1
As you want your PORTB as output then you need to set TRISB properly
TRISB = 0b00000000; // PORTB all outputs
PORTB = 0b00000000; // It is good to make all low by default

Resources