HELP!! I2c adc pic16, pic1LCD

Thread Starter

Sapere

Joined Apr 6, 2022
3
I
want to use two or more adc channel using I2C and lcd. Can someone help me where i am doing wrong? I don't get a code error but also I can't get number on the lcd.

I2c.c

C-like:
#include <xc.h>

#include "I2c.h"


unsigned char RS, i2c_add, BackLight_State = LCD_BACKLIGHT;


//---------------[ I2C Routines ]-------------------

//--------------------------------------------------

void I2C__Init()

{

SSPCON1 = 0x38;

SSPCON2 = 0x00;

SSPSTAT = 0x00;

SSPADD = ((_XTAL_FREQ/4)/I2C_BaudRate) - 1;

SCL_D = 1;

SDA_D = 1;

}


void I2C__Wait()

{

while ((SSPSTAT & 0x04) || (SSPCON2 & 0x1F));

}


void I2C__Start()

{

I2C__Wait();

SEN = 1;

}


void I2C__RepeatedStart()

{

I2C__Wait();

RSEN = 1;

}


void I2C__Stop()

{

I2C__Wait();

PEN = 1;

}


void I2C_ACK(void)

{

ACKDT = 0; // 0 -> ACK

I2C__Wait();

ACKEN = 1; // Send ACK

}


void I2C_NACK(void)

{

ACKDT = 1; // 1 -> NACK

I2C__Wait();

ACKEN = 1; // Send NACK

}


unsigned char I2C__Write(unsigned char data)

{

I2C__Wait();

SSPBUF = data;

while(!SSPIF); // Wait Until Completion

SSPIF = 0;

return ACKSTAT;

}


unsigned char I2C_Read_Byte(void)

{

//---[ Receive & Return A Byte ]---

I2C__Wait();

RCEN = 1; // Enable & Start Reception

while(!SSPIF); // Wait Until Completion

SSPIF = 0; // Clear The Interrupt Flag Bit

I2C__Wait();

return SSPBUF; // Return The Received Byte

}

//======================================================


//---------------[ LCD Routines ]----------------

//------------------------------------------------------


void LCD_Init(unsigned char I2C_Add)

{

i2c_add = I2C_Add;

IO_Expander_Write(0x00);

__delay_ms(30);

LCD_CMD(0x03);

__delay_ms(5);

LCD_CMD(0x03);

__delay_ms(5);

LCD_CMD(0x03);

__delay_ms(5);

LCD_CMD(LCD_RETURN_HOME);

__delay_ms(5);

LCD_CMD(0x20 | (LCD_TYPE << 2));

__delay_ms(50);

LCD_CMD(LCD_TURN_ON);

__delay_ms(50);

LCD_CMD(LCD_CLEAR);

__delay_ms(50);

LCD_CMD(LCD_ENTRY_MODE_SET | LCD_RETURN_HOME);

__delay_ms(50);

}


void IO_Expander_Write(unsigned char Data)

{

I2C__Start();

I2C__Write(i2c_add);

I2C__Write(Data | BackLight_State);

I2C__Stop();

}


void LCD_Write_4Bit(unsigned char Nibble)

{

// Get The RS Value To LSB OF Data

Nibble |= RS;

IO_Expander_Write(Nibble | 0x04);

IO_Expander_Write(Nibble & 0xFB);

__delay_us(50);

}


void LCD_CMD(unsigned char CMD)

{

RS = 0; // Command Register Select

LCD_Write_4Bit(CMD & 0xF0);

LCD_Write_4Bit((CMD << 4) & 0xF0);

}


void LCD_Write_Char(char Data)

{

RS = 1; // Data Register Select

LCD_Write_4Bit(Data & 0xF0);

LCD_Write_4Bit((Data << 4) & 0xF0);

}


void LCD_Write_String(char* Str)

{

for(int i=0; Str!='\0'; i++)

LCD_Write_Char(Str);

}


void LCD_Set_Cursor(unsigned char ROW, unsigned char COL)

{

switch(ROW)

{

case 2:

LCD_CMD(0xC0 + COL-1);

break;

case 3:

LCD_CMD(0x94 + COL-1);

break;

case 4:

LCD_CMD(0xD4 + COL-1);

break;

// Case 1

default:

LCD_CMD(0x80 + COL-1);

}

}


void Backlight()

{

BackLight_State = LCD_BACKLIGHT;

IO_Expander_Write(0);

}


void noBacklight()

{

BackLight_State = LCD_NOBACKLIGHT;

IO_Expander_Write(0);

}


void LCD_SL()

{

LCD_CMD(0x18);

__delay_us(40);

}


void LCD_SR()

{

LCD_CMD(0x1C);

__delay_us(40);

}


