PDA

View Full Version : Giao tiếp I2C


falleaf
07-09-2006, 11:54 PM
Bài báo cáo này do Nguyễn Chí Linh thực hiện trong thời gian làm mod của picvietnam, nhưng không hiểu sao vẫn chưa được đăng. Hôm nay thấy bên dientuvietnam thảo luận về vấn đề này, cho nên mới tìm lại bài báo cáo này và gửi lên.

Chúc vui

bien_van_khat
08-09-2006, 06:19 PM
Em post 1 bài ngoài vấn để kỹ thuật nhé. Chữ I2C đọc là gì nhỉ? Nguyên gốc của nó là IIC hoặc viết I2C nhưng số 2 viết nhỏ phía trên giống số mũ. Có người đọc là "Ai chu xi" (I 2 C đánh vần tiếng Anh :D), em nghĩ đúng phải đọc là "Double I C", tương tự như IEEE đọc là (I triple E).

Nhưng em thích đọc là I 2 C (đánh vần tiếng Việt :D). Không biết mọi người đọc như thế nào nhỉ?

namqn
08-09-2006, 07:14 PM
Em post 1 bài ngoài vấn để kỹ thuật nhé. Chữ I2C đọc là gì nhỉ? Nguyên gốc của nó là IIC hoặc viết I2C nhưng số 2 viết nhỏ phía trên giống số mũ. Có người đọc là "Ai chu xi" (I 2 C đánh vần tiếng Anh :D), em nghĩ đúng phải đọc là "Double I C", tương tự như IEEE đọc là (I triple E).

Nhưng em thích đọc là I 2 C (đánh vần tiếng Việt :D). Không biết mọi người đọc như thế nào nhỉ?
Dân Anh đọc là "ai tu xi", tiếng của họ thì mình cứ đọc theo họ thôi. Đọc "double I C" thì dài hơn "ai tu xi" nên họ không đọc (dân Anh lười lắm), còn tại sao đọc "triple E" thì thử so sánh "I E E E" với "I triple E" xem cái nào dễ đọc hơn (cùng số âm tiết).

Thân,

falleaf
09-09-2006, 01:22 PM
Em post 1 bài ngoài vấn để kỹ thuật nhé. Chữ I2C đọc là gì nhỉ? Nguyên gốc của nó là IIC hoặc viết I2C nhưng số 2 viết nhỏ phía trên giống số mũ. Có người đọc là "Ai chu xi" (I 2 C đánh vần tiếng Anh :D), em nghĩ đúng phải đọc là "Double I C", tương tự như IEEE đọc là (I triple E).

Nhưng em thích đọc là I 2 C (đánh vần tiếng Việt :D). Không biết mọi người đọc như thế nào nhỉ?

Thực ra, mọi người vẫn đọc là "Eye two See". Đây là cách đọc chính xác, không sai. Một cách đọc khác là "Eye square See", đây cũng là một cách đọc đúng. Còn "Double Eye See" thì anh chưa nghe đọc bao giờ. Những cách nói này là anh nói chuyện trực tiếp với bọn nước ngoài, và bọn nó dùng như vậy.

Còn "Eye Triple E" là cách đọc được ghi chú trực tiếp trên trang ieee.org. Ở Pháp thì nó lại đọc (anh viết tiếng Việt) "Y troa dsơ" Cũng đồng nghĩa với I và 3 chữ E.

Do vậy, từ nay về sau, thống nhất trên PICVietnam, chúng ta đọc I2C là "Eye two See", chứ không đọc "Eye Square See" (đề phòng trường hợp cần voice chat, sẽ có một ngày đại hội picvietnam online), còn khi viết thì viết I2C cho nhanh, chứ không nên viết I^2C rất mất công viết công thức Latex.

Chúc vui.

thanhha
11-09-2006, 10:51 AM
Vì mình đang viết thử I2C. Thấy chương trình mẫu(EX_Slave) trong CCS C mô phỏng bộ nhớ ngoài 24xx chuẩn, nên nạp chạy thử thấy: viết từ Master (Ctr Mater lấy ví dụ: EX_EXTEE) ít nhất là 4 lần mới được, còn đọc thì lại ko được. Xem tài liệu thì thấy có rất nhiều bit bẫy tình huống I2C, nhưng các lệnh về I2C trong CCS thì đơn giản và ít. Vậy, có vấn đề gì không.


#include <16F876A.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7) // Jumpers: 8 to 11, 7 to 12


#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0xa0)

typedef enum {NOTHING, CONTROL_READ,
ADDRESS_READ, READ_COMMAND_READ} I2C_STATE;

I2C_STATE fState;
BYTE address, buffer[0x10];


#INT_SSP
void ssp_interupt ()
{
BYTE incoming;

if (i2c_poll() == FALSE) {
if (fState == ADDRESS_READ) { //i2c_poll() returns false on the
i2c_write (buffer[address]);//interupt receiving the second
fState = NOTHING; //command byte for random read operation
}
}
else {
incoming = i2c_read();

if (fState == NOTHING){
fState = CONTROL_READ;
}
else if (fState == CONTROL_READ) {
address = incoming;
fState = ADDRESS_READ;
}
else if (fState == ADDRESS_READ) {
buffer[address] = incoming;
fState = NOTHING;
}
}
}


void main ()
{
int i;

fState = NOTHING;
address = 0x00;
for (i=0;i<0x10;i++)
buffer[i] = 0x00;

enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);

while (TRUE) {}
}

thanhha
12-09-2006, 11:25 AM
Có ai quan tâm vấn đề I2C trong CCS, cho Hà hỏi 1 chút:
i2c_isr_state() hình như không có trong V 3.227. Version này chỉ có các lệnh I2C cho 16F877A là: i2c_start(), i2c_stop(), i2c_read(),i2c_write(), i2c_poll().
Có phải vậy không. Nếu vậy, mình phải tự tạo i2c_irs_state(). Có phải vậy ko?!.

Vì trong Help V4.0,có nói đến i2c_isr_state(), còn Help V3.227 Hà đang dùng thì ko thấy nói đến.
Có ai rành I2C, chỉ giáo giùm chút ít kinh nghiệm.Xin rất cảm ơn!!

hoanf
12-09-2006, 12:52 PM
Chào Hà.
Tui cũng đang mò làm I2C trên CCS đây.
Hà nói là phiên bản 3.227 kô có i2c_irs_state(). Vậy sao Hà kô tải V3.249 về làm.
Mình hi vọng tui cả Hà sẽ cùng nghiên cúu vấn đề này.
Chào
hoanf

thanhha
12-09-2006, 01:00 PM
Hà đang tìm đường link để tải Version khác cao hơn: V3.242 thì sáng tới giờ ko thấy gì. Vậy, mình tìm thử V3.249 xem sao.

Bạn biết link V3.249 thì hướng dẫn Hà với !!
Rất cảm ơn !!!

Thanhha

hoanf
12-09-2006, 02:52 PM
Chào bạn.
Bạn có thể tải bản V3.249 ở đây
http://rapidshare.de/files/32817261/CCSC_3.249.rar

hoanf

thanhha
13-09-2006, 01:59 PM
Hà vừa thử chtr I2c: Master 16F877A, Slave 16F876A, cùng giao tiếp PC để kiểm tra dữ liệu đọc và viết của Master và Slave> Thấy rất tốt ! I2C hay thiệt! Nhiêm vụ bây giờ mình chỉ tạo giao thức dữ liệu, còn chtr service plug&play slave thì thấy hơi khó! Nhưng mònh cố gắn viết thử. Cảm ơn Hoanf, mọi người rất nhiều !!

**********************************************
Chtr Master, mình thay đổi chút ít từ chtr mẫu EX_EXTEE.
1.chỉ liên kết 2401.c (thay vì địa chỉ mặc đinh là 0xa0,
mình thay là 0x10).
2. Vẫn truyền lệnh từ PC
**********************************************
#include <16F877A.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#include <input.c>
#include <2401.c>


void main() {

BYTE value, cmd;
EEPROM_ADDRESS address;

init_ext_eeprom();

do {
do {
printf("\r\nRead or Write: ");
cmd=getc();
cmd=toupper(cmd);
putc(cmd);
} while ( (cmd!='R') && (cmd!='W') );

printf("\n\rLocation: ");

address = gethex1();

if(cmd=='R')
printf("\r\nValue: %X\r\n",READ_EXT_EEPROM( address ) );

if(cmd=='W') {
printf("\r\nNew value: ");
value = gethex();
printf("\n\r");
WRITE_EXT_EEPROM( address, value );
}
} while (TRUE);
}




**********************************************
Chtr Slave, thì có thay đổi chút ít từ chtr mẫu EX_Slave:
1. giám sát 3 ô nhớ trên PC
2. khai báo địa chỉ la 0x10.
**********************************************
#include <16F876A.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10)

BYTE address, buffer[0x10];

#INT_SSP
void ssp_interupt ()
{
BYTE incoming, state;

state = i2c_isr_state();

if(state < 0x80) //Master is sending data
{
incoming = i2c_read();
if(state == 1) //First received byte is address
address = incoming;
if(state == 2) //Second received byte is data
buffer[address] = incoming;
}
if(state == 0x80) //Master is requesting data
{
i2c_write(buffer[address]);
}
}

void main ()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);

while (TRUE) {
printf("\r\nValue0: %X\r\n",buffer[0]);
delay_ms(1000);
printf("\r\nValue1: %X\r\n",buffer[1]);
delay_ms(1000);
printf("\r\nValue2: %X\r\n",buffer[2]);
delay_ms(1000);
printf("\r\nValue3: %X\r\n",buffer[3]);
delay_ms(1000);
}
}
******************************************
Phần mạch điện có File đính kèm :

falleaf
13-09-2006, 04:48 PM
Anh đề nghị em post thêm sơ đồ mạch nguyên lý đi kèm. Thực ra không có gì phức tạp cả, chỉ vì bài viết mà chỉ có code không thôi thì nó không sinh động. Hơn nữa, người sau đọc vào không có hình ảnh đi kèm, nhiều khi người ta không hiểu nổi và ngại đọc. Chỉ cần có một cái hình vào, thì bài viết sẽ sinh động hơn nhiều.

Chúc vui.

hoanf
13-09-2006, 05:24 PM
Chào các bạn và Hà.
Mình mới viết được chương trình giao tiếp I2C đơn giản dùng các hàm của CCS.
Mời các bạn xem và cho nhận xét

Master: truyền dữ liệu cho Slave. Mỗi lần truyền 1 byte.


#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use Delay(Clock=4000000)

#define SLAVE_ADDRESS 0x10
#use i2c(master, sda=PIN_C4, scl=PIN_C3)

void write_I2C(int8 a)
{
i2c_start();
i2c_write(SLAVE_ADDRESS);
i2c_write(a);
i2c_stop();
}

void main()
{
int8 value;

value = 0;
while(1){
write_I2C(value);
value++;
delay_ms(100);
}
}


Slave thì chỉ tiến hành kiểm tra có phải Master truyền hay kô. Nếu truyền thì nhận byte dữ liệu và hiển thị lên port_B:

#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#use delay(Clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10)

int8 value;

#INT_SSP
void i2c_isr()
{
int8 state;
int8 address;
state = i2c_isr_state();
if(state == 0)
address = i2c_read();
else if(state < 0x80)
value = i2c_read();
}

void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);

set_tris_b(0x00);
while(1){
output_b(value);
}
}

Thân
hoanf

hoanf
14-09-2006, 12:34 PM
Chào các bạn!!
Mình gặp trục trặc khi đọc dữ liệu từ Slave về.
Đây là đoạn code sử dụng cho 2 con PIC 18F877A.

Master: Yêu cầu Slave nhận dữ liệu liên tục (cách nhau 500ms) và nó sẽ hiển thị giá trị nhận được lên Port_b. Dùng leds để quan sát.


#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use Delay(Clock=4000000)

#define SLAVE_ADDRESS 0x10
#use i2c(master, sda=PIN_C4, scl=PIN_C3)

int8 read_I2C()
{
int8 value;

i2c_start();
i2c_write(SLAVE_ADDRESS + 1);
value = i2c_read();
i2c_stop();
return value;
}

void main()
{
int8 value;

set_tris_b(0x00);

while(1){
value = read_I2C();
output_b(value);
delay_ms(500);
}
}

Slave: Truyền dữ liệu cho master và mỗi lần truyền thì giá trị cần truyền tăng lên 1 đơn vị.

#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#use delay(Clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10)

int8 value = 0x01;

#INT_SSP
void i2c_isr()
{
int8 state;
int8 address;
state = i2c_isr_state();
if(state >= 0x80){
i2c_write(value);
value++;
}
}

void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);

set_tris_b(0x00);
while(1){
output_b(value);
}
}

thanhha
14-09-2006, 04:24 PM
Theo Hà nghĩ, ở Master, khi mình đọc cũng phải chờ xung ACK từ Slave thì chtr ko bị rối.
Bạn thử thêm một chtr con chờ Bus trong <2401.c>:


//**************code thêm vào*********************
BOOLEAN ext_eeprom_ready()
{
int1 ack;
i2c_start();
ack = i2c_write(SLAVE_ADDRESS);
i2c_stop();
return !ack;
}
//**********************************************
int8 read_I2C()
{
int8 value;
while(!ext_eeprom_ready()); // code thêm vào
i2c_start();
i2c_write(SLAVE_ADDRESS + 1);
value = i2c_read();
i2c_stop();
return (value);
}

void main()
{
int8 value;

value = 0x00;
set_tris_b(0x00);

while(1){
value = read_I2C();
output_b(value);
delay_ms(500);
}
}

**********************************************
Thân mến !!

falleaf
14-09-2006, 04:49 PM
Các em nhớ đặt chương trình trong thẻ [code]...[/code ] (nhớ viết liền lại)

Như vậy thì mọi người sẽ đọc dễ hơn, và nếu code dài quá thì nó cũng thu gọn lại trong một khung cố định.

Ngoài ra, code cũng có thụt ra thụt vào rõ ràng như trong đoạn code mà tụi em copy. Chú ý điều này khi viết bài.

Chúc vui.

Hoanf, và ThanhHa, như anh nói, giúp anh post một cái hình mạch nguyên lý giao tiếp đúng như trong cái đề tài mà tụi em đang thảo luận, để mọi người dễ theo dõi.

Thanks muchie.

hoanf
15-09-2006, 11:02 AM
Chào mọi người và Hà.
Mình làm cho nó chạy được rồi.
Mình có một thắc mắc mong Hà và mọi người giải thích dùm. Đó là thông số "FORCE_HW" mà trong phần #use i2c sử dụng
Mình cho rằng thông số này chỉ được áp dụng khi ta quy định chân của I2C đúng theo chân của PIC quy đinh (đối với Pic hỗ trợ I2C). khi mình áp thông số này thì CCS sẽ biên dịch chương trình sao cho phù hơp với cấu hình phần cứng mà PIC hỗ trợ. Còn nếu kô áp thông số này lên thì nó sẽ thực hiện giao thức I2C hoàn toàn bằng phần mềm.

Và còn một lệnh mình chưa rõ đó là : I2C_POLL()

Mong Hà và các bạn góp ý.
Thân
hoanf

falleaf
15-09-2006, 12:04 PM
Mình có một thắc mắc mong Hà và mọi người giải thích dùm. Đó là thông số "FORCE_HW" mà trong phần #use i2c sử dụng
Mình cho rằng thông số này chỉ được áp dụng khi ta quy định chân của I2C đúng theo chân của PIC quy đinh (đối với Pic hỗ trợ I2C). khi mình áp thông số này thì CCS sẽ biên dịch chương trình sao cho phù hơp với cấu hình phần cứng mà PIC hỗ trợ. Còn nếu kô áp thông số này lên thì nó sẽ thực hiện giao thức I2C hoàn toàn bằng phần mềm.

Và còn một lệnh mình chưa rõ đó là : I2C_POLL()

Mong Hà và các bạn góp ý.
Thân
hoanf

HW = hardware. Có nghĩa là sử dụng giao tiếp phần cứng. Em hình dung như thế này. Một chuẩn giao tiếp, thực ra chỉ là một quy định và dùng chung, gọi là chuẩn. Thế thì một chuẩn, bao gồm những thứ gì?

Anh chỉ nói đơn giản thế này, nó bao gồm chuẩn về kết nối, có nghĩa là các header em dùng để cắm vào, nôm na là chuẩn cơ khí, chuẩn về đường dây (các loại dây để đảm bảo tín hiệu truyền)..chuẩn cáp, chuẩn thứ ba nôm na là chuẩn về điện là các chuẩn về điện áp, dòng điện, và chuẩn thứ tư là chuẩn logic, chuẩn này ảnh hưởng đến số lượng dây truyền, phương thức truyền nhận, tín hiệu trên các dây... Nói chung, một chuẩn truyền bao gồm các chuẩn như vậy. Anh dùng từ ngữ không chính xác lắm, tụi em có thể tra cứu lại các từ ngữ tiếng Anh, anh chỉ cố gắng giải thích theo nghĩa đơn giản nhất thôi.

Như vậy, bây giờ khi em kết nối về mặt cơ khí (với I2C là hàn vào board, hoặc hai dây cắm vào), chuẩn cable là đường mạch in hoặc dây 3000 đồng/sợi... hehehe... vân vân...

Vậy cái cuối cùng, là chuẩn về logic và điện tử. Em thấy rằng, nếu như bây giờ, mình lấy 2 dây nối bất kỳ, nối vào nhau, dùng con PIC, lập trình một chân tạo xung clk, một chân truyền tín hiệu, đưa vào MAX232, thì lập tức em sẽ có được giao tiếp RS232. Cái này em hoàn toàn lập trình được, đối với bất kỳ chân nào, chỉ cần phỏng theo chuẩn logic của RS232 là em có thể lập trình được. Như vậy, người ta gọi cách làm đó là giao tiếp theo chuẩn RS232 bằng phần mềm. Và thực tế là người ta đã làm như vậy. Còn với giao tiếp I2C, thì em thấy nó có khác gì RS232 đâu, nó cũng có thể làm được như vậy bằng phần mềm, chỉ cần lập trình về mặt logic đảm bảo chuẩn truyền của nó.

Với con PIC bất kỳ, không hỗ trợ I2C, em hoàn toàn có thể thực hiện giao tiếp I2C bằng phần mềm theo cách trên. Với các con PIC hỗ trợ I2C, em có 2 cách để thực hiện giao tiếp I2C là phần cứng và phần mềm. Thế thì phần cứng, thực ra là người ta thêm vào đó một khối module phần cứng, thay cho cái việc mình viết một đoạn chương trình để chạy, thì cái module đó nó làm thay mình, và nó được đóng gói theo đúng chuẩn.

CCS C hỗ trợ hai dạng lập trình. Một dạng là lập trình vài dòng để kích hoạt cái module phần cứng của PIC và chạy giao tiếp bằng phần cứng. Một dạng khác, là nó sẽ tạo ra code để thực hiện cái chuẩn giao tiép đó, gọi là phần mềm.

Như vậy, nếu em dùng module phần cứng, bắt buộc, em phải dùng đúng cái chân của nó, vì cái chân đó nó gắn vào module phần cứng I2C của PIC, còn nếu em dùng phần mềm, thì như anh nói, em có thể dùng bất kỳ chân I/O nào, và em chỉ cần định nghĩa nó là chân I/O là xong, em hoàn toàn có thể tự làm chuyện này.

Hôm nào rảnh, anh sẽ tìm lại code I2C viết bằng phần mềm để tụi em tham khảo. Anh viết lâu rồi, nên phải tìm lại, không hứa trước sẽ nhanh.

Trong khi chờ đợi, cho anh cái hình mạch nguyên lý lên đây đi, coi như là đánh đổi nhé :)

Chúc vui

hoanf
15-09-2006, 12:35 PM
Cám ơn anh Falleaf!!
Thực ra mô hình của bạn Hà mới phức tạp nên cần sơ đồ.
Chứ mô hình của em chỉ có 2 con PIC 16F877A nối với nhau qua các chân I2C chứ chả có gì nên em kô post lên.
Nay thấy anh nói vậy thì để em ngồi vẽ post sơ đồ lên.
Còn về chương trình em chưa gửi lên được vì đang tiến hành Optimize. Sẽ post cùng sơ đồ luôn :D.

Thân
hoanf

hoanf
15-09-2006, 02:47 PM
Chào các bạn!!
Cho mình post sơ đồ và code của minh lên đây cho các bạn coi và có gì góp ý cho mình nha.

Đây là đoạn code Master: Master truyền một mảng cho Slave và nhận về mảng mà đã chuyển cho Slave để hiển thị lên port_b(kiểm tra hihi...) giống echo.


#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use Delay(Clock=4000000)

#use i2c(master, sda=PIN_C4, scl=PIN_C3, force_hw)

void write_I2C(int8 value, int8 slave_addr)
{
i2c_start();
i2c_write(slave_addr);
i2c_write(value);
i2c_stop();
}

int8 read_I2C(int8 slave_addr)
{
int8 value_re;
i2c_start();
i2c_write(slave_addr + 1);
value_re = i2c_read(0);
i2c_stop();
return value_re;
}

void main()
{
int8 value_re;
int8 i;
const int8 N = 8;
const int8 DIGITS[N] ={ 0b11111111,
0b11111110,
0b11111100,
0b11111000,
0b11110000,
0b11100000,
0b11000000,
0b10000000,
};
const int8 slave_addr = 0x10;

set_tris_b(0x00);
while(1){
for(i = 0; i<8; i++){
write_I2C(DIGITS[i], slave_addr);
delay_ms(500);
value_re = read_I2C(slave_addr);
output_b(value_re);
}
}
}


Còn đây là đoạn code Slave:


#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#use delay(Clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10, force_hw)

int8 value = 0x01;

#INT_SSP
void i2c_isr()
{
int8 state;

state = i2c_isr_state();
if(state < 0x80)
value = i2c_read();
if(state == 0x80){
i2c_write(value);
}
}

void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);

set_tris_b(0x00);
while(1){
output_b(value);
}
}

falleaf
15-09-2006, 03:35 PM
Đơn giản vậy thôi, các em vừa làm xong một bài hướng dẫn I2C khá đầy đủ rồi :)

Thanks muchie

hoanf
15-09-2006, 05:04 PM
Đơn giản vậy thôi, các em vừa làm xong một bài hướng dẫn I2C khá đầy đủ rồi :)

Thanks muchie
Hay quá ha. Nhưng nếu mà có chương trình nào tự viết bằng C mà kô lấy các hàm của CCS hỗ trợ sãn cho I2c thì hay biết mấy :D.
Vậy chắc phải đợi bài hướng dẫn I2C nâng cao của anh Falleaf qua'.
Tui em đang đợi chương trình của anh đây.
Thân
hoanf

thanhha
15-09-2006, 05:23 PM
Hi các bạn!
Hôm nay I2C không chay, mình dò 1 buổi, phát hiện điện áp cấp 2 Board Master va Slave không đủ 5V và bị lệch(đã nối mass chung 2 board): Master ->4.9V, Slave -> 4.2V. Các bạn nên kiểm tra dòng, áp mạch khi I2C không chạy với chtr đã chuẩn.

Chúc mừng hoanf, bạn đã thành công!!

hoanf
15-09-2006, 05:53 PM
Hi các bạn!
Hôm nay I2C không chay, mình dò 1 buổi, phát hiện điện áp cấp 2 Board Master va Slave không đủ 5V và bị lệch(đã nối mass chung 2 board): Master ->4.9V, Slave -> 4.2V. Các bạn nên kiểm tra dòng, áp mạch khi I2C không chạy với chtr đã chuẩn.

Chúc mừng hoanf, bạn đã thành công!!
Hihi! Cám ơn bạn nha.
Ah còn cái vụ nối mass chung là chuối nhất luôn đo'. Làm cho chuẩn I2C từ 2 dây trở thành 3 dây :(.
Giờ chỉ còn 1 cách đó là nối đất cả 2 board là thành chuẩn 2 dây. Hix.

Ah còn cái zu áp thấp này tui mới thấy đó nha. Đúng là gặp mấy lỗi này thì trời biết. Ông Hà này hay lắm mới tìm ra lỗi này đó.

Thân. Cuối tuần vui vẻ nha.
hoanf

falleaf
15-09-2006, 10:17 PM
Hay quá ha. Nhưng nếu mà có chương trình nào tự viết bằng C mà kô lấy các hàm của CCS hỗ trợ sãn cho I2c thì hay biết mấy :D.
Vậy chắc phải đợi bài hướng dẫn I2C nâng cao của anh Falleaf qua'.
Tui em đang đợi chương trình của anh đây.
Thân
hoanf

Anh không cho chương trình trực tiếp, nhưng anh cho một gợi ý, không biết như vậy có được không nhỉ?

Con PIC16F84A hình như không có tích hợp chức năng I2C? Nếu như anh không nhớ lầm?!

Bắc thang lên hỏi ông trời, ông mà không biết tui mời ông ggô

Chúc vui

falleaf
15-09-2006, 10:42 PM
À, nếu đang nghiên cứu I2C thì anh nghĩ nhân tiện nên đi cho nó tới nơi tới chốn. Tụi em thử làm cái I2C bằng phần mềm xem, tất nhiên source code thì coi như anh cung cấp rồi :), bằng gợi ý.

Ngoài ra, để động viên tinh thần học tập của tụi em, anh xin tặng mỗi em 1 con PIC (nếu tụi em ở SG, thì ghé cửa hàng STH để chọn bất kỳ con nào có ở cửa hàng mà em muốn). Gửi thông tin cá nhân cho anh, để anh nhắn cho anh Lợi.

