Hello all,
I'm using a digital compass for a microcontroller project, that displays the direction the compass is facing on an LCD. I've gotten it working to the point where it displays 0-255 on the LCD thanks to author at EngScope.com!
However, that 0-255 is represented as ASCII characters. I need to convert those to integer values now. I know I can't use atoi since the character bytes aren't null terminated and aren't constant. Here is the code Thanks!
Code:
#include <p24FJ128GA010.h>
#include <stdio.h>
_CONFIG1(JTAGEN_OFF & GCP_OFF & GWRP_OFF & BKBUG_OFF & ICS_PGx2 & FWDTEN_OFF)
_CONFIG2(IESO_OFF & FCKSM_CSDCMD & OSCIOFNC_ON & FNOSC_FRC & POSCMOD_NONE)
void i2c_init(int BRG);
void i2c_start(void);
void i2c_restart(void);
void reset_i2c_bus(void);
char send_i2c_byte(int data);
char i2c_read(void);
char i2c_read_ack(void);
char I2Cread(char addr, char subaddr);
unsigned char I2Cpoll(char addr);
void DelayuSec(unsigned int N);
char testChar ='0';
main()
{
i2c_init(39); //initializes i2c function
LCDInit(); // initalizes LCD
LCDClear(); //clears LCD
while(1)
{
DelayuSec(15000); //15kuS delay
DelayuSec(15000); //15kuS delay
LCDClear(); //clear LCD
testChar = I2Cread(0xC0, 1); //reads compass register 1
//amd returns a value of 0-255
/*
// convert the testChar ASCII value to its equivalent int value
*/
LCDPut(testChar); //prints a character on LCD screen
}
}
//function initiates I2C1 module to baud rate BRG
void i2c_init(int BRG)
{
int temp;
I2C1BRG = BRG; // I2CBRG = 39 for 8Mhz OSCI with 100kHz I2C clock
I2C1CONbits.I2CEN = 0; // Disable I2C Mode
I2C1CONbits.DISSLW = 1; // Disable slew rate control
IFS1bits.MI2C1IF = 0; // Clear Interrupt
I2C1CONbits.I2CEN = 1; // Enable I2C Mode
temp = I2C1RCV; // read buffer to clear buffer full
reset_i2c_bus(); // set bus to idle
}
unsigned char I2Cpoll(char addr)
{
unsigned char temp = 0;
i2c_start();
temp = send_i2c_byte(addr);
reset_i2c_bus();
return temp;
}
char I2Cread(char addr, char subaddr)
{
char temp;
i2c_start();
send_i2c_byte(addr);
send_i2c_byte(subaddr);
DelayuSec(10);
i2c_restart();
send_i2c_byte(addr | 0x01);
temp = i2c_read();
reset_i2c_bus();
return temp;
}
//function iniates a start condition on bus
void i2c_start(void)
{
int x = 0;
I2C1CONbits.ACKDT = 0; //Reset any previous Ack
DelayuSec(10);
I2C1CONbits.SEN = 1; //Initiate Start condition
Nop();
//the hardware will automatically clear Start Bit
//wait for automatic clear before proceding
while (I2C1CONbits.SEN)
{
DelayuSec(1);
x++;
if (x > 20) break;
}
DelayuSec(2);
}
//function iniates a restart condition on bus
void i2c_restart(void)
{
int x = 0;
I2C1CONbits.RSEN = 1; //Initiate restart condition
Nop();
//the hardware will automatically clear restart bit
//wait for automatic clear before proceding
while (I2C1CONbits.RSEN)
{
DelayuSec(1);
x++;
if (x > 20) break;
}
DelayuSec(2);
}
//Resets the I2C bus to Idle
void reset_i2c_bus(void)
{
int x = 0;
//initiate stop bit
I2C1CONbits.PEN = 1;
//wait for hardware clear of stop bit
while (I2C1CONbits.PEN)
{
DelayuSec(1);
x++;
if (x > 20) break;
}
I2C1CONbits.RCEN = 0;
IFS1bits.MI2C1IF = 0; // Clear Interrupt
I2C1STATbits.IWCOL = 0;
I2C1STATbits.BCL = 0;
DelayuSec(10);
}
//basic I2C byte send
char send_i2c_byte(int data)
{
int i;
while (I2C1STATbits.TBF) { }
IFS1bits.MI2C1IF = 0; // Clear Interrupt
I2C1TRN = data; // load the outgoing data byte
// wait for transmission
for (i=0; i<500; i++)
{
if (!I2C1STATbits.TRSTAT) break;
DelayuSec(1);
}
if (i == 500)
{
return(1);
}
// Check for NO_ACK from slave, abort if not found
if (I2C1STATbits.ACKSTAT == 1)
{
reset_i2c_bus();
return(1);
}
DelayuSec(2);
return(0);
}
//function reads data, returns the read data, no ack
char i2c_read(void)
{
int i = 0;
char data = 0;
//set I2C module to receive
I2C1CONbits.RCEN = 1;
//if no response, break
while (!I2C1STATbits.RBF)
{
i ++;
if (i > 2000) break;
}
//get data from I2CRCV register
data = I2C1RCV;
//return data
return data;
}
//function reads data, returns the read data, with ack
char i2c_read_ack(void) //does not reset bus!!!
{
int i = 0;
char data = 0;
//set I2C module to receive
I2C1CONbits.RCEN = 1;
//if no response, break
while (!I2C1STATbits.RBF)
{
i++;
if (i > 2000) break;
}
//get data from I2CRCV register
data = I2C1RCV;
//set ACK to high
I2C1CONbits.ACKEN = 1;
//wait before exiting
DelayuSec(10);
//return data
return data;
}
void DelayuSec(unsigned int N)
{
unsigned int j;
while(N > 0)
{
for(j=0; j < 10; j++);
N--;
}
}