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.