void LCD_Clear()

{

LCD_CMD(0x01);

__delay_us(40);


.

.

.

.

.


I2c .h


/* File: I2C_LCD.h */


#define _XTAL_FREQ 8000000


#define I2C_BaudRate 100000

#define SCL_D TRISC3

#define SDA_D TRISC4


#define LCD_BACKLIGHT 0x08

#define LCD_NOBACKLIGHT 0x00

#define LCD_FIRST_ROW 0x80

#define LCD_SECOND_ROW 0xC0

#define LCD_THIRD_ROW 0x94

#define LCD_FOURTH_ROW 0xD4

#define LCD_CLEAR 0x01

#define LCD_RETURN_HOME 0x02

#define LCD_ENTRY_MODE_SET 0x04

#define LCD_CURSOR_OFF 0x0C

#define LCD_UNDERLINE_ON 0x0E

#define LCD_BLINK_CURSOR_ON 0x0F

#define LCD_MOVE_CURSOR_LEFT 0x10

#define LCD_MOVE_CURSOR_RIGHT 0x14

#define LCD_TURN_ON 0x0C

#define LCD_TURN_OFF 0x08

#define LCD_SHIFT_LEFT 0x18

#define LCD_SHIFT_RIGHT 0x1E

#define LCD_TYPE 2 // 0 -> 5x7 | 1 -> 5x10 | 2 -> 2 lines


//-----------[ Functions' Prototypes ]--------------


//---[ I2C Routines ]---


void I2C__Init();

void I2C__Wait();

void I2C__Start();

void I2C__RepeatedStart();

void I2C__Stop();

void I2C_ACK();

void I2C_NACK();

unsigned char I2C__Write(unsigned char data);

unsigned char I2C_Read_Byte(void);


//---[ LCD Routines ]---


void LCD_Init(unsigned char I2C_Add);

void IO_Expander_Write(unsigned char Data);

void LCD_Write_4Bit(unsigned char Nibble);

void LCD_CMD(unsigned char CMD);

void LCD_Set_Cursor(unsigned char ROW, unsigned char COL);

void LCD_Write_Char(char);

void LCD_Write_String(char*);

void Backlight();

void noBacklight();

void LCD_SR();

void LCD_SL();

void LCD_Clear(void);

.

.


.

.

Mainc



/*

* File: main.c

* Author: microdigisoft.com

*

*/

#include <xc.h>

#include "config.h"

#include "I2c.h"


unsigned char input;

int result_1; 

float Voltage1_result; 

int AN1_Result; 

int AN0_Result; 

int AN2_Result; 


void ADC_Init()

{

TRISA = 0xff; //*set as input port*/

ADCON1 = 0b11110000; //Right Justify, FRC Clock , All pins as Analog Input and setting Reference Voltages

ADCON0 = 0b00000001; //Turn ON ADC and Clock Selection


}


int ReadADC(unsigned char channel)

{ 

int AN_Val;


switch (channel) { 

case 1: //AN1 

ADCON0 = 0x0D; 

break; 


case 2: //AN2 

ADCON0 = 0x55; 

break; 



default: //Any other value will default to AN0 

ADCON0 = 0x45; 

}

__delay_us(10);


ADCON0&=0x81;

ADCON0|= (channel <<2);

GO_DONE=1;

while (ADCON0 & 0x02); 

AN_Val = (ADRESH*256 + ADRESL); 

return AN_Val; 

}

void main(void) {


// Initialize LCD module with I2C address = 0x4E


LCD_Init(0x4E);


I2C__Init();

// Initialize I2C bus function

ADC_Init(); //* initialize 10-bit ADC*/

LCD_Set_Cursor(1,4);

LCD_Write_String("Nikolas");




while(1)

{

AN0_Result = ReadADC(0) ; 

__delay_ms(10); 

AN1_Result = ReadADC(1); 

__delay_ms(10); 

AN2_Result = ReadADC(2); 

__delay_ms(10); 

// 

LCD_Clear();

LCD_Set_Cursor(1,1); 

LCD_Write_Char( ((AN1_Result)%100)/100 );

LCD_Set_Cursor(2, 1);

LCD_Write_Char( ((AN0_Result)%100)/100 );

LCD_Write_String("dgdgj");

}

return;

}
 
Last edited by a moderator:

Ya’akov

Joined Jan 27, 2019
9,070
Welcome to AAC.

You should use CODE tags to make your code readable, it is very hard to help when the code is not formatted.

You can find the CODE tags in the ••• menu on the edit toolbar.

1649249481552.png
 

BobTPH

Joined Jun 5, 2013
8,813
Don’t try to debug everything at once. Can you display a number in the LCD without the rest of the code.

Bob
 
Top