Hiện tại anh đi rồi nên không thể chuyển phát nhanh cho tụi em được (mỗi lần chuyển tốn tiền, và nếu nhờ Chính chuyển thì tốn tiền của Chính). Anh không biết Hà ở đâu, nhưng hình như Hoàn thì ở HCM và có gặp anh rồi thì phải. Nếu Hà ở nơi khác, Hoàn có thể nhận giúp và chuyển lại cho Hà sau có được không?

Tuỳ tụi em quyết định

Chúc vui.

namqn
15-09-2006, 11:56 PM
Hay quá ha. Nhưng nếu mà có chương trình nào tự viết bằng C mà kô lấy các hàm của CCS hỗ trợ sãn cho I2c thì hay biết mấy :D.
Vậy chắc phải đợi bài hướng dẫn I2C nâng cao của anh Falleaf qua'.
Tui em đang đợi chương trình của anh đây.
Thân
hoanf
Tôi đang viết tutorial cho module I2C của dsPIC, tự viết các chương trình con, nhưng còn viết hướng dẫn nữa nên chưa post lên được. Các bạn có thể tham khảo ở đó sau vài ngày nữa.

Ngoài ra còn có chương trình cho PIC18 viết trong C18, dùng kỹ thuật bit-banging, đã thử nghiệm rồi.

Các bạn có thể tìm được nhiều ví dụ tương tự trên net.

Thân,

ntc
16-09-2006, 11:45 AM
À, nếu đang nghiên cứu I2C thì anh nghĩ nhân tiện nên đi cho nó tới nơi tới chốn. Tụi em thử làm cái I2C bằng phần mềm xem, tất nhiên source code thì coi như anh cung cấp rồi , bằng gợi ý.

Ngoài ra, để động viên tinh thần học tập của tụi em, anh xin tặng mỗi em 1 con PIC (nếu tụi em ở SG, thì ghé cửa hàng STH để chọn bất kỳ con nào có ở cửa hàng mà em muốn). Gửi thông tin cá nhân cho anh, để anh nhắn cho anh Lợi.

Hiện tại anh đi rồi nên không thể chuyển phát nhanh cho tụi em được (mỗi lần chuyển tốn tiền, và nếu nhờ Chính chuyển thì tốn tiền của Chính). Anh không biết Hà ở đâu, nhưng hình như Hoàn thì ở HCM và có gặp anh rồi thì phải. Nếu Hà ở nơi khác, Hoàn có thể nhận giúp và chuyển lại cho Hà sau có được không?

Tuỳ tụi em quyết định

Chúc vui.


Ồ, không sao, không sao, một vài triệu thì thiếu, chứ một vài ngàn thì thu xếp được, thu xếp được.

Hoanf có tham gia dự án PID thì phải. Tha hồ mà nhận chip nhẩy. :D.

Mấy bạn cứ gửi địa chỉ lên đây, mình sẽ chuyển chip cho.

Bạn nào muốn viết code I2C bằng phần mềm, ngôn ngữ ASM, có thể ghé mình, cho mượn tài liệu mà nghiên cứu luôn.

Hiểu được cách viết bằng ASM, chuyển code sang C chắc cũng không có vấn đề gì lớn nhẩy.

;)

chumeodihia
17-09-2006, 01:50 AM
Trời ui sao các cụ lão làng nhà ta lai viết giao tiếp bằng ccs không vậy.Tôi thì viết truyền thông I2C bằng cả hai ngôn ngữ luôn ==masterviết bằng CCS và claver viết bằng ASM chạy cực tốt==.MASTER DÙNG 18F452 VÀ CLAVER DUNG 18F4431.HÔM NÀO TUI POST LÊN CHO ANH EM NGHIÊN CỨU CHƠI,hom nay do không đem theo chương trình.
Bác FALLEAF ơi Tôi là thành viên mới vào diễn đàn ghé qua forum này thấy hay nên nhảy vào không biết sau khi post chương trình này lên thì tui được đệ tử mấy túi nhỉ..8-x hehehe.Hỏi thử cho biết thôi chứ không có gì đau

Phong độ chỉ là thoáng qua
Trình độ mới là vĩnh cửu
Chú mèo đihia tái bút
thanks

falleaf
17-09-2006, 02:43 AM
HI, mấy túi không quan trọng, vì có thể spam thật nhiều sẽ có nhiều túi :). Nhưng điều đó không được khuyến khích trong picvietnam. Ở picvietnam có một cách nhìn hơi lạ một chút với các diễn đàn khác, đó là sự tập trung và làm việc.

Hãy cho những gì bạn muốn lấy. Đó là nguyên tắc vô cùng quan trọng.

Chúc vui.

rmitoday
18-09-2006, 11:42 AM
Bẩm báo PIC bang chủ và các trưởng lão? Như bang chủ đã nói là lên học viết ASM trước rùi chuyển qua các ngôn ngữ khác sẽ dễ. Em thấy cần một tutorial cho I2C bằng ASM vì em mới học nên chỉ biết ASM thui. Các cao thủ ra chiêu bằng C ào ào chẳng hiểu mô tê chi hết á.
Xin cảm ơn.

falleaf
18-09-2006, 04:27 PM
Có 2 application notes về master và slave được M cung cấp khá chi tiết, 734, 735 thì phải, không nhớ chính xác là cái nào, bạn có thể tìm hiểu thêm về nó.

Tutorial về I2C bằng MPASM thì Phạm Đức Mạnh đã cung cấp rồi thì phải, bạn tìm lại bài viết của mafd47a.

Chúc vui.

thanhha
18-09-2006, 05:12 PM
Vâng! Đúng như Bác F nói !! Hà đã load tài liệu ASM về I2C này ở đây:
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2121&fragment6_NextRow=101

+Tài liệu AN735 nói về Master.
+Tài liệu AN734 nói về Slave.

Theo Hà nghĩ, mình có thể dùng tài liệu này
để tham khảo tự viết lệnh I2C mới trong CCS C thì rất tốt.
Chương trình viết hay lắm!!

Bạn tham khảo đi !

namqn
21-09-2006, 06:26 PM
Các bạn tham khảo thêm ở đây về I2C:

http://namqn.byethost7.com/Commu.php
Thân,

hoangminh1234
03-10-2006, 02:23 PM
Anh oi, em chua hieu ve I2C lam va tren dien dan lai chang thay ai noi ve chuyen nay. Trong giao thuc I2C trong CCS co ham i2c_read(), nhung ham do chi la ham doc tu master truyen xuong slave dung ko a? Cai ma tui em dang can la nhu vay: master truyen xuong 10byte (10byte nay chua gia tri la vi tri muon dieu khien dong co rc), sau do slave se doc 10 byte do va xuat gia tri dieu khien cho tung dong co ung voi tung byte da duoc truyen tu master. Nhung em ko thay ai noi ve chuyen nay va co thac mac nhu sau, anh chi dum em nhe
- Du lieu tu master truyen xuong se vao dau trong slave(eeprom?),neu trong eeprom thi lam sao de con slave co the lay ra va su dung cac gia tri do?

falleaf
03-10-2006, 02:41 PM
Anh oi, em chua hieu ve I2C lam va tren dien dan lai chang thay ai noi ve chuyen nay. Trong giao thuc I2C trong CCS co ham i2c_read(), nhung ham do chi la ham doc tu master truyen xuong slave dung ko a? Cai ma tui em dang can la nhu vay: master truyen xuong 10byte (10byte nay chua gia tri la vi tri muon dieu khien dong co rc), sau do slave se doc 10 byte do va xuat gia tri dieu khien cho tung dong co ung voi tung byte da duoc truyen tu master. Nhung em ko thay ai noi ve chuyen nay va co thac mac nhu sau, anh chi dum em nhe
- Du lieu tu master truyen xuong se vao dau trong slave(eeprom?),neu trong eeprom thi lam sao de con slave co the lay ra va su dung cac gia tri do?

Bạn đọc thật kỹ tutorial của picvietnam do Linh viết ở ngay bài đầu tiên của luồng này (falleaf gửi thay cho Linh).

Linh viết bài này có một số vấn đề truyền tải chưa được rõ lắm do cách dùng câu chữ mà thôi. F viết lại đôi chút như sau:

trong giao tiếp I2C, có thể có (1 master và 1 slave) hoặc (1master và nhiều slave). Đây là giao thức chuẩn. Tuy nhiên, cải tiến giao thức này một chút, chúng ta sẽ có mạng I2C (nhiều master, mỗi con thay phiên làm master)..

Chúng ta chỉ đề cập giao tiếp I2C ở dạng chuẩn, tức là có duy nhất 1 master trong mạng.

Khi muốn dữ liệu truyền từ A tới B. Có nhiều trường hợp xảy ra như sau:
A là master, B là slave: khi đó A sẽ gửi một loạt dữ liệu có định dạng sẵn (các bạn xem lại định dạng I2C), thì trong định dạng đó có bao gồm mấy thông tin như sau (master muốn đọc hay muốn ghi? địa chỉ của slave là bao nhiêu? master có muốn kiểm tra bằng xung ACK, tức là xung báo đã truyền nhận đầy đủ hay không? và nội dung dữ liệu (nếu master muốn ghi), và địa chỉ thanh ghi của slave (nếu master muốn đọc một thanh ghi nào đó trong slave).

Nếu A là slave, thì slave không được quyền muốn. Khi nào master kêu nhận thì phải nhận, khi nào master kêu gửi, thì phải gửi. Slave thì không được quyền muốn. Nếu muốn thì làm nô tì I-Sau-ra :D.

Còn nếu cả A và B đều là slave, khi master cần truyền dữ liệu từ A sang B, thì Master phải yêu cầu A gửi cho master, nhận xong, master gửi lại cho B.

Như vậy vấn đề học giao tiếp I2C, chỉ đơn giản là học cách định dạng dữ liệu trong frame truyền của I2C (mô tả sơ bộ ở trên), và học cách nối mạng giữa mạng điện áp thấp và điện áp cao (vd: một thiết bị I2C 3.3V, kết nối với thiết bị 5V thì làm thế nào?).. kiểu như vậy thôi là các bạn đã có thể thiết kể rất nhiều ứng dụng với I2C, và làm việc với rất nhiều thiết bị rồi.

Chúc vui.

hoangminh1234
03-10-2006, 04:01 PM
tức là con tớ hoàn toàn bị động trong trường hợp này sao? Nó không thể nào lấy tí thông tin nào đem bán cho các điệp viên để kiếm chút cháo sao? Buồn vậy! Vậy theo anh làm sao giải quyết bài toán mà tụi em đang gặp phải nhỉ:

Một con chủ truyền 10 byte cho con tớ và con tớ có toàn quyền sử dụng 10 byte này??
anh cho em xin ý kiến nhé

Encoder
03-10-2006, 06:05 PM
Đơn giản vậy thôi, các em vừa làm xong một bài hướng dẫn I2C khá đầy đủ rồi :)



Chưa đâu bác. Còn viết I2C trên HTPIC thì sao. Bác đã viết chương trình nào chưa, cho em xin tí code.

hoangminh1234
03-10-2006, 06:17 PM
và địa chỉ thanh ghi của slave (nếu master muốn đọc một thanh ghi nào đó trong slave).


cai nay sao em ko thay trong CCS noi nang gi toivay anh? Nếu ta biết được địa chỉ thanh ghi bên slave thì hoàn toàn có thể lấy ra xài rồi.
Em vừa đọc cái SPI, thấy con tớ đọc dữ liệu trong thanh ghi SSPBUF ( được master truyền xuống) sau đó xuất ra port B.
file: http://ww1.microchip.com/downloads/en/devicedoc/spi.pdf
Nó làm em nghĩ rằng ko biết mình có thể làm tương tự với i2c ko?? cao huynh nào rành i2c cho ý kiến nhé

falleaf
03-10-2006, 09:46 PM
Một con chủ truyền 10 byte cho con tớ và con tớ có toàn quyền sử dụng 10 byte này??
anh cho em xin ý kiến nhé

Khi con Slave nhận được dữ liệu, thì nó nằm trong thanh ghi đệm, thanh ghi nào thì F quên rồi, và khi đã nằm trong bộ đệm của nó, thì nó có toàn quyền sử dụng. Nó thích làm gì thì làm.

Các bạn lưu ý rằng, F nói trường hợp nâng cao, thì chúng ta hoàn toàn có quyền sử dụng mạng Multi Master. Khi bạn setup chip ở chế độ Slave, thì nó thụ động. Nhưng hãy thử nghĩ, tôi làm slave cho mạng này, và làm master của một mạng khác, vậy thì có được không? Vì tôi có tới 40 chân chứ không phải 2 chân.

Vậy nếu tôi làm master cho một mạng khác, mà trong đó slave của tôi lại là master của cái mạng mà tôi làm slave :). Hoàn toàn được.

Nhưng vấn đề nâng cao ở chỗ nữa, nếu làm như vậy, tôi phải tốn 4 dây để làm 2 mạng. Vấn đề trước đây hình như F đặt ra cho Linh, nhưng Linh chưa giải quyết xong, đó là Multi Master trong một mạng dùng 2 dây thôi.

Vấn đề này F tiếp tục treo ở đây chờ người giải quyết.

Chúc vui.

falleaf
03-10-2006, 09:47 PM
cai nay sao em ko thay trong CCS noi nang gi toivay anh? Nếu ta biết được địa chỉ thanh ghi bên slave thì hoàn toàn có thể lấy ra xài rồi.
Em vừa đọc cái SPI, thấy con tớ đọc dữ liệu trong thanh ghi SSPBUF ( được master truyền xuống) sau đó xuất ra port B.
file: http://ww1.microchip.com/downloads/en/devicedoc/spi.pdf
Nó làm em nghĩ rằng ko biết mình có thể làm tương tự với i2c ko?? cao huynh nào rành i2c cho ý kiến nhé

Bạn đọc lại frame truyền từ Master đến Slave ở hai chế độ ghi và đọc

Chúc vui.

hoangminh1234
04-10-2006, 12:41 AM
Khi con Slave nhận được dữ liệu, thì nó nằm trong thanh ghi đệm, thanh ghi nào thì F quên rồi, và khi đã nằm trong bộ đệm của nó, thì nó có toàn quyền sử dụng. Nó thích làm gì thì làm.

Các bạn lưu ý rằng, F nói trường hợp nâng cao, thì chúng ta hoàn toàn có quyền sử dụng mạng Multi Master. Khi bạn setup chip ở chế độ Slave, thì nó thụ động. Nhưng hãy thử nghĩ, tôi làm slave cho mạng này, và làm master của một mạng khác, vậy thì có được không? Vì tôi có tới 40 chân chứ không phải 2 chân.

Vậy nếu tôi làm master cho một mạng khác, mà trong đó slave của tôi lại là master của cái mạng mà tôi làm slave :). Hoàn toàn được.

Nhưng vấn đề nâng cao ở chỗ nữa, nếu làm như vậy, tôi phải tốn 4 dây để làm 2 mạng. Vấn đề trước đây hình như F đặt ra cho Linh, nhưng Linh chưa giải quyết xong, đó là Multi Master trong một mạng dùng 2 dây thôi.

Vấn đề này F tiếp tục treo ở đây chờ người giải quyết.

Chúc vui.

bác Falleaf nghĩ cao siêu quá, cái em hỏi chỉ ở mức cơ sở, chưa nâng cao dữ vậy đâu anh. Theo em nghĩ với yêu cầu truyền một số lượng byte ( 10 byte chẳng hạn) từ một con pic này sang một con pic khác là yêu cầu rất hay gặp . Anh Falleaf nghĩ cao quá nên vẫn chưa trả lời em câu hỏi này nhỉ?
Em nghĩ rằng dữ liệu truyền từ master sang slave sẽ được lưu tạm trong thanh ghi SSPBUF. Nếu mình lấy ra xài đúng lúc thì sẽ giải quyết được câu hỏi mà em đang đặt ra, được ko anh?

falleaf
04-10-2006, 02:15 AM
Anh nói là em đọc lại bài tutorial và frame truyền!

Em chưa đọc kỹ cái bài bạn Thanh Hà gửi về hai cái app mà anh giới thiệu sao?

Chúc vui.

hoangminh1234
04-10-2006, 10:22 PM
hình như mình vẫn chưa hiểu nhau (:)) anh Falleaf nhi?
Như anh đã nói việc truyền và đọc là do con chủ ra lệnh
Cũng như anh đã nói là dữ liệu sẽ được nằm trong thanh ghi SSPBUF của con tớ ( 1thanh ghi ! ?????)
Quan sát hai khung truyền ta thấy rằng việc truyền hay nhận nhiều byte từ master là chuyện nhỏ. Nhưng chuyện không nhỏ ( hay quá nhỏ không ai để ý ) là dữ liệu chạy đi đâu trong con tớ. Khi thằng chủ đưa 10 cô em sang nhà thằng tớ chơi, nhưng thằng tớ nhà nghèo chật hẹp chỉ chứa được một cô thôi, vậy 9 cô kia ở đâu? Không hiểu sao mà khi chủ gọi về thì vẫn đủ 10 cô ?? ( chắc có di động gọi nhau )
Chắc là mấy cô dẫn nhau ra quán Sinh Viên trên đường Bửu Long ngồi đây. Nếu ta biết địa chỉ đường Bửu Long thì hay quá nhỉ :D . Anh Falleaf có biết đường BL nằm đâu ko ?


//sau khi đọc application

À, thì ra nó nằm trong RXbuff, vậy mà sao anh ko nói sớm

namqn
04-10-2006, 10:39 PM
Khi slave nhận ra địa chỉ của mình thì nó cần đảm bảo xử lý ở mức nhanh nhất để không bị mất dữ liệu, nghĩa là nhận được byte nào thì nó chuyển ngay byte đó ra khỏi bộ đệm. Ngoài ra, nó còn được phép kéo dài xung clock (clock stretching), và gửi NACK để báo hiệu là nó chưa sẵn sàng. Với PIC thì các phần này được xử lý bằng phần cứng. Bạn chịu khó đọc thêm tài liệu đi.

Thân,

hoangminh1234
08-10-2006, 02:49 AM
cám ơn trưởng lão

falleaf
08-10-2006, 04:48 AM
Hình như em vẫn chưa đọc cái app note mà Thanh Hà gửi thì phải :D

Em đọc kỹ lại đi xem cách nó xử lý 32 byte được truyền tới như thế nào? Nếu không cần nACK mà xử lý luôn liệu có được không?

Câu trả lời cho câu hỏi của em nằm trong đó :), chỉ vì em không chịu đọc thôi

Chúc vui.

falleaf
03-01-2007, 12:57 PM
Hòa, em viết phần giao tiếp I2C giữa thiết bị 5V và 3.3V vào chỗ này.

Vấn đề đặt ra, lúc trước đáng lẽ có trong báo cáo của Linh, nhưng lâu quá F không để ý, vì Linh ngưng đề tài giữa chừng.

Đó là làm thế nào để giao tiếp I2C giữa thiết bị chuẩn 5V và thiết bị chuẩn 3.3V, 2.5V...

Nguyên tắc I2C đến đây coi như là xong, nhưng trong một mạng I2C, thì làm thế nào để kết nối được giữa các thiết bị có chuẩn điện áp khác nhau. Đây là câu hỏi mở rộng tiếp theo ở phần i2c này.

Phạm Thái Hòa sẽ chủ trì phần này, các bạn tiếp tục nghiên cứu và thảo luận về I2C nhé.

Chúc vui.

vagabond
06-01-2007, 07:25 AM
Hi mọi người,

Thấy câu hỏi này hay nên vagabond cung tham gia trả lời phát.

Đúng là ngày nay, việc kết nối các khối linh kiện có các mức điện áp khác nhau ngày càng nhiều. Đặc biệt là giữa mức 3.3V và 5V. Trở lại câu hỏi trên, do mình quen sử dụng các IC chuyên dụng nên tạm thời không xét đến các giải pháp khác. Các bạn có thể sử dụng IC 74LVXC4245 để chuyển đổi mức điện áp 3.3-5V. IC này cũng cho phép xác định chiều vào/ra của tín hiệu. IC này sẽ được cấp 2 nguồn áp tham chiếu là 5V và 3.3V. Chú ý: theo sơ đồ dưới đây, ta cần phải có thêm 2 tín hiệu để điều khiển chiều ra/vào của tín hiệu ở các ngõ A và B.

http://i132.photobucket.com/albums/q2/vagabondmec/IC74LVXC4245.jpg

Các ngõ A tương ứng với mức điện áp logic 1 là 4.5-5.5V
Các ngõ B tương ứng với mức điện áp logic 1 là 2.7-5.5V
Hai chân ~OE và T/~R cho phép điều khiển tín hiệu đi theo chiều A->B hay B->A hay ở trạng thái HighZ. Mức điện áp điều khiển hai chân này chấp nhận mức logic 1 là 3.3 hay 5V đều được.

Xét trường hợp mạng I2C sẽ có mức logic chuẩn là 5V (hoặc 3.3V) cho toàn mạng và các khối linh kiện có mức logic khác 5V sẽ dùng IC tương thích mức logic. Ta có thể kết nối nhiều khối linh kiện có các mức logic khác nhau trên cùng một mạng I2C.

Bây giờ, ta xét hoạt động của mạng I2C 5V bao gồm một khối linh kiện 3.3V và khối linh kiện 5V.

http://i132.photobucket.com/albums/q2/vagabondmec/I2C.jpg

Khi Master muốn liên lạc với Slave: Slave phải điều khiển IC tương thích điện áp sao cho chiều tín hiệu đi từ A->B (tức là tín hiệu có mức logic 1 từ 5V sẽ chuyển thành 3.3V).

Khi Slave muốn liên lạc với Master, hai chân của IC tương thích điện áp phải được điều khiển để chiều tín hiệu đi từ B->A (tức là tín hiệu có mức logic 1 từ 3.3V sẽ chuyển thành 5V).

Tóm lại việc điều khiển 2 chân ~OE và T/~R của IC tương thích điện áp sẽ do Slave chịu trách nhiệm. Trong ví dụ này, ta đưa thẳng chân ~OE xuống đất và chỉ điều khiển chân T/~R (các bạn coi lại bảng sự thật).

Mạng I2C 3.3V hoàn toàn tương tự như trên. Master và Slave có thể đổi vị trí cho nhau.

Túm lại lần nữa:
- Các bạn có thể kiểm các IC tương thích điện áp có số ngõ ra vào tương ứng với số lượng tín hiệu cần chuyển đổi mức logic. Riêng IC tương thích điện áp chỉ có 2 ngõ ra vào thì mình chưa tìm thấy.
- Đây là một giải pháp an toàn và nhanh, nhất là khi phải làm việc với các mức điện áp khác nhau.
- Tuy nhiên, bù lại bạn phải tốn thêm chỗ cho IC, làm tăng diện tích boar (linh kiện dán CMS vẫn tốn chỗ), phải sử dụng thêm 2 nguồn điện áp, và phải thêm ít nhất là 1 đường tín hiệu để điều khiển chiều A<->B.
- Và một điểm lợi nữa khi cần thiết, bạn có thể cách li hoàn toàn các khối linh kiện với trạng thái HighZ ra khỏi bus I2C (nhưng lại phải tốn thêm tín hiệu điều khiển ~OE).

Có thể có còn các cách khác nữa (diod Zener để ghim điện áp…) nhưng mình … hehehe nhường cho các bạn. Mình chỉ khoái làm việc với các IC chuyên dụng sẵn thôi.

zero_OR_one
12-01-2007, 12:51 AM
Chào các bạn!!
Cho mình post sơ đồ và code của minh lên đây cho các bạn coi và có gì góp ý cho mình nha.

Đây là đoạn code Master: Master truyền một mảng cho Slave và nhận về mảng mà đã chuyển cho Slave để hiển thị lên port_b(kiểm tra hihi...) giống echo.


#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use Delay(Clock=4000000)

#use i2c(master, sda=PIN_C4, scl=PIN_C3, force_hw)

void write_I2C(int8 value, int8 slave_addr)
{
i2c_start();
i2c_write(slave_addr);
i2c_write(value);
i2c_stop();
}

int8 read_I2C(int8 slave_addr)
{
int8 value_re;
i2c_start();
i2c_write(slave_addr + 1);
value_re = i2c_read(0);
i2c_stop();
return value_re;
}

void main()
{
int8 value_re;
int8 i;
const int8 N = 8;
const int8 DIGITS[N] ={ 0b11111111,
0b11111110,
0b11111100,
0b11111000,
0b11110000,
0b11100000,
0b11000000,
0b10000000,
};
const int8 slave_addr = 0x10;

set_tris_b(0x00);
while(1){
for(i = 0; i<8; i++){
write_I2C(DIGITS[i], slave_addr);
delay_ms(500);
value_re = read_I2C(slave_addr);
output_b(value_re);
}
}
}


Còn đây là đoạn code Slave:


#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#use delay(Clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10, force_hw)

int8 value = 0x01;

#INT_SSP
void i2c_isr()
{
int8 state;

state = i2c_isr_state();
if(state < 0x80)
value = i2c_read();
if(state == 0x80){
i2c_write(value);
}
}

void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);

set_tris_b(0x00);
while(1){
output_b(value);
}
}


Bác Hoàn cho em hỏi tý,em thử mô phỏng chương trình của bác(có sửa một tý) với proteus thì thấy kết quả slave hiện đúng,master sai(ví dụ value cho là 0x7f thì master là 0x87,sửa value khác thì master vẫn thế---ở đây value của em có vai trò như 1 thành phần của mảng của bác thôi) .Cũng ko hiểu sao ở slave bác lại cho int8 value = 0x01;,đã thay lại mỗi khai báo int8 value thôi,mô phỏng vẫn thế.Không hiểu do phần mềm hay sao???Thông cảm vì em chưa có điều kiện làm vì ko có đủ 2 con chip.

