PIC Vietnam

Go Back   PIC Vietnam > Truyền thông > Giao tiếp USB, CAN, I2C, SPI, USART...

Tài trợ cho PIC Vietnam
Trang chủ Đăng Kí Hỏi/Ðáp Thành Viên Lịch Bài Trong Ngày Vi điều khiển

Giao tiếp USB, CAN, I2C, SPI, USART... Những giao tiếp được tích hợp trên PIC

Trả lời
 
Ðiều Chỉnh Xếp Bài
Old 27-07-2012, 01:43 AM   #196
khienpzo
Đệ tử 5 túi
 
Tham gia ngày: Sep 2010
Bài gửi: 107
:
Question Giao tiếp I2C điều khiển động cơ DC

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
khienpzo vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 05-10-2012, 03:08 AM   #197
nguyenthangcdt
Đệ tử 1 túi
 
Tham gia ngày: Apr 2012
Bài gửi: 16
:
Smile

Trích:
Nguyên văn bởi thanhha View Post
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:
//**************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 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 06-10-2012, 08:44 AM   #198
nguyenthangcdt
Đệ tử 1 túi
 
Tham gia ngày: Apr 2012
Bài gửi: 16
:
Trích:
Nguyên văn bởi hoanf View Post
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.

Code:
#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:

Code:
#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
nguyenthangcdt vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 27-11-2012, 10:45 AM   #199
khienpzo
Đệ tử 5 túi
 
Tham gia ngày: Sep 2010
Bài gửi: 107
:
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
khienpzo vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 14-12-2012, 10:39 AM   #200
thegioimoiqb
Nhập môn đệ tử
 
Tham gia ngày: Mar 2012
Bài gửi: 3
:
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ỉ.
thegioimoiqb vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 14-12-2012, 11:38 AM   #201
hatuan296
Làm quen với PIC
 
Tham gia ngày: Oct 2005
Nơi Cư Ngụ: Hcm
Bài gửi: 160
:
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
hatuan296 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 14-12-2012, 01:57 PM   #202
thegioimoiqb
Nhập môn đệ tử
 
Tham gia ngày: Mar 2012
Bài gửi: 3
:
Em đang mô phỏng bằng protues thôi anh ah. Có tin được thằng PROTUES k anh nhị.
thegioimoiqb vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 15-12-2012, 04:23 AM   #203
hatuan296
Làm quen với PIC
 
Tham gia ngày: Oct 2005
Nơi Cư Ngụ: Hcm
Bài gửi: 160
:
Trích:
Nguyên văn bởi thegioimoiqb View Post
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
hatuan296 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 15-12-2012, 12:43 PM   #204
thegioimoiqb
Nhập môn đệ tử
 
Tham gia ngày: Mar 2012
Bài gửi: 3
:
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.
thegioimoiqb vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 15-12-2012, 03:06 PM   #205
khienpzo
Đệ tử 5 túi
 
Tham gia ngày: Sep 2010
Bài gửi: 107
:
Mô phỏng chạy nhưng ra phần cứng chưa chắc chạy đâu bạn. Thân
khienpzo vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 08-03-2013, 11:16 AM   #206
copchaua
Nhập môn đệ tử
 
Tham gia ngày: Sep 2011
Bài gửi: 5
:
đã viết code nhận và gửi 2 byte cho từ 1 master và 2 slave chạy good
copchaua vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 08-03-2013, 11:19 AM   #207
copchaua
Nhập môn đệ tử
 
Tham gia ngày: Sep 2011
Bài gửi: 5
:
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 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 08-03-2013, 11:26 AM   #208
copchaua
Nhập môn đệ tử
 
Tham gia ngày: Sep 2011
Bài gửi: 5
:
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
copchaua vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 03-06-2013, 12:05 PM   #209
duydien187
Nhập môn đệ tử
 
Tham gia ngày: May 2013
Bài gửi: 6
:
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
duydien187 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 02-11-2013, 06:01 PM   #210
BDA_6892
Nhập môn đệ tử
 
Tham gia ngày: May 2013
Bài gửi: 1
:
i2c

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.
BDA_6892 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Trả lời


Quyền Sử Dụng Ở Diễn Ðàn
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is Mở
Smilies đang Mở
[IMG] đang Mở
HTML đang Tắt

Chuyển đến


Múi giờ GMT. Hiện tại là 07:58 AM.


Được sáng lập bởi Đoàn Hiệp
Powered by vBulletin®
Page copy protected against web site content infringement by Copyscape
Copyright © PIC Vietnam