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)

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

I2C không chịu chay.
 
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
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à code của 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_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
 
1 Attachment(s)
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

I2C đọc từ slave về master
 
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

Trích:

Nguyên văn bởi TheHouse (Post 41477)
Đị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 viết Help -CCS tiếng Việt rất hay..
 
1 Attachment(s)
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
 
Cam on stupid tai lieu rat hay va chi tiet ;))

quangvanvo 14-03-2011 05:21 PM

4 Attachment(s)
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

Trích:

Nguyên văn bởi minhkhoa1990 (Post 46006)
//
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

I2C...........slave->master
 
1 Attachment(s)
Đụ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

I2C----->>Master<==>Slave
 
1 Attachment(s)
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

Cần anh chị giúp I2C
 
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

giao tiếp với eeprom ngoài(24c64)
 
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

giaotiếp với eeprom ngoài(24c64)
 
1 Attachment(s)
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

giaotiếp với eeprom ngoài(24c64)
 
1 Attachment(s)
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

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

nguyenthangcdt 05-10-2012 03:08 AM

Trích:

Nguyên văn bởi thanhha (Post 4938)
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 06-10-2012 08:44 AM

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);
  }
}


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ỉ.


Múi giờ GMT. Hiện tại là 02:58 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