|
|
View previous topic :: View next topic |
Author |
Message |
tonkostz
Joined: 07 May 2011 Posts: 56 Location: Bulgaria
|
I2C scanner code not working on PIC18F4550 |
Posted: Tue Dec 24, 2024 8:16 am |
|
|
I having issues with comunicating with FM transmitter chip QN8007.
Chip by default is controlled by a STC12C5A60S2 mcu but many functions can't be used so my idea is to replace that mcu witn PIC18F4550 and control it myself.
According to the chip datasheet, default address is: 0101011 (0x2B)
I'm using i2c for the first time and i'm not sure how exactly works.
For example i want to communicate to a device register at address 0x01 and write in that register 0x80.
My defines are as follows:
Code: |
#include <18F4550.h>
#device adc=10
#fuses HSPLL,PLL5,CPUDIV1,NOWDT,MCLR,NOLVP,USBDIV,VREGEN
#use delay(clock=48000000)
#use i2c(master,Fast=100000,sda=PIN_B0,scl=PIN_B1,SMBUS) // Configure Device as Master |
How should my code be?
Code: |
i2c_start();
i2c_write(0x2B) //device address
i2c_write(0x01) //register address
i2c_write(0x80) //register data to be written
i2c_stop();
delay_ms(100);
|
Would you help with the right commands on the i2c bus?
Last edited by tonkostz on Thu Dec 26, 2024 4:14 am; edited 2 times in total |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1912
|
|
Posted: Tue Dec 24, 2024 10:24 am |
|
|
Base address of an I2C chip cannot be odd so I suspect that the address you have is the 7 bit address. Bit shift that left one (x2) for an 8 bit address of 0x56. |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1946 Location: Norman, OK
|
|
Posted: Tue Dec 24, 2024 3:49 pm |
|
|
Driver info for the chip is located here:
https://github.com/gabriel-tenma-white/qn8007_fm_tx
It looks like you can get all your register defines from here to avoid having to
start from scratch. Porting the code to CCS should be pretty straightforward
but will take some time since there are lot of functions. _________________ Google and Forum Search are some of your best tools!!!! |
|
|
tonkostz
Joined: 07 May 2011 Posts: 56 Location: Bulgaria
|
|
Posted: Wed Dec 25, 2024 12:15 am |
|
|
Thanks!
I wonder how the i2c reads/writes can be represented in this way?:
Code: | QND_WriteReg(CH_STOP, tS); |
Maybe i have to define a function QND_WriteReg somewhere and use it multiple time without using i2c_write() each time?
It's very clear that we write in register CH_STOP the tS value.
How will be in CCS?
Code: |
i2c_start();
i2c_write(DEVICE_ADDRESS); //should i write the device's address each time?
i2c_write(CH_STOP); //address of register CH_STOP
i2c_write(tS); //can i write the value tS in this way?
i2c_stop();
|
|
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1946 Location: Norman, OK
|
|
Posted: Wed Dec 25, 2024 6:53 am |
|
|
Yes, making your own function is the best approach.
Do a quick search on the term writereg and you will find a number of examples
how to make your own writereg type functions. Here is one:
http://www.ccsinfo.com/forum/viewtopic.php?t=59960&highlight=writereg
Also recommend using the I2C scanner in the Code Library to "find" the device
on the I2C bus and make sure you can communicate with it. If it doesn't "see"
the device you likely have I2C bus issues that also need to be addressed. _________________ Google and Forum Search are some of your best tools!!!! |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9370 Location: Greensville,Ontario
|
|
Posted: Wed Dec 25, 2024 12:22 pm |
|
|
Yes, I 2nd the 'use I2C Scanner program' !!!
Also be sure you use the correct I2C buss pullup resistors.
4k7 for 5 volt PICs
3k3 for 3 volt PICs
are good starting values
Once you've confirmed the hardware IS there, then the rest is 'just' code...... |
|
|
tonkostz
Joined: 07 May 2011 Posts: 56 Location: Bulgaria
|
|
Posted: Thu Dec 26, 2024 3:07 am |
|
|
I have tried the I2C scanner program and it behaves strange. It shows Start and after that ACK with changing addresses in 2 seconds. After some time it stops on address EE and shows I2C: 112 (112 devices found?). The chip QN8007 is powered from +3.3V and the PIC +5V. There are 3K pull-up resistors to +3.3V. I have tried many things as slowing the mcu clock and using different options in #use_i2c with no result. I can confirm that the QN8007 is working well because i have the original board that controls it with STC mcu. Interesting thing there is that the STC mcu is powered from +4V, with no pull-up resistors for the SDA and SCL pins. Also there are 100ohms series resistor on both lines. The only thing i changed from the original i2c scanner code, is to use a 8x2 LCD display instead of using the serial port. Here is the code:
Code: |
#include <18F4550.h>
#device adc=10
#fuses HSPLL,PLL5,CPUDIV1,NOWDT,MCLR,NOLVP,VREGEN,NOPROTECT
#use delay(clock=48000000)
#use i2c(master,slow,sda=PIN_B0,scl=PIN_B1)
#define LCD_E PIN_D1
#define LCD_RS PIN_D0
#define LCD_DB4 PIN_D2
#define LCD_DB5 PIN_D3
#define LCD_DB6 PIN_D6
#define LCD_DB7 PIN_D4
#include "LCD8x2.c"
// This function writes the slave address to the i2c bus.
// If a slave chip is at that address, it should respond to
// this with an "ACK". This function returns TRUE if an
// ACK was found. Otherwise it returns FALSE.
int8 get_ack_status(int8 address)
{
int8 status;
i2c_start();
status = i2c_write(address); // Status = 0 if got an ACK
i2c_stop();
if(status == 0) return(TRUE);
else return(FALSE);
}
void main()
{
unsigned int8 i;
unsigned int8 status;
unsigned int8 count = 0;
set_tris_b(0b00000011); //set B0 and B1 as inputs 0x03
delay_ms(500); //needed 0.5s delay for the LCD
lcd_init();
lcd_gotoxy(1,1);
printf(lcd_putc,"Start: ");
lcd_gotoxy(1,2);
printf(lcd_putc," ");
delay_ms(1000);
// Try all slave addresses from 0x10 to 0xEF.
// See if we get a response from any slaves
// that may be on the i2c bus.
for(i=0x10; i < 0xF0; i+=2)
{
status = get_ack_status(i);
if(status == TRUE)
{
lcd_gotoxy(1,1);
printf(lcd_putc,"ACK:%X ", i);
count++;
delay_ms(2000); //2000
}
}
if(count == 0)
{
lcd_gotoxy(1,1);
printf(lcd_putc,"Nothing ");
lcd_gotoxy(1,2);
printf(lcd_putc," ");
}
else
{
lcd_gotoxy(1,2);
printf(lcd_putc,"i2c:%u ",count);
}
while(1);
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19649
|
|
Posted: Thu Dec 26, 2024 5:24 am |
|
|
You cannot mix a 3.3v I2C device with a 5v PIC, without level translation
hardware.
Now actually there are ways.
The point is that the I2C _hardware_ requires the input signal on the I2C
bus to go up to 4v. Obviously an I2C bus pulled up to 3.3v won't do this.
Hence disaster.
You can work by using inputs on the PIC that support TTL signal levels,
and setting up a software I2C. Obviously means the code is a bit larger,
but this will work fine. If you look in the data sheet 'Pinout I/O DESCRIPTIONS',
and look for pins that say 'TTL'. In your case the hardware pins support this
when used for normal I/O, so if you change your I2C setup to:
#use i2c(master,slow,sda=PIN_B0,scl=PIN_B1, FORCE_SW)
it should work.
You may also be able to get it to work by telling the code to use SMBUS
signal levels instead of I2C. So;
#use i2c(master,slow,sda=PIN_B0,scl=PIN_B1, SMBUS)
This may work, but on some chips gives problems.
Otherwise you need an I2C level translator between the chips. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9370 Location: Greensville,Ontario
|
|
Posted: Thu Dec 26, 2024 7:15 am |
|
|
As Mr. T points out you can't connect 3V peripherals to 5 V PICS, directly.
Other possible options are
1) use the 'L'ow voltage version of the 4550 (PIC18LF4550.. )
2) use another PIC that runs on 3 volts
3) use logic level translation between the 2
I suspect #3 is your best choice as you have an LCD module,which probably requires 5 volts
Probably 99.44% of all peripheral devices are 3 volts,so you may want to consider choosing a PIC like the 18F46K22 that can run on 3 or 5 volts, especially if you plan on many,many projects.
If you choose a 3 volt only PIC, you can run a 5 v LCD module. All it requires is a free timer to generate a square wave, 2 caps and 2 diodes to make a voltage doubler. One of those 'tips 'n tricks' I've used years ago. |
|
|
tonkostz
Joined: 07 May 2011 Posts: 56 Location: Bulgaria
|
|
Posted: Fri Dec 27, 2024 4:05 am |
|
|
Update: I have checked with a scope and there are pulses on both pins SDA and SCL during the i2c scanner is running but the program does not find any device. Status never gets "0".
I have made more tests this time with different mcu PIC18F23K20. Now both the mcu and the fm transmitter chip QN8007 are powered from +3.3V. There are 3K3 pull-ups on the SDA and SCL pins.
Result is that the simple I2C scanner program won't find anything but keeps counting from the start address to the end address.
Once again to check if the slave chip is working i insert the original control board with the STC mcu and everything works - there is communication with the chip. Ideas?
In the QN8007 datasheet I2C is not mentioned anywhere. They say "2-wire serial control interface". If this is not I2C communication, what could it be and how to control it?
Here is my code now:
Code: |
#include <18F23K20.h>
#device adc=10
#fuses INTRC_IO,NOMCLR,NOWDT,NOBROWNOUT,NOPROTECT
#use delay(clock=2M)
#use i2c(master,sda=PIN_C4,scl=PIN_C3)
#define LCD_DB4 PIN_C2
#define LCD_DB5 PIN_C0
#define LCD_DB6 PIN_C1
#define LCD_DB7 PIN_C7
#define LCD_RS PIN_A7
#define LCD_E PIN_A6
#include <LCD8x2.c>
// This function writes the slave address to the i2c bus.
// If a slave chip is at that address, it should respond to
// this with an "ACK". This function returns TRUE if an
// ACK was found. Otherwise it returns FALSE.
int8 get_ack_status(int8 address)
{
int8 status;
i2c_start();
status = i2c_write(address); // Status = 0 if got an ACK
i2c_stop();
if(status == 0) return(TRUE);
else return(FALSE);
}
void main()
{
unsigned int8 i;
unsigned int8 status;
unsigned int8 count = 0;
delay_ms(500); //needed 0.5s delay for the LCD
lcd_init();
lcd_gotoxy(1,1);
printf(lcd_putc,"Start: ");
lcd_gotoxy(1,2);
printf(lcd_putc," ");
delay_ms(1000);
// Try all slave addresses from 0x10 to 0xEF.
// See if we get a response from any slaves
// that may be on the i2c bus.
for(i=0x10; i < 0xF0; i+=2)
{
status = get_ack_status(i);
if(status == TRUE)
{
lcd_gotoxy(1,1);
printf(lcd_putc,"ACK:%X ", i);
count++;
delay_ms(2000); //2000
}
}
if(count == 0)
{
lcd_gotoxy(1,1);
printf(lcd_putc,"Nothing ");
lcd_gotoxy(1,2);
printf(lcd_putc," ");
}
else
{
lcd_gotoxy(1,2);
printf(lcd_putc,"i2c:%u ",count);
}
while(1);
}
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9370 Location: Greensville,Ontario
|
|
Posted: Fri Dec 27, 2024 7:28 am |
|
|
OK, I got curious..downloaded a datasheet for the qn8007
It is NOT 'I2C', it IS 'I2S' !! Chapter 3.1...
Sounds like a variation on the I2C standard that Philips came out with ,decades ago. I 'think' it's used for audio / home use type equipment ?? 'S' for Sound or Stereo or Simple ?? I'm sure others will know.
You'll have to Google and read up about it to see what the differences are.
Also in my quik look, I see a pin used to control how to access it,so again, you'll need to be sure you've got the hardware wired properly.
3volt PIC, 3k3, 3 volt peripheral is great,so that's a great start.
ok, one google ...
What is the difference between I2S and I2C (I2C vs I2S)? I2C is 2 wire protocol and I2S is 3 wire protocol. I2C supports clock stretching and I2S does not have clock stretching. I2C has an extra overhead start and stop bits and I2S does not have any start and stop bits.
so you WILL have to do a lot more reading !!!
I found the QN8007B.pdf, well google did. It EXPLAINS how to setup the THREE wire I2S connections and HOW communications is done. Chapter 6. also has ALL the registers and what they do..... |
|
|
tonkostz
Joined: 07 May 2011 Posts: 56 Location: Bulgaria
|
|
Posted: Fri Dec 27, 2024 9:56 am |
|
|
I2S is the Digitial Audio Interface Protocol. Chip can transmit music from USB flash too which communicates on different pins via I2S.
Control is via 2-wire or 3-wire serial control interface and it is properly configured on the board - 2-wire interface is selected and the default 7-bit IC address is 0101011.
All looks like I2C to me - see the timing diagrams. There is a ACK bit too.
I see all the registers but i want to make sure i am able to communicate with the chip and then i will think about the registers.
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9370 Location: Greensville,Ontario
|
|
Posted: Fri Dec 27, 2024 10:22 am |
|
|
so , is SEB high or low ? That's really important to confirm.
I've never used I2S but there might be something it needs that I2c doesn't.
Maybe others who have used it can reply soon !!! |
|
|
tonkostz
Joined: 07 May 2011 Posts: 56 Location: Bulgaria
|
|
Posted: Fri Dec 27, 2024 10:36 am |
|
|
SEB is connected to ground - it is low. I2S is only for the audio to the chip on different pins. SDA and SCL are for the 2-wire serial control interface. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19649
|
|
Posted: Fri Dec 27, 2024 12:42 pm |
|
|
The interface in 2 wire mode is I2C on the control interface. It should
respond to the scanner program.
One important thing though. This chip is very slow to wake. You need
to wait about 3/4 second after the PIC wakes before making any attempt
to talk to it. |
|
|
|
|
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
|