完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我有PIC24FJ256GA705,我尝试用中断来制作SPI奴隶。不幸的是,我正在努力使它工作。中断是从来没有触发的。我怀疑有一些东西我错过了设置或配置。我使用SPI3模块。为此,SPI3SS连接到PIN 12SPI3O-MOSI连接到PIN 11SPI3YMISO连接到引脚13SPI3Y-CLK连接到引脚15。这是我的配置:这是我的代码:我正在发送。SPI数据(附加屏幕截图)。我知道,从来没有调用过SPI3RX中断,因为在该函数中没有执行(“DeLyOn())宏可以)。如何使这个SPI从机工作?我错过了什么?
以上来自于百度翻译 以下为原文 I have PIC24FJ256GA705 and I'm trying to make SPI slave with interrupts. Unfortunately I'm struggling to make it work. The interrupt is never triggered. I suspect there is something I'm missing to set or configure. I use SPI3 module for this. SPI3_SS is connected to pin 12 SPI3_MOSI is connected to pin 11 SPI3_MISO is connected to pin 13 SPI3_CLK is connected to pin 15 This is my configuration: #pragma config BWRP = OFF // Boot Segment Write-Protect bit (Boot Segment may be written) #pragma config BSS = DISABLED // Boot Segment Code-Protect Level bits (No Protection (other than BWRP)) #pragma config BSEN = OFF // Boot Segment Control bit (No Boot Segment) #pragma config GWRP = OFF // General Segment Write-Protect bit (General Segment may be written) #pragma config GSS = DISABLED // General Segment Code-Protect Level bits (No Protection (other than GWRP)) #pragma config CWRP = OFF // Configuration Segment Write-Protect bit (Configuration Segment may be written) #pragma config CSS = DISABLED // Configuration Segment Code-Protect Level bits (No Protection (other than CWRP)) #pragma config AIVTDIS = OFF // Alternate Interrupt Vector Table bit (Disabled AIVT) // FBSLIM #pragma config BSLIM = 0x1FFF // Boot Segment Flash Page Address Limit bits (Boot Segment Flash page address limit) // FSIGN // FOSCSEL #pragma config FNOSC = FRCPLL // Oscillator Source Selection (Fast RC Oscillator with divide-by-N with PLL module (FRCPLL) ) //#pragma config FNOSC = FRC #pragma config PLLMODE = PLL4X // PLL Mode Selection (8x PLL selected) //#pragma config PLLMODE = PLL96DIV1 #pragma config IESO = ON // Two-speed Oscillator Start-up Enable bit (Start up device with FRC, then switch to user-selected oscillator source) // FOSC #pragma config POSCMD = NONE // Primary Oscillator Mode Select bits (Primary Oscillator disabled) #pragma config OSCIOFCN = ON // OSC2 Pin Function bit (OSC2 is general purpose digital I/O pin) #pragma config SOSCSEL = OFF // SOSC Power Selection Configuration bits (Digital (SCLKI) mode) #pragma config PLLSS = PLL_FRC // PLL Secondary Selection Configuration bit (PLL is fed by the on-chip Fast RC (FRC) oscillator) #pragma config IOL1WAY = ON // Peripheral pin select configuration bit (Allow only one reconfiguration) //#pragma config FCKSM = CSECME // Clock Switching Mode bits (Both Clock switching and Fail-safe Clock Monitor are enabled) //#pragma config FCKSM = CSECMD #pragma config FCKSM = CSECME // FWDT #pragma config WDTPS = PS32768 // Watchdog Timer Postscaler bits (1:32,768) #pragma config FWPSA = PR128 // Watchdog Timer Prescaler bit (1:128) #pragma config FWDTEN = OFF // Watchdog Timer Enable bits (WDT and SWDTEN disabled) #pragma config WINDIS = OFF // Watchdog Timer Window Enable bit (Watchdog Timer in Non-Window mode) #pragma config WDTWIN = WIN25 // Watchdog Timer Window Select bits (WDT Window is 25% of WDT period) #pragma config WDTCMX = WDTCLK // WDT MUX Source Select bits (WDT clock source is determined by the WDTCLK Configuration bits) #pragma config WDTCLK = LPRC // WDT Clock Source Select bits (WDT uses LPRC) // FPOR #pragma config BOREN = ON // Brown Out Enable bit (Brown Out Enable Bit) #pragma config LPCFG = OFF // Low power regulator control (No Retention Sleep) #pragma config DNVPEN = ENABLE // Downside Voltage Protection Enable bit (Downside protection enabled using ZPBOR when BOR is inactive) // FICD #pragma config ICS = PGD1 // ICD Communication Channel Select bits (Communicate on PGEC1 and PGED1) #pragma config JTAGEN = OFF // JTAG Enable bit (JTAG is disabled) // FDEVOPT1 #pragma config ALTCMPI = ENABLE // Alternate Comparator Input Enable bit (C1INC, C2INC, and C3INC are on their standard pin locations) #pragma config TMPRPIN = OFF // Tamper Pin Enable bit (TMPRN pin function is disabled) #pragma config SOSCHP = ON // SOSC High Power Enable bit (valid only when SOSCSEL = 1 (Enable SOSC high power mode (default)) #pragma config ALTI2C1 = ALTI2CEN This is my code: void config() { CLKDIVbits.RCDIV=0b001; CLKDIVbits.PLLEN=1; CLKDIVbits.CPDIV=0b00; OSCCONbits.NOSC=0b001; OSCCONbits.CLKLOCK=0; OSCCONbits.OSWEN=1; OSCDIVbits.DIV=0; ANSA=0; ANSB=0; ANSC=0; LED_TRIS=0; } void setupSPI() { SPI3_CLK_TRIS=1; SPI3_MOSI_TRIS=1; SPI3_MISO_TRIS=0; SPI3_SS_TRIS=1; // SPI3 slave // SPI3_MOSI = RB12 = RP12 // SPI3_SS = RB13 = RP13 // SPI3_MISO = RA10 = RP28 // SPI3_CLK = RB14 = RP14 RPINR28bits.SCK3R=14; // RP14, CLK3 RPINR28bits.SDI3R=12; // RP12, MOSI3 RPINR29bits.SS3R=13; // RP13, SS3 RPOR14bits.RP28R=23; // 23 = SDO3, MISO RPOR6bits.RP12R=0; RPOR6bits.RP13R=0; RPOR7bits.RP14R=0; SPI3CON1Lbits.SPIEN=0; _SPI3RXIP=3; IEC3bits.SPI3RXIE=1; IEC5bits.SPI3IE=1; _SPI3BUFL=0; SPI3CON1bits.DISSDO=0; SPI3CON1bits.DISSDI=0; SPI3CON1bits.DISSCK=0; SPI3CON1bits.MODE16=0; SPI3CON1Lbits.CKP=0; SPI3CON1Lbits.CKE=0; SPI3CON1Lbits.MSTEN=0; SPI3CON1Lbits.SSEN=1; SPI3CON1Lbits.SMP=0; SPI3STATLbits.SPIROV=0; SPI3CON1Lbits.SPIEN=1; _SPI3BUFL=0; } int main(void) { config(); setupSPI(); _GIE=1; while (1) {} } void __attribute__ ((interrupt, no_auto_psv)) _SPI3RXInterrupt(void) { LED_ON(); _SPI3RXIF=0; } I'm sending SPI data (attached screenshot). I know that _SPI3RXInterrupt is never called, because nothing within that function is executed ("LED_ON()" macro is OK). How to make this SPI slave work? What I am missing? Attached Image(s) |
|
相关推荐
13个回答
|
|
当使用PPS引脚时,您需要在分配之前解锁它们。请参阅数据表部分:115.4.1控制寄存器锁从我的PIC24代码中获取了一些://开锁寄存器*BuuthTiNnRead EXCONCOL(OSCCon和0xBF);/PPS寄存器分配到这里/ /锁寄存器α-BuuGuiTnIn Read EnCONCOL(OSCCon 0x40);
以上来自于百度翻译 以下为原文 When using PPS pins, you need to unlock them before assignment. See datasheet section: 11.5.4.1 Control Register Lock Grabbed this out of some of my PIC24 code: // Unlock Registers __builtin_write_OSCCONL(OSCCON & 0xbf); // PPS register assignment goes here // Lock Registers __builtin_write_OSCCONL(OSCCON | 0x40); |
|
|
|
这似乎并不是问题。以前我配置了PIC24作为SPI主机,用PPS分配,并且它工作(没有显式的解锁)。iOLoCK在默认情况下被禁用。现在我尝试在您发布时使用解锁和锁定,这没有帮助。所以我认为问题在别的地方。SPI大师被配置为SPI1。我为SPI3配置SPI从机。
以上来自于百度翻译 以下为原文 This doesn't seem to be the problem. Previously I configured this PIC24 as SPI master, with PPS assignments, and it worked (without explicit unlocking). IOLOCK is disabled by default. Now I tried to use unlocking & locking as you posted, it did not help. So I think the problem is somewhere else. SPI master was configured for SPI1. I configure SPI slave for SPI3. |
|
|
|
@ STEVLAP - PPS锁位的上电复位条件是它被解锁,这允许PPS寄存器被改变。此外,当OP的IOL1WAVE配置位设置为“on”时,锁定PPS寄存器意味着它们不能在没有重置的情况下再次解锁。我的建议是,总是将IOL1WAVE配置设置设置为0(OFF),这样您就可以根据需要频繁地解锁PPS寄存器。不过,我也建议你不要锁定PPS寄存器,直到你有一切工作,你准备把你的代码投入生产。只需将PPS解锁/锁定在代码中,直到开发过程结束,并为自己省去很多麻烦。@ CUPACABRAS,您不必解锁OSCCon寄存器的NOSC位。请参阅数据表的第9.4部分,并查看该MCU的振荡器FRM部分以获得代码示例。另外,请看XC16用户指南,说明如何使用Y-BuuthIngxxx宏来帮助实现这一点。但是,你不会看到这一点,因为配置设置会将这个默认值设为“1”,这正是你试图将其设置为的值。此外,这不应该影响你所陈述的问题。也不需要设置GIE它默认为1。实际上,作为一般注释,您设置了相当多的设置为其默认值。虽然这没有什么不对,但它也有点浪费代码空间和运行时循环。您没有为一般中断提供ISR,所以不要设置SPI3IE位,否则如果SPI外围设备出了问题,您将得到重置。注册为您正在使用的引脚作为输入-它们默认为0无论如何,我也不会打扰改变中断优先级。我发现只有在需要嵌套中断时才有必要更改默认值,这是非常罕见的。考虑到MISO线路上的可怕响应,它是否连接到可能拖下它的任何东西上?我会把一个值设置成SSPBUF(比如说0x55),这样你就可以看到它是用SCK脉冲来上下运动的,这表明外围设备已经被SS 线激活,并且设置是正确的。(我必须承认,如果你的设备完全在运行,这会让我发怒。你试过调试它吗?)你试过不使用中断并确保你确实收到了什么东西吗?苏珊
以上来自于百度翻译 以下为原文 @steverap - the power on reset condition for the PPS lock bit is that it is unlocked which allows the PPS registers to be altered. Also as the OP has the IOL1WAY config bit set to 'on', locking the PPS registers means that they cannot be unlocked again without a reset. My recommendation is that you always set the IOL1WAY config setting to 0 (off) so that you can unlock the PPS registers as often as you like. However I also recommend that you DO NOT lock the PPS registers until you have everything working and you are ready to put your code into production. Just leave the PPS unlocking/locking out of the code until near the end of the development process and save yourself a lot of trouble. @Chupacabras - you cannot update the NOSC bits of the OSCCON register without unlocking it. See Section 9.4 of the data sheet and also look at the Oscillator FRM section for this MCU for code examples. Also look at the XC16 User Guide for how to use the __builtin_xxx macros to help with this. However you would not be seeing this as the CONFIG settings would default this to '1' which is the value you are trying to set it to. Also this should not impact on your stated problem. Also you don't need to set the GIE it - it defaults to 1. In fact as a general comment, you set quite a few settings to their default values. While there is nothing wrong with this, it is also a bit of a waste of code space and runtime cycles. You have not provided an ISR for the general interrupts so don't set the SPI3IE bit or you will get a reset if something does go wrong with the SPI peripheral. I would not bother writing to the RPORx registers for the pins that you are using as inputs - they default to 0 anyway. Also I would not bother with altering the Interrupt priority. I have found it necessary to change the default only when I need nested interrupts and this is very rare. Given the horrible response on the MISO line, is that connected to anything that might be pulling it down? I would set a value into the SSPBUF (say 0x55) so that you can see that it is going up and down with the SCK pulses - this would show that the peripheral has been activated by the SS line and the setup is correct. (I must admit that this makes me winder if your device is running at all - have you tried to debug it?) Have you tried not using interrupts and making sure that you are actually receiving something? Susan |
|
|
|
苏珊,谢谢你的代码审查和评论。我很感激。我知道很多台词都是多余的。我只是不顾一切,试图添加这些线路,以确保这些值被设定好。你是正确的,信号的质量是可怕的。这是因为探针的接地不良,并且长的电线会进入电路板。MCU没有重新启动。我启动启动闪烁状态的LED。所以它在启动时闪烁,然后一直关闭。现在我把响应值改为0x55,这是一个很好的主意;我在示波器上看到了正确的响应,所以SPI模块在工作。所以这个问题被限制在中断本身,而不是触发。
以上来自于百度翻译 以下为原文 @Susan, thank you for code review and comments. I appreciate that. I know many lines are redundant. I was just desperate and tried to add those lines just to be sure the values are set ok. You are right that the quality of signals is horrible. It's because of poor probes grounding, and long wires going to breadboard. MCU is not rebooting. I put startup blinking of the status LED. So it blinks at the startup, and then is off all the time. Now I changed the response value to 0x55, that is excellent idea ;) I see correct response on oscilloscope, so the SPI module is working. So the problem is narrowed to interrupt itself, it is not triggering. Attached Image(s) |
|
|
|
假设你在启动时闪动了LED,我假设你现在使用的代码与上面发布的代码不一样。你能告诉我们整个代码(最好是一个小而完整的应用程序,显示出问题)?你能试着创建一个SPI TX ISR并启用它吗?Exchange完成后,您应该同时触发ISR。我注意到您正在使用双速启动。在这种情况下,处理器从FRC开始运行,然后缝合到指定的模式(FRCPLL,在您的情况下使用4xPLL)。我开始思考疯狂的想法,但我想知道FRC是否运行得足够长以初始化SPI外围设备,但是PLL没有足够快地启动(或根本)响应中断。我不能为我的生活看这会发生什么(除非有硬件问题)。您可以尝试打开CKO函数或将RIFCK输出映射到输出引脚T,以确保振荡器在模式切换之后正确运行,或者在您知道硬件正常工作之后,不必担心模式切换,直到苏珊正确运行。
以上来自于百度翻译 以下为原文 Given that you flash the LED on start up, I assume that the code you are now using is not the same as the code posted above. Can you show us the entire code (preferably a small but complete app that exhibits the problem)? Can you try creating a SPI Tx ISR and enabling that? You should get both ISRs triggered when the exchange is complete. I note that you are using two-speed startup. In that situation, the processor starts with the FRC running and then stitches to the specified mode (FRCPLL with a 4x PLL in your case). I'm starting to think crazy thoughts but I'm wondering if the FRC is running long enough to initialise the SPI peripheral but the PLL is not starting fast enough (or at all) to respond to the interrupt. I can't for the life of me see what this would happen (unless there was a hardware problem). You could try turning on the CLKO function or mapping the REFCLK output to an output pin t make sure that the oscillator is running correctly after the mode switch - or don't bother with the mode switch at all until after you know the hardware is functioning correctly. Susan |
|
|
|
我正在修改代码,因为我正在试验并试图解决这个问题。我换了芯片,把新的芯片放到我的板上。它的行为是一样的。所以似乎没有旧的芯片是错误的。我把更多的LED到它。LeD1一直闪烁,所以我知道MCU不是FROZEN。LID2打开上SPI3CdultDele3打开上SPI3RXBufftLeDe3接通SPI3TX中断时,我发送SPI命令从我的主人,只有LeD2灯。我有可能。被误解或未被正确配置的东西。当前完整代码:
以上来自于百度翻译 以下为原文 I am modifying code because I am experimenting and trying to figure that out. I changed chip, put new one to my board. It behaves the same. So it doesn't seem that old chip was faulty. I put some more LEDs to it. LED1 is blinking all the time, so I know MCU is not frozen. LED2 turns on on SPI3Interrupt LED3 turns on on SPI3RXInterrupt LED3 turns on on SPI3TXInterrupt When I send SPI command from my master, only LED2 lights on. I have probably something misunderstood or not configured properly. Current full code: // PIC24FJ256GA705 Configuration Bit Settings // 'C' source line config statements // FSEC #pragma config BWRP = OFF // Boot Segment Write-Protect bit (Boot Segment may be written) #pragma config BSS = DISABLED // Boot Segment Code-Protect Level bits (No Protection (other than BWRP)) #pragma config BSEN = OFF // Boot Segment Control bit (No Boot Segment) #pragma config GWRP = OFF // General Segment Write-Protect bit (General Segment may be written) #pragma config GSS = DISABLED // General Segment Code-Protect Level bits (No Protection (other than GWRP)) #pragma config CWRP = OFF // Configuration Segment Write-Protect bit (Configuration Segment may be written) #pragma config CSS = DISABLED // Configuration Segment Code-Protect Level bits (No Protection (other than CWRP)) #pragma config AIVTDIS = OFF // Alternate Interrupt Vector Table bit (Disabled AIVT) // FBSLIM #pragma config BSLIM = 0x1FFF // Boot Segment Flash Page Address Limit bits (Boot Segment Flash page address limit) // FSIGN // FOSCSEL #pragma config FNOSC = FRCPLL // Oscillator Source Selection (Fast RC Oscillator with divide-by-N with PLL module (FRCPLL) ) //#pragma config FNOSC = FRC #pragma config PLLMODE = PLL4X // PLL Mode Selection (8x PLL selected) //#pragma config PLLMODE = PLL96DIV1 #pragma config IESO = ON // Two-speed Oscillator Start-up Enable bit (Start up device with FRC, then switch to user-selected oscillator source) // FOSC #pragma config POSCMD = NONE // Primary Oscillator Mode Select bits (Primary Oscillator disabled) #pragma config OSCIOFCN = ON // OSC2 Pin Function bit (OSC2 is general purpose digital I/O pin) #pragma config SOSCSEL = OFF // SOSC Power Selection Configuration bits (Digital (SCLKI) mode) #pragma config PLLSS = PLL_FRC // PLL Secondary Selection Configuration bit (PLL is fed by the on-chip Fast RC (FRC) oscillator) #pragma config IOL1WAY = OFF // Peripheral pin select configuration bit (Allow only one reconfiguration) //#pragma config FCKSM = CSECME // Clock Switching Mode bits (Both Clock switching and Fail-safe Clock Monitor are enabled) //#pragma config FCKSM = CSECMD #pragma config FCKSM = CSECME // FWDT #pragma config WDTPS = PS32768 // Watchdog Timer Postscaler bits (1:32,768) #pragma config FWPSA = PR128 // Watchdog Timer Prescaler bit (1:128) #pragma config FWDTEN = OFF // Watchdog Timer Enable bits (WDT and SWDTEN disabled) #pragma config WINDIS = OFF // Watchdog Timer Window Enable bit (Watchdog Timer in Non-Window mode) #pragma config WDTWIN = WIN25 // Watchdog Timer Window Select bits (WDT Window is 25% of WDT period) #pragma config WDTCMX = WDTCLK // WDT MUX Source Select bits (WDT clock source is determined by the WDTCLK Configuration bits) #pragma config WDTCLK = LPRC // WDT Clock Source Select bits (WDT uses LPRC) // FPOR #pragma config BOREN = ON // Brown Out Enable bit (Brown Out Enable Bit) #pragma config LPCFG = OFF // Low power regulator control (No Retention Sleep) #pragma config DNVPEN = ENABLE // Downside Voltage Protection Enable bit (Downside protection enabled using ZPBOR when BOR is inactive) // FICD #pragma config ICS = PGD1 // ICD Communication Channel Select bits (Communicate on PGEC1 and PGED1) #pragma config JTAGEN = OFF // JTAG Enable bit (JTAG is disabled) // FDEVOPT1 #pragma config ALTCMPI = ENABLE // Alternate Comparator Input Enable bit (C1INC, C2INC, and C3INC are on their standard pin locations) #pragma config TMPRPIN = OFF // Tamper Pin Enable bit (TMPRN pin function is disabled) #pragma config SOSCHP = ON // SOSC High Power Enable bit (valid only when SOSCSEL = 1 (Enable SOSC high power mode (default)) #pragma config ALTI2C1 = ALTI2CEN // Alternate I2C pin Location (SDA1 and SCL1 on RB9 and RB8) // #pragma config statements should precede project file includes. // Use project enums instead of #define for ON and OFF. #define _XTAL_FREQ 32000000 #define FCY 16000000UL // FCY=FOSC/2 // LED 1 #define LED1_ON_TRIS TRISCbits.TRISC0 #define LED1 LATCbits.LATC0 #define LED1_ON() LED1=1 #define LED1_OFF() LED1=0 // LED 2 #define LED2_ON_TRIS TRISBbits.TRISB2 #define LED2 LATBbits.LATB2 #define LED2_ON() LED2=1 #define LED2_OFF() LED2=0 // LED 3 #define LED3_ON_TRIS TRISCbits.TRISC1 #define LED3 LATCbits.LATC1 #define LED3_ON() LED3=1 #define LED3_OFF() LED3=0 // LED 4 #define LED4_ON_TRIS TRISBbits.TRISB4 #define LED4 LATBbits.LATB4 #define LED4_ON() LED4=1 #define LED4_OFF() LED4=0 #define SPI3_CLK_TRIS TRISBbits.TRISB14 #define SPI3_MOSI_TRIS TRISBbits.TRISB12 #define SPI3_MISO_TRIS TRISAbits.TRISA10 #define SPI3_SS_TRIS TRISBbits.TRISB13 #include #include #include void config() { CLKDIVbits.RCDIV=0b001; CLKDIVbits.PLLEN=1; CLKDIVbits.CPDIV=0b00; // CLKDIVbits.DOZE=0; OSCCONbits.NOSC=0b001; OSCCONbits.CLKLOCK=0; OSCCONbits.OSWEN=1; OSCDIVbits.DIV=0; ANSA=0; ANSB=0; ANSC=0; ANSCbits.ANSC0=0; LED1_ON_TRIS=0; ANSBbits.ANSB2=0; LED2_ON_TRIS=0; ANSCbits.ANSC1=0; LED3_ON_TRIS=0; LED4_ON_TRIS=0; } void setupSPI() { ANSBbits.ANSB12=0; ANSBbits.ANSB13=0; ANSBbits.ANSB14=0; ANSB=0; ANSA=0; TRISAbits.TRISA7 = 1; TRISBbits.TRISB15 = 1; SPI3_CLK_TRIS=1; SPI3_MOSI_TRIS=1; SPI3_MISO_TRIS=0; SPI3_SS_TRIS=1; // SPI3 slave // SPI3_MOSI = RB12 = RP12 // SPI3_SS = RB13 = RP13 // SPI3_MISO = RA10 = RP28 // SPI3_CLK = RB14 = RP14 RPINR28bits.SCK3R=14; // RP14, CLK3 RPINR28bits.SDI3R=12; // RP12, MOSI3 RPINR29bits.SS3R=13; // RP13, SS3 RPOR14bits.RP28R=23; // 23 = SDO3, MISO RPOR6bits.RP12R=0; RPOR6bits.RP13R=0; RPOR7bits.RP14R=0; SPI3CON1Lbits.SPIEN=0; SPI3STATLbits.SPIROV=0; SPI3STATLbits.SPIRBF=0; SPI3STATLbits.SPIRBE=0; _SPI3RXIF=0; _SPI3TXIF=0; _SPI3IF=0; // _SPI3RXIP=3; IEC3bits.SPI3RXIE=1; IEC5bits.SPI3TXIE=1; IEC5bits.SPI3IE=1; // spi rx int //- SPIROV = 1 // new byte received but SPIxBUF full //- SPIRBF = 1 // received //- SPIRBE = 1 // manual read from SPIxBUF // spi tx int //- SPITUR = 1 // buffer has no data to transfer //- SPITBF = 1 // manual write to SPIxBUF //- SPITBE = 1 // transferred // spi int //- FRMERR = 1 // frame error //- SPIBUSY = 1 // spi active //- SRMT = 1 // no data to transmit or receive // _SPI3BUFL=0x55; SPI3CON1bits.DISSDO=0; SPI3CON1bits.DISSDI=0; SPI3CON1bits.DISSCK=0; SPI3CON1bits.MODE16=0; SPI3CON1bits.ENHBUF=0; SPI3CON1Lbits.CKP=0; SPI3CON1Lbits.CKE=0; SPI3CON1Lbits.MSTEN=0; SPI3CON1Lbits.SSEN=1; SPI3CON1Lbits.SMP=0; SPI3IMSKLbits.SPIRBEN=1; SPI3IMSKLbits.SPIRBFEN=1; SPI3IMSKLbits.SPITBEN=1; SPI3IMSKLbits.SPITBFEN=1; SPI3IMSKLbits.SPIROVEN=1; SPI3IMSKLbits.SPITUREN=1; SPI3IMSKLbits.SRMTEN=1; SPI3IMSKLbits.BUSYEN=1; SPI3IMSKLbits.FRMERREN=1; // SPI3IMSKL=0xffff; // SPI3IMSKHbits.RXWIEN=1; // SPI3IMSKHbits.TXWIEN=1; SPI3CON1Lbits.SPIEN=1; _SPI3BUFL=0x55; } int main(void) { config(); __delay_ms(100); setupSPI(); _GIE=1; __delay_ms(1000); LED1_ON(); LED2_ON(); LED3_ON(); LED4_ON(); __delay_ms(300); LED1_OFF(); LED2_OFF(); LED3_OFF(); LED4_OFF(); __delay_ms(300); // unsigned char xx=0; while (1) { LED1_ON(); __delay_ms(300); LED1_OFF(); __delay_ms(300); } } void __attribute__ ((interrupt, no_auto_psv)) _SPI3Interrupt(void) { _SPI3IF=0; LED2_ON(); return; } void __attribute__ ((interrupt, no_auto_psv)) _SPI3RXInterrupt(void) { _SPI3RXIF=0; LED3_ON(); return; } void __attribute__ ((interrupt, no_auto_psv)) _SPI3TXInterrupt(void) { _SPI3TXIF=0; LED4_ON(); } |
|
|
|
只包括“xc.h”文件而不是特定于处理器的文件。您选择IDE中的实际设备,并将其传递给XC.H,然后它包含适当的设备特定文件。在我键入这个文件时,我注意到您引用了SPI3CON1BIT.XXX(以及SPI3CON1LSP.XXX)。前一个引用应该(可能)不被允许,因为它指的是一个不存在的寄存器——应该使用“L”或“H”。这可能意味着在IDE中选择了不同的MCU,并且这两个包含文件的使用实际上允许生成坏代码。只是一个猜测,但这可能是你的问题的根源。(当然,编译器可能允许SPI3CON1BIT.XXX引用并将它们翻译成SPI3CONL1LSP.xxx,但我会有点惊讶。)下面是“上面的注释”的“中断代码”……您仍然有代码试图设置OSCCon位而不解锁它。因此,这些代码中没有一个是有效的(在“CONFIG”函数中)。但是,正如我前面所说的,只要振荡器在运行,那么这不是你的问题,但是它将需要被固定,以便你的代码按照你所期望的那样运行。你仍然有很多不必要的代码,一些“ANSB”位在“配置”和“StuppSPI”中至少被清除了3次。功能。这说明(至少对我来说)代码纪律很差——如果你以后尝试重用你的代码,它会开始做各种意想不到的事情。事实上,SPI3一般中断是指FRMRR(帧错误)、SPIXOLL(SPI外围设备正在做某事)之一。正在设置SRMT(没有挂起的操作)状态标志。我会在ISR中设置一个断点,看看它是哪一个。我猜想是SRMT,因为它指示移位寄存器是空的(即空闲),如果DEL2几乎不受影响地出现。您将需要清除ISR中的这些位,或者ISR将继续被调用。(BTW——您不需要ISR中的“返回”。编译器不会把它转换成一个ReTI指令,但这是不必要的。)我仍然会尝试确保我先交换一个没有中断的值,然后再添加中断处理。苏珊。
以上来自于百度翻译 以下为原文 Only include the "xc.h" file and not the processor-specific one. You select the actual device in the IDE and that is passed to the xc.h which then includes the proper device-specific file. As I was typing this I noticed that you refer to SPI3CON1bits.xxx (and also SPI3CON1Lbits.xxx). The former reference should (probably) not be allowed as it is referring to a register that does not exist - the 'L' or 'H' should be used. This may indicate that you have a different MCU selected in the IDE and that the use of both include files is actually allowing bad code to be generated. Just a guess but this could be the source of your problems. (Of course the compiler may actually allow the SPI3CON1bits.xxx references and translate them to SPI3CON1Lbits.xxx but I'd be a bit surprised.) The following is the 'interrupted code' for the above comment..... You still have code that tries to set OSCCON bits without unlocking it. Therefore none of that code will be effective (in the 'config' function). But, as I said before, as long as the oscillator is running then that is not your problem here but it will need to be fixed for your code to run as you expect it to. You still have a lot of unnecessary code in there - some of the ANSB bits are cleared at least 3 times in the 'config' and 'setupSPI' functions. This shows (to me at least) poor code discipline - if you were to try to reuse your code later on, it will start to do all sorts of unexpected things. The fact that the SPI3 general interrupt is triggering means that one of the FRMERR (Frame error), SPIBUSY (the SPI peripheral is doing something) or SRMT (there are no pending operations) status flags is being set. I would set a breakpoint in that ISR and see which one(s) it is. My guess would be SRMT as it indicates that the shift register is empty (i.e. idle) if the LED2 comes on almost immedately. You will need to clear these bits in your ISR or the ISR will continue to be called. (BTW - you don't need a 'return' in an ISR. It doesn't hurt as the compiler will convert it to an RETI instruction, but it is unnecessary.) I would still try to make sure that I am exchanging a value without interrupts first and then add the interrupt processing later. Susan |
|
|
|
该项目被正确配置为“PIC24FJ256GA705”。因此,我删除了“& lt;p24fj256GA705.h & gt”。你是对的,这是多余的。XC.H.G.包括它,SPI3CONL1BIT和SPI3CON1BIT是相同的。我已经把它统一到“SPI3CONL1BIT”。我已经删除了“OSCCon”的东西。我已经从中断的末尾删除了“返回;”行。没有任何这些改变对我的问题有任何影响,但是我感谢你们的评论。这个代码的质量现在不是优先考虑的,所有的冗余代码AR。在SPI3STATE发射之前,SPI3STAT看起来是这样的:SpurBe= 1SPITBF= 1其他所有的比特都是有意义的,因为发送缓冲器是在配置后正确写入的(πSPI3BUFL=0x55;)当SPI3中断被触发时(当我从M发送SPI消息时)SPAS3STAT看起来像这样:Spulbe=1SPITBF=1SPICONSTORY= 1其他所有的比特都是有意义的,SPI只是接收数据。我将努力确保数据在不中断的情况下交换。
以上来自于百度翻译 以下为原文 The project is properly configured for "PIC24FJ256GA705". So I deleted " SPI3CON1Lbits and SPI3CON1bits is the same. I have unified it to "SPI3CON1Lbits". I have removed "OSCCON" stuff. I have removed "return;" lines from the end of interrupts. None of these changes has any influence to my problem, yet I thank you for comments. The quality of this code is not the priority at this moment, all of that redundant code are just remains from experimenting, and previous code. Before SPI3Interrupt is fired, SPI3STAT looks like this: SPIRBE=1 SPITBF=1 all other bits are 0 That makes sense, because transmit buffer is being written right after config (_SPI3BUFL=0x55;) When SPI3Interrupt is fired (when I send SPI message from master), SPI3STAT looks like this: SPIRBE=1 SPITBF=1 SPIBUSY=1 all other bits are 0 That makes sense, SPI is just receiving data. I will try to make sure data is exchanging without interrupts. |
|
|
|
我通过注释这些行来禁止中断:并将主代码更改为:所有状态位看起来都很好。它们的行为与我预期的完全一样。SPI命令被正确地接收,中断被禁用。因此,问题似乎不是SPI通信本身而是中断。可能配置错误?
以上来自于百度翻译 以下为原文 I have disabled interrupts by commenting out these lines: // IEC3bits.SPI3RXIE=1; // IEC5bits.SPI3TXIE=1; // IEC5bits.SPI3IE=1; and changed main code to this: int main(void) { config(); __delay_ms(100); setupSPI(); __delay_ms(1000); LED1_ON(); LED2_ON(); LED3_ON(); LED4_ON(); __delay_ms(300); LED1_OFF(); LED2_OFF(); LED3_OFF(); LED4_OFF(); __delay_ms(300); // values of SPI3STAT here: //SPIRBE=1 //SPITBF=1 while (SPI3STATLbits.SPITBE==0) { } LED2_ON(); while (SPI3STATLbits.SPIRBF==0) { } LED3_ON(); // values of SPI3STAT here: //SRMT=1 //SPITBE=1 //SPIRBF=1 unsigned char received=0; received=_SPI3BUFL; // I received correct value here: 0b11000001 // values of SPI3STAT here: //SRMT=1 //SPIRBE=1 //SPITBE=1 while (1) { LED1_ON(); __delay_ms(300); LED1_OFF(); __delay_ms(300); } } All the status bits look OK to me. They behave exactly as I would expect. SPI command is received correctly with interrupts disabled. So, it seems that the problem is not in SPI communication itself but in interrupts. Possibly misconfigured? |
|
|
|
我发现了问题的原因。当这两个寄存器设置为1:SPI3IMSKLITS时,不触发RX中断。SpBiBix= 1;Sp3imSkList.SpBFFIN=1;当只有其中一个设置为1时触发RX中断。同样适用于TX中断。这些寄存器中只有一个可以设置为1:SPI3IMSKLBIT。SPITBEN=1;Sp3imksList.SPITBFEN=1;我不知道这背后的原因是什么,但我通过实验来理解这一点。
以上来自于百度翻译 以下为原文 I found the reason of my problem. RX interrupt is not triggered when both these registers are set to 1: SPI3IMSKLbits.SPIRBEN=1; SPI3IMSKLbits.SPIRBFEN=1; RX interrupt is triggered when only one of them is set to 1. The same apply for TX interrupt. Only one of these registers can be set to 1: SPI3IMSKLbits.SPITBEN=1; SPI3IMSKLbits.SPITBFEN=1; I don't know what's the reason behind this, but I figured this out by experimenting. |
|
|
|
为什么你要中断“缓冲满”和“缓冲空”?你确定你没有对你的想法有相反的问题,即中断不断地触发吗?
以上来自于百度翻译 以下为原文 Why did you want interrupts on both "buffer full" and "buffer empty" ? Are you sure you didn't have the opposite problem to what you thought, i.e. that interrupts were triggering continually? |
|
|
|
不,中断根本没有触发。正如我在以前的帖子中解释的那样,当我设置这两个寄存器时,中断似乎根本不会触发。我的意图不是在“缓冲满”和“缓冲空”两个方面使用中断。我只是想中断工作,所以要确保它们会被触发,我将SPI3IMSKLBIT中的所有位设置为1。我期待这会确保中断会被触发。这种奇怪的行为在PIC24F和PIC24F参考手册的SPI部分没有解释。
以上来自于百度翻译 以下为原文 No, interrupts were not triggering at all. As I explained it in previous posts. It doesn't seem right to me that when I set both those registers the interrupt won't trigger at all. My intention is not to use interrupt on both "buffer full" and "buffer empty". I just wanted to make interrupts to work, so to be sure they will get triggered I set all bits in SPI3IMSKLbits to 1. I was expecting that this will assure that interrupt will get triggered. This odd behavior is not explained in datasheet nor in SPI section of PIC24F Reference Manual. |
|
|
|
如果你认为在硅或数据表中有一个错误,那么你应该用Microchip来购买一张票。但是我确实认为用你的方式来设置这个设备(使用通用的ISR为缓冲区空和缓冲区满)不是我所认为的“正常”操作模式。-我必须承认,我很难想象一个真实的情况,这将是有用的,在其他方面更难处理。苏珊。
以上来自于百度翻译 以下为原文 If you think that there is a fault in the silicon or the data sheet then you should raise a ticket with Microchip. However I do think that setting the device up in the way you have (using the general ISR for both buffer empty and buffer full) is not what I would think of as a 'normal'operating mode - I must admit that I'm a bit hard pressed to think of a real situation where this would be useful that cannot be handled more easily in other ways. Susan |
|
|
|
只有小组成员才能发言,加入小组>>
5158 浏览 9 评论
1997 浏览 8 评论
1926 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3169 浏览 3 评论
请问电源和晶体值之间有什么关系吗?PIC在正常条件下运行4MHz需要多少电压?
2222 浏览 5 评论
723浏览 1评论
606浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
494浏览 1评论
PIC Kit3出现目标设备ID(00000000)与预期的设备ID(02c20000)不匹配。是什么原因
620浏览 0评论
519浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-19 12:18 , Processed in 1.585787 second(s), Total 102, Slave 86 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号