Hi there,
I am newer at ARM programming but I need to get I2C communication working to read from accelerometer. For beggining I would like to get at least some bits transfered on I2C pins. In this forum I have found I2C example: http://www.keil.com/forum/58249/
I have included it to me project so now it should send some data on timmer interrupt. But at I2C pins connected scope only shows 1 pulse down to 0V at timmer interrupts.
Any help would be appreciate.
Please find me source code bellow:
#include "LPC11xx.h" /* LPC11xx definitions */ #include "gpio.h" #include <cr_section_macros.h> #include <NXP/crp.h>
// Variable to store CRP value in. Will be placed automatically // by the linker when "Enable Code Read Protect" selected. // See crp.h header for more information __CRP const unsigned int CRP_WORD = CRP_NO_CRP ;
int i=0; unsigned int status = 0;
void timer16_0_setup(void) { //Set up 16 bit timer LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7); //enable timer clock LPC_TMR16B0->PR = 48000-1; //prescaler 48000 = 1ms LPC_TMR16B0->MCR = (3<<3); //interrupt and reset counter match1 LPC_TMR16B0->CCR = 0; //timer mode LPC_TMR16B0->MR1 = 1000-1; //set match1 time in us NVIC_EnableIRQ(TIMER_16_0_IRQn); //enable interrupt LPC_TMR16B0->TCR = 1; //start timer }
void I2C_Init(void) { LPC_SYSCON->PRESETCTRL |= (1<<1); //De-Asserts Reset Signal to I2C LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5); //Enable I2C Clock
LPC_IOCON->PIO0_4 &= ~0x3F; LPC_IOCON->PIO0_4 |= 0x01; //SCL
LPC_IOCON->PIO0_5 &= ~0x3F; LPC_IOCON->PIO0_5 |= 0x01; //SDA
//I2C 100 LPC_I2C->SCLH = 360; //I2PCLK is 72MHz LPC_I2C->SCLL = 360; //I2PCLK is 72MHz
LPC_I2C->CONCLR = 0xFF; //Clear All Flags LPC_I2C->CONSET = (1<<6); //I2C Interface Enable } void I2C_Start(void) { LPC_I2C->CONCLR = 0X28; LPC_I2C->CONSET |= 0x20; //Set the Start Bit while(LPC_I2C->STAT!=0x08); //Wait for the Status Bit } void I2C_Restart(void) { LPC_I2C->CONCLR = 0X28; LPC_I2C->CONSET |= 0x20; //Set the Start Bit while(LPC_I2C->STAT!=0x10); //Wait for the Status Bit } void I2C_Stop(void) { LPC_I2C->CONSET |= 0x14; //Stop I2C LPC_I2C->CONCLR = 0x08; } void I2C_Write(unsigned char data,unsigned char status) { LPC_I2C->CONCLR = 0X28; LPC_I2C->DAT = data; LPC_I2C->CONCLR = 0X28; //Clear Start Flag and SI Interrupt //while(LPC_I2C->STAT!=status); //Wait for the Status Byte } unsigned char I2C_Read(void) { LPC_I2C->CONCLR = 0X2C; //Cleat SI and Asset Acknowledgment Flag while(LPC_I2C->STAT!=0x58); return(LPC_I2C->DAT); }
//Timer interrupt void TIMER16_0_IRQHandler(void) { if(LPC_TMR16B0->IR & (1<<1)) //match1 interrupt? { if (i==0) {GPIOSetValue( 1, 7, 1 ); i=1;} else {GPIOSetValue( 1, 7, 0 ); i=0;}
I2C_Start(); I2C_Write(100,1); I2C_Stop();
} LPC_TMR16B0->IR = (1<<1); //reset flag
} //end match1 interrupt
int main (void) {
//Set up timer timer16_0_setup(); I2C_Init(); GPIOInit();
// Set port for LED to output GPIOSetDir( 1, 7, 1 );
while (1) // Loop forever {
} }
Any ideas?
Sorry chum, but i don't have time to look at a messed up post like that.
Maybe if you posted more carefully, so people could view the code more easily, you'd get some helpful responses.
Thanks for your comment mate, I don't know but somehow when I was copying it from editor everything messed up. Once again sorry for a messy post. I have try one more time to post me source code:
#include "LPC11xx.h" /* LPC11xx definitions */ #include "gpio.h" #include <cr_section_macros.h> #include <NXP/crp.h> __CRP const unsigned int CRP_WORD = CRP_NO_CRP ;
void timer16_0_setup(void) //Set up 16 bit timer { LPC_SYSCON->SYSAHBCLKCTRL |= (1<<7); //enable timer clock LPC_TMR16B0->PR = 48000-1; //prescaler 48000 = 1ms LPC_TMR16B0->MCR = (3<<3); //interrupt and reset counter match1 LPC_TMR16B0->CCR = 0; //timer mode LPC_TMR16B0->MR1 = 1000-1; //set match1 time in us NVIC_EnableIRQ(TIMER_16_0_IRQn); //enable interrupt LPC_TMR16B0->TCR = 1; //start timer }
LPC_I2C->SCLH = 360; //I2PCLK is 72MHz LPC_I2C->SCLL = 360; //I2PCLK is 72MHz
LPC_I2C->CONCLR = 0xFF; //Clear All Flags LPC_I2C->CONSET = (1<<6); //I2C Interface Enable }
void I2C_Start(void) { LPC_I2C->CONCLR = 0X28; LPC_I2C->CONSET |= 0x20; //Set the Start Bit while(LPC_I2C->STAT!=0x08); //Wait for the Status Bit }
void I2C_Restart(void) { LPC_I2C->CONCLR = 0X28; LPC_I2C->CONSET |= 0x20; //Set the Start Bit while(LPC_I2C->STAT!=0x10); //Wait for the Status Bit }
void I2C_Stop(void) { LPC_I2C->CONSET |= 0x14; //Stop I2C LPC_I2C->CONCLR = 0x08; }
void I2C_Write(unsigned char data,unsigned char status) { LPC_I2C->CONCLR = 0X28; LPC_I2C->DAT = data; LPC_I2C->CONCLR = 0X28; //Clear Start Flag and SI Interrupt //while(LPC_I2C->STAT!=status); //Wait for the Status Byte }
unsigned char I2C_Read(void) { LPC_I2C->CONCLR = 0X2C; //Cleat SI and Asset Acknowledgment Flag while(LPC_I2C->STAT!=0x58); return(LPC_I2C->DAT); }
//Timer interrupt void TIMER16_0_IRQHandler(void) { if(LPC_TMR16B0->IR & (1<<1)) //if match interrupt { I2C_Start(); I2C_Write(100,1); I2C_Stop(); } LPC_TMR16B0->IR = (1<<1); //reset timer interrupt flag }
Hope this is more clear. This code is trying to send some data through I2C at every timer interrupt. As I have wrote before with scope I cannot see any signals on SDA SCK pins.
I have found where it messed up. After posting to this forum. When I previewing it it looks ok, but after posting it it messed up. To overcome this problem I have upload it online here: http://txt.do/5uxdf Looking forward to any solutions.
If you had spent some time looking at the information presented to you before you posted, you could have ended up with code looking like:
#include <stdio.h> int main(void) { printf("Hello World!\n"); return 0; }
There is a reason why the posting instructions has a sentence starting with "Place source code between [...]".
Oh dear.
You can lead a horse to water but it's pretty damn crowded there because of all the men you tried to teach to fish with that other proverb.
Ok, no problem, but does anyone have answer to me topic instead of writing stupid jokes
-> In this forum I have found I2C example: -> http://www.keil.com/forum/58249/ The mentioned thread and the source code there, is for LPC1343, not for LPC1111. And you can't just copy some code from one project to another, without any understanding, expecting it would work for you.
Try to find some example designed for LPC1111. Study it before use it.
Thanks, jap I have checked. For me all registers used in this source code look the same. I suppose I2C is one of the simples communication way so it shouldn't be so hard, but I am strugling with it.
void I2C_Init(void) { LPC_SYSCON->PRESETCTRL |= (1<<1); //De-Asserts Reset Signal to I2C LPC_SYSCON->SYSAHBCLKCTRL |= (1<<5); //Enable I2C Clock LPC_IOCON->PIO0_4 &= ~0x3F; LPC_IOCON->PIO0_4 |= 0x01; //SCL LPC_IOCON->PIO0_5 &= ~0x3F; LPC_IOCON->PIO0_5 |= 0x01; //SDA
Can you confirm that for LPC1111, the PIO0_4, PIO0_5 are for I2C SCL, SDA?
Yes they are. I am using HVQFN 33 package of LPC1111. I am getting now pulse down on SCL and SDA pins every timer match interrupt. I have spoted one thing in me code that can be wrong:
I guess I need to exchange lines to this
I2C_Write(100,1); I2C_Start(); I2C_Stop();
I will check this later.
I have exchange lines and tested. LPC hangs in write function.
void I2C_Write(unsigned char data,unsigned char status). I don't know what argument "status" should be.
while(LPC_I2C->STAT!=status); //Wait for the Status Byte
Any ideas what status I need to wait for?
Thanks
And that's the core of your actual problem: instead of learning how I2C in general, or the I2C implementation on this micro actually works, you just start throwing wild guesses around. That's no way to develop low-level software.
And after roughly a half dozen hints, you still can't be bothered to format your source code properly. Combined these two indicate that you either cannot, or don't want to be helped.
Actually, I2C is rather more complicated than some - with all the Start Conditions, Stop Conditions, Addressing, ACKs, etc.
"I am strugling with it"
As already noted, you really do need to take some time to understand what's going on with both I2C in general and the I2C hardware within your particular microcontroller & peripheral.
The full I2C specification is here:
www.nxp.com/.../UM10204.pdf
The datasheet and/or User Manual for the microcontroller will explain how its I2C hardware works. Also check the manufacturer's website for examples, application notes, etc. In this case, NXP: www.nxp.com/.../8kb-flash-4kb-sram-hvqfn32-package:LPC1111FHN33
If you're using a library, you will need to study its documentation to find out how to use it effectively.
In this case (NXP), see also: http://www.lpcware.com/
or https://www.lpcware.com/
Thanks,
To learn from source examples is much easier for me, but looks like i will do try to study I2C basics.