tact
19-01-2007, 06:02 PM
chắc bác sửa thế nào ý chứ, em copy về, mô phỏng thấy chạy ngon re. nhưng em làm 1 con master, 4 con slaver thì thôi rồi, tịt ngỏm luôn. bận quá, chẳng co thời gian nghiên cứu nữa. Vậy nên em làm theo cách khác. vẫn chủ đề là 1 M giao tiếp với vài S. hôm qua làm xong rồi. CCS có cái hay là làm giao tiếp cực mạnh.
em lấy ví dụ: 1 Master có thể có nhiều Slaver giao tiếp qua RS232 ( thậm chí giao lưu văn nghệ với nhau chỉ có 1 "đường tơ" cả GND là 2. em chỉ thử dc có 150m thôi vì ko có dây(ko khuếch đại, đệm chốt gì. PIN-2-PIN))
em sẽ về nghiên cứu thêm cái thằng I2C và SPI. công nhận hay thật

huybkdn
31-03-2007, 11:20 PM
Chào các bạn, mình mới lần đầu giao tiếp I2C dùng C để giao tiếp giữa 2 pic 16f877a, nên gặp nhiều vấn đề, hôm trước mình có tải chương trình của Hoàn về chạy thử nhưng không được, hi vọng Hoàn, các anh và các bạn cho mình một chương trình mẫu đơn giản có cả chạy mô phỏng bằng Proteus chính xác,rất cám ơn. Email của mình: quanghuy12c4@yahoo.com. Chúc tât cả vui!

hoanf
02-04-2007, 10:09 AM
Chào các bạn, mình mới lần đầu giao tiếp I2C dùng C để giao tiếp giữa 2 pic 16f877a, nên gặp nhiều vấn đề, hôm trước mình có tải chương trình của Hoàn về chạy thử nhưng không được, hi vọng Hoàn, các anh và các bạn cho mình một chương trình mẫu đơn giản có cả chạy mô phỏng bằng Proteus chính xác,rất cám ơn. Email của mình: quanghuy12c4@yahoo.com. Chúc tât cả vui!

Chào bạn,

Mình đã kiểm tra lại chương trình và test trên Protues 6.9 SP5 thấy nó chạy vẫn OK kô có vấn đề gì (Mạch chỉ dùng 1 con Master và 1 con Slave)
Ngoài mình cũng sử dụng chương trình này để test trực tiếp lên phần cứng và cũng OK

Bạn thử kiểm tra lại mạch coi có nối 2 con điện trở 2.2k ở 2 chân SCL và SDA chưa; tần số dao động dùng đúng chưa ...

Chúc vui
hoanf

linhnc308
04-04-2007, 03:23 PM
- Trong giao tiếp I2C thì các bạn nên chú ý trong việc sử dụng mạng giao tiếp giữa các IC này với nhau. Trước tôi đã làm giao tiếp với MS là 877A, 6 slave là 18F4331 để điều khiển rồi, chạy khá tốt. Nếu bạn nào làm mà không giao tiếp được thì cần kiểm tra lại khai báo về I2C (cho soft viết bằng CCS thôi nhé), đảm bảo phải giống nhau ở cả Master và Slave, tất nhiên với Slave có thêm phần khai báo địa chỉ.
- Hàm i2c_isr_state() này chỉ có với phiên bản CCS mới (từ 249), nên nếu bạn nào dùng bản cũ sẽ thấy báo lỗi.
- Trường hợp khai báo đúng mà vẫn không giao tiếp được thì cần kiểm tra lại đường giao tiếp I2C (chân SDA và SCL của PIC có thể bị hỏng, cái này tôi đã gặp mấy lần, và khi thử cho giao tiếp với DS1307 hay 24Cxx thì thấy ko đc, thay IC khác hay lái chân SDA, SCL sang chân khác thì lại OK) , vì vậy khi bạ n đã làm đúng các thủ tục mà đọc vẫn thấy 0xFF thì xem lại.
- Vì giao tiếp I2C là onboard nên tôi cũng chưa thử kéo dài đường bus. Để giao tiếp với các thiết bị 3V3, tôi thấy có thể dùng mach phân áp trở cũng tạm đc, nếu bạn nào đã làm AVR giao tiếp với thẻ MMC sẽ thấy sơ đồ mạch đó( http://www.captain.at/electronic-atmega-mmc.php )
- Cái hay của CCS là sẽ tự sinh mã I2C nếu HW ko hỗ trợ, do đó ta có thể tùy biến lái các chân tín hiệu này đến một chân bất kỳ, cả SPI cũng vậy.

Chúc thành công.

huybkdn
08-04-2007, 11:44 PM
Mình cảm ơn các bạn rất nhiều, mình đã làm được rồi, mình viết chương trình đơn giản thôi, chỉ dùng Master điều khiển 1 Slave hiển thị LCD và chạy tốt. Cho mình hỏi ngoài luồng một tí, mình đang làm đề tài điều khiển từ xa qua mạng điện thoại, cũng đã tham khảo datasheet và một số tài liệu nhưng chưa thành công, bạn nào có tài liệu cho mình xin, đặc biệt là cái khoản điều khiển con MT8880, đề tài mình gần hết hạn rồi, đang lo lắm, hi vọng được sự giúp đở. Bye,chúc tất cả vui !

minhpupil
11-05-2007, 06:43 PM
Chào các cao thủ , em có bài tập lớn về mạng I2C , trong đó có
2 master( 2 con Pic) , vậy có huynh nào biết rõ về phần này chỉ đệ với.

Đệ thắc mắc như sau:
Trong I2C có 7 bit địa chỉ , vậy có 128 thiết bị.
Vậy địa chỉ cho 2 con master này mình chọn thế nào?
và viết khai báo trong CCSC như thế nào?

#use i2c(master, sda=PIN_C4, scl=PIN_C3)

đệ thấy trong các phần khai báo của các master ko có ghi địa chỉ
của master trong mạng ?
Theo như bài tập của đệ thì tại 1 thời điểm chỉ có 1 con Pic
là master , con còn lại là slave , vậy đệ phải làm sao để con
kia biết nó là slave tại thời điểm đó ? Có phải nó dùng
i2c_isr_state () để đọc ko ạ?


Đệ mới học về I2C , còn ngu dại , mong các huynh chỉ giáo ạ.

nkh
12-05-2007, 01:52 PM
Xin cho đóng góp chút công sức nhé.

namqn: bạn nên đưa link đến post đã chứa file được upload, thay vì upload thêm lần nữa.
http://www.picvietnam.com/forum//showthread.php?p=8624#post8624

zero
24-05-2007, 11:22 PM
oa giao tiếp I2C hay thiệt đó.
Từ sưa đến j mình chỉ làm nội bộ trong 1 con Chíp chưa thử giao tiếp với bên ngoài theo các chuẩn có sẵn.
Ok mình sẽ nghiên cứu về cái này rồi post ý kiến lên sau. :D Rất cám ơn về các bài viết trên.

hieuhic
26-05-2007, 05:26 PM
Thế giới số hay thật

xzero
27-05-2007, 04:27 PM
Mình đang viết I2C kết nối PIC 16F877A voi DS1307 bằng CCS C. bien dich thi khog thay bao loi nhung vao mo phong thi khong thay duoc j het. Các Bác giúp mình với. Code minh co dinh kem...thanhks!!!

tda
27-05-2007, 05:47 PM
đệ thấy trong các phần khai báo của các master ko có ghi địa chỉ
của master trong mạng ?
Theo như bài tập của đệ thì tại 1 thời điểm chỉ có 1 con Pic
là master , con còn lại là slave , vậy đệ phải làm sao để con
kia biết nó là slave tại thời điểm đó ? Có phải nó dùng
i2c_isr_state () để đọc ko ạ?

Master thì cần địa chỉ làm gì? Vua thì ai mà chả biết là vua, trừ khi có vua 1, vua 2 cùng 1 vương quốc, lúc đó thì đánh nhau là cái chắc rồi.

Bạn thử dùng cách này thử xem.
Khi cần Pic làm master thì khai báo dòng
#use i2c(master, sda=PIN_C4, scl=PIN_C3, force_hw)
ngay trước cau lệnh master

còn khi cần là slave thì khai bao:
#use i2c(slave, sda=PIN_C4, scl=PIN_C3, address=..., force_hw)
ngay trước cau lệnh slave

Mình thấy trong CSS có sử dụng cách này để thay đổi chân truyền RS232 tại thời điểm cần thiết nhưng chưa thử với I2C

loveall
27-05-2007, 10:34 PM
hình bạn post mờ quá!!

huybo02
06-06-2007, 06:22 PM
Giúp mình tí nha. Đang tìm hiểu về I2C nên mới viết vài lệnh đơn giản để hiểu nó làm gì. Đã truyền được data từ master sang slave tuy nhiên có rắc rối nhỏ khi slave nhận được thì nó không thực hiện chương trình chính trong main() nữa. Mọi người giúp cách khắc phục.

master: Nhấn button ở RB0 => truyền data2

#include<16F877A.h>
#use delay(clock=1000000)
#include<def_877a.h>
#use i2c (master,SCL=PIN_C3,SDA=PIN_C4)
#use fast_io(d)
int data,data2;
#int_EXT
void ngat_RB0()
{
i2c_start();
i2c_write(0x10); // slave address
i2c_write(data2); // Data to slave
delay_ms(100);
i2c_stop();
portd =data2;
data2++;
}
void main()
{
ENABLE_INTERRUPTS(INT_EXT);
ENABLE_INTERRUPTS(GLOBAL);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
trisd=0;
portd=0xF0;
data2 = 0x5;
if (data2==255) data2 = 0;
while (true)
{
}
}


slave: Nhận data2 hiển thị portD, port B thực hiện dịch bit. Nhưng khi nhận thì portB không dịch bit nữa


#include<def_877a.h>
#use i2c (slave,SCL=PIN_C3,SDA=PIN_C4,address =0x10)
#use fast_io(d)
#use fast_io(b)
int a,value,b;
#INT_SSP
void i2c_isr()
{
int8 state;
state = i2c_isr_state();
if(state < 0x80)
{
value = i2c_read(0);
}
if(state == 0x80)
{
i2c_write(b);
}
portb = value;
}

main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
trisd=0;
a=1;
b=0b10101010;
trisb=0;
portb=0;
while (true)
{
portd =a;
delay_ms(500);
if (a==128)
{
a=1;
}
else
{
a=a<<1;
}
}
}



Sẵn đây hỏi luôn làm sao để master đọc từ slave về. Và khi slave truyền bằng i2c_write() thì nó truyền dữ liệu nào?? i2c_write(b) thì nó truyền giá trị của "b" ???

ngohaibac
06-06-2007, 09:17 PM
Master đọc dữ liệu từ Slave theo cơ chế : đầu tiên Master chiếm quyền làm chủ (start hay restart) rùi truyền 1 byte hoặc 2 byte đầu chứa địa chỉ của slave và chế độ đọc hoặc ghi (R/W) tương ứng. R/W = 1 tức chế độ Read.

Slave sẽ luôn luôn nghe ngóng đường truyền, nếu tương thích với địa chỉ Master truyền thì nó sẽ gửi ACK xác nhận. Và khi đó, master bắt đầu đọc dữ liệu.

Chúc bạn thành công.

minhpupil
09-06-2007, 02:32 AM
Anh Falleaf có viết:

Các bạn lưu ý rằng, F nói trường hợp nâng cao, thì chúng ta hoàn toàn có quyền sử dụng mạng Multi Master. Khi bạn setup chip ở chế độ Slave, thì nó thụ động. Nhưng hãy thử nghĩ, tôi làm slave cho mạng này, và làm master của một mạng khác, vậy thì có được không? Vì tôi có tới 40 chân chứ không phải 2 chân.

Vậy nếu tôi làm master cho một mạng khác, mà trong đó slave của tôi lại là master của cái mạng mà tôi làm slave . Hoàn toàn được.

Nhưng vấn đề nâng cao ở chỗ nữa, nếu làm như vậy, tôi phải tốn 4 dây để làm 2 mạng. Vấn đề trước đây hình như F đặt ra cho Linh, nhưng Linh chưa giải quyết xong, đó là Multi Master trong một mạng dùng 2 dây thôi.

Vấn đề này F tiếp tục treo ở đây chờ người giải quyết.

Để hiểu thêm về Multi master này em phải đọc thêm ở tài liệu nào vậy anh?

Em nghĩ như thế này được không anh?
Giả sử trên mạng có 2 con Master 1 và 2 , tại 1 thời điểm chỉ có 1 con là Mater , con còn lại là Slave . Em lấy chân A0 đọc tín hiệu kích về , khi nào nó là 0 thì Master1 là master , khi nào A0=1 thì Master 2 là master.

Rồi em thay đoạn code viết trong CCS của 2 con master như sau:
Giả sử mặc định ban đầu A0=0 , tức Master1 là master:

cho Master1
#use i2c(master, sda=PIN_C4, scl=PIN_C3, force_hw)
..............



void main()
{

set_tris_a(0x01); // A0 là chân nhập
Do
{
if (input(pin_A0))
{
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10, force_hw)
// cho master 1 là Slave , nhưng phần này em nghĩ là chỉ đặt đầu
//chương trình không thể đưa ra dây.Nên ở đây em định chèn đoạn
// code assembly để kích thanh ghi như sau:
#asm
em đưa đoạn code assembly để kích thanh ghi SSPSTAT,SSPCON1
và SSPCON2 để đưa master 1 về slave?
#endasm
}
else
{
// em đưa đoạn code assembly để đưa Master 1 thành master
}

............
}While (1)

}


Đối với Master 2 em làm ngược lại. Như vậy đúng không anh?
Em đọc datasheet của Pic 16f877A trang 105 có nói về multi master , nhưng em chưa hiể rõ lắm, mong anh chủ giúp

tda
09-06-2007, 07:46 PM
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10, force_hw)
// cho master 1 là Slave , nhưng phần này em nghĩ là chỉ đặt đầu
//chương trình không thể đưa ra dây.Nên ở đây em định chèn đoạn
// code assembly để kích thanh ghi như sau:

cai' nay` cung nhu 1 ham` trong C thoi, no' se set cac thanh ghi tuong ung, nen minh` nghi ko can che`n code ASM nua. Noi' the thoi, chu' minh chua thu.

falleaf
09-06-2007, 08:56 PM
Vấn đề khó khăn ở chỗ, hai con PIC hoạt động độc lập với nhau, nó không thể nào biết con nào hiện đang làm master hay slave. Vấn đề xảy ra khi hai con đều "cho rằng mình là master" và gửi một thông tin lên cùng một mạng. Vậy thì sẽ có sự tranh chấp. Lưu ý mạng I2C là mạng 2 dây, khi gửi lên như vậy mọi con đều nhận được và đều sử lý. Hơn nữa, nên nhớ là xung clock của master để giữ nhịp cho toàn bộ mạng, thế thì nếu 2 con cùng lúc tạo ra xung nhịp thì sẽ thế nào? Giá sử như hai con tạo ra xung nhịp khác nhau?

Những vấn đề này xử lý khá loằng ngoằng, nhưng nó được miêu tả rõ trong application note của Microchip, cái này thì F quên mất là AN số bao nhiêu, các bạn tự tìm lại.

Tuy nhiên, lúc F giao cho Linh làm cái bài này, thì vì Linh sử dụng CCS C, cho nên gặp một số khó khăn vì chưa quen sử dụng. Vậy bạn nào có thể làm lại cái AN của Microchip chăng và phân tích rõ vấn đề hơn.

Chúc vui.

namqn
09-06-2007, 09:19 PM
Trong datasheet của các chip thường có nói về chế độ multi-master trong giao tiếp I2C (PIC16F877A chẳng hạn) và trong AN735 có ví dụ về cách hiện thực I2C multi-master.

Trong AN736 đề cập đến mạng sử dụng giao thức I2C, trong này cũng có hiện thực I2C multi-master.

Tinh thần chính là sử dụng ngắt báo hiệu xung đột bus khi một chip thử trở thành master (thực sự) trên bus, dùng cờ ngắt BCLIF. Khi phục vụ ngắt này, chip sẽ chờ một khoảng thời gian ngẫu nhiên nào đó và thử thực hiện lại việc chiếm quyền chỉ huy bus.

Thân,

minhpupil
21-06-2007, 12:36 AM
em có nghiên cứu sơ về I2C multimaster , có một số tài liệu post lên cho mọi người tham khảo (tài liệu tham khảo thôi không chắc đúng , he he nhất là
tham khao i2c multimaster.doc đó).

Sau đây là trang web viết lập trình I2C multi master của CCSC

http://www.ccsinfo.com/forum/viewtopic.php?p=40688&sid=731fec584599477292535d38622cb8a4

vandungevn
12-10-2007, 12:42 PM
Ai đã làm trên MCC18 giao tiếp I2C chạy chưa, Dũng chỉ ghi được nhưng chưa đọc được, đang làm các mô đun tổng thể đưa ra giáo trình MCC18, anh em giúp với nhé, thanks.

Beginner
18-10-2007, 12:25 PM
Các bác cho em hỏi tý:
int8 read_I2C(int8 slave_addr)
{
int8 value_re;
i2c_start();
i2c_write(slave_addr + 1);
value_re = i2c_read(0);
i2c_stop();
return value_re;
}

Khi nào thì dùng i2c_read(0),khi nào thì dùng i2c_read(1).
Có phải là(???):i2c_read(1):ra dấu ACK,tiếp tục nhận dữ liệu
i2c_read(0):ra dấu NACK,báo quá trình nhận dữ liệu kết thúc.
Như vậy là code trên nhận đúng 1byte phải không ạ?Em nghĩ thế ko biết đúng hay sai?

vandungevn
24-10-2007, 06:40 PM
i2c_read(0); // No ACK - Stop read i2c
i2c_read(1); // ACK - Reply after read i2c

theo mình thì: đọc 1 byte dùng lệnh i2c_read(1); là ok .
bạn muốn rõ hơn thì đọc về i2c trong datasheet của DS1307, trong đó giới thiệu về cách truyền và nhận i2c.

Chúc thành công....!

tiendungkct
27-10-2007, 10:47 AM
mình có tài liệu viết i2c bấng phần mền khá hay mong sẽ giúp dc các bạn
bạn xem từ trang 340

tiendungkct
27-10-2007, 10:55 AM
sao em khong thể úp lên dc vậy

namqn: bạn kiểm tra dung lượng tập tin của bạn xem có vượt quá giới hạn cho phép khi upload hay không. Nếu vượt quá dung lượng cho phép thì bạn có thể gửi email cho F (địa chỉ email nằm ở phần chữ ký của F).

tungtot_vl
14-12-2007, 09:52 AM
các anh giúp em với. em copy bài các bài trên xuống dùng và chạy bình thường. nhưng khi dùng cho 2 con slever thì gặp vấn đề. nếu con 1 chạy thì con 2 không chạy. nếu bỏ đoạn con 1 trong master thì con 2 chạy. nếu dùng cả 2 con thì chỉ có con 1 chạy xong rồi đứng yên. không rỏ nguyên nhân vì sao. mong chỉ giáo


#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use Delay(Clock=4000000)
#use i2c(master, sda=PIN_C4, scl=PIN_C3, force_hw)
void write_I2C(int8 value, int8 slave_addr)
{
i2c_start();
i2c_write(slave_addr);
i2c_write(value);
i2c_stop();
}
//==============================================
/*void write_I2C2(int8 value, int8 slave_addr1)
{
i2c_start();
i2c_write(slave_addr1);
i2c_write(value);
i2c_stop();
}*/
int8 read_I2C(int8 slave_addr)
{
int8 value_re;
i2c_start();
i2c_write(slave_addr+1);
value_re = i2c_read(0);
i2c_stop();
return value_re;
}
void main()
{
int8 value_re;
int8 i,a;
const int8 N = 8;
const int8 DIGITS[N] ={ 0b11111111,
0b11111110,
0b11111100,
0b11111000,
0b11110000,
0b11100000,
0b11000000,
0b10000000,
};

set_tris_b(0x00);
while(1)
{
// con 1
for(i = 0; i<8; i++)
{
write_I2C(DIGITS[i], 0x10);
delay_ms(500);
value_re = read_I2C(0x10);
output_b(value_re);
}
// con 2
for(a = 0; a<8; a++)
{
write_I2C(DIGITS[a],0x20);
delay_ms(500);
value_re = read_I2C(0x20);
output_b(value_re);
}
}
}
con slever1
#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(Clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10, force_hw)
int8 value = 0x01;
#INT_SSP
void i2c_isr()
{
int8 state;
state = i2c_isr_state();
if(state < 0x80)
value = i2c_read();
if(state == 0x80)
{
i2c_write(value);
}
}
void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
set_tris_b(0x00);
while(1)
{
output_b(value);
}
}
con slever 2
#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(Clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x20, force_hw)
int8 value1 = 0x01;
#INT_SSP
void i2c_isr()
{
int8 state;
state = i2c_isr_state();
if(state < 0x80)
value1 = i2c_read();
if(state == 0x80)
{
i2c_write(value1);
}
}
void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
set_tris_b(0x00);
while(1)
{
output_b(value1);
}
}

Beginner
15-12-2007, 06:35 PM
Em cũng đang gặp vấn đề tương tự với 1 master và nhiều slave.Mong các bác có kinh nghiệm hướng dẫn.

Khi chỉ có 1 slave thì chạy tốt nhưng có nhiều slave thì có triệu chứng như của bạn tungtot_vl ở trên.

picthanh
16-01-2008, 11:50 AM
xin lỗi các huynnh cho đệ hỏi 1 câu ngu ngóc .em muốn tìm mua một con pic loại rẻ tiền nhất mà có đáp ứng nhu cầu sau: kết nối với bàn phím 4x3 và truyền thông tin phím nhấn ra bus I2C .em chỉ cần hai tinh năng đó thôi.chú ý là loại nào có giá thấp nhất mà có bán trên thị trường Việt Nam.mong các huynh quan tâm giúp đỡ ,tiểu đệ xin cảm ơn trước.

tiendungkct
18-01-2008, 07:07 PM
bạn có thể tìm con 16f887 giá hình như 48.000vnd bạn có thể liên hệ anh F

picthanh
18-01-2008, 07:43 PM
bạn tiendungkct oi ! mình vừa xem datasheet of con 16f887 xong thấy nó có nhiều ký hiệu lạ trên các chân quá (trước giờ mình mới làm việc việc với con 16f877a thôi)mình thấy con 16f876/873 chỉ có 28 chân nhưng ko biết giá nó bao nhiêu nhỉ.mình o nha trang nếu mua trên picvietnam thì ko biết nhận thế nào nhỉ,và trả tiền ra sao? a nhân tiện bạn cho mình hỏi mình có thể mua bàn phím 4x3 (loại chế tạo sẵn có vỏ bọc bảo vệ ,chống nước ,vì mình muốn đặt nó ngoài trời để điều khiển mà) ở đâu và bao nhiêu?

quoc_nguyen
29-02-2008, 12:49 AM
Bạn nào cho mình hỏi muốn gửi xung NACK từ Master --> slave thì làm thế nào.
Thanks

namqn
29-02-2008, 01:29 AM
Bạn nào cho mình hỏi muốn gửi xung NACK từ Master --> slave thì làm thế nào.
Thanks
Bạn đọc phần I2C ở trang web sau vậy, vì bạn không cho biết là PIC 8-bit hay 16-bit.
http://namqn.byethost7.com/Commu.php

Master gửi ACK/NACK khi nó đọc từ slave, muốn làm việc này thì ở thao tác đọc chỉ cần cho phép ACK/NACK và bật/tắt bit trạng thái ACK/NACK (bật là NACK, tắt là ACK).

Thân,

quoc_nguyen
01-03-2008, 12:20 AM
Cam on ban Namqn. Web bạn gửi mình đọc không được. Mình dùng 2 con 16f877a giao tiếp qua i2c và lập trình css C. có phải i2c_read(0) tức là nhận dữ liệu và gửi xung NACK đi không. Mình gửi 5byte dữ liệu liên tiếp từ slave--->master, giờ cho nó dừng lại để làm việc khác nhưng không biết dừng bằng cách nào hết. Bạn cho mình biết rõ hơn về lệnh i2c_isr_state() , giá trị 0x80 và lớn hơn 0x80 khác nhau chỗ nào.
thanks.

namqn
01-03-2008, 01:09 AM
Cam on ban Namqn. Web bạn gửi mình đọc không được. Mình dùng 2 con 16f877a giao tiếp qua i2c và lập trình css C. có phải i2c_read(0) tức là nhận dữ liệu và gửi xung NACK đi không. Mình gửi 5byte dữ liệu liên tiếp từ slave--->master, giờ cho nó dừng lại để làm việc khác nhưng không biết dừng bằng cách nào hết. Bạn cho mình biết rõ hơn về lệnh i2c_isr_state() , giá trị 0x80 và lớn hơn 0x80 khác nhau chỗ nào.
thanks.
Trang web của tôi cũng chỉ dùng Unicode như diễn đàn này thôi, có điều lần đầu load trang web thì có thể bạn phải chấp nhận thông tin bảo mật là không khớp (không rõ bộ phận quản trị mạng của ĐHBK HCM làm thế nào đó mà sinh ra lỗi này). Tôi không dùng CCS C, nên nếu trả lời các vấn đề cụ thể trong CCS C thì cũng chỉ mở tài liệu hướng dẫn của CCS C ra để đọc giúp bạn thôi. Bạn có thể tự làm điều đó.

