![]() |
|
Tài trợ cho PIC Vietnam |
Giao tiếp USB, CAN, I2C, SPI, USART... Những giao tiếp được tích hợp trên PIC |
![]() |
|
Ðiều Chỉnh | Xếp Bài |
|
![]() |
#1 |
Nhập môn đệ tử
Tham gia ngày: Dec 2007
Bài gửi: 5
: |
Vấn đề với 18f2550 với flash spi 8Mbit
Mình đang làm giao tiếp 18f2550 với SPI flash A25L80P 8Mbit. Lần đầu ghi xuống một kí tự và đọc ngược trở lên thì dc, nhưng sang lần 2 thì không ghi được, giá trị đọc lên sai. Nguồn nuôi toàn bộ là 3.3V tuơng thích với Flash,MCU.18f2550 giao tiếp với PC thông qua uart usb có sẵn trên PIC
Code của mình //main.h Code:
#include <18F2550.h> //configure a 20MHz crystal to operate at 48MHz #fuses HS,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN //#fuses USBDIV, PLL1, CPUDIV1, PROTECT, NOCPD, noBROWNOUT,HSPLL,NOWDT,nolvp, VREGEN #use delay(clock=20000000) #include <usb_cdc.h> #include <25L80.c> void main() { char RcvUSB,Rcv; #use standard_io(A) usb_cdc_init(); usb_init(); init_ext_eeprom(); output_bit( PIN_A0, 1); erase_ext_eeprom(); output_bit( PIN_A0, 0); while(!usb_cdc_connected()) {} do { usb_task(); if (usb_enumerated()) { printf(usb_cdc_putc, "\r\nType a character : !"); RcvUSB = usb_cdc_getc(); write_ext_eeprom(1, RcvUSB); delay_ms(250); output_bit( PIN_A0, 1); delay_ms(250); output_bit( PIN_A0, 0); Rcv=read_ext_eeprom(1); usb_cdc_putc(Rcv); } } while (TRUE); } Code:
#ifndef EEPROM_SELECT #define EEPROM_SELECT PIN_B0 #define EEPROM_CLK PIN_B1 #define EEPROM_DI PIN_B2 #define EEPROM_DO PIN_B4 #endif #define EEPROM_ADDRESS int32 #define EEPROM_SIZE 1048576 void init_ext_eeprom() { output_high(EEPROM_SELECT); output_low(EEPROM_DI); output_low(EEPROM_CLK); } BOOLEAN ext_eeprom_ready() { BYTE cmd[1], i, data; cmd[0] = 0x05; //rdsr opcode output_low(EEPROM_SELECT); for(i=1; i<=8; ++i) { output_bit(EEPROM_DI, shift_left(cmd,1,0)); output_high(EEPROM_CLK); //data latches output_low(EEPROM_CLK); //back to idle } for(i=1; i<=8; ++i) { output_high(EEPROM_CLK); //data latches shift_left(&data,1,input(EEPROM_DO)); output_low(EEPROM_CLK); //back to idle } output_high(EEPROM_SELECT); return !bit_test(data, 0); } void erase_ext_eeprom() { BYTE i, wren, erase; wren = 0x06; // wren opcode erase = 0xc7; // chip erase // Wait until the eeprom is done with a previous write while(!ext_eeprom_ready()); output_low(EEPROM_SELECT); for(i=0; i<8; ++i) { output_bit(EEPROM_DI, shift_left(&wren, 1, 0)); output_high(EEPROM_CLK); // data latches output_low(EEPROM_CLK); // back to idle } output_high(EEPROM_SELECT); output_low(EEPROM_SELECT); for(i=0; i<8; ++i) { output_bit(EEPROM_DI, shift_left(&erase, 1, 0)); output_high(EEPROM_CLK); // data latches output_low(EEPROM_CLK); // back to idle } output_high(EEPROM_SELECT); delay_ms(40000); // tCE } void write_ext_eeprom(EEPROM_ADDRESS address, BYTE data) { BYTE cmd[5]; BYTE i; BYTE wren; wren=0x06; cmd[0]=data; cmd[1]=address; cmd[2]=(address>>8); cmd[3]=(address>>16); cmd[4]=0x02; // Wait until the eeprom is done with a previous write while(!ext_eeprom_ready()); output_low(EEPROM_SELECT); for(i=0; i<8; ++i) { output_bit(EEPROM_DI, shift_left(&wren,1,0)); output_high(EEPROM_CLK); output_low(EEPROM_CLK); } output_high(EEPROM_SELECT); output_low(EEPROM_SELECT); for(i=0; i<40; ++i) { output_bit(EEPROM_DI, shift_left(cmd,5,0)); output_high(EEPROM_CLK); output_low(EEPROM_CLK); } output_high(EEPROM_SELECT); } BYTE se_ext_eeprom(EEPROM_ADDRESS address) { BYTE cmd[4]; BYTE i,data; cmd[0]=address; cmd[1]=(address>>8); cmd[2]=(address>>16); cmd[3]=0xd8; // Wait until the eeprom is done with a previous write while(!ext_eeprom_ready()); output_low(EEPROM_SELECT); for(i=0; i<32; ++i) { output_bit(EEPROM_DI, shift_left(cmd,4,0)); output_high(EEPROM_CLK); output_low(EEPROM_CLK); } for(i=0; i<8; ++i) { shift_left(&data,1,input(EEPROM_DO)); output_high(EEPROM_CLK); output_low(EEPROM_CLK); } output_high(EEPROM_SELECT); return(data); } BYTE read_ext_eeprom(EEPROM_ADDRESS address) { BYTE cmd[4]; BYTE i,data; cmd[0]=address; cmd[1]=(address>>8); cmd[2]=(address>>16); cmd[3]=0x03; // Wait until the eeprom is done with a previous write while(!ext_eeprom_ready()); output_low(EEPROM_SELECT); for(i=0; i<32; ++i) { output_bit(EEPROM_DI, shift_left(cmd,4,0)); output_high(EEPROM_CLK); output_low(EEPROM_CLK); } for(i=0; i<8; ++i) { shift_left(&data,1,input(EEPROM_DO)); output_high(EEPROM_CLK); output_low(EEPROM_CLK); } output_high(EEPROM_SELECT); return(data); } http://www.amictechnology.com/pdf/A25L80P.pdf Thanks |
![]() |
![]() |
![]() |
#2 |
Đệ tử 2 túi
Tham gia ngày: Jul 2005
Bài gửi: 35
: |
Bạn thử dùng mạch nạp để kiểm tra thử eeprom có die không?
Xem lại datasheet của eeprom,chú ý thời gian lên và xuống của các xung để hiệu chỉnh các xung lập trình phù hợp. Chúc bạn thành công. |
![]() |
![]() |
![]() |
|
|