PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Giao tiếp USB, CAN, I2C, SPI, USART... (http://www.picvietnam.com/forum/forumdisplay.php?f=45)
-   -   Giao tiếp I2C (http://www.picvietnam.com/forum/showthread.php?t=611)

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

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

#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

Trích:

Nguyên văn bởi minhminh17 (Post 21607)
...
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

lạ
 
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

Trích:

Nguyên văn bởi thientaisodo (Post 22664)
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

Trích:

Nguyên văn bởi thientaisodo (Post 22695)
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
Code:

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

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

Giao tiếp I2C giữa 877a và 88
 
1 Attachment(s)
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
Code:

#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,bits=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 )
Code:

#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,address=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

Trích:

Nguyên văn bởi haquang (Post 25102)
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:

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

Trích:

Nguyên văn bởi nhoczin (Post 25139)
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

I2C gặp vấn đề!
 
Trích:

Nguyên văn bởi hoanf (Post 4955)
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);
  }
}


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

Trích:

Nguyên văn bởi vagabond (Post 6710)
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

Trích:

Nguyên văn bởi inventor_bk (Post 29862)
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

Trích:

Nguyên văn bởi hoanf (Post 4955)
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);
  }
}


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

Vấn đề ngắt i2c trong chip SLAVE
 
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

i2c
 
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

Trích:

Nguyên văn bởi dt_cn (Post 33314)
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_Inte..._Standard.html
http://namqn.byethost7.com/Commu.php#i2c
http://www.esacademy.com/en/library/...s/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

Trích:

Nguyên văn bởi dt_cn (Post 33316)
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

Trích:

Nguyên văn bởi dt_cn (Post 33319)
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.


Múi giờ GMT. Hiện tại là 03:25 PM.

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam