PIC Vietnam

Go Back   PIC Vietnam > Microchip PIC > Các ngôn ngữ lập trình khác (CCS C, HT PIC,...)

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

Trả lời
 
Ðiều Chỉnh Xếp Bài
Old 03-11-2012, 04:44 AM   #1
lab.cdt
Đệ tử 1 túi
 
Tham gia ngày: May 2012
Bài gửi: 19
:
Giao tiep I2C voi PIC 16f877a

Chào các cậu. Tớ đang tự học CCS C và đến phần giao tiếp I2C. Tớ đã đọc code mẫu trong help của CCS C và đã đọc code mẫu của các bạn hoanf và ha trong topic I2C nhưng tớ chưa hiểu lắm. Ý tưởng ban đầu của tớ đơn giản chỉ là truyền một byte (chỉ 1 byte và 1 lần) từ con mater xuống con slave.
////////////////////////////////////////////////////////////////////////////////////////////////
//dùng PIC 16f877a ////////////
//các đoạn khai báo ban đầu tương tự như các bài hướng dẫn trên diễn đàn////////////
//nên tớ không viết lại (vì admin có yêu cầu là chỉ post phần thắc mắc và ý tưởng)////
////////////////////////////////////////////////////////////////////////////////////////////////
//code cho con mater:

#define slave_address 0x10
#use i2c(master, sda=PIN_C4, scl=PIN_C3)
void write_I2C(int8 value)
{
i2c_start();//mater tao tin hieu start
i2c_write(slave_addr);//Gửi địa chỉ và bít hướng R/W = 0 (Mode write) đến Slave
i2c_write(value);//Gửi dữ liệu byte thứ nhất
i2c_stop();// Master tạo tín hiệu Stop
}
void main()
{
int8 a = 0xFF;
write_I2C(a);
}

//code cho slave

#use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, address=0x10)
int8 value;
#INT_SSP
void i2c_isr()
{
int8 state;
state = i2c_isr_state();
if(state == 0)
i2c_read();
else if(state < 0x80)
value = i2c_read();
}
void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
set_tris_b(0);
output_b(value);
}

Khi tớ mô phỏng trên protues thì 8 con led ở portB của con slave ko sáng cùng lúc (giá trị tại các pin của portB ở con slave là mức cao thì led sáng) mà nó chớp tắt như là tớ truyền liên tục một byte xuống từ con master với giá trị khởi tạo là " a = 0x01 " và cứ mỗi lần truyền thì a tăng lên 1 đơn vị (giá trị tiếp theo của a là " a = 0x02 " và cứ thế..) đến khi " a = 0xFF" (8 con sáng cùng 1 lúc) thì nó lại tắt và bắt đầu lại từ đầu. Tớ suy nghĩ nhiều lần mà không hiểu dc, vì tớ chỉ truyền 1 lần thì con slave chỉ nhận 1 lần chứ. Như vậy thì 8 con led ở con slave sáng đồng thời và giữ nguyên...nhưng ở đây thì nó lại chớp tắt như trên. Mong các cậu biết giải thích hộ tớ. Tớ gửi lời cảm ơn và lời chúc sứ khỏe đến các cậu..
..thân...
lab.cdt vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 03-11-2012, 06:55 AM   #2
lab.cdt
Đệ tử 1 túi
 
Tham gia ngày: May 2012
Bài gửi: 19
:
Tớ mô phỏng trên protues dc rồi. code không thay đổi. Vậy mà từ tối hôm qua tới giờ mô phỏng không được..(mô phỏng chỉ để tớ kiểm tra nguyên lý xem tớ hiểu có đúng không thôi...^^)..không hiểu cái CCS C của tớ bị sao vậy nè...lúc nọ lúc kia...
lab.cdt vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 03-11-2012, 04:31 PM   #3
lab.cdt
Đệ tử 1 túi
 
Tham gia ngày: May 2012
Bài gửi: 19
:
Chào các cậu, tớ tiếp tục làm bài toán ngược lài là truyền dữ liệu từ con slave (và lúc nay slave ko nhận dữ liệu từ master) đến con master và cụ thể là chỉ truyền 1 byte cho dễ. tớ có tham khảo code trong help của CCS C và trên diễn đàn PIC việt nam nhưng tớ vẫn chưa làm được. đây là code mẫu của tớ:
////code cho con master..

#include <16f877a.h>
#use delay (clock = 4000000)

#use i2c (master, sda = pin_c4, scl = pin_c3)
#define slave_address 0x10

void read_i2c()
{
int8 value;
i2c_start();//Master tạo tín hiệu Start
i2c_write(slave_address + 1);//Gửi địa chỉ và bít hướng R/W = 1 (Mode read) đến Slave
value = i2c_read();// Đọc dữ liệu byte thứ nhất (truong hop nay slave chi gui co 1 byte..^^..cho don gian
i2c_stop();// Master tạo tín hiệu Stop
return value;//ham tra ve gia tri da truyen tu slave den master
}

void main()
{
int8 a;
set_tris_b(0);
a = read_i2c();
output_b(a);//xuat gia tri ra portB để kiểm tra kết quả..
}

//code cho con slave

#include <16f877a.h>
#use delay (clock = 4000000)

