I did my code on mikroC because i dont like the weird way cubloc is ^^...
anyway:
original version:
http://www.lextronic.fr/P1773-module-boussole-cmps03.htmlthis test code basically draws a circle on the center of the screen, then changes its color and another circles tracks your angular movements...
nothing complicated
/** PIC16F88 * Clock: 8.0MHz ???????
* Device Flags:
#include "bit.h"
// module connections
#define I2C_PORT PORTB // User defined
#define I2C_PIN_SDA 1 // User defined
#define I2C_PIN_SCL 0 // User defined
#define I2C_TRIS TRISB // User defined
// Software I2C connections
sbit Soft_I2C_Scl at RB0_bit;
sbit Soft_I2C_Sda at RB1_bit;
sbit Soft_I2C_Scl_Direction at TRISB0_bit;
sbit Soft_I2C_Sda_Direction at TRISB1_bit;
// End Software I2C connections
// Internal macros
#define I2C_SDA_0 resBit(I2C_TRIS, I2C_PIN_SDA) //Port = o/p (Drive low).
#define I2C_SCL_0 resBit(I2C_TRIS, I2C_PIN_SCL) //Port = o/p (Drive low).
#define I2C_SDA_1 setBit(I2C_TRIS, I2C_PIN_SDA) //Port = i/p (Res pulls high).
#define I2C_SCL_1 setBit(I2C_TRIS, I2C_PIN_SCL) //Port = i/p (Res pulls high).
#define I2C_SDA_IN testBit(I2C_PORT, I2C_PIN_SDA)
#define I2C_SCL_IN testBit(I2C_PORT, I2C_PIN_SCL)
// End module connections
char i,j,k,k1,k2,rgbh,rgbl,temp,tmp,xt,yt;
unsigned char errorcom,angleH,angleL;
unsigned int xm,ym,angle;
char x,y;
char txt[15];
//////////////////////////////////////////////////////////////////////
void Soft_I2C1_Init(unsigned long speed) {
// must do following in one go else port takes time to do it so R-M-F stops it.
I2C_PORT &= ~( (1<<I2C_PIN_SDA) | (1<<I2C_PIN_SCL) );
I2C_SDA_1; // release data (high).
I2C_SCL_1; // release clock (high).
}
//////////////////////////////////////////////////////////////////////
// 100kHz set here (very approximate). Will be slower than 100kHz.
static void I2C_delay(void) {
Delay_us(2); // 1us
}
//////////////////////////////////////////////////////////////////////
// Start command
//
// SDA 1-0-0
// SCL 1-1-0
//
// Asumptions : coming from bus free state (d=1,ck=1)
void Soft_I2C1_Start(void) {
I2C_SDA_1;
I2C_SCL_1;
I2C_delay();
I2C_SDA_0;
I2C_delay();
I2C_SCL_0;
I2C_delay();
}
//////////////////////////////////////////////////////////////////////
// Stop command
//
// SDA 0-0-1
// SCL 0-1-1
//
void Soft_I2C1_Stop(void) {
I2C_SCL_0; // Force to zero as can be sent at any time.
I2C_SDA_0; // Clock 1st so do not make a command.
I2C_delay();
I2C_SCL_1;
I2C_delay();
I2C_SDA_1;
I2C_delay();
}
//////////////////////////////////////////////////////////////////////
unsigned short Soft_I2C1_Read(unsigned short ack) {
unsigned short i;
char ddata;
I2C_SDA_1; // Release the data pin
// grab the data
for(i=0;i<8;i++) {
ddata <<=1;
I2C_SCL_0;
I2C_delay(); // Clock is low
I2C_SCL_1; // Clock released to high.
while (I2C_SCL_IN==0) {;} // Wait here if clock is pulled low by slave
if (I2C_SDA_IN) {ddata |= 1;} // Sample the data
I2C_delay(); // Clock is high
}
// Send ACK or NACK
I2C_SCL_0;
if (ack) I2C_SDA_0; // ACK
else I2C_SDA_1; // NACK
I2C_delay(); // low T/w.
I2C_SCL_1;
I2C_delay(); // high T/2.
I2C_SCL_0; // Return clock to safe state.
return ddata;
}
//////////////////////////////////////////////////////////////////////
// Returns 0 for no errors = the ACK bit from the slave
unsigned short Soft_I2C1_Write(unsigned short xdata) {
unsigned short ret=0,i;
// grab the data
for(i=0;i<8;i++) {
I2C_SCL_0; // Clock low
if (xdata & 0x80) I2C_SDA_1; else I2C_SDA_0; // Data output
xdata <<= 1; // Next data bit.
I2C_delay(); // low T/2.
I2C_SCL_1; // Clock released to high.
I2C_delay(); // high T/2.
}
// get ACK or NACK
I2C_SCL_0;
I2C_SDA_1; // Release the data line
I2C_delay(); // low T/2.
I2C_SCL_1;
// Sample the ACK
ret = I2C_SDA_IN;
I2C_delay(); // high T/2.
I2C_SCL_0; // Return clock to safe state
return ret;
}
/*unsigned int Read_temp(unsigned char com)
{
unsigned int SensorRaw;
Soft_I2C1_Start();// issue I2C start signal
Soft_I2C1_Write(0x00);// send address (device address + W)
Soft_I2C1_Write(com);// send command
Soft_I2C1_Start();// issue I2C signal repeated start
Soft_I2C1_Write(0x01);// send address (device address + R)
SensorLow = Soft_I2C1_Read(1);// Read temp. low byte (acknowledge)
SensorHigh = Soft_I2C1_Read(1);// Read temp. high byte (acknowledge)
PEC = Soft_I2C1_Read(1);// Read PEC (not used) (acknowledge)
Soft_I2C1_Stop();// issue I2C stop signal
SensorRaw = SensorLow + (SensorHigh << 8);// Build temp. word
return SensorRaw;
} */
/*****/
void main() {
OSCCON = 0x70; // 0b0110 0000 = 4MHz
ANSEL=0; // all digital
CMCON=0X07; // comparators off
PORTA=0;
TRISA=0; // ports setup
TRISB=0b00000100;
PORTB=0b00100100;
rgbh=0;rgbl=0;temp=0;k=0;k1=0;k2=0;
//interrupt config
Delay_ms(1500);
// Initialize hardware UART1 and establish communication at 9600 bps
UART1_Init(19200);
Delay_ms(100);
UART1_Write_Text("U");
Delay_ms(200);
UART1_Write_Text("E");
Delay_ms(200);
UART1_Write_Text("p");
UART1_Write(0x01);
Delay_ms(1);
UART1_Write_Text("C");
UART1_Write(64);
UART1_Write(64);
UART1_Write(63);
UART1_Write(0b00010000);
UART1_Write(0b01000010);
Delay_ms(100);
// write a word ^^
UART1_Write_Text("s");
UART1_Write(0x01);
Delay_ms(1);
UART1_Write(0x08);
UART1_Write(0x00);
UART1_Write(0x4E);
UART1_Write(0x7E);
UART1_Write_Text("Ouest");
UART1_Write(0x00);
Delay_ms(100);
// write a word ^^
UART1_Write_Text("s");
UART1_Write(0x09);
Delay_ms(1);
UART1_Write(0x01);
UART1_Write(0x00);
UART1_Write(0x4E);
UART1_Write(0x7E);
UART1_Write_Text("Nord");
UART1_Write(0x00);
Delay_ms(100);
// write a word ^^
UART1_Write_Text("s");
UART1_Write(0x12);
Delay_ms(1);
UART1_Write(0x08);
UART1_Write(0x00);
UART1_Write(0x4E);
UART1_Write(0x7E);
UART1_Write_Text("Est");
UART1_Write(0x00);
Delay_ms(100);
// write a word ^^
UART1_Write_Text("s");
UART1_Write(0x09);
Delay_ms(1);
UART1_Write(0x0E);
UART1_Write(0x00);
UART1_Write(0x4E);
UART1_Write(0x7E);
UART1_Write_Text("Sud");
UART1_Write(0x00);
Delay_ms(100);
// i2C sensor
//xm=0;ym=0;
while(1) {
/* k+=8;
if (k==32) {k=0;
k1+=8;
if (k1==64) {
k1=0;
k2+=8;
if (k2==32) { k2=0;};
};
};
temp=(k1<<5)&0b11100000;
tmp=k2&0b00011111;
rgbl=temp|tmp;
temp=(k1 >> 3)&0b00000111;
tmp= (k << 3)&0b11111000;
rgbh= temp | tmp;
i=20;
UART1_Write_Text("p");
UART1_Write(0x00); // 1 for line 0 for solid
Delay_ms(1);
UART1_Write_Text("C");
UART1_Write(64); // x
UART1_Write(64); // y //64 64 63 00 1f
UART1_Write(i); // radius
UART1_Write(rgbh); // rgbh
UART1_Write(rgbl); // rgbl
*/
Delay_ms(1000);
// UART1_Write_Text("E");
// Delay_ms(50);
Soft_I2C1_Init(100000);
Soft_I2C1_Start();
Soft_I2C1_Write(0xC0); //Adresse du module CMPS03
Soft_I2C1_Write(0); //Selectionne adresse registre a lire
Soft_I2C1_Start();//Condition Start I2C
Soft_I2C1_Write(0xC1);// Selectionne condition de lecture I2C
tmp = Soft_I2C1_Read(1);//Lecture N° revision module CMPS03
Delay_ms(5);
tmp = Soft_I2C1_Read(1); //lecture valeur angle (0 - 255)
Delay_ms(5);
angleH=Soft_I2C1_Read(1);// Recupere octet poids fort angle
Delay_ms(5);
angleL=Soft_I2C1_Read(0);//Recupere octet poids faible angle
Soft_I2C1_Stop();
angle=angleH;
angle=(angle<<8)+angleL;
angle=angle/10;
// ####### Dessine aiguille boussole ##############
x = (cosE3(angle) * 32/1000) ;
y = (sinE3(angle) * 32/1000) ;
UART1_Write_Text("L");
UART1_Write(x);
UART1_Write(y);
UART1_Write(127-x);
UART1_Write(127-y);
UART1_Write(0xFF);// ' efface rond
UART1_Write(0xFF);
Delay_ms(200);
UART1_Write_Text("C");
UART1_Write(127-x);
UART1_Write(127-y);
UART1_Write(4);// ' efface rond
UART1_Write(0xf4);// ' efface rond
UART1_Write(0xe0);
Delay_ms(200);
};
}