完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
你好,我一直在研究使用SPI在PIC18F87J94和来自ST公司的外部EEPROM模块M95M02-DRMN6TP之间进行通信。我能够在逻辑分析仪和示波器上看到SPI通信,但是由于某些原因,我不能在PIC中得到代码来读取其值。NEED的EEPROM。当BF标志变为真时,SSP1BUF上的值总是0x00。PIC数据表指定SDI/MISO的三态由外围设备管理,因此在下面的代码中,我省略了设置TRIS寄存器。我的经验是,设置TRIS寄存器使得SSP1BUF寄存器总是读取0xFF,而清除寄存器使得它总是读取0x00。有没有可能错过一些显而易见的问题?我觉得我失去了一些小东西,但是很重要。
以上来自于百度翻译 以下为原文 Hello, I've been working on using SPI to communicate between a PIC18F87J94 and an external EEPROM module from ST, the M95M02-DRMN6TP. I've been able to see the SPI communication on a logic analyzer and on an oscilloscope, but for some reason, I can't get the code in the PIC to read the value being sent by the EEPROM. The value on SSP1BUF is always 0x00 when the BF flag becomes true. The PIC datasheet specifies that SDI/MISO's tristate is managed by the peripheral, so in the code below I've omitted setting the TRIS register. My experience has been that setting the TRIS register is causing the SSP1BUF register to always read 0xFF, and clearing the register causes it to always read 0x00. I've included a sample code file which exhibits the problem and is very closely based on my actual code. Is there any chance I'm missing something obvious that would cause this issue? I feel like I'm missing something small, but important. /* * File: main.c * Author: sysadmin * * Created on January 4, 2017, 9:25 PM */ #pragma config STVREN = ON // Stack Overflow/Underflow Reset (Enabled) #pragma config XINST = OFF // Extended Instruction Set (Disabled) #pragma config BOREN = ON // Brown-Out Reset Enable (Controlled with SBOREN bit, disabled in Deep Sleep) #pragma config BORV = 0 // Brown-out Reset Voltage (2.0V) #pragma config CP0 = OFF // Code Protect (Program memory is not code-protected) #pragma config FOSC = FRCPLL // Oscillator (Fast RC Oscillator with PLL module (FRCPLL)) #pragma config SOSCSEL = LOW // T1OSC/SOSC Power Selection Bits (Low Power T1OSC/SOSC circuit selected) #pragma config CLKOEN = OFF // Clock Out Enable Bit (CLKO output disabled on the RA6 pin) #pragma config IESO = OFF // Internal External Oscillator Switch Over Mode (Disabled) #pragma config PLLDIV = NODIV // PLL Frequency Multiplier Select bits (96 MHz PLL selected; No divide - Oscillator used directly (4 MHz input)) #pragma config POSCMD = NONE // Primary Oscillator Select (Primary oscillator disabled) #pragma config FSCM = CSECMD // Clock Switching and Monitor Selection Configuration bits (Clock switching is enabled, fail safe clock monitor is disabled) #pragma config WPFP = WPFP255 // Write/Erase Protect Page Start/End Boundary (Write Protect Program Flash Page 255) #pragma config WPDIS = WPDIS // Segment Write Protection Disable (Disabled) #pragma config WPEND = WPENDMEM // Segment Write Protection End Page Select (Write Protect from WPFP to the last page of memory) #pragma config WPCFG = WPCFGDIS // Write Protect Configuration Page Select (Disabled) #pragma config T5GSEL = T5G // TMR5 Gate Select bit (TMR5 Gate is driven by the T5G input) #pragma config CINASEL = DEFAULT// CxINA Gate Select bit (C1INA and C3INA are on their default pin locations) #pragma config EASHFT = ON // External Address Shift bit (Address Shifting enabled) #pragma config ABW = MM // Address Bus Width Select bits (8-bit address bus) #pragma config BW = 16 // Data Bus Width (16-bit external bus mode) #pragma config WAIT = OFF // External Bus Wait (Disabled) #pragma config IOL1WAY = OFF // IOLOCK One-Way Set Enable bit (the IOLOCK bit can be set and cleared using the unlock sequence) #pragma config LS48MHZ = SYSX2 // USB Low Speed Clock Select bit (Divide-by-2 (System clock must be 12 MHz)) #pragma config MSSPMSK2 = MSK7 // MSSP2 7-Bit Address Masking Mode Enable bit (7 Bit address masking mode) #pragma config MSSPMSK1 = MSK7 // MSSP1 7-Bit Address Masking Mode Enable bit (7 Bit address masking mode) #pragma config WDTWIN = PS25_0 // Watch Dog Timer Window (Watch Dog Timer Window Width is 25 percent) #pragma config WDTCLK = LPRC // Watch Dog Timer Clock Source (Always use INTOSC/LPRC) #pragma config WDTPS = 32768 // Watchdog Timer Postscale (1:32768) #pragma config WDTEN = OFF // Watchdog Timer Disabled; SWDTEN can control WDT #pragma config WINDIS = WDTSTD // Windowed Watchdog Timer Disable (Standard WDT selected; windowed WDT disabled) #pragma config WPSA = 128 // WDT Prescaler (WDT prescaler ratio of 1:128) #pragma config RETEN = OFF // Retention Voltage Regulator Control Enable (Retention not available) #pragma config VBTBOR = OFF // VBAT BOR Enable (VBAT BOR is disabled) #pragma config DSBOREN = OFF // Deep Sleep BOR Enable (BOR enabled in Deep Sleep) #pragma config DSBITEN = ON // DSEN Bit Enable bit (Deep Sleep is controlled by the register bit DSEN) #pragma config DSWDTPS = DSWDTPS1F// Deep Sleep Watchdog Timer Postscale Select (1:68719476736 (25.7 Days)) #pragma config DSWDTEN = OFF // Deep Sleep Watchdog Timer Enable (DSWDT Enabled) #pragma config DSWDTOSC = LPRC // DSWDT Reference Clock Select (DSWDT uses LPRC as reference clock) // #pragma config statements should precede project file includes. // Use project enums instead of #define for ON and OFF. #include #include #include #define EEPROM_SS (LATBbits.LATB0) uint8_t dummy; void main(void) { ACTCON = 0x90; while (OSCCON2bits.LOCK == 0); LATA = 0x0; LATB = 0x0; LATC = 0x0; LATD = 0x0; LATE = 0x0; LATF = 0x0; LATG = 0x0; LATH = 0x0; LATJ = 0x0; ANCON1 = 0x00; ANCON2 = 0x00; ANCON3 = 0x00; TRISA = 0x00; TRISB = 0x00; TRISC = 0x00; TRISD = 0x00; TRISE = 0x00; TRISF = 0x00; TRISG = 0x00; TRISH = 0x00; INTCON2bits.RBPU = 1; WPUB = 0xFF; PADCFG1 = 0x00; MEMCONbits.EBDIS = 1; ODCON1bits.SSP1OD = 0; LATBbits.LATB0 = 1; EEPROM_SS = 1; //Initialize to high for inactive //Configure PPS-Lite OSCCON2bits.IOLOCK = 0; //Unlock PPS-Lite RPOR8_9bits.RPO9R = 0x4; //SDO1 -> RP9 RPINR8_9bits.SDI1R = 0x6; //SDI -> RP24 RPOR22_23bits.RPO23R = 0x3; //SCK -> RP23 RPINR10_11bits.SS1R = 0x9; //Set SS to RP14 to get rid of it OSCCON2bits.IOLOCK = 1; //Lock PPS-Lite PMD1bits.SSP1MD = 0; SSP1CON1bits.CKP = 0; //Clock idle low SSP1STATbits.CKE = 0; //Transmit on Idle->Active SSP1STATbits.SMP = 0; //Sample at middle of TX time SSP1CON1bits.SSPM = 0b0010; // Fosc/64 SSP1CON1bits.SSPEN = 1; dummy = SSP1BUF; //Dump the data in buffer, if any. while (1) { //Read the status EEPROM_SS = 0; SSP1BUF = 5; while (SSP1STATbits.BF == 0); dummy = SSP1BUF; SSP1BUF = 255; while (SSP1STATbits.BF == 0); dummy = SSP1BUF; EEPROM_SS = 1; //This EEPROM seems to like a short quiet period with SS High. for (uint8_t i = 0; i < 3; i++); //Enable Writes EEPROM_SS = 0; SSP1BUF = 6; while (SSP1STATbits.BF == 0); dummy = SSP1BUF; EEPROM_SS = 1; //This EEPROM seems to like a short quiet period with SS High. for (uint8_t i = 0; i < 3; i++); //Read the status EEPROM_SS = 0; SSP1BUF = 5; while (SSP1STATbits.BF == 0); dummy = SSP1BUF; SSP1BUF = 255; while (SSP1STATbits.BF == 0); dummy = SSP1BUF; EEPROM_SS = 1; for (uint8_t i = 0; i < 3; i++); } } |
|
相关推荐
4个回答
|
|
如果BF正在设定,那么你的时钟信号就没问题了。我用一大块盐把它设定为输入,这不会有什么坏处,所以我无论如何都会这么做。如果改变TRIS位有影响,那么数据表显然是错误的。不要包括pic18f87j94.h已经为您完成了,所以这样做两次,如果换设备,就会出错。不要试图用for()循环创建自己的延迟,优化器会出错。使用内置的_u._us()宏。如何检查读取的值?这段代码中从来不使用“dummy”变量。如果在调试器下运行,请在变量声明中添加“volatile”限定符,以确保优化器不会丢弃对它的写入。(编辑:修正了“SSPUFF1”到“SSP1BUF”)
以上来自于百度翻译 以下为原文 If BF is getting set, then your clock signal is ok. I'd take that with a big grain of salt. It can't hurt to set it as an input, so I'd do it anyway. If changing the TRIS bit has an effect, then the datasheet is plainly wrong. #include #include #include Don't include pic18f87j94.h Including xc.h has already done that for you, so you're doing it twice, and it will trip you up if you change devices. //This EEPROM seems to like a short quiet period with SS High. for (uint8_t i = 0; i < 3; i++); Don't try to create your own delays with for() loops, the optimiser will trip you up. Use the built in __delay_us() macro. How are you checking the value that was read? The "dummy" variable is never used in this code. If you are running under a debugger, add a "volatile" qualifier to the variable declaration to make sure the optimiser doesn't discard writes to it. n.b. Do not run this under the debugger with the SSP1BUF register in the watch window! (Edit: corrected "SSPBUF1" to "SSP1BUF") |
|
|
|
你好,我正在附加SPI.C和SPI. H。它非常适合于PIC18F设备,希望这能帮助您……SPI设备,PIC18F设备SPI CS<----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------但下面对你有帮助。V= TF2SFSM6FQGOPE它帮助你——TS9
以上来自于百度翻译 以下为原文 Hi, I am attaching SPI.c and SPI.h . It perfectly works at my end for PIC18F device . Hope this helps you... SPI Device PIC18F Device SPI CS <--------- SPI CS SCK <--------- SCK SPI_OUT ---------> SPI_IN (4.7 K Pullup ) SPI_IN <--------- SPI_OUT For PPS I don't have idea ... But Below is helpful for you. https://www.youtube.com/watch?v=tf2SfSm6fQg Hope it helps you -- TS9 Attachment(s) spi.zip (0.80 KB) - downloaded 16 times |
|
|
|
是的,从我的经验来看,在PIC18S中,你不需要对SCK信号进行双重映射…
以上来自于百度翻译 以下为原文 Yeah, from my experience, in PIC18s you had no need to double-map the SCK signal... |
|
|
|
我实施了一些建议以及一些其他提到的变化。(使用_u._us,volatile关键字,将SSP1BUF保留在Watch窗口之外)。我还添加了SCK1的映射作为输入。双映射SCK1信号似乎没有影响。设置TRIS寄存器仍然产生0xFF,而清除寄存器则产生0x00。我修改了下面的代码,以便能够使用逻辑分析器捕获通信,并且仍然能够确定读取了非零、非255值。我还包括了逻辑分析器的屏幕截图,确认SDI行正在修改。如果需要的话,我可以提供屏幕截图。
以上来自于百度翻译 以下为原文 I implemented some of the suggestions as well as a few other changes mentioned. (using __delay_us, volatile keyword, keep SSP1BUF out of Watch window). I've added the mapping for SCK1 as an Input as well. Double-mapping the SCK1 signal did not seem to have an affect. Setting the TRIS register is still yielding 0xFF, and clearing the register yields 0x00. I modified the code below so that I can capture the communication using a logic analyzer and still be able to determine that a non-zero, non-255 value was read. I've also included a screen capture of my logic analyzer confirming that the SDI line is being modified. I can provide oscope screenshots if needed as well. /* * File: main.c * Author: sysadmin * * Created on January 4, 2017, 9:25 PM */ #pragma config STVREN = ON // Stack Overflow/Underflow Reset (Enabled) #pragma config XINST = OFF // Extended Instruction Set (Disabled) #pragma config BOREN = ON // Brown-Out Reset Enable (Controlled with SBOREN bit, disabled in Deep Sleep) #pragma config BORV = 0 // Brown-out Reset Voltage (2.0V) #pragma config CP0 = OFF // Code Protect (Program memory is not code-protected) #pragma config FOSC = FRCPLL // Oscillator (Fast RC Oscillator with PLL module (FRCPLL)) #pragma config SOSCSEL = LOW // T1OSC/SOSC Power Selection Bits (Low Power T1OSC/SOSC circuit selected) #pragma config CLKOEN = OFF // Clock Out Enable Bit (CLKO output disabled on the RA6 pin) #pragma config IESO = OFF // Internal External Oscillator Switch Over Mode (Disabled) #pragma config PLLDIV = NODIV // PLL Frequency Multiplier Select bits (96 MHz PLL selected; No divide - Oscillator used directly (4 MHz input)) #pragma config POSCMD = NONE // Primary Oscillator Select (Primary oscillator disabled) #pragma config FSCM = CSECMD // Clock Switching and Monitor Selection Configuration bits (Clock switching is enabled, fail safe clock monitor is disabled) #pragma config WPFP = WPFP255 // Write/Erase Protect Page Start/End Boundary (Write Protect Program Flash Page 255) #pragma config WPDIS = WPDIS // Segment Write Protection Disable (Disabled) #pragma config WPEND = WPENDMEM // Segment Write Protection End Page Select (Write Protect from WPFP to the last page of memory) #pragma config WPCFG = WPCFGDIS // Write Protect Configuration Page Select (Disabled) #pragma config T5GSEL = T5G // TMR5 Gate Select bit (TMR5 Gate is driven by the T5G input) #pragma config CINASEL = DEFAULT// CxINA Gate Select bit (C1INA and C3INA are on their default pin locations) #pragma config EASHFT = ON // External Address Shift bit (Address Shifting enabled) #pragma config ABW = MM // Address Bus Width Select bits (8-bit address bus) #pragma config BW = 16 // Data Bus Width (16-bit external bus mode) #pragma config WAIT = OFF // External Bus Wait (Disabled) #pragma config IOL1WAY = OFF // IOLOCK One-Way Set Enable bit (the IOLOCK bit can be set and cleared using the unlock sequence) #pragma config LS48MHZ = SYSX2 // USB Low Speed Clock Select bit (Divide-by-2 (System clock must be 12 MHz)) #pragma config MSSPMSK2 = MSK7 // MSSP2 7-Bit Address Masking Mode Enable bit (7 Bit address masking mode) #pragma config MSSPMSK1 = MSK7 // MSSP1 7-Bit Address Masking Mode Enable bit (7 Bit address masking mode) #pragma config WDTWIN = PS25_0 // Watch Dog Timer Window (Watch Dog Timer Window Width is 25 percent) #pragma config WDTCLK = LPRC // Watch Dog Timer Clock Source (Always use INTOSC/LPRC) #pragma config WDTPS = 32768 // Watchdog Timer Postscale (1:32768) #pragma config WDTEN = OFF // Watchdog Timer Disabled; SWDTEN can control WDT #pragma config WINDIS = WDTSTD // Windowed Watchdog Timer Disable (Standard WDT selected; windowed WDT disabled) #pragma config WPSA = 128 // WDT Prescaler (WDT prescaler ratio of 1:128) #pragma config RETEN = OFF // Retention Voltage Regulator Control Enable (Retention not available) #pragma config VBTBOR = OFF // VBAT BOR Enable (VBAT BOR is disabled) #pragma config DSBOREN = OFF // Deep Sleep BOR Enable (BOR enabled in Deep Sleep) #pragma config DSBITEN = ON // DSEN Bit Enable bit (Deep Sleep is controlled by the register bit DSEN) #pragma config DSWDTPS = DSWDTPS1F// Deep Sleep Watchdog Timer Postscale Select (1:68719476736 (25.7 Days)) #pragma config DSWDTEN = OFF // Deep Sleep Watchdog Timer Enable (DSWDT Enabled) #pragma config DSWDTOSC = LPRC // DSWDT Reference Clock Select (DSWDT uses LPRC as reference clock) // #pragma config statements should precede project file includes. // Use project enums instead of #define for ON and OFF. #include #include #define _XTAL_FREQ 64000000 #define EEPROM_SS (LATBbits.LATB0) volatile uint8_t dummy; void main(void) { ACTCON = 0x90; while (OSCCON2bits.LOCK == 0); LATA = 0x0; LATB = 0x0; LATC = 0x0; LATD = 0x0; LATE = 0x0; LATF = 0x0; LATG = 0x0; LATH = 0x0; LATJ = 0x0; ANCON1 = 0x00; ANCON2 = 0x00; ANCON3 = 0x00; TRISA = 0x00; TRISB = 0x00; TRISC = 0x00; TRISD = 0x00; TRISE = 0x00; TRISF = 0x00; TRISG = 0x00; TRISH = 0x00; INTCON2bits.RBPU = 1; WPUB = 0xFF; PADCFG1 = 0x00; MEMCONbits.EBDIS = 1; ODCON1bits.SSP1OD = 0; EEPROM_SS = 1; //Initialize to high for inactive //Configure PPS-Lite EECON2 = 0x55; EECON2 = 0xAA; OSCCON2bits.IOLOCK = 0; //Unlock PPS-Lite RPOR8_9bits.RPO9R = 0x4; //SDO1 -> RP9 RPINR8_9bits.SDI1R = 0x6; //SDI -> RP24 RPOR22_23bits.RPO23R = 0x3; //SCK -> RP23 RPINR8_9bits.SCK1R = 0x5; RPINR10_11bits.SS1R = 0x9; //Set SS to RP14 to get rid of it EECON2 = 0x55; EECON2 = 0xAA; OSCCON2bits.IOLOCK = 1; //Lock PPS-Lite PMD1bits.SSP1MD = 0; SSP1CON1bits.CKP = 0; //Clock idle low SSP1STATbits.CKE = 0; //Transmit on Idle->Active SSP1STATbits.SMP = 0; //Sample at middle of TX time SSP1CON1bits.SSPM = 0b0010; // Fosc/64 //TRISDbits.TRISD4 = 1; SSP1CON1bits.SSPEN = 1; dummy = SSP1BUF; //Dump the data in buffer, if any. __delay_ms(1000); while (1) { //Read the status EEPROM_SS = 0; dummy = 100; __delay_us(1); SSP1BUF = 5; while (SSP1STATbits.BF == 0); dummy = SSP1BUF; SSP1BUF = 255; while (SSP1STATbits.BF == 0); dummy = SSP1BUF; EEPROM_SS = 1; //This EEPROM seems to like a short quiet period with SS High. __delay_us(50); if (dummy == 0 || dummy == 255) { //Enable Writes EEPROM_SS = 0; __delay_us(1); SSP1BUF = 6; while (SSP1STATbits.BF == 0); dummy = SSP1BUF; EEPROM_SS = 1; //This EEPROM seems to like a short quiet period with SS High. __delay_us(50); //Read the status EEPROM_SS = 0; __delay_us(1); SSP1BUF = 5; while (SSP1STATbits.BF == 0); dummy = SSP1BUF; SSP1BUF = 255; while (SSP1STATbits.BF == 0); dummy = SSP1BUF; EEPROM_SS = 1; __delay_us(50); } } while (1); } Attached Image(s) |
|
|
|
只有小组成员才能发言,加入小组>>
5198 浏览 9 评论
2016 浏览 8 评论
1940 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3188 浏览 3 评论
请问电源和晶体值之间有什么关系吗?PIC在正常条件下运行4MHz需要多少电压?
2243 浏览 5 评论
753浏览 1评论
640浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
542浏览 1评论
PIC Kit3出现目标设备ID(00000000)与预期的设备ID(02c20000)不匹配。是什么原因
652浏览 0评论
552浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-3 22:01 , Processed in 1.285791 second(s), Total 84, Slave 67 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号