Để có thể thực hiện thao tác ACK/NACK với hàm i2c_read(), bạn phải dùng 2 tham số, như trong tài liệu hướng dẫn đã viết. Nếu muốn NACK và bạn chỉ có 1 stream, bạn có thể dùng i2c_read(0, 0). Bạn cũng nên có stream = 0 trong phần dẫn hướng #use i2c. Ý nghĩa của trị trả về của hàm i2c_isr_state() đã được ghi rõ trong tài liệu hướng dẫn, 0x80 là địa chỉ khớp, cần đáp ứng bằng một hàm i2c_write(), còn 0x81 - 0xFF là hoàn thành việc phát dữ liệu, và đã nhận được ACK, cần đáp ứng bằng một hàm i2c_write().

Thân,

quoc_nguyen
22-03-2008, 11:11 AM
Mình thực hiện truyền dữ liệu giữa 2 con Pic6f877a bằng I2C (master --> slave), sử dụng CSS C. Việc truyền từng byte thì OK, còn truyên liên tiếp nhiều byte thì mình gặp rắc rối ở chỗ sau khi truyền xong thì không dừng chương trình được. Mình nghĩ bị lỗi ở chỗ không gửi được tín hiệu Nack qua slave. Mong nhh.mecha chỉ giáo. bạn giải thích mình cách dùng i2c_read(), và i2c_read(0); làm sao để dừng giao tiếp i2c sau khi đã truyền một lúc nhiều byte.

nhh
22-03-2008, 12:07 PM
- i2c_read(); đọc 1 byte từ bus i2c và tạo xung ACK
- i2c_read(0); đọc 1 byte từ bus i2c và tạo xung NACK, dùng trước khi i2c_stop(); kết thúc đọc dữ liệu.

Muốn ghi nhiều byte liên tiếp tới SLAVE: Sau khi gửi địa chỉ, gửi liên tiếp các byte cần ghi, muốn ngừng dùng i2c_stop();

Bạn tham khảo tutorial ở trang 1 của anh F gửi, xem format ghi nhận dữ liệu.

Bạn có thể gửi code lên.

quoc_nguyen
02-04-2008, 03:54 PM
Bạn nào đã làm giao tiếp i2c chế độ một master nhiều slave cho mình hỏi tí.
Mình dùng Css C, sử dụng 3 con pic 16f877a trong đó 1 master và 2 slave có một bàn phím ở master để điều khiển lấy dữ liệu từ slave. không hiểu sao chỉ chạy đúng được một trong 2 con, sau đó luôn gửi về giá trị 255.

tam_pascal
22-04-2008, 06:24 PM
Bạn nào đã làm giao tiếp i2c chế độ một master nhiều slave cho mình hỏi tí.
Mình dùng Css C, sử dụng 3 con pic 16f877a trong đó 1 master và 2 slave có một bàn phím ở master để điều khiển lấy dữ liệu từ slave. không hiểu sao chỉ chạy đúng được một trong 2 con, sau đó luôn gửi về giá trị 255.

- Mình dùng thêm một dây nữa nối từ M-S, dây này do S điều khiển = 0 báo cho M biết là S muốn truyền dữ liệu đến M, khi S truyền xong thì cho dây này =1. Còn M cứ thấy dây này =0 là hỏi S và nhận data về. Chứ kết nối hai dây thì M cứ phải hỏi liên tục( mỏi miệng)..hihi. chúc vui
- Tiện thể cho mình hỏi một chút: mình dùng Master =18f4550 và slave=16f877a địa chỉ 0x10 thì tốt, khi chuyển sang dùng 2 con đều là 18f4550 khi lại không đc, (vẫn địa chỉ 0x10) Hay ở 18f4550 con slave phải có địa chỉ khác nhỉ. Ai biết chỉ giúp mình với....xin cảm ơn trước.

electronicltv
24-04-2008, 12:46 PM
Cấu hình cho I2C của pic8F4431 dùng pin_D2 và pin_D3 như sau:
trường hợp 1:
#include <18F4431.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,SSP_RD
#use delay(clock=20000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C5, address=0xa0,force_hw,slow)
trường hợp 2:
#include <18F4431.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,SSP_RD
#use delay(clock=20000000)
#use i2c(SLAVE, SDA=PIN_D2, SCL=PIN_D3, address=0xa0,force_hw,slow)

Tìm hoài k thấy tài liệu hướng dẫn về dzụ này. Với trường hợp 1 thì chạy đúng mặc dù phần mềm chọn pin_c4 và C5 còn phần cứng dùng Pin_D2 và D3. Còn trường hợp 2 là pó chíu luôn, kô xảy ra ngắt SSP luôn. Tìm ra hai trường hợp này là phải ngồi "mò" cả ngày, hic
Vậy giải thích hai trường hợp này: do CCS "chuối" hay do người dùng "gà" quá?

pictd03
28-04-2008, 02:28 AM
xin cho mình hỏi, có ai đã từng làm giao tiếp PIC16f877a với RS_485 chưa? vì mình đang thiết kế mạng dùng 485 kết nối với PIC, nếu có hướng dẫn dùm mình nha, thanks!
Anh Nam nếu biết chỉ giáo em với nha! thanks

namqn
28-04-2008, 02:50 AM
xin cho mình hỏi, có ai đã từng làm giao tiếp PIC16f877a với RS_485 chưa? vì mình đang thiết kế mạng dùng 485 kết nối với PIC, nếu có hướng dẫn dùm mình nha, thanks!
Anh Nam nếu biết chỉ giáo em với nha! thanks
Tôi thử dùng các từ khóa "PIC" và "RS-485" thì thấy có nhiều project trên mạng, có sơ đồ nguyên lý và mã nguồn. Tôi chưa từng làm về vấn đề này, nên có lẽ không giúp gì cho bạn được.

Thân,

Table
13-05-2008, 12:06 AM
Cấu hình cho I2C của pic8F4431 dùng pin_D2 và pin_D3 như sau:
trường hợp 1:
#include <18F4431.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,SSP_RD
#use delay(clock=20000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C5, address=0xa0,force_hw,slow)
trường hợp 2:
#include <18F4431.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,SSP_RD
#use delay(clock=20000000)
#use i2c(SLAVE, SDA=PIN_D2, SCL=PIN_D3, address=0xa0,force_hw,slow)

Tìm hoài k thấy tài liệu hướng dẫn về dzụ này. Với trường hợp 1 thì chạy đúng mặc dù phần mềm chọn pin_c4 và C5 còn phần cứng dùng Pin_D2 và D3. Còn trường hợp 2 là pó chíu luôn, kô xảy ra ngắt SSP luôn. Tìm ra hai trường hợp này là phải ngồi "mò" cả ngày, hic
Vậy giải thích hai trường hợp này: do CCS "chuối" hay do người dùng "gà" quá?

Cái này cũng có nghe rồi, mấy bồ đã bị thì kêu CCS chuối. còn tui đang làm trên C18 thấy tình hình còn...chuối hơn. huhu

tungtot_vl
13-05-2008, 09:01 AM
bác nào làm giao tiếp i2c giữa pic với eeprom 24XX rồi chỉ cho tôi với.
dùng protue có mô phỏng eeprom 24XX được không hả các bác.
khi tôi mô phỏng thì không thấy chạy gì cả. kích chuột vào eeprom thì thấy nó đòi có file binary ở phần initial contents ò memory không biết file này phải lấy từ đâu ra nhỉ mong các cao thủ chie giúp

toanck86
20-05-2008, 11:44 PM
Chào mọi người!
Cho mình hỏi về ví dụ của bạn Hoanf (ví dụ có kèm hình sơ đồ nguyên lý), mình mô phỏng bằng protues thì chạy đúng như yêu cầu bài toán, nhưng lắp mạch thật thì không chạy được. Có cẩn phải chú ý gì từ sơ đồ đó không! :(

cuong86vt
15-06-2008, 05:10 PM
Chào mọi người!
Cho mình hỏi về ví dụ của bạn Hoanf (ví dụ có kèm hình sơ đồ nguyên lý), mình mô phỏng bằng protues thì chạy đúng như yêu cầu bài toán, nhưng lắp mạch thật thì không chạy được. Có cẩn phải chú ý gì từ sơ đồ đó không!
Thằng Toàn làm được mạch I2C chạy ngon lành luôn rồi cũng không thèm Post lên diễn đàn cho mọi người cùng học hỏi gì cả ! Đề nghị Admin tước level "1 túi" của nó ! :mad:

:happyday: PICVIETNAM tròn 1 tuổi ! :beer:

Mình mới viết xong một chương trình I2C dùng 1 Master điều khiển mạng 4 Slave bằng 4 nút ngắt RB, tất cả đều dùng 16f877a, mình xin post lên đây mong các bạn góp ý.

Phần cứng: 4 nút nhấn ngắt ngoài rb4 -> rb7 dùng để điều khiển 4 Slave, nhấn nút nào thì Master gọi Slave đó chạy ct Master gửi xuống, còn các Slave khác "ngồi chơi". 2 chân SDA và SCL của các VDK nối nhau kéo lên 4k7, PORTD của 4 Slave quét 8 led...

Phần mềm: 4 Slave có địa chỉ lần lượt là 0x10, 0x20, 0x30, 0x40 nên chương trình của 4 Slave hoàn toàn như nhau, chỉ khác cái khai báo ban đầu address là 4 địa chỉ trên.


ct của Master:
#include <16f877a.h>
#include <def_877a.h>
#use delay(clock = 20000000)
#fuses HS, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOPROTECT
#use i2c(MASTER, SDA=PIN_C4, SCL=PIN_C3, force_hw)

const unsigned int8 dulieu[]={1,2,4,8,16,32,64,128};
const unsigned int8 address_slave[]={0,0x10,0x20,0x30,0x40};
int8 a,i,kytu;

void ghi(int8 address,int8 data)
{
i2c_start();
i2c_write(address);
i2c_write(data);
i2c_stop();
}

#INT_RB
void ngat_RB()
{
if((RBIF)&&(RBIE))
{
if(RB4==0)
{
a=1;
i=0;
}
else if(RB5==0)
{
a=2;
i=0;
}
else if(RB6==0)
{
a=3;
i=0;
}
else if(RB7==0)
{
a=4;
i=0;
}
}
RBIF=0;
}

void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_RB);
set_tris_d(0);
portd=0;

while(TRUE)
{
kytu=a;
delay_ms(100);

while(kytu==a)
{
if(a!=0)
{
delay_ms(50);
ghi(address_slave[a],dulieu[i]);
i++;
if(i==8)
{
i=0;
}
}
}

}
}

ct của 4 Slave, chỉ khác nhau 4 address:
#include <16f877a.h>
#include <def_877a.h>
#use delay(clock = 20000000)
#fuses HS, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOPROTECT
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10, force_hw)

int8 dulieu;

#INT_SSP
void ngat_i2c()
{
int8 state;
state = i2c_isr_state();
if(state < 0x80)
{
dulieu = i2c_read();
portd = dulieu;
delay_ms(50);
}
}

void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
set_tris_d(0);

while(TRUE)
{
portd = 0;
}
}

Mạch mình chạy mô phỏng bằng Proteus thấy có đặc điểm: nếu chỉ nối 1 M và 1 S thì quét led đúng thời gian delay 50ms, còn nối 4 S vào thì dường như led quét rất chậm không đúng 50 ms nữa, nhưng mình nghĩ Proteus chỉ mô phỏng thời gian thực, còn nếu là phần cứng thật thì sẽ chạy đúng yêu cầu như trong code...

Em muốn post sơ đồ mạch lên mà không biết chèn code như thế nào, mong Admin chỉ giùm em cách tải file từ máy...

hopeman
04-07-2008, 12:29 PM
Cấu hình cho I2C của pic8F4431 dùng pin_D2 và pin_D3 như sau:
trường hợp 1:
#include <18F4431.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,SSP_RD
#use delay(clock=20000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C5, address=0xa0,force_hw,slow)
trường hợp 2:
#include <18F4431.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,SSP_RD
#use delay(clock=20000000)
#use i2c(SLAVE, SDA=PIN_D2, SCL=PIN_D3, address=0xa0,force_hw,slow)

Tìm hoài k thấy tài liệu hướng dẫn về dzụ này. Với trường hợp 1 thì chạy đúng mặc dù phần mềm chọn pin_c4 và C5 còn phần cứng dùng Pin_D2 và D3. Còn trường hợp 2 là pó chíu luôn, kô xảy ra ngắt SSP luôn. Tìm ra hai trường hợp này là phải ngồi "mò" cả ngày, hic
Vậy giải thích hai trường hợp này: do CCS "chuối" hay do người dùng "gà" quá?

mình cũng đã từng gặp trường hợp như bạn. theo mình nghĩ thì có thể là vì từ khóa "force_hw" tức là dùng phần cứng mặc định, vì vậy dù bạn khai là chân D2 và D3 nhưng tín hiệu vẫn ra chân C4 C5 ( con 4431 có 2 đường i2c mà ), bạn thử bỏ từ khóa này đi xem sao .

mấy hôm rồi mình bị mất đồng bộ gửi nhận suốt, các bạn nếu mới làm nhớ để ý bên con slaver trong quá trình nhận nhé
mình khuyến cáo nên dùng cấu trúc sau để nhận trong trình xử lý ngắt #INT_SSP ssp :
while(count_i2c!=4) {

while(!i2c_poll()) ;

buffer[count_i2c++]= i2c_read(); //Read Next

}
hy vọng ko ai phải mất thời gian về i2c nhiều như mình .hichic

dientubk3
15-08-2008, 04:24 PM
Hi ! Có bạn nào nghiên cứu về I2CSB-I2C Slave Base không thươ1ng dẫn em nhé!Thanks.Có tài liệu chi tiết nào về sơ đồ khối hay gì đó thì send cho em nhé!Thiết kế I2CSB giống nhu thiết kế 1 khối IP phải ko ạh?Help me please!!!

dientubk3
16-08-2008, 12:16 AM
Đây là sơ đồ khối chi tiết cuả I2CSB!Bạn nào biết phân tích chi tiết nhiệm vụ và chức năng của từng khối cho mình nhé!mình cảm ơn nhiều.Và nếu mình thiết kế 1 khối IP-I2CSB như vậy thì cần phải bắt đầu như thế nào ,mong các bạn góp ý nhé!Thanks a lot!!!

namqn
16-08-2008, 02:06 AM
Đây là sơ đồ khối chi tiết cuả I2CSB!Bạn nào biết phân tích chi tiết nhiệm vụ và chức năng của từng khối cho mình nhé!mình cảm ơn nhiều.Và nếu mình thiết kế 1 khối IP-I2CSB như vậy thì cần phải bắt đầu như thế nào ,mong các bạn góp ý nhé!Thanks a lot!!!
Bạn đang tìm hiểu việc hiện thực module I2C ở chế độ slave trên logic khả trình (programmable logic) phải không? Nếu đúng thì bạn nên hỏi ở www.dientuvietnam.net, diễn đàn này chủ yếu dành cho PIC.

Thân,

dientubk3
16-08-2008, 10:08 AM
Vậy trong www.dientuvietnam.net bạn có biết topic nào nói về I2C không thì chỉ cho mình với nhé?Hoặc có trang web tiếng việt nào bàn về I2C ko thì báo dùm mình với nhé!!!Thanks.

minhsondaklak
16-08-2008, 07:31 PM
I2C với Pic 16f877A:
http://www.picvietnam.com/forum//showthread.php?t=2644

I2C với Pic 16f84A:
http://www.picvietnam.com/forum//showthread.php?t=2671

hmk
17-08-2008, 04:30 PM
Chào các bạn,

Tôi đang dùng PIC 18F4520 làm đồng hồ thời gian thực sử dụng ds1307. Dùng MPLAB C18 để lập trình và các thư viện chuẩn của MCC18. Tôi mô phỏng trên proteus thì chạy ngon lành nhwng mang ra làm mạch thật thì không chạy. Tôi dùng hàm OpenI2C(MASTER, SLEW_OFF) để cho phép I2C và tạo tốc độ 100kHz trên SCL (theo chú thích trong thư viện) nhưng thực tế thì khi dùng osciloscope để đo tần số trên SCL thì thấy tốc độ khoảng 500kHz khi có truyền dữ liệu. Bạn nào biết lý do tại sao và cách khắc phục thi giúp tôi nhé. Thanks nhiều.

hmk

ntn60
29-08-2008, 06:45 PM
Chào các bạn,

Tôi đang dùng PIC 18F4520 làm đồng hồ thời gian thực sử dụng ds1307. Dùng MPLAB C18 để lập trình và các thư viện chuẩn của MCC18. Tôi mô phỏng trên proteus thì chạy ngon lành nhwng mang ra làm mạch thật thì không chạy. Tôi dùng hàm OpenI2C(MASTER, SLEW_OFF) để cho phép I2C và tạo tốc độ 100kHz trên SCL (theo chú thích trong thư viện) nhưng thực tế thì khi dùng osciloscope để đo tần số trên SCL thì thấy tốc độ khoảng 500kHz khi có truyền dữ liệu. Bạn nào biết lý do tại sao và cách khắc phục thi giúp tôi nhé. Thanks nhiều.

hmk
Có thể do bạn dùng thạch anh tần số gấp 5 lần, thường thì các hàm trong thư viện dùng với thạch anh 4MHz

hopeman
03-09-2008, 04:01 PM
Chào các bạn,

Tôi đang dùng PIC 18F4520 làm đồng hồ thời gian thực sử dụng ds1307. Dùng MPLAB C18 để lập trình và các thư viện chuẩn của MCC18. Tôi mô phỏng trên proteus thì chạy ngon lành nhwng mang ra làm mạch thật thì không chạy. Tôi dùng hàm OpenI2C(MASTER, SLEW_OFF) để cho phép I2C và tạo tốc độ 100kHz trên SCL (theo chú thích trong thư viện) nhưng thực tế thì khi dùng osciloscope để đo tần số trên SCL thì thấy tốc độ khoảng 500kHz khi có truyền dữ liệu. Bạn nào biết lý do tại sao và cách khắc phục thi giúp tôi nhé. Thanks nhiều.

hmk

bạn hãy để ý lại phần khai báo tần số dao động của mình, tôi nghĩ là đã có nhầm lẫn ở đâu đó trong phần này dẫn tới các hàm của bạn dùng tính toán với tần số dao động bị sai

dientubk3
09-09-2008, 11:06 AM
Chào!Mình đang nghiên cứ giao tiếp giữa LCD thường với I2c điều khiển bởi Master là Pic.Vậy giao tiếp giữa LCD và I2C trên thực tế phần cứng mình phải giao tiếp như thế nào đây,giao tiếp những chân nào với nhau ?Còn đối vớ Rom thì sao?Vì Rom ngoài địa chỉ Slave ra còn có địa chỉ của từng thanh ghi trong Rom ,Mình sẽ giao tiếp với từng thanh ghi như thế nào đây?Trên thị trường hiện nay có Lcd,Rom nào tích hợp sẵn I2C không nhỉ?Hepl me!Please!

dientubk3
09-09-2008, 11:11 AM
Àh,hình như chuẩn I2C không có cơ chế báo lỗi bit trên đường truyền phải không các bạn?Ngoài ACK chỉ dùng báo khi truyền hết một byte dữ liệu còn Nack chỉ dùng khi không nhận được vậy còn cơ chế báo lỗi ,kiểm tra lỗi bit hay lỗi trên đường truyên thì không có phải không?Ai biết giúp mình với nhé!Thanks.

tallht
09-09-2008, 06:37 PM
theo mình được biết thì có mấy loại eeprom của atmel có tích hợp i2c đó: At24c01,at24c02,04,...

dientubk3
11-09-2008, 12:46 AM
Chà !Sao ko thấy anh em giúp mình vậy cà?Help me ,please!!!

dientubk3
11-09-2008, 12:52 AM
Àh,còn câu hỏi nữa là các đường SDA,SCL sử dụng theo hàm "And "nối dây.Vậy thì trên một bus I2C có nhiều Mater và Slave thì cấu trúc mạch thực tế như thế nào ?Có hàm And nối dây trên mạch hay không ?Có gì úp dùm mình một tấm hình thực tế nhé!Mình nghĩ đây cũng là những điều cơ bản về I2C.Chắc mọi người sẽ dành thời gian giúp mình .Thanks a lot!

hopeman
11-09-2008, 11:22 AM
Àh,hình như chuẩn I2C không có cơ chế báo lỗi bit trên đường truyền phải không các bạn?Ngoài ACK chỉ dùng báo khi truyền hết một byte dữ liệu còn Nack chỉ dùng khi không nhận được vậy còn cơ chế báo lỗi ,kiểm tra lỗi bit hay lỗi trên đường truyên thì không có phải không?Ai biết giúp mình với nhé!Thanks.

việc ở trạng thái thông thường cả SDA và SCL ở mức cao cũng là một cách để nhận biết được sự cố "đứt dây" trong quá trình truyền, còn cơ chế báo lỗi bit thì thực sự là mình chưa nghe nói đến ở chuẩn giao tiếp I2C

piano lover
13-09-2008, 02:57 PM
Cho mình hỏi cách khai báo tốc độ truyền I2C trong CCS như thế nào, vì phần cứng chỉ hổ trợ tối đa 400 Kbps nhưng trong phần help có ví dụ fast=450000 (sets the target speed to 450 KBSP) và giá trị đó khai báo bao nhiêu cũng không báo lỗi, chẳng bít thằng CCS nó hiểu như thế nào? và 400Kbps là tốc độ tối đa trong Pic hay là tốc độ tối đa của chuẩn I2C? chiều dài tối đa của bus I2C hổ trợ là bao nhiêu? trên trang web này nó bảo là 100m ở tốc độ 500Hz http://www.esacademy.com/faq/i2c/q_and_a/faq/i2cqa1.htm

thienthan_den
17-09-2008, 05:47 PM
Em có một chút thắc mắc về giao tiếp I2C: Không biết quá trình truyền và nhận dữ liệu giữa master và slave được đồng bộ nhờ phần cứng hay là nhờ thằng CSS hoặc là tự mình phải làm lấy? Chuyện gì xảy ra khi master truyền dữ liệu mà không nhận được ACK từ slave? Nó sẽ truyền lại byte dó hay là cứ chờ? Một vấn đề nữa là khi dùng hàm i2c_isr_state() đọc trạng thái của bus i2c và trả về giá trị <0x80 thì mình có phải đợi cho dữ liệu ổn định bằng cách dùng delay_ms(x) trước khi dùng i2c_read() không? Chương trình của em viết khi không có delay_ms() thì slave không đọc được giá trị về? Không biết có phải em viết sai không. Mong mọi người giúp đỡ.
PS: hôm nay không mang code theo nên không up lên được,mong mọi người thông cảm.

piano lover
19-09-2008, 05:49 PM
Sao không ai giúp mình hết vậy?

dientubk3
05-10-2008, 10:19 PM
Mình đang làm về I2CSB,dùng để diều khiển các thiết bị thụ động như LCD ,ram.Bây giờ mình ra ngoài thị trường mua loại LCD bình thường không tích hợp bus I2C và một Pic có tích hợp I2C làm Master điều khiển.con I2CSB mình sẽ tạo ra ,vậy mình nên mua lạoi LCD nào ?Pic nào phổ biến trên thị trường để phục vụ cho nghiên cứu của mình đây!Vui lòng giúp mình nhé!!!Thanks

duong4747
06-10-2008, 09:21 AM
Chào các bác, e đang viết chương trình giao tiếp dùng I2C giữa Pic16f877 và DS1307 trong MPLAP IDE mà không được, vấn đề nằm ở chỗ khai báo sử dụng chân SCL và SDA trong portc. Xin hỏi bác nào có đoạn code khai báo viết trong MPLAP IDE thì port lên cho e với, e cảm ơn nhiều!

tungtot_vl
09-10-2008, 11:39 AM
chào các bác mình đang làm giao tiếp i2c với 24c64.
mình coppy trong file hell của ccs ra và chạy thử cho 1 byte.
khi hàm ghi và đọc được dùng ở ngoài vòng lặp white() thì chương trình đọc đúng giá trị ghi vào.
nhưng khi bỏ hàm ghi và đọc và vòng lặp white() thì chương trình chỉ đọc đúng lần đầu tiên. khi lặp lại vòng lặp thì bị sai.
hoặc nếu ghi và đọc nhiều lần cho từng byte thì data dọc ra cũng bị sai. mình không rỏ vì sao mong các bạn chỉ giúp.
#include<18f4680.h>
#fuses NOLVP,NOWDT,PUT,hs,NOPROTECT,NOBROWNOUT
#device 18f4680*=16 ADC=10 // high_ints=true
#use delay(clock=20000000)
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#use fast_io(e)
int k;

////////////////////////////////////////////////////////////////////////
#ifndef EEPROM_SDA

#define EEPROM_SDA PIN_b1 //b1
#define EEPROM_SCL PIN_b0//b0

#endif

#use i2c(master, sda=EEPROM_SDA, scl=EEPROM_SCL)

#define EEPROM_ADDRESS long int
#define EEPROM_SIZE 8192

void init_ext_eeprom()
{
output_FLOAT(EEPROM_SCL);
output_FLOAT(EEPROM_SDA);
}

void write_ext_eeprom(long int address, BYTE data)
{
short int status;
i2c_start();
i2c_write(0xa0);
i2c_write((address>>8)&0x1f);
i2c_write(address);
i2c_write(data);
i2c_stop();
status=i2c_write(0xa0);
while(status==1)
{
i2c_start();
status=i2c_write(0xa0);
}
}

BYTE read_ext_eeprom(long int address) {
BYTE data;
i2c_start();
i2c_write(0xa0);
i2c_write((address>>8)&0x1f);
i2c_write(address);
i2c_start();
i2c_write(0xa1);
data=i2c_read(0);
i2c_stop();
output_d(data);
return(data);
}

