![]() |
|
Tài trợ cho PIC Vietnam |
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 |
![]() |
|
Ðiều Chỉnh | Xếp Bài |
![]() |
#1 |
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 ạ? |
![]() |
![]() |
![]() |
#2 | |
Trưởng lão PIC bang
|
Trích:
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 |
|
![]() |
![]() |
![]() |
#3 |
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 |
![]() |
![]() |
![]() |
#4 | |
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:
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 ạ. |
|
![]() |
![]() |
![]() |
#5 |
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! |
![]() |
![]() |
![]() |
#6 |
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.
|
![]() |
![]() |
![]() |
#7 |
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.
|
![]() |
![]() |
![]() |
#8 | |
Trưởng lão PIC bang
|
Trích:
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 |
|
![]() |
![]() |
![]() |
#9 |
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 |
![]() |
![]() |
![]() |
#10 |
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! |
![]() |
![]() |
![]() |
#11 | |
Trưởng lão PIC bang
|
Trích:
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 |
|
![]() |
![]() |
![]() |
|
|