PIC Vietnam

Go Back   PIC Vietnam > Microchip PIC > dsPIC - Bộ điều khiển tín hiệu số 16-bit

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

dsPIC - Bộ điều khiển tín hiệu số 16-bit Theo dự kiến của Microchip, vào khoảng năm 2011 dsPIC sẽ có doanh số lớn hơn PIC

Trả lời
 
Ðiều Chỉnh Xếp Bài
Old 29-07-2009, 09:26 AM   #1
trangham283
Nhập môn đệ tử
 
Tham gia ngày: Jul 2009
Bài gửi: 7
:
Thắc mắc về giao tiếp SPI

Xin chào mọi người,

Em đã có đọc qua tìm hiểu về giao tiếp SPI và em đang viết chương trình để thử đọc và viết vào EEPROM 25LC256 nhờ dsPIC30F2011. Em đã tham khảo tài liệu cũng như code mẫu của microchip, cụ thể là cái này:

http://www.microchip.com/stellent/id...pnote=en023868

đã thay đổi một số chỗ sao cho phù hợp với dsPIC của mình.

Hiện giờ em có thắc mắc về phần configuration cho thanh ghi SPI1CON của PIC, cụ thể là phần chọn Mode: word hay byte communication.

Trong tài liệu của EEPROM, theo em hiểu thì EEPROM sẽ chỉ nhận từng byte một, ("The 25LC256 contains an 8-bit instruction register), như vậy có phải em sẽ phải chọn chế độ giao tiếp byte?

Phần em không hiểu hiện giờ là: thanh đệm SPI1BUF của PIC dài 16 bit, khi viết dữ liệu cần chuyển đi cũng là viết 16 bit, như vậy khi giao tiếp theo chế độ 1 byte thì cái byte còn lại nó vứt đi đâu ạ?
trangham283 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 29-07-2009, 10:07 AM   #2
namqn
Trưởng lão PIC bang
 
Tham gia ngày: Feb 2006
Nơi Cư Ngụ: Tp. HCM, Việt Nam
Bài gửi: 3,025
:
Send a message via Yahoo to namqn
Trích:
Nguyên văn bởi trangham283 View Post
Xin chào mọi người,

Em đã có đọc qua tìm hiểu về giao tiếp SPI và em đang viết chương trình để thử đọc và viết vào EEPROM 25LC256 nhờ dsPIC30F2011. Em đã tham khảo tài liệu cũng như code mẫu của microchip, cụ thể là cái này:

http://www.microchip.com/stellent/id...pnote=en023868

đã thay đổi một số chỗ sao cho phù hợp với dsPIC của mình.

Hiện giờ em có thắc mắc về phần configuration cho thanh ghi SPI1CON của PIC, cụ thể là phần chọn Mode: word hay byte communication.

Trong tài liệu của EEPROM, theo em hiểu thì EEPROM sẽ chỉ nhận từng byte một, ("The 25LC256 contains an 8-bit instruction register), như vậy có phải em sẽ phải chọn chế độ giao tiếp byte?

Phần em không hiểu hiện giờ là: thanh đệm SPI1BUF của PIC dài 16 bit, khi viết dữ liệu cần chuyển đi cũng là viết 16 bit, như vậy khi giao tiếp theo chế độ 1 byte thì cái byte còn lại nó vứt đi đâu ạ?
Mời bạn đọc tutorial sau:

http://www.picvietnam.com/forum/showthread.php?t=2481

Thông tin liên quan đến thắc mắc của bạn đã được đề cập trong tutorial đó.

Thân,
__________________
Biển học mênh mông, sức người có hạn.

Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau:
http://www.picvietnam.com/forum/showthread.php?t=1263
namqn vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 29-07-2009, 12:28 PM   #3
Serenade
Nhập môn đệ tử
 
Tham gia ngày: Oct 2008
Bài gửi: 6
:
Đương nhiên là cấu hình byte rùi bạn.

Code:
#define EE_SSPIF_BIT IFS2bits.SPI2IF
#define SPIREAD     0x03
#define SPIWRITE    0x02
#define SPIWRDI     0x04
#define SPIWREN     0x06
#define SPIRDSR     0x05
#define SPIWRSR     0x01

/*********************************************************************/
void EE_SPIPut(BYTE v)
{
   BYTE dummy;

   EE_SSPIF_BIT = 0;
   dummy = EE_SSPBUF_REG; 
   EE_SSPBUF_REG = v;
   while(EE_SSPIF_BIT == 0 );
}
/*********************************************************************/
BYTE EE_SPIGet(void)
{
   EE_SPIPut(0x00);
   return EE_SSPBUF_REG; 
}
/*********************************************************************/

BYTE NVMRead(DWORD address)// read a 16-bit value starting at an even address
{
 	BYTE msb,lsb,temp;
	
	// wait until any work in progress is completed
	do 
	{
		SPISelectEEPROM();
		EE_SPIPut(SPIRDSR);
		temp = EE_SPIGet();//read status register
		SPIUnselectEEPROM();
	}while(temp & 0x03);
	
	// perform a 16-bit read sequence (two byte sequential read)
	SPISelectEEPROM();			// select the Serial EEPROM
	EE_SPIPut(SPIREAD);// read command
	EE_SPIPut(address >> 8);	// address MSB first
	EE_SPIPut(address & 0xff);// address LSB (word aligned)
	//msb = EE_SPIGet();
	lsb = EE_SPIGet();	
	SPIUnselectEEPROM();
	return (lsb);

}//ReadNVM
/*********************************************************************/
void NVMWrite( DWORD address, BYTE data)
{ // write a 16-bit value starting at an even address
	BYTE temp;
	// wait until any work in progress is completed
	do
	{
		SPISelectEEPROM();
		EE_SPIPut(SPIRDSR);
		temp = EE_SPIGet();//read status register
		SPIUnselectEEPROM();
	}while(temp & 0x03);
	// Set the Write Enable Latch
	SPISelectEEPROM();
	EE_SPIPut(SPIWREN);
	SPIUnselectEEPROM();
	
	// perform a 16-bit write sequence (2 byte page write)
	SPISelectEEPROM();					// select the Serial EEPROM
	EE_SPIPut(SPIWRITE);
	EE_SPIPut(address >> 8);		//address MSB first
	EE_SPIPut(address & 0xff);	// address LSB (word aligned)
	EE_SPIPut(data);
	SPIUnselectEEPROM();

}//WriteNVM

thay đổi nội dung bởi: namqn, 29-07-2009 lúc 05:43 PM. Lý do: định dạng code
Serenade vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 29-07-2009, 12:32 PM   #4
trangham283
Nhập môn đệ tử
 
Tham gia ngày: Jul 2009
Bài gửi: 7
:
Em cảm ơn anh Nam, ý anh là đoạn này ạ? Em có đọc qua tutorial này rồi, nhưng em vẫn không hiểu lắm :"> Anh có thể làm ơn giải thích thêm cho em về thao tác truyền dữ liệu sang slave được không ạ?

Trích:
Master có thể ghi dữ liệu mới vào bộ đệm SPI khi dữ liệu cũ đang được dịch ra. Khi
thanh ghi dịch trống thì dữ liệu mới sẽ được chuyển từ bộ đệm vào. Người dùng chỉ
cần chú ý kiểm tra bit SPITBF trong thanh ghi SPIxSTAT tương ứng để tránh ghi vào bộ
đệm khi nó đang chứa dữ liệu.

Cùng lúc với dữ liệu được dịch ra từ bộ đệm truyền, dữ liệu cũng được lấy vào
thanh ghi dịch, và khi bộ đệm nhận đã nhận đủ số bit cần thiết thì dữ liệu sẽ được
chuyển vào bộ đệm nhận
, và bit SPIIF sẽ được bật. Nếu ngắt SPI được cho phép, bằng cách bật bit SPIIE, thì một ngắt SPI sẽ được tạo ra. Bit SMP trong thanh ghi SPIxCON
cho phép chọn vị trí lấy mẫu dữ liệu vào, ở giữa hay cuối mỗi chu kỳ của bit.

Bit SPIRBF trong thanh ghi SPIxSTAT cho biết bộ đệm nhận có dữ liệu. Nếu dữ liệu
này không được đọc ra khi thanh ghi dịch hoàn tất thao tác dịch dữ liệu mới vào thì sẽ
xảy ra tràn bộ đệm nhận, với bit SPIROV trong thanh ghi SPIxSTAT được bật. Khi đó
dữ liệu mới sẽ không được chuyển vào bộ đệm và bị mất
.
Có nghĩa là nếu em config giao tiếp 8-bit, sau khi SPIxSR nhận 8 bit, 8 bit này sẽ được chép vào SPIxRXB rồi sẽ cần được đọc ra để tránh tràn và mất dũ liệu?

Em xin lỗi nếu em lại đọc sót phần quan trọng :P, nhưng em vẫn không hiểu thao tác truyền dữ liệu. Đoạn trên là nhân dữ liệu từ slave, vậy nếu em muốn gửi dữ liệu, em cần viết vào SPIxBUF, thì vẫn là viết 16 bit phải không ạ? Hay là em phải dùng lệnh mov.b? (Em đang tập viết bằng hợp ngữ)

Em cảm ơn anh nhiều ạ.
trangham283 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 29-07-2009, 12:42 PM   #5
trangham283
Nhập môn đệ tử
 
Tham gia ngày: Jul 2009
Bài gửi: 7
:
Cảm ơn bạn Serenade, rất tiếc mình đang viết chương trình bằng hợp ngữ, mình lại chưa lập trình bằng C bao giờ cả nên code bạn viết mình không hiểu lắm.

Dù sao cũng rất cảm ơn bạn!
trangham283 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 29-07-2009, 12:49 PM   #6
Serenade
Nhập môn đệ tử
 
Tham gia ngày: Oct 2008
Bài gửi: 6
:
Bắt đầu viết bằng hợp ngữ thì tốt,nhưng mình khuyên là sau này nên chuyển qua C vì những chương trình lớn viết bằng hợp ngữ không nổi đâu.
Serenade vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 29-07-2009, 12:59 PM   #7
Serenade
Nhập môn đệ tử
 
Tham gia ngày: Oct 2008
Bài gửi: 6
:
Mình sẽ nói sơ về giao tiếp spi nhé.Giao tiếp spi sử dụng chung bộ đệm truyền nhận dữ liệu,một đầu dữ liệu đẩy ra ngoài thì đồng thời đầu còn lại của bộ đệm được đưa dữ liệu vào.do đó bạn muốn nhận dữ liệu từ slave (eeprom) thì phải gửi một byte bất kỳ,còn muốn truyền dữ liệu đi thì trước hết phải đọc 1 byte dump trong vùng đệm trước khi truyền để tránh trường hợp tràn vùng đệm nhận vì bạn truyền 1 byte đi đồng nghĩ với việc bạn nhận một byte từ slave.
Serenade vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 29-07-2009, 05:51 PM   #8
namqn
Trưởng lão PIC bang
 
Tham gia ngày: Feb 2006
Nơi Cư Ngụ: Tp. HCM, Việt Nam
Bài gửi: 3,025
:
Send a message via Yahoo to namqn
Trích:
Nguyên văn bởi trangham283 View Post
Em cảm ơn anh Nam, ý anh là đoạn này ạ? Em có đọc qua tutorial này rồi, nhưng em vẫn không hiểu lắm :"> Anh có thể làm ơn giải thích thêm cho em về thao tác truyền dữ liệu sang slave được không ạ?

Có nghĩa là nếu em config giao tiếp 8-bit, sau khi SPIxSR nhận 8 bit, 8 bit này sẽ được chép vào SPIxRXB rồi sẽ cần được đọc ra để tránh tràn và mất dũ liệu?

Em xin lỗi nếu em lại đọc sót phần quan trọng :P, nhưng em vẫn không hiểu thao tác truyền dữ liệu. Đoạn trên là nhân dữ liệu từ slave, vậy nếu em muốn gửi dữ liệu, em cần viết vào SPIxBUF, thì vẫn là viết 16 bit phải không ạ? Hay là em phải dùng lệnh mov.b? (Em đang tập viết bằng hợp ngữ)

Em cảm ơn anh nhiều ạ.
Ngay dưới đoạn mà bạn vừa đưa lên là thông tin chọn cấu hình, nếu đặt bit MODE16 = 0 thì bạn sẽ dùng chế độ truyền thông 8-bit. Trong chế độ này, chỉ có 8 bit được dịch ra chân SDO, và 8 bit được dịch vào chân SDI.

Bạn ghi bao nhiêu bit vào SPIxBUF thì cũng chỉ có 8 bit thấp nhất được gửi sang slave khi chọn MODE16 = 0, và cũng chỉ có 8 bit thấp nhất là dữ liệu thực sự nhận được từ slave trong trường hợp này. Không nhất thiết phải dùng lệnh mov.b để lọc 8 bit dữ liệu nhận được từ slave, nhưng đó là một cách tốt.

Thân,
__________________
Biển học mênh mông, sức người có hạn.

Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau:
http://www.picvietnam.com/forum/showthread.php?t=1263
namqn vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 30-07-2009, 02:26 AM   #9
trangham283
Nhập môn đệ tử
 
Tham gia ngày: Jul 2009
Bài gửi: 7
:
Cảm ơn mọi người đã giúp mình trả lời những câu hỏi trên. Hic hic đây là code mình viết, mình dùng UART để kiểm tra xem việc đọc/viết dữ liệu nhưng vẫn không thành công.

Mình trước đó đã có một code riêng để kiểm tra UART, nên mình khá chắc chắn vấn đề nằm ở cái SPI này...

Các cao thủ có thể nhìn qua code này rồi giúp em được không ạ? Cảm ơn mọi người nhiều nhiều!


Code:
;Instruction shortcuts:
.equ 	RDINS,3
.equ	WRINS,2
.equ	WRDI,4
.equ	WREN,6
.equ	RDSR,5
.equ	WRSR,1


ADDR:		.space 2				;Current Memory address
TOSEND:		.space 2
NUM:		.space 2

RDATA:		.space 2
OUTWORD:	.space 2




call	_spi_init

mov		#0xFFFF,W0
mov		W0,NUM

;WREN:
call	cslow
mov		#WREN,W0
mov		W0,OUTWORD
call	output
call	cshigh

call	cslow
mov		#WRINS,W0
mov		W0,OUTWORD
call 	output

;Write address:
mov		ADDR,W0				;MSB of address
swap	W0
mov		W0,OUTWORD
call	output

mov		ADDR,W0				;LSB of address
mov		W0,OUTWORD
call	output

;Write data
mov 	NUM,W0				;This would write only LSB
mov		W0,OUTWORD
call	output
call 	cshigh


;Polling:
poll:
call	cslow
mov		#RDSR,W0
mov		W0,OUTWORD
call	output
mov		#0x0000,W0			;Dummy send to read
mov		W0,OUTWORD
call	output
mov		RDATA,W0
and		#0x0001,W0			;Is WIP bit clear?
bra		nz,poll
call	cshigh

send:
clr		ADDR

memrd1:

call	cslow
mov		#RDINS,W0
mov		W0,OUTWORD
call	output

;Write address:
mov		ADDR,W0				;address MSB
swap	W0
mov		W0,OUTWORD
call	output

mov		ADDR,W0				;address LSB
mov		W0,OUTWORD
call	output

mov		#0x00,W0			;Dummy write to retain clock
mov		W0,OUTWORD	
call	output
call	cshigh

mov		RDATA,W0
mov		W0,TOSEND

;Send to PC via UART

call	chktr	
mov		TOSEND,W0
mov		W0,U1TXREG
swap	        W0
call	        chktr
mov		W0,U1TXREG

done:
bra		done
;..............................................................................
;Subroutine: SPI Initialization
;..............................................................................
_spi_init:
mov		#0x013E,W0			;SS not used anyway
							;SDO pin controlled by module
                                ;Communication byte-wide
				;Input sampled at middle of data output line
				;CKE = 1: Output data changes on transition from CLK active to idle
				;CKP = 0: Idle state for CLK at low level
			        ;Master enable, scale: fsck = fcy/4	= 1MHz

mov		W0,SPI1CON
bclr	SPI1STAT,#SPIROV
bset	SPI1STAT,#SPIEN
clr		ADDR						;Set first memory address to write to: 0x0000
return

;Sending instructions to EEPROM
output:
mov		OUTWORD,W8
mov		W8,SPI1BUF

chktrans:							;Is transmit buffer empty??
mov		SPI1STAT,W2
and		#0x0002,W2
bra		nz,chktrans

chkrd:
mov		SPI1STAT,W2
and		#0x0001,W2					;Is receive buffer full?
bra		z,chkrd


mov		SPI1BUF,W8					;Dump received data
mov		W8,RDATA
bclr	SPI1STAT,#SPIROV

return

cslow:
bclr	PORTB,#RB2
return

cshigh:
bset	PORTB,#RB2
return

chktr:
;Check if UART transmit buffer is full
mov		U1STA,W2
and		#0x0200,W2
bra		nz,chktr
return

thay đổi nội dung bởi: trangham283, 30-07-2009 lúc 02:28 AM. Lý do: sửa code
trangham283 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 30-07-2009, 05:21 AM   #10
trangham283
Nhập môn đệ tử
 
Tham gia ngày: Jul 2009
Bài gửi: 7
:
Update:

Hôm nay em đã kiểm tra mạch bằng máy đo dao động. Em cho hiện 4 kênh: SCK, CS, SDO và SDI.

Các kênh SCK, CS và SDO của PIC hoạt động đúng như em dự định, em có thấy các lệnh viết, đọc được dịch ra chân SDO một cách hợp lý. Tuy nhiên riêng kênh SDI thì luôn luôn 0. Điều này làm em nghĩ vấn đề nằm ở đoạn nhận lại dữ liệu từ EEPROM...

Mọi người có thể đọc qua code post ở phía trên của em rồi góp ý được không ạ?

Cảm ơn mọi người nhiều nhiều!
trangham283 vẫn chưa có mặt trong diễn đàn   Trả Lời Với Trích Dẫn
Old 30-07-2009, 09:35 AM   #11
namqn
Trưởng lão PIC bang
 
Tham gia ngày: Feb 2006
Nơi Cư Ngụ: Tp. HCM, Việt Nam
Bài gửi: 3,025
:
Send a message via Yahoo to namqn
Trích:
Nguyên văn bởi trangham283 View Post
Update:

Hôm nay em đã kiểm tra mạch bằng máy đo dao động. Em cho hiện 4 kênh: SCK, CS, SDO và SDI.

Các kênh SCK, CS và SDO của PIC hoạt động đúng như em dự định, em có thấy các lệnh viết, đọc được dịch ra chân SDO một cách hợp lý. Tuy nhiên riêng kênh SDI thì luôn luôn 0. Điều này làm em nghĩ vấn đề nằm ở đoạn nhận lại dữ liệu từ EEPROM...

Mọi người có thể đọc qua code post ở phía trên của em rồi góp ý được không ạ?

Cảm ơn mọi người nhiều nhiều!
Bạn kiểm tra lại phần cứng xem có lỗi hay không. Nếu không có lỗi phần cứng thì bạn kiểm tra lại timing của các tín hiệu để xem EEPROM có làm việc được ở tốc độ đó hay không.

Thân,
__________________
Biển học mênh mông, sức người có hạn.

Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau:
http://www.picvietnam.com/forum/showthread.php?t=1263
namqn 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à 03:13 PM.


Đượ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