void main()
{
set_tris_A(0x00);
set_tris_b(0x00);
set_tris_C(0x00);
set_tris_D(0x00);
set_tris_E(0x00);
/////////////////////////
write_ext_eeprom(10,8);
read_ext_eeprom(10);
while(1)
{
delay_ms(1000);

}
}
/////////////////////////////////////////////////
nếu bỏ các hàm vào vòng lặp thì chỉ chạy đúng lần đầu tiên. các lần còn lại là sai
while(1)
{
write_ext_eeprom(10,8);
read_ext_eeprom(10);
delay_ms(1000);

}
//////////////////////////////
ghi và đọc nhiều lần cũng bị sai data
while(1)
{
write_ext_eeprom(10,8);
read_ext_eeprom(10);
delay_ms(1000);
write_ext_eeprom(12,6);
read_ext_eeprom(12);
delay_ms(1000);


}

ketxanh
22-10-2008, 03:04 PM
tui moi lam xong giao tiep i2c giữa pic8f2550 và pic 18f4550, chương trình chạy ngon lành. anh em nào có hứng thú tui post lên cho

falleaf
09-11-2008, 01:14 PM
tui moi lam xong giao tiep i2c giữa pic8f2550 và pic 18f4550, chương trình chạy ngon lành. anh em nào có hứng thú tui post lên cho

Bạn nên post bài của bạn lên luôn, vì rất nhiều người đã làm vấn đề này, và cần càng nhiều bài tham khảo càng tốt, từ đó người đọc sẽ biết thêm nhiều cách để tối ưu code của mình.

Chúc vui

ketxanh
23-11-2008, 11:21 PM
Xin lỗi anh em vi minh post hơi chậm.Mong mọi người đóng góp ý kiến nhé

ketxanh
04-12-2008, 08:30 AM
không biết co ai quan tâm cái i2c của tui không, mà không thấy đóng góp ý kiên gì, hay cái cảm ơn gì hết ta.....buồn wa. không thi mọi ngừoi chê tui cũng được đặng tui còn biết để mà sửa lỗi lầm

bien_van_khat
05-12-2008, 10:19 AM
không biết co ai quan tâm cái i2c của tui không, mà không thấy đóng góp ý kiên gì, hay cái cảm ơn gì hết ta.....buồn wa. không thi mọi ngừoi chê tui cũng được đặng tui còn biết để mà sửa lỗi lầm

Có thể bây giờ chưa có bạn nào gặp rắc rối về I2C, tuy nhiên mai mốt, ai đó cần code mẫu về I2C cho cả slave - master viết = CCS chắc chắn sẽ rất cảm ơn code của bạn. :D

dientubk3
19-12-2008, 11:06 PM
Hi các Pro !Em có chương trình viết cho Pic 16f877A,chế độ Mater i2c.Giao tiếp với LCD16x2 chế độ 4bit,giao tiếp với i2c slave và bàn phím 4x4 nữa!Chương trình của em là :
+Khi nhấn một phím 4x4 thì sẽ phát một dữ liệu lên LCD và đồng thời dữ liệu đó cũng được truyền trên I2C Bus tới Slave.Em chỉ mới biết C cho CCS ,còn non quá!Bác nào có thể chỉ giáo em giao tiếp pic 16f877a với bàn phím 4x4 đồng thời hiển thị LCD và truyền I2C như trên được ko ?Thanks các Pro!

minhminh17
22-12-2008, 09:33 PM
chuong trinh ban lam minh co thu ma sao khi chi can nhan rb3 den rb7 deu xay ra ngat dong loat ma minh nho rb3 dau co ngat dau ma sao no cung thanh ngat luon la sao
va khi vao ngat no thuc hien tat ca cac ngat tu rb4 den rb7 khong chua cai nao roi thoat khoi ngat la sao vay??
mong ban giai thich dieu vo ly do.

ct của Master:
#include <16f877a.h>
#include <def_877a.h>
#use delay(clock = 20000000)
#fuses HS, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOPROTECT
#use i2c(MASTER, SDA=PIN_C4, SCL=PIN_C3, force_hw)

const unsigned int8 dulieu[]={1,2,4,8,16,32,64,128};
const unsigned int8 address_slave[]={0,0x10,0x20,0x30,0x40};
int8 a,i,kytu;

void ghi(int8 address,int8 data)
{
i2c_start();
i2c_write(address);
i2c_write(data);
i2c_stop();
}

#INT_RB
void ngat_RB()
{
if((RBIF)&&(RBIE))
{
if(RB4==0)
{
a=1;
i=0;
}
else if(RB5==0)
{
a=2;
i=0;
}
else if(RB6==0)
{
a=3;
i=0;
}
else if(RB7==0)
{
a=4;
i=0;
}
}
RBIF=0;
}

void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_RB);
set_tris_d(0);
portd=0;

while(TRUE)
{
kytu=a;
delay_ms(100);

while(kytu==a)
{
if(a!=0)
{
delay_ms(50);
ghi(address_slave[a],dulieu[i]);
i++;
if(i==8)
{
i=0;
}
}
}

}
}

ct của 4 Slave, chỉ khác nhau 4 address:
#include <16f877a.h>
#include <def_877a.h>
#use delay(clock = 20000000)
#fuses HS, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOPROTECT
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10, force_hw)

int8 dulieu;

#INT_SSP
void ngat_i2c()
{
int8 state;
state = i2c_isr_state();
if(state < 0x80)
{
dulieu = i2c_read();
portd = dulieu;
delay_ms(50);
}
}

void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
set_tris_d(0);

while(TRUE)
{
portd = 0;
}
}

Mạch mình chạy mô phỏng bằng Proteus thấy có đặc điểm: nếu chỉ nối 1 M và 1 S thì quét led đúng thời gian delay 50ms, còn nối 4 S vào thì dường như led quét rất chậm không đúng 50 ms nữa, nhưng mình nghĩ Proteus chỉ mô phỏng thời gian thực, còn nếu là phần cứng thật thì sẽ chạy đúng yêu cầu như trong code...

Em muốn post sơ đồ mạch lên mà không biết chèn code như thế nào, mong Admin chỉ giùm em cách tải file từ máy...[/QUOTE]

namqn
22-12-2008, 11:55 PM
...
Em muốn post sơ đồ mạch lên mà không biết chèn code như thế nào, mong Admin chỉ giùm em cách tải file từ máy...
Bạn đọc hướng dẫn ở luồng sau:
http://www.picvietnam.com/forum/showthread.php?t=3289

Thân,

quychienvodich
02-01-2009, 02:09 PM
mình làm mạch i2c 1 master+4slaver đều là 16f877a điều khiển 20động cơ bước 2 tuần trước mạch chạy ngon lành lun nạp xuống là chạy!!!!!!
nhưng sau 2tuần không động tới mạch thì hữi ui mạch không chạy lun vẫn mạch đó chương trình đó không đổi 1 cái gì vậy mà không chạy nhục wá bó tay h không bít sao nữa
tháng 3 báo cáo đề tài rùi mà không có cái mạch đó cắhc nhảy lầu

thientaisodo
17-02-2009, 02:30 PM
Các bạn cho mình hỏi địa chỉ để giao tiếp với ROM (vd:24c64) thì qui định thế nào. Tìm mãi chẳng có bài viết nào nhắc đến cả. Ở đây mình muốn kết nối I2C của 1PIC F877A(master), cùng một PIC 877A (slave) và một ROM 24C64.
Mong được chỉ giáo !

namqn
17-02-2009, 05:47 PM
Các bạn cho mình hỏi địa chỉ để giao tiếp với ROM (vd:24c64) thì qui định thế nào. Tìm mãi chẳng có bài viết nào nhắc đến cả. Ở đây mình muốn kết nối I2C của 1PIC F877A(master), cùng một PIC 877A (slave) và một ROM 24C64.
Mong được chỉ giáo !
Bạn tự quyết định địa chỉ của EEPROM bằng cách đặt trạng thái xác định cho các chân địa chỉ của nó (A0, A1, và A2). Địa chỉ của PIC slave cũng cần khác với địa chỉ của EEPROM.

Thân,

thientaisodo
18-02-2009, 09:58 AM
Cảm ơn bạn, mình đã hiểu rồi, vậy là địa chỉ của EEPROM sẽ được định nghĩa từ các chân trên nó và có 8 địa chỉ từ 00 - 07 đúng không bạn ? :)

namqn
18-02-2009, 03:52 PM
Cảm ơn bạn, mình đã hiểu rồi, vậy là địa chỉ của EEPROM sẽ được định nghĩa từ các chân trên nó và có 8 địa chỉ từ 00 - 07 đúng không bạn ? :)
Đúng vậy.

Thân,

haquang
22-04-2009, 12:50 PM
Các anh cho em hỏi vấn đề về I2C cái: Em copy chương trình ở thread này và dùng giao tiếp 2 PIC thì có vấn đề như sau: Khi sử dụng để mô phỏng thì chạy bình thường như ý muốn nhưng khi chạy với mạch thật và thêm modul RS232 để đưa lên Terminal trên PC để check thì chỉ thấy có FF được gửi lên. Cao thủ nào từng gặp lỗi này thì gợi ý em cách debug cái :) many thanks!

Code: Master
[#include <16F877A.H>
#include <DEFS_16F877A.h>
#include <def_877a.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use Delay(Clock=20000000)
#define use_portd_lcd TRUE
#include <lcd.c>
#include <STDLIBM.H>
//#include <toanlcd.c>
#use i2c(master, sda=PIN_C4, scl=PIN_C3)
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7)
int8 value_re;

unsigned char* data_in;
const int8 N = 20;
//================================================== ======
void putch(unsigned char a)
{
/* output one byte */
while(!TXIF) /* set when register is empty */
continue;
TXREG = a;
}
void write_I2C(unsigned char* digit,int8 slave_addr,int n)
{
int i;
i2c_start();
i2c_write(slave_addr);
for (i=0;i<N;i++)
i2c_write(digit[i]);
i2c_start();
i2c_write(slave_addr);
i2c_stop();
}
void read_I2C()
{
int i;
i2c_start();
i2c_write(0x11);
for (i=0;i<N;i++)
{
value_re = i2c_read();
data_in[i]=value_re;
}
i2c_start();
i2c_write(0x11);
i2c_stop();
}

void main()
{
int8 value_re=2;
int8 i=10;


char* DIGITS[N] ={ 0b11111111,
0b11111110,
0b11111100,
0b11111000,
0b11110000,
0b11100000,
0b10101010,
0b01010101,
};
const int8 slave_addr = 0x10;
set_tris_b(0x00);
putch('a');
data_in=malloc(50);
//write_I2C(DIGITS,0x10,8);

read_I2C();
for (i=0;i<N;i++)
{
output_b(data_in[i]);
putch(data_in[i]);
delay_ms(1000);
}

}]

Code slave:
:[#include <16F877A.H>
#include <STDLIBM.H>
#fuses HS,NOWDT,NOPROTECT,NOLVP

#use delay(Clock=20000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10)
char* data;
int8 value = 0x01,valueh=0,valuel=0;
int8 state;
#INT_SSP
void i2c_isr()
{
state = i2c_isr_state();
if(state >=0x80)i2c_write(data[state-0x80]);
else if(state>0)data[state-1]=i2c_read();
}

void main()
{
const int N=20;
int i;
data=malloc(N);
for (i=0;i<N;i++)
data[i]=i;
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
set_tris_b(0x00);
while(1);
}]

thanks

nhoczin
23-04-2009, 12:59 AM
Em làm giao tiếp I2C giữa 877a ( master ) và 88 ( slave ) : 877a đếm từ 0 >> 255 hiển thị LCD và truyền giá trị đó tới 88, 88 nhận, nếu là chẵn thì rb0 = 1, nếu ko thì rb0 = 0, gặp phải vấn đề sau:

Khi truyền dữ liệu từ 877a đến 88 thì 88 không nhận được, cụ thể là 88 không nhảy vào ngắt, xung I2C vẫn truyền bình thường, khi mô phỏng thì 877a vẫn chạy bình thường, 88 không thấy thay đổi gì. Khi nạp vào mạch thật thì 877a không hoạt động được ( không thể đếm và hiển thị lên LCD ) 88 không thay đổi gì. Em đã kiểm tra nhưng chưa phát hiện được gì. Em hi vọng được sự trợ giúp của mọi người trong 4r.

Code 877a master

#include <16F877A.h>
#device *=16
#device adc=8

#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected

#use delay(clock=20000000)
//#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bi ts=8)
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3,force_hw)
#include <def_877a.h>
#include <lcd_4bit.c>

void write_data(int8 n, int8 address)
{
i2c_start();
i2c_write(address);
i2c_write(n);
i2c_stop();
}

void main()
{
int8 n = 0;
trisd = 0x00;
portd = 0x00;
trisc = 0xff;
lcd_init();
lcd_clear();
while(true)
{
lcd_int8(n,1,2); // Hiển thị số n ra LCD tại cột 1 hàng 2
write_data(n,1);
delay_ms(100);
n++;
}


}


Code 88 ( slave )

#include <16F88.h>
#device adc=8

#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT //No Power Up Timer
#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOFCMEN //Fail-safe clock monitor disabled
#FUSES NOIESO //Internal External Switch Over mode disabled

#use delay(clock=20000000)
#use i2c(Slave,Fast,sda=PIN_B1,scl=PIN_B4,force_hw,addr ess=0x01)
#include <def_88.h>

int8 value = 0, address;
int1 count = 0;

#int_SSP
void SSP_isr(void)
{
int8 byte_in, state;
state = i2c_isr_state();
byte_in = i2c_read();
if(state == 0)
address = byte_in;
else if(state < 0x80)
value = byte_in;
count++; // Nếu có vào ngắt thì biến count thay đổi và hiển thị trên RA0
}



void main()
{
trisb0 = 0;
trisa0 = 0;
trisb1 = 1;
trisb4 = 1;

enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);

while(true)
{
ra0 = count;
if(value%2 == 0) rb0 =1;
else rb0 = 0;
}

}


Em hỏi việc sử dụng biến address, khai báo ở biến toàn cục là có tác dụng gì vậy, và cách gán nó bằng biến byte_in trong chương trình ngắt. Theo em hiểu là nó sẽ đọc địa chỉ khi con master gửi, nhưng em không thấy chỗ nào tương tác với biến address cả, chỉ thấy trên phần khai bảo của con slave có chỗ address.

rien
23-06-2009, 11:04 AM
Các anh cho em hỏi vấn đề về I2C cái: Em copy chương trình ở thread này và dùng giao tiếp 2 PIC thì có vấn đề như sau: Khi sử dụng để mô phỏng thì chạy bình thường như ý muốn nhưng khi chạy với mạch thật và thêm modul RS232 để đưa lên Terminal trên PC để check thì chỉ thấy có FF được gửi lên. Cao thủ nào từng gặp lỗi này thì gợi ý em cách debug cái :) many thanks!



void read_I2C()
{
int i;
i2c_start();
i2c_write(0x11);
for (i=0;i<N-1;i++)
{
value_re = i2c_read(1);
data_in[i]=value_re;
}
value_re = i2c_read(0);
data_in[N-1]=value_re;
i2c_stop();
}


Bạn thử chương trình read_i2c() này xem thử có được không

rien
23-06-2009, 11:27 AM
Em làm giao tiếp I2C giữa 877a ( master ) và 88 ( slave ) : 877a đếm từ 0 >> 255 hiển thị LCD và truyền giá trị đó tới 88, 88 nhận, nếu là chẵn thì rb0 = 1, nếu ko thì rb0 = 0, gặp phải vấn đề sau:

Khi truyền dữ liệu từ 877a đến 88 thì 88 không nhận được, cụ thể là 88 không nhảy vào ngắt, xung I2C vẫn truyền bình thường, khi mô phỏng thì 877a vẫn chạy bình thường, 88 không thấy thay đổi gì. Khi nạp vào mạch thật thì 877a không hoạt động được ( không thể đếm và hiển thị lên LCD ) 88 không thay đổi gì. Em đã kiểm tra nhưng chưa phát hiện được gì. Em hi vọng được sự trợ giúp của mọi người trong 4r.


Bạn sửa địa chỉ của slave thành 0x10.
Nếu bạn đặt địa chỉ của slave là 0x01 thì khi mater ghi dữ liệu xuống slave, Slave sẽ hiểu nhầm là master cần đọc dữ liệu. Khi đó biến State >=0x80 và hàm ngắt của bạn không làm gì cả.

dung h
21-07-2009, 04:41 PM
Chào các bạn!!
Cho mình post sơ đồ và code của minh lên đây cho các bạn coi và có gì góp ý cho mình nha.

Đây là đoạn code Master: Master truyền một mảng cho Slave và nhận về mảng mà đã chuyển cho Slave để hiển thị lên port_b(kiểm tra hihi...) giống echo.


#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use Delay(Clock=4000000)

#use i2c(master, sda=PIN_C4, scl=PIN_C3, force_hw)

void write_I2C(int8 value, int8 slave_addr)
{
i2c_start();
i2c_write(slave_addr);
i2c_write(value);
i2c_stop();
}

int8 read_I2C(int8 slave_addr)
{
int8 value_re;
i2c_start();
i2c_write(slave_addr + 1);
value_re = i2c_read(0);
i2c_stop();
return value_re;
}

void main()
{
int8 value_re;
int8 i;
const int8 N = 8;
const int8 DIGITS[N] ={ 0b11111111,
0b11111110,
0b11111100,
0b11111000,
0b11110000,
0b11100000,
0b11000000,
0b10000000,
};
const int8 slave_addr = 0x10;

set_tris_b(0x00);
while(1){
for(i = 0; i<8; i++){
write_I2C(DIGITS[i], slave_addr);
delay_ms(500);
value_re = read_I2C(slave_addr);
output_b(value_re);
}
}
}


Còn đây là đoạn code Slave:


#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#use delay(Clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10, force_hw)

int8 value = 0x01;

#INT_SSP
void i2c_isr()
{
int8 state;

state = i2c_isr_state();
if(state < 0x80)
value = i2c_read();
if(state == 0x80){
i2c_write(value);
}
}

void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);

set_tris_b(0x00);
while(1){
output_b(value);
}
}


sao mình viết vd của bạn mà o thấy chạy gì cả? ai có thể giải thích giúp mình chưong trình trên và vài vấn đề sau:
- khi mater muốn truyền data thì cần phải làm gì?
- khi master muốn nhận thì phải làm gì?
- khi master đang truyền mà muồn dừng lại để nhận thì làm thế nào?
thanks!

nguyenhung1811
21-07-2009, 11:12 PM
chuong trinh minh viet co j sai ko ha cac ban? sao minh viet mai ma` no' chi thuc hien duoc 1 lan ghi, sau cau lenh i2c_stop() thi no' khong the doc ghi duoc nua?
-----------------------------------------------------------------------------------
#include <16f877a.h>
#include <def_16f877a.h>
#device *=16 ADC=8
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG,

NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#use I2C(master,sda=PIN_C4,scl=PIN_C3) // dung i2c =

phan cung
#include <lcd_lib_4bit.c> // Thu vien ham cho LCD

void write(int8 value, int8 add)
{
i2c_start();
i2c_write(0xD0);
i2c_write(add);
i2c_write(value);
i2c_stop();
delay_us(3);
}

int8 read(int8 add)
{
int8 value_re;
i2c_start();
i2c_write(0xD0);
i2c_write(add);
i2c_start();
i2c_write(0xD1);
value_re = i2c_read();
i2c_stop();
delay_us(3);
return(value_re);
}
void khoitao(){
i2c_start();
i2c_write(0xD0); //den dia chi

ds1307.
i2c_write(0x00); //den dia chi

thanh ghi 00H.
i2c_write(0x00); //s
i2c_write(0x00); //m
i2c_write(0x52); //h
i2c_write(0x02); //day
i2c_write(0x03); //date
i2c_write(0x04); //mth
i2c_write(0x05); //y
i2c_write(0x10); //tao xung vuong

1Hz.
i2c_stop();
delay_us(3);
}

int h,m,s,day,date,month,year,con;

void main()
{
int value;
set_tris_b(0x00);

write(0x90,0x07);// o day tao xung 1hz
delay_ms(2000); //
write(0x00,0x07);// ket thuc qua trinh tao xung. nhung mo phong thi no khong the tat chan SWQ duoc?????
}
-----------------------------------------------------------------------------
o tren, minh chi ghi duoc giu lieu duoc 1 lan, sau cau lenh i2c_stop() thi minh khong the dung cac ham write() va read() duoc, co' phai do chuong trinh dich bi loi hay sao? minh dung CCS 4.057.

inventor_bk
28-09-2009, 11:48 PM
Nhờ các anh chị giúp em này chút: Em định làm giao tiếp I2C giữa 2 Pic 18F4331, em tìm hiểu kĩ phần này, nhưng em vẫn thắc mắc 1 điều là địa chỉ slave, lấy từ đâu. Theo em biết địa chỉ slave là từ datasheet, mà em đọc mà chẳng biết con 18f4331 có địa chỉ bao nhiêu. Mà hầu hết các Pic em đều thấy lấy địa chỉ là 0x10. Vậy em có dùng lại địa chỉ này không. Cảm ơn các anh chị nhiều.

inventor_bk
28-09-2009, 11:59 PM
Trang này bị khóa rồi mà em không biết, xin lỗi

thanhctdt07
29-09-2009, 12:29 AM
Mình cần một người giúp mình viết và giải thích dùm một chương trình quét led ma trận và có thêm phần hiển thị lên led ma trận từ bàn phím có (6x6) 36 nút nhấn các ký tự ABC
Vd: ta nhập tên “thanh” thì chử sẽ được hiển thị lên led ma trận 8led ma trận 8x8 và nhấn thêm một phím nữa dể chử vừa nhập “thanh” chay theo lập trình ./.
Giá cả không thành vấn đề có thể thương lượng sau,ai giúp được thì liên lạc số đt :0937567594 gặp Đạt hoặc 01226688701 gặp Phương Duy
Cần gấp !!!!!!!!!!minh` ở TP HCM bạn nào ở HCM thì càng tốt

bebungbu
30-09-2009, 01:30 AM
Hi mọi người,

Các bạn có thể sử dụng IC 74LVXC4245 để chuyển đổi mức điện áp 3.3-5V. IC này cũng cho phép xác định chiều vào/ra của tín hiệu. IC này sẽ được cấp 2 nguồn áp tham chiếu là 5V và 3.3V. Chú ý: theo sơ đồ dưới đây, ta cần phải có thêm 2 tín hiệu để điều khiển chiều ra/vào của tín hiệu ở các ngõ A và B.

Cho mình hỏi IC để chuyển điện áp này có thể mua ở đâu vậy ?

nhuhuan86
30-09-2009, 12:25 PM
em mới vào tìm hiểu vì i2c có chỗ này ko hiểu lắm mong các bác giúp đỡ:vấn đề là em giao tiếp 2 con chip 16f877a.Con master gui yêu cầu xuống slave đọc adc.con slave khi đọc dữ liệu, rồi gửi dữ liệu adc đó qua i2c tới con Master.vậy em phải làm thế nào?mong các bác cho ý cao kiến.Thanks

nhamdtk4
30-09-2009, 07:51 PM
Theo em biết địa chỉ slave là từ datasheet
Điều này đúng với các linh kiện mà bạn ko thể lập trình cho nó (chỉ ghi đọc dữ liệu) còn VĐK thì khác bạn có thể gán cho nó một địa chỉ bất kỳ mà modul I2C có thể hỗ trợ.

inventor_bk
01-10-2009, 04:51 PM
Cảm ơn bạn nhé.

TRTien
16-10-2009, 09:41 PM
Chào các bạn!!
Cho mình post sơ đồ và code của minh lên đây cho các bạn coi và có gì góp ý cho mình nha.

Đây là đoạn code Master: Master truyền một mảng cho Slave và nhận về mảng mà đã chuyển cho Slave để hiển thị lên port_b(kiểm tra hihi...) giống echo.


#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use Delay(Clock=4000000)

#use i2c(master, sda=PIN_C4, scl=PIN_C3, force_hw)

void write_I2C(int8 value, int8 slave_addr)
{
i2c_start();
i2c_write(slave_addr);
i2c_write(value);
i2c_stop();
}

int8 read_I2C(int8 slave_addr)
{
int8 value_re;
i2c_start();
i2c_write(slave_addr + 1);
value_re = i2c_read(0);
i2c_stop();
return value_re;
}

void main()
{
int8 value_re;
int8 i;
const int8 N = 8;
const int8 DIGITS[N] ={ 0b11111111,
0b11111110,
0b11111100,
0b11111000,
0b11110000,
0b11100000,
0b11000000,
0b10000000,
};
const int8 slave_addr = 0x10;

set_tris_b(0x00);
while(1){
for(i = 0; i<8; i++){
write_I2C(DIGITS[i], slave_addr);
delay_ms(500);
value_re = read_I2C(slave_addr);
output_b(value_re);
}
}
}


Còn đây là đoạn code Slave:


#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#use delay(Clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10, force_hw)

int8 value = 0x01;

#INT_SSP
void i2c_isr()
{
int8 state;

state = i2c_isr_state();
if(state < 0x80)
value = i2c_read();
if(state == 0x80){
i2c_write(value);
}
}

void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);

set_tris_b(0x00);
while(1){
output_b(value);
}
}


Cho mình hỏi với, sao mình mô phỏng trên proteus theo chương trình này thì không chạy gì cả vậy?
Có ai mô phỏng rồi thì bảo mình với, mới học PIC + I2C nên mình chưa biết gì cả.

thevinhbk3i
17-10-2009, 07:32 PM
các bác ! em đang làm đồ án môn học thcn về giao thức can ! các bác có biết thì chỉ bảo giùm em với

suphuhocdoi89
17-10-2009, 07:56 PM
anh pic bang chủ ơi!
anh add dùm nickname của em vào box 09.em đăng nhập vào diễn đàn nhưng ko thấy hộp box 09.anh kiểm tra lại giúp em với.
username :suphuhocdoi89

