|
|
View previous topic :: View next topic |
Author |
Message |
jayanthd
Joined: 06 Dec 2012 Posts: 47 Location: Banned - pirate
|
I2C Example needed *** Locked *** jayanthd banned for piracy |
Posted: Thu Mar 21, 2013 11:42 am |
|
|
Hello
I am new to CCS C Compiler. I need an example code for I2C Communication between one master PIC and 2 slave PICs. The slaves read temperatures from LM35 using ADC and display it on LCD connected to them. This data should be sent to master when master reads the slaves and the data is printed on the master's LCD.
LCD of slave 1 displays T1 = 25
LCD of slave 2 displays T2 = 50
LCD of master displays T1 = 25 T2 = 50
like that. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Mar 21, 2013 11:50 am |
|
|
Let me you give you general advice on sample code. I have posted, over
the years, a very large number of sample programs. Use the search page.
Search for:
For the author line, put it:
Also set for: Search for all Terms
You will find some useful code.
Do not immediately ask more questions. Try the code. Try it in
hardware. Don't expect i2c slave to work in Proteus. At least, it's not
easy. Proteus has too many strange features, such as "Analog pullup"
and "Digital pullup". All of these affect the i2c slave. I don't care
about Proteus. I don't want to, and won't help you make it work in
Proteus.
Also, read all the i2c slave threads. Learn from the mistakes of other
previous forum users.
The main point is don't irritate the forum by asking simple questions that
can be answered by you reading the CCS manual, and the forum
archives, etc. |
|
|
jayanthd
Joined: 06 Dec 2012 Posts: 47 Location: Banned - pirate
|
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sat Mar 23, 2013 3:41 am |
|
|
When the programs are as small as about 40-50 lines you can post them directly to this forum. Use the 'Code' button to preserve the text layout.
One big error in your main program is that you enable the SSP interrupt but there is no interrupt handler code present. Now, when I2C data is received the hardware will call the interrupt routine and never return. The processor hangs.
Do you really want to print the received data every 20ms? This will be faster than you can ever read.
Setting the TRIS registers is rarely done in the CCS compiler. The compiler will by default set the TRIS register on every input and output function call. More info can be found in the manual for the function '#USE STANDARD_IO'.
Here is your main program with a few changes:
- I removed all unneeded include files.
- Removed the lines for enabling the SSP interrupt
- Removed all TRIS setting lines.
- Added a delay of 500ms before starting the next slave reading loop. Code: | #include <16F887.h>
#fuses HS, NOWDT, PROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=20MHz) //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3)
#define SLAVE1_WRT_ADDR 0x14
#define SLAVE1_READ_ADDR 0x15
#define SLAVE2_WRT_ADDR 0x28
#define SLAVE2_READ_ADDR 0x29
#define LCD_ENABLE_PIN PIN_D2
#define LCD_RS_PIN PIN_D0
#define LCD_RW_PIN PIN_D1
#define LCD_DATA4 PIN_D4
#define LCD_DATA5 PIN_D5
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7
#include <lcd.c>
void main()
{
int8 data1,data2;
delay_ms(250);
lcd_init();
delay_ms(250);
lcd_putc("\fMaster...\n");
while(TRUE)
{
i2c_start();
i2c_write(SLAVE1_READ_ADDR);
data1 = i2c_read(0);
i2c_stop();
delay_ms(10);
i2c_start();
i2c_write(SLAVE2_READ_ADDR);
data2 = i2c_read(0);
i2c_stop();
delay_ms(10);
printf(" [ %3U %3U ] \r\n", data1,data2);
delay_ms(500);
}
} |
|
|
|
jayanthd
Joined: 06 Dec 2012 Posts: 47 Location: Banned - pirate
|
|
Posted: Sat Mar 23, 2013 4:34 am |
|
|
Thank you ckielstra
What I asked is is there any way I can attach .rar files to my posts. I have to attach project files in my posts. I know I can use code tags to post codes.
Is my master code correct? Will your slave code work? I will try your slave code.
I don't want the master to print the displayed data continuously. I will change the master code and make it print only if the value is changed.
I have a doubt. I don't see slave sending temp in the slave code i.e., i2c_write(temp); Then how does the value of temp in slave goes to master?
Also in master code why it is not writing the slave_wrt_address? Without sending the slave address how does slave respond?
Should not master send i2c_write(SLAVE1_WRT_ADDR); ??
Last edited by jayanthd on Sat Mar 23, 2013 4:53 am; edited 1 time in total |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Sat Mar 23, 2013 4:49 am |
|
|
Hi,
Would you please post a photo of your hardware? This might help us to understand what your problem might be!
Thanks!
John |
|
|
jayanthd
Joined: 06 Dec 2012 Posts: 47 Location: Banned - pirate
|
|
Posted: Sat Mar 23, 2013 4:59 am |
|
|
ezflyr wrote: | Hi,
Would you please post a photo of your hardware? This might help us to understand what your problem might be!
Thanks!
John |
Sorry I don't have a camera with me right now and the camera in my mobile doesn't have good resolution hence I can't post the circuit of my hardware. My circuit is ok. everything is working except i2c. I have posted the schematic (proteus file). That is my circuit. In hardware I have crystal, power supply and other things needed.
Somebody just give me the code for one master and one slave. In my project file for which I have provided the uppit link please check the master and slave codes.
Why master is not writing the slave address first?
Here is my circuit http://www.pixhost.org/show/2231/16397636_i2c_ms.jpg
See the code here https://www.ccsinfo.com/forum/viewtopic.php?t=36695
The master first sends the slave address but in my code master is not sending slave address.
Please somebody fix the i2c code of master and slave. |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sat Mar 23, 2013 5:31 am |
|
|
jayanthd wrote: | What I asked is is there any way I can attach .rar files to my posts. I have to attach project files in my posts. I know I can use code tags to post codes. | No, there is no option to attach files to your posts on this forum. What you did, post a link to an external website is one of the better options.
For us, we don't need all your project files, list files, hex files, etc. Just post your code for 1 master and 1 slave and we can help you improve on this.
The link to an external website has the disadvantage that over time these will stop working, so important information will get lost for people reading this thread in a few years.
Quote: | Is my master code correct? Will your slave code work? I will try your slave code. | I posted master code...
Quote: | I don't want the master to print the displayed data continuously. I will change the master code and make it print only if the value is changed. | Bad idea. For a first test, keep it simple as possible. The advantage of a running text is that you get confirmation the program is still running.
Quote: | I have a doubt. I don't see slave sending temp in the slave code i.e., i2c_write(temp); Then how does the value of temp in slave goes to master? | I assumed this was intentional. ??
Your slave, as it is, always sends the same code to the master. Good for testing because then you know communication is working. For sending the real temperature value to the master you have to make a few small changes. I want to leave that to you as an exercise. You are the student given a task, I don't want to do your work and you not learning anything.
Quote: | Also in master code why it is not writing the slave_wrt_address? Without sending the slave address how does slave respond?
Should not master send i2c_write(SLAVE1_WRT_ADDR); ?? | Well.... it helps when you do a tiny bit of reading on the I2C protocol.
In I2C the address is in the 7 most significant bits, the remaining least significant bit defines read or write request. Code: | #define SLAVE1_WRT_ADDR 0x14
#define SLAVE1_READ_ADDR 0x15 | Defining the address like this is confusing because now it looks like there are two different addresses, but there is only one: 0x14 == 0b0001 0100 ==> 7 bits == 0b0000 1010 == 0x0A
When you call I2C_read() the device driver will replace the LSB automagically by a 1
Many people have problems with this addressing thing and it depends on the driver you are using whether you have to pass the 7 address bits in the upper or lower part of the byte you send to the driver.
If you want more or better example code, then I suggest you do some more digging. The last week several more I2C questions have popped up, I assume from others students in your class? All these people were given hints. With a little bit of effort you should be able to find tons of information on the I2C topic in this forum.
Have you even tried to look in the CCS Examples directory on your computer? The manual has a short explanation of each example. |
|
|
jayanthd
Joined: 06 Dec 2012 Posts: 47 Location: Banned - pirate
|
|
Posted: Sat Mar 23, 2013 5:39 am |
|
|
ckielstra
Here is my Master and Slave codes
Quote: | but there is only one: 0x14 == 0b0001 0100 ==> 7 bits == 0b0000 1010 == 0x0A |
How did you get this? 0b0000 1010?
Ok. I got it. 7 MSB = 0000 101 and this is converted to 0000 1010 to make it eight bits and it becomes 0x0A
Quote: | The last week several more I2C questions have popped up, I assume from others students in your class? |
I am not a student. I am a working professional. I have done a lot of projects including i2c and spi with Hi Tech C, C18, XC, mikroC, Wiz-C Compilers. I am new to CCS C Compiler. I just want know how to do i2c in CCS C.
Is there any option in CCS C to see the inside code of library functions like i2c_read(), i2c_start(), i2c_write(), etc...?
MASTER CODE
Code: | #include <16F887.h>
#device adc=10
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=20000000) //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(Master, sda=PIN_C4, scl=PIN_C3, FORCE_HW)
#define SLAVE1_WRT_ADDR 0x14
#define SLAVE1_READ_ADDR 0x15
#define SLAVE2_WRT_ADDR 0x28
#define SLAVE2_READ_ADDR 0x29
int8 data1 = 0, data2 = 0, pdata1 = 0, pdata2 = 0;
#define LCD_ENABLE_PIN PIN_D2
#define LCD_RS_PIN PIN_D0
#define LCD_RW_PIN PIN_D1
#define LCD_DATA4 PIN_D4
#define LCD_DATA5 PIN_D5
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7
#include <lcd.c>
void main()
{
//set_tris_c(0b10111111);
set_tris_d(0x00);
output_c(0x00);
output_d(0x00);
delay_ms(250);
lcd_init();
delay_ms(250);
lcd_putc("\fMaster...\n");
//enable_interrupts(INT_SSP);
//enable_interrupts(GLOBAL);
while(TRUE)
{
i2c_start();
i2c_write(SLAVE1_READ_ADDR);
data1 = i2c_read(0);
i2c_stop();
delay_ms(10);
i2c_start();
i2c_write(SLAVE2_READ_ADDR);
data2 = i2c_read(0);
i2c_stop();
delay_ms(10);
if((data1 !=pdata1) || (data2 != pdata2)) {
printf(" [ %3U %3U ] \r\n", data1,data2);
pdata1 = data1;
pdata2 = data2;
delay_ms(500);
}
delay_ms(1000);
}
} |
SLAVE CODE
Code: | #include <16F887.h>
#device adc=10
#include <ctype.h>
#include <errno.h>
#include <math.h>
#include <string.h>
#fuses HS, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=20000000) //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x14, FORCE_HW)
#define LCD_ENABLE_PIN PIN_D2
#define LCD_RS_PIN PIN_D0
#define LCD_RW_PIN PIN_D1
#define LCD_DATA4 PIN_D4
#define LCD_DATA5 PIN_D5
#define LCD_DATA6 PIN_D6
#define LCD_DATA7 PIN_D7
#include <lcd.c>
float temp = 0, old_val = 0, i2csend = 0;
#INT_SSP
void ssp_interrupt()
{
int8 incoming, state;
state = i2c_isr_state();
if(state < 0x80) // Master is sending data
{
incoming = i2c_read();
}
if(state >= 0x80) // Master is requesting data from slave
{
i2c_write(14);
}
}
void main()
{
int16 adc_val = 0;
set_tris_a(0xFF);
set_tris_c(0b10111111);
set_tris_d(0x00);
output_a(0x00);
output_c(0x00);
output_d(0x00);
setup_adc_ports(sAN0|VREF_VREF);
setup_adc(ADC_CLOCK_DIV_2);
setup_comparator(NC_NC_NC_NC);// This device COMP currently not supported by the PICWizard
delay_ms(250);
lcd_init();
delay_ms(250);
lcd_putc("\fSlave 1...\n");
delay_ms(1000);
set_adc_channel(0);
delay_us(20);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
while(TRUE)
{
adc_val = read_adc();
delay_ms(20);
temp = (float)(adc_val * 0.196078431372549);
if(old_val != temp){
printf(lcd_putc, "\f%3.4f", temp);
printf("Temperature is: %3.4f", temp);
printf(" Degree Centigrade\r\n");
}
old_val = temp;
}
} | [/quote] |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Sat Mar 23, 2013 6:34 am |
|
|
Quote: | I am not a student. I am a working professional. I have done a lot of projects including i2c and spi with Hi Tech C, C18, XC, mikroC, Wiz-C Compilers. I am new to CCS C Compiler. I just want know how to do i2c in CCS C. | PCM programmer has already pointed you in the right direction.
I can't tell from your latest post exactly what your problem is.
I suggest:-
1) Start with your master and a standrd I2C peripheral.
2) Get that to work first, with CCS code.
3) If 1) doesn't work use PCM p's diagnostic to sort it out.
4) When 1) works progress to a slave. Use the CCS sample slave code.
5) Work in small simple stages.
6) When you have a problem tell us what you've done, what works and what doesn't.
Simply saying "does not work" is not very helpful.
You're making us all guess.
You're the one wanting help, you need to give us as much useful information as possible so that we can help you.
Mike |
|
|
jayanthd
Joined: 06 Dec 2012 Posts: 47 Location: Banned - pirate
|
|
Posted: Sat Mar 23, 2013 6:59 am |
|
|
I have posted the codes as mentioned. I just need a sample code for master and slave.
What is PCM p's diagnostic. Where is it and how to use it?
I am testing in hardware and also proteus but none is working. I know proteus is not supported but proteus tells Unsupported mode.
http://www.pixhost.org/show/3164/16398879_error.jpg
This might help people analyse and help me.
http://www.pixhost.org/show/3164/16398899_i2cdbg.jpg
Actually Master is not giving out SCL
Last edited by jayanthd on Sat Mar 23, 2013 7:16 am; edited 1 time in total |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Sat Mar 23, 2013 7:11 am |
|
|
Quote: | I am not a student. I am a working professional. I have done a lot of projects including i2c and spi with Hi Tech C, C18, XC, mikroC, Wiz-C Compilers. I am new to CCS C Compiler. I just want know how to do i2c in CCS C | I do believe you. It's just that:* you are working on a Saturday,
* I2C hasn't been asked for the last months and now 3 times in a week
* your code has several coding constructs that a seasoned programmer would do different.
Quote: | Is there any option in CCS C to see the inside code of library functions like i2c_read(), i2c_start(), i2c_write(), etc...? | Inside pic16F887.h place the line with #NOLIST in comments.
What bothers me is that I gave you a hint to do something, but you didn't do it. (the TRIS registers, which is a bug now)
Another hint I gave was to not do something, but you did. (keeping your code short and simple until proven to work).
You ask for help but decide not to follow it up. Not very encouraging. |
|
|
jayanthd
Joined: 06 Dec 2012 Posts: 47 Location: Banned - pirate
|
|
Posted: Sat Mar 23, 2013 7:20 am |
|
|
Quote: | I do believe you. It's just that: |
I can't prove. All I can say is I am a working professional with 10 years experience in embedded and PC programming.
I am using CCS C since 3 days and I have already done ADC project with it.
I did all the things you told. I commented the tris in master and slave and tried but it didn't work.
I changed the line #NOLIST to //#NOLIST and compiled but it didn't show me the code of functions. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Sat Mar 23, 2013 7:30 am |
|
|
With #nolist remmed out, the code will be in the .LST file. Normally it is omitted.
Best Wishes |
|
|
jayanthd
Joined: 06 Dec 2012 Posts: 47 Location: Banned - pirate
|
|
Posted: Sat Mar 23, 2013 7:54 am |
|
|
Ttelmah wrote: | With #nolist remmed out, the code will be in the .LST file. Normally it is omitted.
Best Wishes |
Here is one of the projects I did using mikroC. It used I2C RTC and USB
http://www.edaboard.com/thread271146.html |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|