#use i2c (slave, sda = pin_c4, scl = pin_c3, address = 0x10)

int8 value = 0x01;
#INT_SSP
//ham doc ve byte address va ghi du lieu ra bus để truyền cho con master..
void write_i2c()
{
int8 state;
state = i2c_isr_state();
if(state >= 0x80)
i2c_write(value);//thuc hien viec ghi du lieu ra bus
}

void main()
{
enable_interrupts(global);
enable_interrupts(INT_SSP);
set_tris_b(0);
output_b(value);///hien thi tren port B de kiem tra gia tri..
}

Sau khi mô phỏng trên protues thi tớ chỉ thay có mỗi led ở con slave sáng..còn led bên con master ko sáng..các ngõ ra ở port ở trang thái mức thấp (ko co tín hiệu ra).để led sang thi cac ngõ ra ở các pin của các port tuong ứng ở mức cao. Mong các cậu giải thích hộ tớ..thân..

thay đổi nội dung bởi: lab.cdt, 03-11-2012 lúc 04:56 PM.
lab.cdt vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 03-11-2012, 05:16 PM   #4
lab.cdt
Đệ tử 1 túi
 
Tham gia ngày: May 2012
Bài gửi: 19
:
Các cậu ơi,,tớ làm được rồi..cũng code đó và mạch không đồi..tớ xóa hết đi và làm lại thì nó chạy và mô phỏng tốt..không hiểu sao cứ mỗi lần tớ post câu hỏi lên diễn đàn là tớ lại làm ra...^^. 2 ví dụ của tớ là 2 ví dụ đơn giản bước đầu làm quen và hiểu về I2C. Hi vong 2 ví dụ của tớ sẽ giúp ích cho các bạn khi mới bước vào mò mẫm I2C.Thân..^^
lab.cdt vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 04-11-2012, 03:14 PM   #5
lab.cdt
Đệ tử 1 túi
 
Tham gia ngày: May 2012
Bài gửi: 19
:
Giờ tớ lại có vấn đề tiếp. Tớ đã truyền được từ mater đến slave bao nhiêu byte cũng được. Nhưng để truyền từ slave lên mater thì tớ chỉ truyền được một byte đầu tiên. Ý tớ là nếu tớ truyền 8 byte bất kỳ (có thể nhiều hơn cũng được) chẳng hạn như: { 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80, 0x00}. Thì tớ chỉ có truyền được 1 byte đầu tiên là : 0xFF. Nguyên lý truyền thì tớ đã nắm được nhưng tớ lại gặp vấn đề về code. Đây là code mẫu của tớ. Các cậu sửa giúp tớ nhé :

//code cho mater

#include <16F877A.H>
#use Delay(Clock=4000000)

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

/////////////////////////////////////////////////////////////////////////////////////////////////
////// doan code co muc dich la con mater ra lenh con slave gui du lieu len cho no///
///// doc gia tri tra ve //////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
int8 read_I2C()
{
int8 value;

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

void main()
{
int8 value, i;
/////////////////////////////////////////////////////////////////////////////////////////////////
////// doan code co muc dich la goi ham read_i2c() 8 lan ////////////////////////
////// va xuat gia tri tra ve ra cac pin cua portB ///////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////
set_tris_b(0);
for(i = 1; i < 9; i++)
{
value = read_I2C();
output_b(value);
}
}

//code cho 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 DIGIT[8] = { 0xFE, 0xFC, 0xF8, 0xF0, 0xE0, 0xC0, 0x80, 0x00};
#INT_SSP

//////////////////////////////////////////////////////////////////////////////////////////////////
///// doan code co muc dich la nhan tin hieu dieu khien tu mater /////////////////
//// va truyen 8 byte len mater //////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////
void i2c_isr()
{
int8 state;
state = i2c_isr_state();
if(state >= 0x80)
{
i2c_write(DIGIT[state - 0x80]);

}
}

void main()
{
enable_interrupts(GLOBAL);
enable_interrupts(INT_SSP);
////////////////////////////////////////////////////////////////////////////////////////////
//doan code nay co muc dich kiem tra xem con slave co truyen dung khong////////
////////////////////////////////////////////////////////////////////////////////////////////
set_tris_b(0);
int8 i;
for (i = 1; i < 9; i++)
{
output_b(DIGIT[i - 1]);
delay_ms(100);
}
}

tớ không hiểu là con mater ra lệnh điều khiển 8 lần thì mỗi lần biến trạng thái state = i2c_isr_state() nằm ở chương trình con slave phải tăng lên tuần tự chứ và bắt đầu là 0x80 ( tiếp theo là 0x81, 0x82......). nhưng sao biến state ở chương trình con slave lại không tăng lên nhỉ. Nó cứ nằm ở 0x80 hoài...???? giúp tớ với...thân...

thay đổi nội dung bởi: lab.cdt, 04-11-2012 lúc 03:21 PM.
lab.cdt vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 04-11-2012, 10:55 PM   #6
lab.cdt
Đệ tử 1 túi
 
Tham gia ngày: May 2012
Bài gửi: 19
:
Các cậu ơi...giúp tớ với....
lab.cdt 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à 05:34 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