success.tl
28-10-2009, 08:08 AM
Mình có viết chương trình ngắt cho SLAVE như sau:
//////////////////////////////////////////////////////////
#INT_SSP
void i2c_isr()
{
state = i2c_isr_state();
if(state >=0x80)
i2c_write(mang_truyen[state-0x80]);
else if(state>0) mang_nhan[state-1]=i2c_read();
}
//////////////////////////////////////////////////////////
mang_truyen gán sẵn giá trị, mang-truyen và mang_nhan riêng biệt.
Trong chip MASTER, mình viết vòng lặp để ghi và đọc dữ liệu với SLAVE:
//////////////////////////
while (1)
{
write_I2C(1,2,3,4,5,6);
delay_ms(10);
read_I2C();
...
}
/////////////////////////
Nhưng dữ liệu nhận được từ SLAVE khi hiển thị ra LCD thì chỉ đúng trong lần read_I2C() đầu tiên. Còn khi vòng lặp while(1){...} lặp lại lần thứ 2, 3,... thì thu được dữ liệu là các số 255. không đúng theo yêu cầu.
Hiện tượng trên lặp lại khi mình Reset chip SLAVE.
Còn nếu Reset chip MASTER thì luôn thu được các số 255.
************************************************** ****************
Các bạn giúp mình với.
Cảm ơn nhiều.

success.tl
28-10-2009, 08:32 AM
À, mình sửa được rồi các bạn ạ!
Bên MASTER đọc liên tiếp 6 bytes, bên SLAVE mình chỉ khai báo mảng truyền 6 phần tử nên mới có hiện tượng này. Mình khai báo lại mảng truyền >6 phần tử thì lại hoạt động đúng.
Như vậy là vì sao nhỉ? Mình mới lập trình nên chưa hiểu lắm!

thanhluanbk
10-11-2009, 07:07 AM
Em đang chuẩn bị làm về kết nối hai vi điều khiển là 16F và dsPIC33FJMC202. Các bác cho em biết cần lưu ý điều gì, vì hai vi điều khiển nào thuộc 2 họ khác nhau, có xung nhịp khác nhau.

Cảm ơn các bác!

rikimaru87
11-11-2009, 12:09 AM
Mọi người cho em hỏi tí:
em thiết kế mạch gồm : 4 con eeprom 24c256 và 1 mạch ds1307 giao tiếp i2c. vậy em phải chọn address cho từng thiết bị như thế nào khi giao tiếp ạ :
cụ thể biến address trong hàm dưới này chọn ntn ạ
void write_ext_eeprom(long int address, BYTE data)
{
short int status;
i2c_start();
i2c_write(0xa0);
i2c_write(address>>8);
i2c_write(address);
i2c_write(data);
i2c_stop();
i2c_start();
status=i2c_write(0xa0);
while(status==1)
{
i2c_start();
status=i2c_write(0xa0);
}
i2c_stop();
}

rikimaru87
11-11-2009, 12:12 AM
chân A0 A1 của 4 con 24c256 nối lần lượt là 00 01 10 11.
ds1307 nối bình thường .

rikimaru87
11-11-2009, 07:42 AM
hi. chào mọi người . em giải quyết đc rùi . tại chưa đọc kĩ datasheet. :D

vinasheva
04-12-2009, 11:00 PM
Có ai có mẫu dùng I2C bằng phần mềm cho các loại PIC k có sẵn module I2C?

huskie
21-01-2010, 06:39 PM
Mình vừa mới vào topic đã thấy mọi người nói là làm I2C với CCS, vậy không biết CCS là gì và cài đặt như thế nào, mong các pro chỉ giúp! Thanks!

dt_cn
25-01-2010, 12:16 PM
Các bác ơi em làm đồ án về truyền thông I2C ,nhưng em không biết khoảng cách của nó truyền được bao xa ,và có hay bị nhiễu không ,nếu muốn truyến với khoảng cách xa thì có loại IC nào hỗ trợ không ,các bác giúp em với .
Thanks

namqn
25-01-2010, 12:52 PM
Các bác ơi em làm đồ án về truyền thông I2C ,nhưng em không biết khoảng cách của nó truyền được bao xa ,và có hay bị nhiễu không ,nếu muốn truyến với khoảng cách xa thì có loại IC nào hỗ trợ không ,các bác giúp em với .
Thanks
Tham khảo thông tin ở đây:
http://www.interfacebus.com/I2C_Interface_Bus_Standard.html
http://namqn.byethost7.com/Commu.php#i2c
http://www.esacademy.com/en/library/technical-articles-and-documents/miscellaneous/i2c-bus/frequently-asked-questions/i2c-faq.html

Không có con số cụ thể cho khoảng cách truyền tối đa, vì nó phụ thuộc vào tốc độ clock, loại cáp được dùng, và số vi mạch trên bus. Chú ý là có thể dùng các bộ lặp tín hiệu để nâng khoảng cách.

Thân,

dt_cn
25-01-2010, 02:45 PM
Vâng ạ em cảm ơn anh .
Đề tài của em làm là nhà thông minh ý định của em là định sử dụng 10-15con PIC6F88 slave đặt ở các khu vực hiện trường(như cầu thang,cửa,nhà bếp....)và 1 con master 16F877A mater thu thập dữ liệu từ các slave và kết nối với PC,tốc độ xung clock của em là 500khz,cáp xoắn đôi thì những ý tưởng của em đó liệu trong thực tế có ổn không anh?
Mong các bá giúp đỡ thanks các bác nhiều.

dt_cn
25-01-2010, 02:52 PM
Em tìm hiểu trên mạng thì được biết có con IC 82B715 để nâng cao khoảng cách truyền thông I2C ,nhưng em ko biết con này có mặt trên thị trường không nhỉ?em tìm mua mà không thấy có ,bác nào biết chỉ giùm em với.
thanks

dt_cn
26-01-2010, 11:44 AM
Vâng ạ em cảm ơn anh .
Đề tài của em làm là nhà thông minh ý định của em là định sử dụng 10-15con PIC6F88 slave đặt ở các khu vực hiện trường(như cầu thang,cửa,nhà bếp....)và 1 con master 16F877A mater thu thập dữ liệu từ các slave và kết nối với PC,tốc độ xung clock của em là 500khz,cáp xoắn đôi thì những ý tưởng của em đó liệu trong thực tế có ổn không anh?
Mong các bá giúp đỡ thanks các bác nhiều.
Không có bác nào giúp em à !huhu

TRTien
26-02-2010, 10:17 PM
Em tìm hiểu trên mạng thì được biết có con IC 82B715 để nâng cao khoảng cách truyền thông I2C ,nhưng em ko biết con này có mặt trên thị trường không nhỉ?em tìm mua mà không thấy có ,bác nào biết chỉ giùm em với.
thanks

:D, con này 85k.
Mình đã dùng con này, truyền được 15m ngon.

hangocminh1989
08-04-2010, 06:58 PM
không có hình các bạn ơi????????????mình không hiểu

keluhanh
15-04-2010, 03:23 PM
bác nào có chương trình giao tiếp i2c với con TC74 và 16F877A ko,cho mình xin với

manhdungmta
15-08-2010, 06:03 AM
khi giao tiếp i2c giữa hai pic 16f877a có bác nào gặp trường hợp M truyền không đúng địa chỉ nhưng S vẫn nhận khí thế không? cái này em chưa làm mạch thật, mới mô phỏng và thấy vậy.

manhdungmta
21-08-2010, 12:56 PM
hì, giờ mới làm mạch thật giao tiếp I2C giữa 1 con master ( 16f877a ) và 2 con sleve ( 16f877a ) thấy nó đều hoạt động đúng, chứ không như mô phỏng. ngày trước thì chỉ là làm giao tiếp với ds1307 thôi, mãi đến hôm nay có người nhờ mới làm tới giao tiếp giữa các pic với nhau. non quá, mong các bác giúp đỡ nhiều nhé.

manhdungmta
21-08-2010, 01:00 PM
à, tới em định học về ARM có bác nào rỗi rãi chỉ giúp em nhé

manhdungmta
09-10-2010, 10:07 PM
bác namquan cho em hỏi, vì sao khi em nạp luôn ct example về ethenet của 16f877a có sẵn trong mikroc lại không chạy gì cả, nhưng vẫn cái mạch ấy em nạp ct của con 18f4580 vẫn chạy ạ, đó là vì sao hả bác?

chungcb86
11-10-2010, 04:39 PM
Các bác giúp e vụ i2c này với. code lấy của bác Hoàn. mô phỏng thì chạy cứ ầm ầm. nhưng vô mạch thật thì ... híc híc e nó nằm im.
Đây là code của Master

#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use Delay(Clock=4000000)

#use i2c(master, sda=PIN_C4, scl=PIN_C3, force_hw)

void write_I2C(int8 value, int8 slave_addr)
{
i2c_start();
i2c_write(slave_addr);
i2c_write(value);
i2c_stop();
}

int8 read_I2C(int8 slave_addr)
{
int8 value_re;
i2c_start();
i2c_write(slave_addr + 1);
value_re = i2c_read(0);
i2c_stop();
return value_re;
}

void main()
{
int8 value_re;
int8 i;
const int8 N = 8;
const int8 DIGITS[N] ={ 0b11111111,
0b11111110,
0b11111100,
0b11111000,
0b11110000,
0b11100000,
0b11000000,
0b10000000,
};
const int8 slave_addr = 0x10;

set_tris_b(0x00);
while(1){
for(i = 0; i<8; i++){
write_I2C(DIGITS[i], slave_addr);
delay_ms(500);
value_re = read_I2C(slave_addr);
output_b(value_re);
}
}
}



Còn đây là code của Slave:

#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#use delay(Clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10, force_hw)

int8 value = 0x01;

#INT_SSP
void i2c_isr()
{
int8 state;

state = i2c_isr_state();
if(state < 0x80)
value = i2c_read();
if(state == 0x80){
i2c_write(value);
}
}

void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);

set_tris_d(0x00);
while(1){
output_d(value);
}
}

chungcb86
12-10-2010, 09:51 AM
Bác nào sử bít code bị mắc ở đâu sửa giúp mình với.

chungcb86
13-10-2010, 10:59 AM
ok mach đã chạy. nguyên nhân : đứt mạch nên 1 chân không được nối với trở thanh

liemcena
25-10-2010, 10:02 AM
giúp em i2c với em mới học về pic và i2c : dipswitch truyền dữ liệu cho master , master truyền cho slave ,slave hiển thị lên led(giống việc điều khiển đèn bằng dipswitch qua chuẩn i2c)
code Master:
#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use Delay(Clock=4000000)
#byte portb=0x06
#define SLAVE_ADDRESS 0x10
#use i2c(master, sda=PIN_C4, scl=PIN_C3)
#use Fast_IO(b)
void write_I2C(int8 data)
{
i2c_start();
i2c_write(SLAVE_ADDRESS);
i2c_write(data);
i2c_stop();
}
void main()
{
int8 data;
set_tris_b(255);
data=input_b();
while(1)
{
write_I2C(data);
delay_ms(100);
}
}
code slave:

#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(Clock=4000000)
#use i2c(SLAVE,SDA=PIN_C4,SCL=PIN_C3)
#define SLAVE_ADDRESS 0x10
#use Fast_IO(b)

void read_I2C()
{
int8 data;
i2c_start();
i2c_read(SLAVE_ADDRESS);
data=i2c_read();
delay_ms(100);
i2c_stop();
}


void main()
{
int8 data;
set_tris_b(0x00);

while(1)
{
read_I2C();
output_b(data);
}
}
không biết sai ở đâu nữa mô phỏng bằng proteus không chạy gì cả

dark_dragon6789
19-11-2010, 09:47 PM
em dùng code của bác Hoan cho vô protues thì không thấy chạy gì cả, không hiểu sai chỗ nào luôn

winphys03
09-12-2010, 04:03 PM
Các bác giúp gửi giá trị của thang ghi POSCNTH, POSCNTL từ slave lên master với

Code Master:

#include <18f4431.h>
#include <stdlib.h>
#include <math.h>
#include <def_4431.c>
#FUSES NOWDT, HS, NOPUT, NOPROTECT
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bi ts=8)
#use I2C(MASTER,SDA=PIN_D2,SCL=PIN_D3)
#define slave 0x10
///////////////////////////////////////////////////////////////
///////////////////////Khai bao bien PID//////////////////////
int16 read;
int8 v=0,high,low;
int16 PWM;
int16 feedback_value = 0,real_v;
/////////////////////////////////////////////////////////////
/////////////////////////Nhan du lieu tu may tinh////////////
#INT_RDA
void getvalue()
{
int i;
char s[3];
for(i=0;i<3;i++)
s[i]=getc();
v=atol(s);
}
////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////
int16 read_I2C_2byte(int8 slave_address)
{
int16 value_read;
i2c_start();
i2c_write(slave_address+1);
high=i2c_read(1);
delay_us(10);
low=i2c_read(0);
i2c_stop();
value_read=make16(high,low);
value_read=value_read/5.2;
printf(" %Ld\n\r",value_read);
return value_read;
}
//////////////////////Setup QEI/////////////////////////////////
void setup_QEI()
{
QEICON = QEI_4XPER | VELOCITY_DIV_4;
QEICON = 0b11011011;
MAXCNT = 800;
POSCNT = 0;
POSCNTH = 0; // High byte of 16-bit encoder count
POSCNTL = 0; // low byte
CAP1CON = 0b010011000;
DFLTCON = 0b01110010;
setup_timer_5 (T5_INTERNAL | T5_DIV_BY_4);
}
//////////////////////////////////////////////////////////
//////////////////Read Encoder///////////////////////////
#INT_TIMER1
void read_encoder()
{
set_timer1(32875);
read = POSCNT;
POSCNT=0;
real_v = read/5.2;
read=0;
}
/////////////////////////////////////////////////////////
////////////////////PID Control/////////////////////////
void pidcontrol()
{
unsigned char kp = 2;
unsigned char ki = 0.000003;
unsigned char kd = 0.005;
int16 set_value = 0;
int16 delta_t=0.0065;
signed long error_value = 0;
static signed long pre_error = 0;
static signed long integral = 0;
signed long derivative = 0;
feedback_value = real_v;
set_value = v;
error_value = set_value -feedback_value;
integral = integral + error_value;
derivative = (error_value - pre_error)/delta_t;
PWM = PWM+ (kp * error_value) + (ki * integral) + (kd * derivative);
if (PWM > 1020)
{ PWM = 1020; }
else if (PWM < -1020)
{PWM = -1020;}
pre_error = error_value;
}

///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////

void main()
{
int16 value_read;
delay_ms(500);
setup_QEI();
enable_interrupts(INT_RDA);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
setup_timer_2(T2_DIV_BY_1,255,1);
setup_ccp2(CCP_PWM);
set_pwm2_duty(0);
set_timer1(32875);
while(true)
{
pidcontrol();
set_pwm2_duty(PWM);
value_read=read_I2C_2byte(slave);
}
}

Code Slave
#include <18f4431.h>
#include <stdlib.h>
#include <math.h>
#include <def_4431.c>
#FUSES NOWDT, HS, NOPUT, NOPROTECT
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bi ts=8)
#use I2C(SLAVE,SDA=PIN_D2,SCL=PIN_D3,address=0x10,fast= 500000,force_hw)
///////////////////////////////////////////////////////////////
///////////////////////Khai bao bien PID//////////////////////
int8 value_read;
int16 read;
int16 PWM;
int16 feedback_value = 0,real_v;
///////////////////////////////////////////////////////////

//////////////////////Setup QEI/////////////////////////////////
void setup_QEI()
{
QEICON = QEI_4XPER | VELOCITY_DIV_4;
QEICON = 0b11011011;
MAXCNT = 800;
POSCNT = 0;
POSCNTH = 0; // High byte of 16-bit encoder count
POSCNTL = 0; // low byte
CAP1CON = 0b010011000;
DFLTCON = 0b01110010;
setup_timer_5 (T5_INTERNAL | T5_DIV_BY_4);
}
//////////////////////////////////////////////////////////
//////////////////Read Encoder///////////////////////////
#INT_TIMER1
void read_encoder()
{
set_timer1(32875);
read = POSCNT;
POSCNT=0;
real_v = read/5.2;
read=0;
}
/////////////////////////////////////////////////////////
////////////////////Send to Master/////////////////////////
#INT_SSP
void i2c_isr()
{
int8 state;
state = i2c_isr_state();

if(state<0x80)
value_read = i2c_read();


if(state>=0x80)
{
if (state==0x80)
i2c_write(POSCNTH);
if (state==0x81)
i2c_write(POSCNTL);

}
}

////////////////////////////////////////////////////////////////
////////////////////PID Control/////////////////////////
void pidcontrol()
{
unsigned char kp = 2;
unsigned char ki = 0.000003;
unsigned char kd = 0.005;
int16 set_value = 0;
int16 delta_t=0.0065;
signed long error_value = 0;
static signed long pre_error = 0;
static signed long integral = 0;
signed long derivative = 0;
feedback_value = real_v;
set_value = 20;
error_value = set_value -feedback_value;
integral = integral + error_value;
derivative = (error_value - pre_error)/delta_t;
PWM = PWM+ (kp * error_value) + (ki * integral) + (kd * derivative);
if (PWM > 1020)
{ PWM = 1020; }
else if (PWM < -1020)
{PWM = -1020;}
pre_error = error_value;
}

///////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////

void main()
{

setup_QEI();
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);
setup_timer_2(T2_DIV_BY_1,255,1);
setup_ccp2(CCP_PWM);
set_pwm2_duty(0);
set_timer1(32875);
while(true)
{
pidcontrol();
set_pwm2_duty(PWM);
delay_ms(100);
}
}

anhkhoa4589
05-01-2011, 10:17 AM
Cho mình hỏi mọi người 1 tí, phần địa chỉ của Slave mình khai báo theo qui tắc nào vậy, như trong code của bạn Hoanf là address=0x10, làm sao để có con số 0x10.

Mong được mọi người giúp đỡ

TheHouse
12-01-2011, 11:53 PM
Cho mình hỏi, nếu giao tiếp với EEPROM 24Cxx thì mình làm sao biết địa chỉ của slave eeprom của mình. Nếu cố định (A0, A1, A2) thì làm sao đọc dữ liệu ở các ngăn địa chỉ còn lại được.

Địa chỉ của slave có phải là địa chỉ của A0, A1, A2 không, nếu đúng vậy thì làm sao mình đọc được dữ liệu từ được địa chỉ 0x01 (khi A2.A1.A0 = 001). Vì có bạn nói là gửi địa chỉ 0x01 thì làm slave hiểu nhầm là đọc i2c từ slave lên.

nttrungut
13-01-2011, 11:12 PM
Địa chỉ của slave có phải là địa chỉ của A0, A1, A2 không, nếu đúng vậy thì làm sao mình đọc được dữ liệu từ được địa chỉ 0x01 (khi A2.A1.A0 = 001). Vì có bạn nói là gửi địa chỉ 0x01 thì làm slave hiểu nhầm là đọc i2c từ slave lên.
A0,A1,A2 là do mình cố định. Địa chỉ của Slave có 7 bit. Khi giao tiếp I2C thì Device Address có 8 bit gồm 7 bit địa chỉ AT24 và 1 bit LSB R/W. Bạn tham khảo datasheet để biết thêm chi tiết về 1 khung dữ liệu trong I2C nhé

quangvanvo
17-02-2011, 11:02 AM
-các anh chị ơi làm ơn cho em mail của các anh chị được không vây?
-em viết chương trình về i2c, pwm mà sao em text trên protues hoài ma nó không chịu chạy??
-thật sự em không biết lý do tai sao luôn áh!!! em đọc trên wed em về làm giống y ma nó cũng không chiu chay.
-cho em mail để em giử chương trình cùng với protues để các anh chị kiểm tra giùm em với!!!!!!!! pleasea!!!!!!
<<phieudu_cunggio951@yahoo.com.vn>> thanks

quangvanvo
17-02-2011, 11:18 AM
các anh chị làm ơn gianh chút thời gian giúp em với !!!!!!!!!! làm ơn!!!!!!!!

stupid11
04-03-2011, 10:35 PM
tài liệu này rất chi tiết..các bạn dơn về tham khảo..nếu thấy hay thì "thanks" dùm mình cái nghen...

nguyen_de89
04-03-2011, 10:40 PM
Cam on stupid tai lieu rat hay va chi tiet ;))

quangvanvo
14-03-2011, 05:21 PM
mình hỏi tài liệu trên picvietnam ma không ai thèm tra lời chắc là do mình không có file đẩy đủ cho anh em, mình viết trong 2 tuần nay thấy nó chay cũng tạm được ma sao mình thẩy chương trinh của mình không giống với các anh chị viết . giờ em giửi chương trình cùng với protues em mới viết anh chị xem giùm có thiếu sót gì không.
nhưng em thấy nó chạy rất ngon lanh, hjhjhj

quangvanvo
22-03-2011, 12:09 PM
nếu có ai có mạch thực tế thì text giùm coi nó có chạy thực tế ở ngoài có vấn đề gì không.
mình chỉ text trên protues thì thấy nó chạy tốt. mình chưa có mạch thực để text mong các bạn đóng gốp ý kiến về chương trình của mình cho mình biết với nha!!! thanks

phamdactoan
12-05-2011, 03:32 PM
các bác cho e hỏi câu này với.hiện e đang viết chương trình giao tiếp bus i2c phần slaver.em viết bang verilog tren FPGA.em đã xây dựng xong các khối slaver.jo e mún kiểm tra xem khối của e có đúng không nên e mún dùng 1 con pic 887 làm master để truyền wa con slave.mà jo em dang thắc mắc không bít viết code cho con pic bang ccs ra sao?bác nào gơi ý jup e voi
Nhập data từ keyboard--->I2C master(tuc con pic)--->I2C slave(tren FPGA)-->>hiện lên LCD

minhkhoa1990
10-06-2011, 05:23 AM
//
int16 read_I2C_2byte(int8 slave_address)
{
int16 value_read;
i2c_start();
i2c_write(slave_address+1);?????????
high=i2c_read(1);
delay_us(10);
low=i2c_read(0);
i2c_stop();
value_read=make16(high,low);
value_read=value_read/5.2;
printf(" %Ld\n\r",value_read);
return value_read;
}
///////////
các bác cho em hỏi hàm i2c_write(slave_address+1) có ý nghĩa như thế nào và địa chỉ:slave_address+1 là sao.......... thanks các bác nhiều

minhkhoa1990
11-06-2011, 09:02 AM
ko có bác nào giúp em ah. hix

truongvanquan
12-06-2011, 06:32 PM
//
int16 read_I2C_2byte(int8 slave_address)
{
int16 value_read;
i2c_start();
i2c_write(slave_address+1);?????????
high=i2c_read(1);
delay_us(10);
low=i2c_read(0);
i2c_stop();
value_read=make16(high,low);
value_read=value_read/5.2;
printf(" %Ld\n\r",value_read);
return value_read;
}
///////////
các bác cho em hỏi hàm i2c_write(slave_address+1) có ý nghĩa như thế nào và địa chỉ:slave_address+1 là sao.......... thanks các bác nhiều


Theo em nghĩ thì đây là một chương trình con.

ở trên bác dùng một biến: int16 read_I2C_2byte(int8 slave_address)
nên ở dưới nó sẽ dùng biến này!

VD như bác điều khiển DS1307 thì địa chỉ của nó là 0b1101000x. (0xD..)
như vậy i2c_write(slave_address+1) sẽ là i2c_write(0xD1) ->> đọc thông tin từ DS1307

thân,

moonlight_mta
17-07-2011, 11:24 AM
Mình mới học về giao tiếp I2C,mình viết code cho PIC6F877A và DS1307 hiển thị LCD.Mình không sử dụng các hàm có sẵn của CCS.Khi chạy thì nó không thoát ra được khỏi vòng lặp wait_ngắt,tức chờ cho cờ ngắt SSPIF = 1.Code của nó như sau,các bạn giúp mình nhé
#include<16f877a.h>
#include<def_877.c>
#include<LCD_mod.h>
#use delay(clock = 20000000)
void wait_ngat(void);
unsigned char DECBCD2(unsigned char);
void main()
{
unsigned char s,p,h,d,m,y;
TRISB = 0x00;
TRISD = 0x00;
wrcmd(0x38);
wrcmd(0x01);
wrcmd(0x0e);

SSPCON = 0x38; //ko truyen du lieu vao sspbuf khi che do truyen du lieu chua san sang
//ko du lieu dc nhan vao sspbuf khi du lieu cu chua dc doc
// cho phep cong giao tiep mssp
// che do I2C master mode,cl SCL= Fosc/(4*(SSPADD+1)
SSPADD = 0;
INTCON7 = 1; //cho phep tat ca ngat
INTCON6 = 1; //cho phep ngat ngoai vi

PIE13 = 1; // cho phep ngat ssp

// bat dau wa trinh truyen nhan du lieu
TRISC3 = 0; // cac pin sda va scl
TRISC4 = 0;
PORTC3 = 1;
PORTC4 = 1;
SSPCON20 = 1; // sspcon2<0> = 1 thiet lap start
wait_ngat();
SSPBUF = 11010000; // address and write
PIR13 = 0;

wait_ngat();
SSPBUF = 0;
PIR13 = 0;

wait_ngat();
SSPBUF = 0;
PIR13 = 0;

wait_ngat();
SSPBUF = 0;
PIR13 = 0;

wait_ngat();
SSPBUF = 0;
PIR13 = 0;

wait_ngat();
SSPBUF = 0x01;
PIR13 = 0;

wait_ngat();
SSPBUF = 0x01;
PIR13 = 0;

wait_ngat();
SSPBUF = 0x01;
PIR13 = 0;

wait_ngat();
SSPBUF = 0x11;
PIR13 = 0;

SSPCON22 = 1;
wait_ngat();
PIR13 = 0;

//................................
SSPCON20 = 1;
wait_ngat();
SSPBUF = 11010000;
PIR13 = 0;

wait_ngat();
SSPBUF = 0;
PIR13 = 0;

wait_ngat();
SSPCON22 = 1;
PIR13 = 0;

wait_ngat();
PIR13 = 0;
//.....................................
TRISC3 = 1;
TRISC4 = 1;
SSPCON20 = 1;
wait_ngat();
SSPBUF = 11010001;
PIR13 = 0;

wait_ngat();
PIR13 = 0;

wait_ngat();
PIR13 = 0;
wait_ngat();
s = SSPBUF;
PIR13 = 0;

wait_ngat();
PIR13 = 0;
wait_ngat();
p = SSPBUF;
PIR13 = 0;

wait_ngat();
PIR13 = 0;
wait_ngat();
h = SSPBUF;
PIR13 = 0;

wait_ngat();
PIR13 = 0;
wait_ngat();
d = SSPBUF;
PIR13 = 0;

wait_ngat();
PIR13 = 0;
wait_ngat();
m = SSPBUF;
PIR13 = 0;

wait_ngat();
PIR13 = 0;
wait_ngat();
y = SSPBUF;
PIR13 = 0;

SSPCON22 = 1;
wait_ngat();
PIR13 = 0;

//...........................
DECBCD2(s);
DECBCD2(p);
DECBCD2(h);
DECBCD2(d);
DECBCD2(m);
DECBCD2(y);
wrdata(s);
wrdata(p);
wrdata(h);
wrdata(d);
wrdata(m);
wrdata(y);
}
//........................
void wait_ngat(void)
{
while(PIR13 == 0);
}
//........................
unsigned char DECBCD2(unsigned char BCD)
{
unsigned char L,H;
L = BCD & 0x0f;
H = (BCD>>4) *10;
return(L+H);
}

tan_truong
15-11-2011, 07:15 PM
Đụng lại vấn đề cũ của mấy huynh
Em mô phỏng chuẩn I2C giữa 2 con 18f4431, tình hình là nó chạy rất tào lao( tại người làm chuối quá)
Em gửi kèm file mô phỏng, mấy anh xem hộ cho thèn em với
Cảm ơn mọi người

tan_truong
16-11-2011, 02:36 PM
Chào tất cả mọi nguời, sau 1 khi tìm hiểu về I2C để giải quyết vấn đề mình có đặt ra bên trên thì tạm thời mình mô phỏng được việc truyền nhận dữ liệu 2 chiều Master<==>Slave
Mọi nguời có hứng thì tham khảo và góp ý nhé
P/S: 1) Cảm ơn anh Hoanf và tất cả mọi nguời đã đóng góp xây dựng thread này
2) Vấn đề mình thắc mắc ở trên thì vẫn chưa giải quyết ^^, tiếp tục help me nhé :)

chuvanhuu
27-11-2011, 11:19 PM
các bác ơi, cho em hỏi chút, có phải I2C là nhất thiết phải dùng ngắt ko ạ?
ko biết là có bác nào từng nghiên cứu vấn đề này chưa, nhưng mình thấy là dùng lệnh while đi kèm lệnh điều kiện thì chức năng cũng có thể gần giống ngắt, ví dụ như chương trình này, (mình làm ko thành công, nên thuật giải cũng ko chắc chắn đúng)
<code>//chuong trinh cho slave
#include <16f877a.h>
#include <def_877a.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock= 4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10)
int8 data, state;
#define slave 0x10
void main()
{
data=0;
trisd=0;
while(1)
{
state= i2c_isr_state();
switch (state)
{
case 0x80:
{
data++;
if( data==255 )
{
data= 0;
}
i2c_write(data);
break;
}
case 0x81: i2c_write(slave);
break;
}
portd= data;
}
}</code>

tan_truong
28-11-2011, 10:50 AM
Chào bạn,
Thứ 1, bạn viết chương trình cho Slave mà sao hok có hàm nhận mà chỉ có hàm truyền ko vậy?
Thứ 2, nếu bạn dùng ccs thì vào phần help để xem lại lệnh state=i2c_isr_state(); bạn xem thử giá trị state bằng bao nhiêu thì gửi, bao nhiêu thì nhận.
Thứ 3, nếu con vđk của bạn còn làm việc khác nữa thì nên xem lặp cách dùng vòng lặp thế này.
Chúc bạn thành công.

chuvanhuu
30-11-2011, 12:38 AM
cảm ơn bạn, đây là code con master, cái này thực ra ko phải mình viết
<code>
// chuong trinh cho master
#include <16f877a.h>
#include <def_877a.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock= 4000000)
#use i2c(master, SDA=PIN_C4, SCL=PIN_C3)
int8 data, bo, i;
#define slave 0x10
void doc_i2c()
{
i= 0;
while( i!=2)
{
i++;
i2c_start();
i2c_write( slave+1); //nhan du lieu tu Slave
switch ( i)
{
case 1: data= i2c_read( 1);
break;
case 2: bo= i2c_read( 0);
break;
}
}
}
void main()
{
trisd= 0;
portd= 0;
while(true)
{
doc_i2c();
portd= data;
delay_ms( 100);
}
}
</code>
===============================================

còn đây là code cho Slave nguyên mẫu, code slave bên trên do mình chỉnh sửa từ đây
<code>
// chuong trinh cho master
#include <16f877a.h>
#include <def_877a.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock= 4000000)
#use i2c(master, SDA=PIN_C4, SCL=PIN_C3)
int8 data, bo, i;
#define slave 0x10
void doc_i2c()
{
i= 0;
while( i!=2)
{
i++;
i2c_start();
i2c_write( slave+1); //nhan du lieu tu Slave
switch ( i)
{
case 1: data= i2c_read( 1);
break;
case 2: bo= i2c_read( 0);
break;
}
}
}
void main()
{
trisd= 0;
portd= 0;
while(true)
{
doc_i2c();
portd= data;
delay_ms( 100);
}
}

</code>

slove
11-12-2011, 12:24 AM
Có bạn nào truyền giữa 1 master với nhiều slave chưa? Không hiểu sao không đúng địa chỉ mà của mình mà slave vần nhảy vào ngắt nhận và đọc giá trị từ buffer về.
Mình truyền cho 5 con slave thì cả 5 lần cả 5 con đều nhảy vào ngắt nhận. Không hiểu tại sao nữa.

vangtranglanh
05-04-2012, 11:22 AM
Em mới chập chững học i2c nên còn nhiều thắc mắc và nhiều chỗ không hiểu ,anh chị cho em hỏi giả sử bên slave của em có một biến đếm n,cứ sau 1 giây thì n++;bây h em mún gởi giá trị của n qua máter thì code ở mater và slave sẽ được viết như thế nào ạ?
Mong anh chị giúp dỡ ,xin cảm ơn!

truong298
12-04-2012, 01:16 AM
các anh ơi. e mới học pic. giờ đang phải làm giao tiếp giữa pic và eeprom(truyền dữ liệu cho eeprom) và giao tiếp với ds1307. e kô biết phải làm sao. mong các anh giúp đỡ

neunhu50
18-05-2012, 12:16 PM
có bạn nào làm 1 pic master điều khiển 3 pic slave để điều khiển 12 động cơ step chưa (1pic 4 stepmotor), chia sẽ mình với.

quyen bk
20-05-2012, 11:17 AM
Help!
Các anh(chị) ơi help me em với!
Em có nhận bài tập của ông thầy với nội dung đề ra:
Viết chương trình nhập từ bàn phím 4x4 với các số tùy ý từ 0-9, rồi hiển thị các số vừa nhập đó ra lcd, nhưng các số vừa nhập đó sẽ được lưu vào eeprom ngoài (dùng eeprom 24c64) và khi ta nhập lại số lúc đầu nếu nhập đúng thì xuât ra lcd với dòng chữ là ‘ok’, còn nhập sai thì là là dòng chữ “sai” ví dụ:
Lần 1: lúc đầu ta nhập “1234” nhấn nút ok( nút ok cụ thể là nút dấu = trong mô phỏng)
Lần 2: + Nếu ta nhập lại “1234” thì xuất ra lcd ở dòng 1 là “1234” và ở dòng 2 là chữ “ok”

+ nếu ta nhập “2356.v.v.” thì xuất ra lcd ở dòng 1 là “2356.v.v.” và ở dòng 2 là chữ “sai”
Về phần cứng em nghĩ ra và vẽ như thế đã đúng chưa anh( chị)?
Vậy xin các anh (chị) có làm qua hay gặp vấn đề tương tự thì giúp em, em đang tìm hiểu về ccs nếu có code C thì quá tốt rồi!
Em thank trước nha!!!!!!!!!!!!

quyen bk
20-05-2012, 11:19 AM
Help!
Các anh(chị) ơi help me em với!
Em có nhận bài tập của ông thầy với nội dung đề ra:
Viết chương trình nhập từ bàn phím 4x4 với các số tùy ý từ 0-9, rồi hiển thị các số vừa nhập đó ra lcd, nhưng các số vừa nhập đó sẽ được lưu vào eeprom ngoài (dùng eeprom 24c64) và khi ta nhập lại số lúc đầu nếu nhập đúng thì xuât ra lcd với dòng chữ là ‘ok’, còn nhập sai thì là là dòng chữ “sai” ví dụ:
Lần 1: lúc đầu ta nhập “1234” nhấn nút ok( nút ok cụ thể là nút dấu = trong mô phỏng)
Lần 2: + Nếu ta nhập lại “1234” thì xuất ra lcd ở dòng 1 là “1234” và ở dòng 2 là chữ “ok”

+ nếu ta nhập “2356.v.v.” thì xuất ra lcd ở dòng 1 là “2356.v.v.” và ở dòng 2 là chữ “sai”
Về phần cứng em nghĩ ra và vẽ như thế đã đúng chưa anh( chị)?
Vậy xin các anh (chị) có làm qua hay gặp vấn đề tương tự thì giúp em, em đang tìm hiểu về ccs nếu có code C thì quá tốt rồi!
Em thank trước nha!!!!!!!!!!!!
mail của em nề: vanquyen1690@gmail.com

quyen bk
20-05-2012, 11:21 AM
Help!
Các anh(chị) ơi help me em với!
Em có nhận bài tập của ông thầy với nội dung đề ra:
Viết chương trình nhập từ bàn phím 4x4 với các số tùy ý từ 0-9, rồi hiển thị các số vừa nhập đó ra lcd, nhưng các số vừa nhập đó sẽ được lưu vào eeprom ngoài (dùng eeprom 24c64) và khi ta nhập lại số lúc đầu nếu nhập đúng thì xuât ra lcd với dòng chữ là ‘ok’, còn nhập sai thì là là dòng chữ “sai” ví dụ:
Lần 1: lúc đầu ta nhập “1234” nhấn nút ok( nút ok cụ thể là nút dấu = trong mô phỏng)
Lần 2: + Nếu ta nhập lại “1234” thì xuất ra lcd ở dòng 1 là “1234” và ở dòng 2 là chữ “ok”

+ nếu ta nhập “2356.v.v.” thì xuất ra lcd ở dòng 1 là “2356.v.v.” và ở dòng 2 là chữ “sai”
Về phần cứng em nghĩ ra và vẽ như thế đã đúng chưa anh( chị)?
Vậy xin các anh (chị) có làm qua hay gặp vấn đề tương tự thì giúp em, em đang tìm hiểu về ccs nếu có code C thì quá tốt rồi!
Em thank trước nha!!!!!!!!!!!!
mail của em nề: vanquyen1690@gmail.com

khienpzo
27-07-2012, 01:43 AM
Em có một đề tài về I2C rất mong được sự chia sẻ của các anh chị đi trước ạ . EM có 2 PIC 16f877a giao tiếp I2C để điều khiển tốc độ or vị trí động cơ DC . PICA : Bàn phím nhập thông số tốc độ or vị trí (góc quay) . PICB : điều khiển động cơ DC và hiển thị thông số trên led 7 đoạn. Em mới bắt tay vào làm nên còn nhiều bỡ ngỡ mong các anh chị chỉ giáo . Em xin chân thành cảm ơn

nguyenthangcdt
05-10-2012, 03:08 AM
Theo Hà nghĩ, ở Master, khi mình đọc cũng phải chờ xung ACK từ Slave thì chtr ko bị rối.
Bạn thử thêm một chtr con chờ Bus trong <2401.c>:


//**************code thêm vào*********************
BOOLEAN ext_eeprom_ready()
{
int1 ack;
i2c_start();
ack = i2c_write(SLAVE_ADDRESS);
i2c_stop();
return !ack;
}
//**********************************************
int8 read_I2C()
{
int8 value;
while(!ext_eeprom_ready()); // code thêm vào
i2c_start();
i2c_write(SLAVE_ADDRESS + 1);
value = i2c_read();
i2c_stop();
return (value);
}

void main()
{
int8 value;

value = 0x00;
set_tris_b(0x00);

while(1){
value = read_I2C();
output_b(value);
delay_ms(500);
}
}

**********************************************
Thân mến !!

bạn ơi cho mình hỏi là tai sao trong hàm "read_i2c()" tai sao i2c_write(SLAVE_ADDRESS + 1) ! mình khboong hiểu chỗ " SLAVE_ADDRESS + 1 " BẠN LAMMFOWN GIẢI THÍCH HỘ MÌN ĐƯỢC KHÔNG ! VÀ NẾU BẠN CÓ CHƯƠNG TRÌNH NÀO MÀ VBIEECJ ĐỌC VÀ TRUYỀN DỮ LIỆU ĐỒNG THỜI THÌ CHO MÌNH XIN THAM KHẢO NHÉ ! MÌNH CẢM ƠN CẬU TRƯỚC NHÉ HJ !

nguyenthangcdt
06-10-2012, 08:44 AM
Chào các bạn!!
Cho mình post sơ đồ và code của minh lên đây cho các bạn coi và có gì góp ý cho mình nha.

Đây là đoạn code Master: Master truyền một mảng cho Slave và nhận về mảng mà đã chuyển cho Slave để hiển thị lên port_b(kiểm tra hihi...) giống echo.


#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use Delay(Clock=4000000)

#use i2c(master, sda=PIN_C4, scl=PIN_C3, force_hw)

void write_I2C(int8 value, int8 slave_addr)
{
i2c_start();
i2c_write(slave_addr);
i2c_write(value);
i2c_stop();
}

int8 read_I2C(int8 slave_addr)
{
int8 value_re;
i2c_start();
i2c_write(slave_addr + 1);
value_re = i2c_read(0);
i2c_stop();
return value_re;
}

void main()
{
int8 value_re;
int8 i;
const int8 N = 8;
const int8 DIGITS[N] ={ 0b11111111,
0b11111110,
0b11111100,
0b11111000,
0b11110000,
0b11100000,
0b11000000,
0b10000000,
};
const int8 slave_addr = 0x10;

set_tris_b(0x00);
while(1){
for(i = 0; i<8; i++){
write_I2C(DIGITS[i], slave_addr);
delay_ms(500);
value_re = read_I2C(slave_addr);
output_b(value_re);
}
}
}


Còn đây là đoạn code Slave:


#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#use delay(Clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10, force_hw)

int8 value = 0x01;

#INT_SSP
void i2c_isr()
{
int8 state;

state = i2c_isr_state();
if(state < 0x80)
value = i2c_read();
if(state == 0x80){
i2c_write(value);
}
}

void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);

set_tris_b(0x00);
while(1){
output_b(value);
}
}


minhf copy rooif paste vao nhuwng khoong chayj banj ah

khienpzo
27-11-2012, 10:45 AM
Có ai viết vòng lặp đọc dữ liệu 2 Slave về Master chạy ok rồi không ạ ? Cho mình tham khảo với

thegioimoiqb
14-12-2012, 10:39 AM
Mấy anh ơi, cho em hỏi: Chương trình của em tự viết không nói. em đưa y nguyên ct của đồng chí hoanf vào CCS 4.038 rùi mà PIN RC3 và RC4 cứ nhấp nháy hoài. master không nhận được dữ liệu từ slave. Mong các bác sớm chỉ rõ cho e. (nói thật vì cái đồ án, e mất ngủ cả đêm nay rùi mà vẫn chưa tìm ra lỗi tại sao. Có khi viết lại toàn bộ asm mà cũng chung một kết quả _ thi thoảng truyền được địa chỉ nhận về được ack nhưng đến lượt đọc thì im lim)
đây là code của master:
#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use Delay(Clock=4000000)

#define SLAVE_ADDRESS 0x10
#use i2c(master, sda=PIN_C4, scl=PIN_C3)
BOOLEAN ext_eeprom_ready()
{
int1 ack;
i2c_start();
ack = i2c_write(SLAVE_ADDRESS);
i2c_stop();
return !ack;
}
//**********************************************
int8 read_I2C()
{
int8 value;
while(!ext_eeprom_ready()); // code thêm vào
i2c_start();
i2c_write(SLAVE_ADDRESS + 1);
value = i2c_read();
i2c_stop();
return (value);
}

void main()
{
int8 value;

value = 0x00;
set_tris_b(0x00);

while(1){
value = read_I2C();
output_b(value);
//LCD_gotoxy(1,1);
//printf(LCD_putc,"gtri: %3u",value);
delay_ms(500);
}
}
đây là code của slave:
#include <16F877A.H>
#fuses XT,NOWDT,NOPROTECT,NOLVP

#use delay(Clock=4000000)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10)

int8 value = 0x01;

#INT_SSP
void i2c_isr()
{
int8 state;
int8 address;
state = i2c_isr_state();
if(state >= 0x80){
i2c_write(value);
//value;
}
}

void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);

set_tris_b(0x00);
while(1){
output_b(value);
}
}

NÓ không chạy, em bắt đầu tin vào ma quỷ rùi đây. Sao máy các anh chạy máy em lại không? hay tại trình biên dịch nhỉ.

hatuan296
14-12-2012, 11:38 AM
Bạn kiểm tra xem 2 con điện trở kéo lên của các chân SDA , SCL có bị lỏng không

thegioimoiqb
14-12-2012, 01:57 PM
Em đang mô phỏng bằng protues thôi anh ah. Có tin được thằng PROTUES k anh nhị.

hatuan296
15-12-2012, 04:23 AM
Em đang mô phỏng bằng protues thôi anh ah. Có tin được thằng PROTUES k anh nhị.

Mô phỏng về thời gian , timer ,vv... thì không chính xác lắm đâu . Tốt nhất là bạn dùng bread board để test

thegioimoiqb
15-12-2012, 12:43 PM
thanks u ! ko mô phỏng trên phần mềm dùng phần cứng thì hơi đau phần cứng do các lỗi. :(

khienpzo
15-12-2012, 03:06 PM
Mô phỏng chạy nhưng ra phần cứng chưa chắc chạy đâu bạn. Thân

copchaua
08-03-2013, 11:16 AM
đã viết code nhận và gửi 2 byte cho từ 1 master và 2 slave chạy good

copchaua
08-03-2013, 11:19 AM
Các bạn lưu ý khi dùng Pic 18F4431 và trình dịch CCS thì khi giao tiếp I2C mặc dù trên code viết cho cả master và slaver dùng chân C4 và C5 nhưng khi ráp mạch thực tế thì trên master chúng ta nối chân C4,C5 và slaver là D2 và D3 thì mới chạy được nhé. Cái này không biết lỗi gì chắc là do CCS

copchaua
08-03-2013, 11:26 AM
Code hoàn chỉnh đã test mạch thực tế giao tiếp giữa 1 master và 2 slaver, truyền và nhận 2 byte luôn, các bạn có thể tham khảo. Master sẽ gửi 1 số int16 (gừi từ 0, mỗi lần gửi xong tăng lên 1 đơn vị) xuống slave, slaver nhận được và gửi trở lại master. các bạn nhớ dùng Rs232 dọc về máy tính dể kiểm tra chính xác nhé

Code master:
#include <18f4431.h>
#include <def_4331.h>
#device 18f4431*=16 ADC=10
#include <stdlib.h> //tien xu li khi su dung ham ATOI()
#include <stdio.h> // for printf() call
#fuses nowdt,noprotect,nolvp,xt,put,hs
#use delay(clock=20000000)
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,b its=8)
#define slave_address_1 0x10
#define slave_address_2 0x20
#use i2c(master, sda=PIN_C4, scl=PIN_C5)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#use fast_io(a)


void write_slave_1(int16 a)
{ int8 hi,lo;
hi=make8(a,1);
lo=make8(a,0);
i2c_start();
i2c_write(slave_address_1);
delay_ms(1);
i2c_write(hi);
delay_ms(1);
i2c_write(lo);
i2c_stop();
}

void write_slave_2(int16 b)
{
int8 hi,lo;
hi=make8(b,1);
lo=make8(b,0);
i2c_start();
i2c_write(slave_address_2);
delay_ms(1);
i2c_write(hi);
delay_ms(1);
i2c_write(lo);
i2c_stop();
}


int16 read_slave_1()
{
int16 value_re_1;
int8 hi,lo;
i2c_start();
i2c_write(slave_address_1 + 1);
hi = i2c_read(1);
lo = i2c_read(0);
i2c_stop();
value_re_1 = make16(hi,lo);
return value_re_1;
}


int16 read_slave_2()
{
int16 value_re_2;
int8 hi,lo;
i2c_start();
i2c_write(slave_address_2 + 1);
hi = i2c_read(1);
lo = i2c_read(0);
i2c_stop();
value_re_2 = make16(hi,lo);
return value_re_2;
}



void main()
{
int16 value,value_re_1,value_re_2;
value = 0;

while(1)
{
write_slave_1(value);
write_slave_2(-value);
value++;
delay_ms(500);
value_re_1=read_slave_1();
value_re_2=read_slave_2();
printf("%ld",value_re_1);
printf(" ");
printf("%ld",value_re_2);
printf(" ");
delay_ms(100);
}
}

Code slaver 1:

#include <18f4431.h>
#include <def_4331.h>
#device 18f4431*=16 ADC=10
#include <stdlib.h> //tien xu li khi su dung ham ATOI()
#include <stdio.h> // for printf() call
#fuses nowdt,noprotect,nolvp,xt,put,hs
#use delay(clock=20000000)
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,b its=8)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C5, address=0x10)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#use fast_io(a)

boolean a;
int16 value;
int8 hi,lo;

#INT_SSP
void i2c_isr()
{
int8 state;
state = i2c_isr_state();
if (state<= 0x80)
{
if(state == 1 )
{ hi = i2c_read(1);

}
if(state == 2)
{ lo = i2c_read(1);
a=true;
}
}

if (state >= 0x80)
{
if(state==0x80)
i2c_write(hi);
if(state==0x81)
i2c_write(lo);
}

}



void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);

a=false;

while(1)
{
if (a==true)
{value=make16(hi,lo);
printf("%ld",value);
printf(" ");
a=false;
}
}
}


Code slave 2:

#include <18f4431.h>
#include <def_4331.h>
#device 18f4431*=16 ADC=10
#include <stdlib.h> //tien xu li khi su dung ham ATOI()
#include <stdio.h> // for printf() call
#fuses nowdt,noprotect,nolvp,xt,put,hs
#use delay(clock=20000000)
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7,b its=8)
#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C5, address=0x20)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#use fast_io(a)

boolean a;
int16 value;
int8 hi,lo;

#INT_SSP
void i2c_isr()
{
int8 state;
state = i2c_isr_state();
if (state<= 0x80)
{
if(state == 1 )
{ hi = i2c_read(1);

}
if(state == 2)
{ lo = i2c_read(1);
a=true;
}
}

if (state >= 0x80)
{
if(state==0x80)
i2c_write(hi);
if(state==0x81)
i2c_write(lo);
}
}



void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);

a=false;

while(1)
{
if (a==true)
{value=make16(hi,lo);
printf("%ld",value);
printf(" ");
a=false;
}
}
}


CHÚC CÁC BẠN MAY MẮN

duydien187
03-06-2013, 12:05 PM
cac bac cho em hoi la e dung con 16f685 hok co ngat SSP cho giao tiep I2C.e lai dang lam cai gaio tiep I2C giua 16f685 va PCF8583.. bac nao biet chi giao em vs. thanhks all

BDA_6892
02-11-2013, 06:01 PM
mình viết y chang nhưng sao không mô phỏng được
chỗ code của slave , cuối cùng là output_b chứ hả, mình thấy giá trị output của slave lúc nào cũng là value=0x01 ban đầu.....không có sự thay đổi nên chắc chưa có giao tiếp giữa slave và master.

grapefruit
22-03-2014, 03:52 AM
Anh Chị thân!
Hiện tại em đang viết chương trình giao tiếp I2C giữa Pic18f4550 và DS1307 đã chạy trên proteus nhưng ko hiểu tại sao khi chuyển sang con pic18f4520 giao tiếp với ds1307 thì lại ko chạy mà theo như em tìm hiểu thì cấu trúc thanh ghi về I2C của 2 con này ko khác nhau ko hiểu vì lý do j mà lại ko chạy.Anh Chị nào đã từng viết cho pic18f4520 có thể chỉ giúp em với đc ko ạ?còn có 1 tuần nữa nộp đồ án rùi mà mô phỏng chưa chạy thì mạch ko biết thế nào đây
còn dưới đây là chương trình của em Anh chị nào giúp em với,Help Me!
em cảm ơn!

#include "p18f4520.h"
#include "stdio.h"
#include "i2c.h"
#include "delays.h"

#pragma config OSC = HS
#pragma config IESO = OFF
#pragma config PWRT = OFF
#pragma config WDT = OFF
#pragma config WDTPS = 32768
#pragma config MCLRE = ON
#pragma config LVP = OFF
#pragma config DEBUG = ON

#define l1 PORTDbits.RD0
#define l2 PORTDbits.RD1
#define l3 PORTDbits.RD2
#define l4 PORTDbits.RD3
#define l5 PORTDbits.RD4
#define l6 PORTDbits.RD5

unsigned char M[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x9 0};
char m[32];
unsigned char s,giay,phut,gio;
unsigned char x,a;


void ghids(unsigned char diachi,unsigned char dulieu)
{
unsigned char b;
b=dulieu;//((((dulieu/10)<<4)&0xf0)+((dulieu%10)&0x0f));
StartI2C();
IdleI2C();

WriteI2C(0xd0);
IdleI2C();

WriteI2C(diachi);
IdleI2C();

WriteI2C(b);
IdleI2C();
StopI2C();
}
void docds1307(unsigned char slave1,unsigned char diachi)
{
unsigned char x;
StartI2C();
IdleI2C();

WriteI2C(slave1);
IdleI2C();

WriteI2C(diachi);
IdleI2C();

RestartI2C();
IdleI2C();

WriteI2C(slave1+1);
IdleI2C();

x=ReadI2C();
a=(x>>4)*10+(x&0x0f);

NotAckI2C();
IdleI2C();
StopI2C();
return x;
}
void hienthi(void)
{
docds1307(0xd0,0x00);giay=x;Delay1KTCYx(10);
l1=1;PORTB=M[(giay/10)];Delay1KTCYx(10);l1=0;
l2=1;PORTB=M[(giay%10)];Delay1KTCYx(10);l2=0;
docds1307(0xd0,1);phut=a;Delay1KTCYx(10);
l3=1;PORTB=M[(phut/10)];Delay1KTCYx(10);l3=0;
l4=1;PORTB=M[(phut%10)];Delay1KTCYx(10);l4=0;
docds1307(0xd0,2);gio=a;Delay1KTCYx(10);
l5=1;PORTB=M[(gio/10)];Delay1KTCYx(10);l5=0;
l6=1;PORTB=M[(gio%10)];Delay1KTCYx(10);l6=0;
}

void main()
{
TRISB=0X00;
TRISC=0b11110111;
TRISD=0x00;
ADCON1=0x0f;
Delay1KTCYx(10);
OpenI2C(MASTER,SLEW_OFF);
SSPADD=0x63;//49; //xung nhip=Fosc/(4*(SSPADD=49+1);
Delay1KTCYx(10);
//ghids1307(0x19,0x19,0x57);
gio=0;
giay=0;
phut=0;
ghids(0x00,0x14);
SSPCON1bits.SSPM3=1;
SSPCON1bits.SSPM2=0;
SSPCON1bits.SSPM1=0;
SSPCON1bits.SSPM0=0;
SSPCON2bits.RCEN=1;
Delay1KTCYx(10);
while(1)
{
hienthi();
}
}

mitsuvietnam
06-08-2016, 09:25 AM
Cảm anh đã chia sẻ bài viết!!!

supperchon
05-07-2021, 09:06 AM
se puee comprar cialis en andorra (https://www.grupopenascal.com/2020/11/16/se-puee-comprar-cialis-en-andorra)
precios de viagra cialis y levitra en farmacia con receta (https://www.grupopenascal.com/2020/11/16/precios-de-viagra-cialis-y-levitra-en-farmacia-con-receta)
precio de cialis en farmacias espanolas (https://www.grupopenascal.com/2020/11/16/precio-de-cialis-en-farmacias-espanolas)
donde comprar cialis generico en farmacias espanolas (https://www.grupopenascal.com/2020/11/16/donde-comprar-cialis-generico-en-farmacias-espanolas)
sildenafilo masticable precio (https://www.grupopenascal.com/2020/11/16/sildenafilo-masticable-precio)
precios en farmacia viagra gerenico (https://www.grupopenascal.com/2020/11/16/precios-en-farmacia-viagra-gerenico)
viagra boys espana 2019 (https://www.grupopenascal.com/2020/11/16/viagra-boys-espana-2019)
comprar sobres viagra (https://www.grupopenascal.com/2020/11/16/comprar-sobres-viagra)
cialis en farmacias necesita recete (https://www.grupopenascal.com/2020/11/16/cialis-en-farmacias-necesita-recete)
vardenafilo cinfa 10 mg 4 comprimidos bucodispersables precio (https://www.grupopenascal.com/2020/11/16/vardenafilo-cinfa-10-mg-4-comprimidos-bucodispersables-precio)
como conseguir cialis en espana (https://www.grupopenascal.com/2020/11/16/como-conseguir-cialis-en-espana)
precio de pastillas cialis 5 mg (https://www.grupopenascal.com/2020/11/16/precio-de-pastillas-cialis-5-mg)
cenforce extra opinion (https://www.grupopenascal.com/2020/11/16/cenforce-extra-opinion)
cenforce 100 precio (https://www.grupopenascal.com/2020/11/16/cenforce-100-precio)
donde comprar viagra generica sin receta en murcia (https://www.grupopenascal.com/2020/11/16/donde-comprar-viagra-generica-sin-receta-en-murcia)
comprar cialis a contra (https://www.grupopenascal.com/2020/11/16/comprar-cialis-a-contra)
costo del cialis generico en mexico (https://www.grupopenascal.com/2020/11/16/costo-del-cialis-generico-en-mexico)
comprar kamagra 24h (https://www.grupopenascal.com/2020/11/16/comprar-kamagra-24h)
comprar vidalista 10 mg (https://www.grupopenascal.com/2020/11/16/comprar-vidalista-10-mg)
fildena extra power 150 mg (https://www.grupopenascal.com/2020/11/16/fildena-extra-power-150-mg)
sildenafilo stada 50 mg precio (https://www.grupopenascal.com/2020/11/16/sildenafilo-stada-50-mg-precio)
te venden cialis sin receta (https://www.grupopenascal.com/2020/11/16/te-venden-cialis-sin-receta)
comprar cialis y viagra (https://www.grupopenascal.com/2020/11/16/comprar-cialis-y-viagra)
para comprar viagra (https://www.grupopenascal.com/2020/11/16/para-comprar-viagra)
que precio tiene la cialis (https://www.grupopenascal.com/2020/11/16/que-precio-tiene-la-cialis)
comprar generico viagra 4 comprimidos (https://www.grupopenascal.com/2020/11/16/comprar-generico-viagra-4-comprimidos)
comprar cialis sin recta (https://www.grupopenascal.com/2020/11/16/comprar-cialis-sin-recta)
precio del viagra en argentina 2020 (https://www.grupopenascal.com/2020/11/16/precio-del-viagra-en-argentina-2020)
donde comprar viagra en estados unidos (https://www.grupopenascal.com/2020/11/16/donde-comprar-viagra-en-estados-unidos)
cialis generico online (https://www.grupopenascal.com/2020/11/16/cialis-generico-online)
viagra generico comprar segura (https://www.grupopenascal.com/2020/11/16/viagra-generico-comprar-segura)
comprar viagra generico barato india (https://www.grupopenascal.com/2020/11/16/comprar-viagra-generico-barato-india)
comprar tadalafilo stada precio (https://www.grupopenascal.com/2020/11/16/comprar-tadalafilo-stada-precio)
comprar cialis en alcobendas (https://www.grupopenascal.com/2020/11/16/comprar-cialis-en-alcobendas)
comprar cialis a cobro revertido (https://www.grupopenascal.com/2020/11/16/comprar-cialis-a-cobro-revertido)

supperchon
14-07-2021, 05:37 AM
precio tadalafilo teva (https://www.grupopenascal.com/2020/11/16/precio-tadalafilo-teva)
el medico te receta cialis si se lo pides (https://www.grupopenascal.com/2020/11/16/el-medico-te-receta-cialis-si-se-lo-pides)
que es cialis precio (https://www.grupopenascal.com/2020/11/16/que-es-cialis-precio)
comprar en farmacia online levitra (https://www.grupopenascal.com/2020/11/16/comprar-en-farmacia-online-levitra)
lista precios sildenafilo en farmacias (https://www.grupopenascal.com/2020/11/16/lista-precios-sildenafilo-en-farmacias)
comprar viagra contrareembolso 24h (https://www.grupopenascal.com/2020/11/16/comprar-viagra-contrareembolso-24h)
comprar cialis a particulares (https://www.grupopenascal.com/2020/11/16/comprar-cialis-a-particulares)
cialis generico 20 mg opiniones (https://www.grupopenascal.com/2020/11/16/cialis-generico-20-mg-opiniones)
cialis generico barcelona (https://www.grupopenascal.com/2020/11/16/cialis-generico-barcelona)
sildenafilo cinfa 50 mg se puede comprar sin receta (https://www.grupopenascal.com/2020/11/16/sildenafilo-cinfa-50-mg-se-puede-comprar-sin-receta)
cialis generixo espana farmacias baratas (https://www.grupopenascal.com/2020/11/16/cialis-generixo-espana-farmacias-baratas)
comprar levitra en la india (https://www.grupopenascal.com/2020/11/16/comprar-levitra-en-la-india)
comprar cialis en farmacia registrada (https://www.grupopenascal.com/2020/11/16/comprar-cialis-en-farmacia-registrada)
se puede comprar viagra en espana sin receta (https://www.grupopenascal.com/2020/11/16/se-puede-comprar-viagra-en-espana-sin-receta)
comprar viagra espana en mano madrid (https://www.grupopenascal.com/2020/11/16/comprar-viagra-espana-en-mano-madrid)
cialis generico saldra a la venta espana (https://www.grupopenascal.com/2020/11/16/cialis-generico-saldra-a-la-venta-espana)
donde comprar cialis sin receta en espana (https://www.grupopenascal.com/2020/11/16/donde-comprar-cialis-sin-receta-en-espana)
comprar viagra de pfizer (https://www.grupopenascal.com/2020/11/16/comprar-viagra-de-pfizer)
precio vardenafilo (https://www.grupopenascal.com/2020/11/16/precio-vardenafilo)
pastilla cialis aplastada (https://www.grupopenascal.com/2020/11/16/pastilla-cialis-aplastada)
comprar cialis en garmacias (https://www.grupopenascal.com/2020/11/16/comprar-cialis-en-garmacias)
cialis espana online (https://www.grupopenascal.com/2020/11/16/cialis-espana-online)
mejor generico de cialis (https://www.grupopenascal.com/2020/11/16/mejor-generico-de-cialis)
donde puedo comprar viagra de mujer (https://www.grupopenascal.com/2020/11/16/donde-puedo-comprar-viagra-de-mujer)
pastillas cialis 5 mg precio (https://www.grupopenascal.com/2020/11/16/pastillas-cialis-5-mg-precio)
cialis generico 50 mg (https://www.grupopenascal.com/2020/11/16/cialis-generico-50-mg)
levitra 10 mg comprar (https://www.grupopenascal.com/2020/11/16/levitra-10-mg-comprar)
comprar cialis generico online canadian pharmacy (https://www.grupopenascal.com/2020/11/16/comprar-cialis-generico-online-canadian-pharmacy)
como comprar viagra en chile (https://www.grupopenascal.com/2020/11/16/como-comprar-viagra-en-chile)
puedo comprar viagra en cualquier farmacia peru (https://www.grupopenascal.com/2020/11/16/puedo-comprar-viagra-en-cualquier-farmacia-peru)
pastilla viagra comprar (https://www.grupopenascal.com/2020/11/16/pastilla-viagra-comprar)
precio cialis generico 4 (https://www.grupopenascal.com/2020/11/16/precio-cialis-generico-4)
fildena professional 100mg (https://www.grupopenascal.com/2020/11/16/fildena-professional-100mg)
comprar sildenafilo con seguridad (https://www.grupopenascal.com/2020/11/16/comprar-sildenafilo-con-seguridad)
se puede comprar cialis sin receta en farmacia en galicia (https://www.grupopenascal.com/2020/11/16/se-puede-comprar-cialis-sin-receta-en-farmacia-en-galicia)

supperchon
18-07-2021, 09:56 PM
comprar viagra en manresa (https://www.grupopenascal.com/2020/11/16/comprar-viagra-en-manresa)
comprar levitra en badajoz (https://www.grupopenascal.com/2020/11/16/comprar-levitra-en-badajoz)
viagra generico envio 24 horas espana (https://www.grupopenascal.com/2020/11/16/viagra-generico-envio-24-horas-espana)
sildenafil cenforce 150 mg precio (https://www.grupopenascal.com/2020/11/16/sildenafil-cenforce-150-mg-precio)
tadalafilo generico precio (https://www.grupopenascal.com/2020/11/16/tadalafilo-generico-precio)
comprar cialis seguro por internet (https://www.grupopenascal.com/2020/11/16/comprar-cialis-seguro-por-internet)
donde comprar viagra contrareembolso en espana (https://www.grupopenascal.com/2020/11/16/donde-comprar-viagra-contrareembolso-en-espana)
donde comprar viagra generico en farmacia sin receta (https://www.grupopenascal.com/2020/11/16/donde-comprar-viagra-generico-en-farmacia-sin-receta)
precio farmacia cialis 20 mg (https://www.grupopenascal.com/2020/11/16/precio-farmacia-cialis-20-mg)
comprar kamagra online (https://www.grupopenascal.com/2020/11/16/comprar-kamagra-online)
cenforce 120 (https://www.grupopenascal.com/2020/11/16/cenforce-120)
ya ha salido la levitra generico (https://www.grupopenascal.com/2020/11/16/ya-ha-salido-la-levitra-generico)
la viagra necesita receta medica en espana (https://www.grupopenascal.com/2020/11/16/la-viagra-necesita-receta-medica-en-espana)
viagra mujer espana (https://www.grupopenascal.com/2020/11/16/viagra-mujer-espana)
comprar cialis femenina contrareembolso (https://www.grupopenascal.com/2020/11/16/comprar-cialis-femenina-contrareembolso)
viagra hombre comprar precio (https://www.grupopenascal.com/2020/11/16/viagra-hombre-comprar-precio)
comprar viagra reino unido (https://www.grupopenascal.com/2020/11/16/comprar-viagra-reino-unido)
mejor tienda cialis generico (https://www.grupopenascal.com/2020/11/16/mejor-tienda-cialis-generico)
comprar viagra farmacia uk (https://www.grupopenascal.com/2020/11/16/comprar-viagra-farmacia-uk)
donde comprar viagra cialis etc en espana in situ (https://www.grupopenascal.com/2020/11/16/donde-comprar-viagra-cialis-etc-en-espana-in-situ)
comprar cialis original online (https://www.grupopenascal.com/2020/11/16/comprar-cialis-original-online)
cialis 10 mg precio dos dosis (https://www.grupopenascal.com/2020/11/16/cialis-10-mg-precio-dos-dosis)
viagra sildenafil 100 mg precio (https://www.grupopenascal.com/2020/11/16/viagra-sildenafil-100-mg-precio)
comprar cialis en alcorcon (https://www.grupopenascal.com/2020/11/16/comprar-cialis-en-alcorcon)
comprar viagra mano almeria (https://www.grupopenascal.com/2020/11/16/comprar-viagra-mano-almeria)
compra cialis malaga (https://www.grupopenascal.com/2020/11/16/compra-cialis-malaga)
cialis 10 mg precio farmacia argentina (https://www.grupopenascal.com/2020/11/16/cialis-10-mg-precio-farmacia-argentina)
se puede comprar libremente viagra en la farmacia (https://www.grupopenascal.com/2020/11/16/se-puede-comprar-libremente-viagra-en-la-farmacia)
cialis 20 mg precio en farmacias (https://www.grupopenascal.com/2020/11/16/cialis-20-mg-precio-en-farmacias)
comprar viagra cialis (https://www.grupopenascal.com/2020/11/16/comprar-viagra-cialis)
donde puedo comprar levitra 10 mg contrareembolso (https://www.grupopenascal.com/2020/11/16/donde-puedo-comprar-levitra-10-mg-contrareembolso)
donde comprar cialis de forma segura por internet (https://www.grupopenascal.com/2020/11/16/donde-comprar-cialis-de-forma-segura-por-internet)
donde comprar viagra en andorra sin receta (https://www.grupopenascal.com/2020/11/16/donde-comprar-viagra-en-andorra-sin-receta)
precios de viagra cialis y levitra (https://www.grupopenascal.com/2020/11/16/precios-de-viagra-cialis-y-levitra)
comprar vidalista online espana foro donde (https://www.grupopenascal.com/2020/11/16/comprar-vidalista-online-espana-foro-donde)

supperchon
20-07-2021, 01:05 PM
fildena comprar (https://www.grupopenascal.com/2020/11/16/fildena-comprar)
precio sildenafilo en la farmacia (https://www.grupopenascal.com/2020/11/16/precio-sildenafilo-en-la-farmacia)
es fiable comprar cialis por internet (https://www.grupopenascal.com/2020/11/16/es-fiable-comprar-cialis-por-internet)
sildenafilo cinfamed 100 mg donde comprarlo (https://www.grupopenascal.com/2020/11/16/sildenafilo-cinfamed-100-mg-donde-comprarlo)
cialis en espana (https://www.grupopenascal.com/2020/11/16/cialis-en-espana)
comprar levitra madrid (https://www.grupopenascal.com/2020/11/16/comprar-levitra-madrid)
donde comprar cialis en farmacias sin receta (https://www.grupopenascal.com/2020/11/16/donde-comprar-cialis-en-farmacias-sin-receta)
cenforce professional 100 mg (https://www.grupopenascal.com/2020/11/16/cenforce-professional-100-mg)
comprar viagra en logrono (https://www.grupopenascal.com/2020/11/16/comprar-viagra-en-logrono)
levitra precio peru (https://www.grupopenascal.com/2020/11/16/levitra-precio-peru)
cual es el precio de cialis 5 mg (https://www.grupopenascal.com/2020/11/16/cual-es-el-precio-de-cialis-5-mg)
comprar viagra castellon (https://www.grupopenascal.com/2020/11/16/comprar-viagra-castellon)
puedo comprar viagra en una farmacia (https://www.grupopenascal.com/2020/11/16/puedo-comprar-viagra-en-una-farmacia)
las pastillas genericas de cialis se compran con receta (https://www.grupopenascal.com/2020/11/16/las-pastillas-genericas-de-cialis-se-compran-con-receta)
viagra contrareembolso comprar andorra (https://www.grupopenascal.com/2020/11/16/viagra-contrareembolso-comprar-andorra)
precio cialis en una farmacia legal fisica en espana (https://www.grupopenascal.com/2020/11/16/precio-cialis-en-una-farmacia-legal-fisica-en-espana)
comprar viagra en coruna (https://www.grupopenascal.com/2020/11/16/comprar-viagra-en-coruna)
cialis generico en farmacias fisicas2019 (https://www.grupopenascal.com/2020/11/16/cialis-generico-en-farmacias-fisicas2019)
cenforce contrareembolso (https://www.grupopenascal.com/2020/11/16/cenforce-contrareembolso)
comprar viagra para diabeticos (https://www.grupopenascal.com/2020/11/16/comprar-viagra-para-diabeticos)
generico de cialis en espana (https://www.grupopenascal.com/2020/11/16/generico-de-cialis-en-espana)
sildenafilo espana precios (https://www.grupopenascal.com/2020/11/16/sildenafilo-espana-precios)
comprar generico cialis (https://www.grupopenascal.com/2020/11/16/comprar-generico-cialis)
sildenafilo mylan 50 mg comprar (https://www.grupopenascal.com/2020/11/16/sildenafilo-mylan-50-mg-comprar)
precio de viagra en santo domingo (https://www.grupopenascal.com/2020/11/16/precio-de-viagra-en-santo-domingo)
comprar viagra real (https://www.grupopenascal.com/2020/11/16/comprar-viagra-real)
comprar en farmacia viagra (https://www.grupopenascal.com/2020/11/16/comprar-en-farmacia-viagra)
se puede comprar viagra sin receta en espana en farmacias (https://www.grupopenascal.com/2020/11/16/se-puede-comprar-viagra-sin-receta-en-espana-en-farmacias)
como comprar viagra ou cialis (https://www.grupopenascal.com/2020/11/16/como-comprar-viagra-ou-cialis)
viagra en andorra precio (https://www.grupopenascal.com/2020/11/16/viagra-en-andorra-precio)
se compra viagra con receta o sin receta (https://www.grupopenascal.com/2020/11/16/se-compra-viagra-con-receta-o-sin-receta)
telefono para comprar levitra (https://www.grupopenascal.com/2020/11/16/telefono-para-comprar-levitra)
la viagra se puede comprar en farmacias sin receta (https://www.grupopenascal.com/2020/11/16/la-viagra-se-puede-comprar-en-farmacias-sin-receta)
sildenafilo 100 mg actavis precio (https://www.grupopenascal.com/2020/11/16/sildenafilo-100-mg-actavis-precio)
seguridad medica en la compra de levitra (https://www.grupopenascal.com/2020/11/16/seguridad-medica-en-la-compra-de-levitra)

supperchon
20-07-2021, 08:49 PM
levitra 10 mg precio (https://www.grupopenascal.com/2020/11/16/levitra-10-mg-precio)
comprar levitra gibraltar (https://www.grupopenascal.com/2020/11/16/comprar-levitra-gibraltar)
viagra natural que se compra la reposteria (https://www.grupopenascal.com/2020/11/16/viagra-natural-que-se-compra-la-reposteria)
como conseguir viagra en espana (https://www.grupopenascal.com/2020/11/16/como-conseguir-viagra-en-espana)
cialis precio sevilla (https://www.grupopenascal.com/2020/11/16/cialis-precio-sevilla)
donde comprar cialis de modo seguro online (https://www.grupopenascal.com/2020/11/16/donde-comprar-cialis-de-modo-seguro-online)
cialis 20 mg 10 pastilla (https://www.grupopenascal.com/2020/11/16/cialis-20-mg-10-pastilla)
puedo comprar viagra en farmacias guadalajara (https://www.grupopenascal.com/2020/11/16/puedo-comprar-viagra-en-farmacias-guadalajara)
cialis chile sin receta (https://www.grupopenascal.com/2020/11/16/cialis-chile-sin-receta)
comprar levitra en internet (https://www.grupopenascal.com/2020/11/16/comprar-levitra-en-internet)
sildenafilo cinfa 50 mg 8 comprimidos masticable precio (https://www.grupopenascal.com/2020/11/16/sildenafilo-cinfa-50-mg-8-comprimidos-masticable-precio)
comprar super vidalista (https://www.grupopenascal.com/2020/11/16/comprar-super-vidalista)
tadalafilo 10 cinfa precio (https://www.grupopenascal.com/2020/11/16/tadalafilo-10-cinfa-precio)
tadalafilo 10 mg precio cinfa (https://www.grupopenascal.com/2020/11/16/tadalafilo-10-mg-precio-cinfa)
comprar levitra en huelva (https://www.grupopenascal.com/2020/11/16/comprar-levitra-en-huelva)
viagra generico online espana (https://www.grupopenascal.com/2020/11/16/viagra-generico-online-espana)
comprar viagra generico barcelona (https://www.grupopenascal.com/2020/11/16/comprar-viagra-generico-barcelona)
farmacias en zaragoza cialis generico precio (https://www.grupopenascal.com/2020/11/16/farmacias-en-zaragoza-cialis-generico-precio)
viagra 50 mg precio mercadolibre (https://www.grupopenascal.com/2020/11/16/viagra-50-mg-precio-mercadolibre)
viagra professional 100 mg espana (https://www.grupopenascal.com/2020/11/16/viagra-professional-100-mg-espana)
comprar levitra en jaen (https://www.grupopenascal.com/2020/11/16/comprar-levitra-en-jaen)
receta necesaria para cialis o viagra (https://www.grupopenascal.com/2020/11/16/receta-necesaria-para-cialis-o-viagra)
comprar cialis 5 mg barato (https://www.grupopenascal.com/2020/11/16/comprar-cialis-5-mg-barato)
pastillas para la ereccion cialis on line (https://www.grupopenascal.com/2020/11/16/pastillas-para-la-ereccion-cialis-on-line)
viagra precio barato (https://www.grupopenascal.com/2020/11/16/viagra-precio-barato)
comprar viagra en farmacia 2020 (https://www.grupopenascal.com/2020/11/16/comprar-viagra-en-farmacia-2020)
donde comprar viagra en murcia (https://www.grupopenascal.com/2020/11/16/donde-comprar-viagra-en-murcia)
comprar tadalafilo en andorra (https://www.grupopenascal.com/2020/11/16/comprar-tadalafilo-en-andorra)
cialis 5 mg precio farmacia guadalajara (https://www.grupopenascal.com/2020/11/16/cialis-5-mg-precio-farmacia-guadalajara)
levitra generico 20 mg (https://www.grupopenascal.com/2020/11/16/levitra-generico-20-mg)
comprar cialis 40 mg contrareembolso (https://www.grupopenascal.com/2020/11/16/comprar-cialis-40-mg-contrareembolso)
comprar cialis 10 mg online (https://www.grupopenascal.com/2020/11/16/comprar-cialis-10-mg-online)
comprar levitra de 5mg (https://www.grupopenascal.com/2020/11/16/comprar-levitra-de-5mg)
levitra generico desde cuando (https://www.grupopenascal.com/2020/11/16/levitra-generico-desde-cuando)
cialis 1 pastilla (https://www.grupopenascal.com/2020/11/16/cialis-1-pastilla)

knnhubi
18-01-2023, 04:22 PM
https://t.me/pump_upp - best crypto pumps on telegram
Make 1000% and more within 1 day, join channel @pump_upp !