Audio PIC32MX:SPI1CON.SPIBUSY位永远不会被清除

Audio PIC32MX:SPI1CON.SPIBUSY位永远不会被清除,audio,spi,mplab,pic32,i2s,Audio,Spi,Mplab,Pic32,I2s,我试图用一个PIC32MX250F128B产生一个简单的正弦波声音,通过I2S与DAC+放大器从模块(MAX98257)通信。最终目标是为学校项目制作一个带键盘的合成器 我用MPLABX(v.5.40)创建了一个基本项目。我现在不使用Harmony或任何其他框架,我只是想有一个基本的声音生成和工作代码 代码如下: 微控制器配置位: // DEVCFG3 #pragma config USERID = 0xFFFF // Enter Hexadecimal value (Ente

我试图用一个PIC32MX250F128B产生一个简单的正弦波声音,通过I2S与DAC+放大器从模块(MAX98257)通信。最终目标是为学校项目制作一个带键盘的合成器

我用MPLABX(v.5.40)创建了一个基本项目。我现在不使用Harmony或任何其他框架,我只是想有一个基本的声音生成和工作代码

代码如下:

微控制器配置位:

// DEVCFG3
#pragma config USERID = 0xFFFF          // Enter Hexadecimal value (Enter Hexadecimal value)
#pragma config PMDL1WAY = ON            // Peripheral Module Disable Configuration (Allow only one reconfiguration)
#pragma config IOL1WAY = ON             // Peripheral Pin Select Configuration (Allow only one reconfiguration)
#pragma config FUSBIDIO = ON            // USB USID Selection (Controlled by the USB Module)
#pragma config FVBUSONIO = ON           // USB VBUS ON Selection (Controlled by USB Module)

// DEVCFG2
#pragma config FPLLIDIV = DIV_2         // PLL Input Divider (2x Divider)
#pragma config FPLLMUL = MUL_18         // PLL Multiplier (18x Multiplier)
#pragma config UPLLIDIV = DIV_12        // USB PLL Input Divider (12x Divider)
#pragma config UPLLEN = OFF             // USB PLL Enable (Disabled and Bypassed)
#pragma config FPLLODIV = DIV_1         // System PLL Output Clock Divider (PLL Divide by 1)

// DEVCFG1
#pragma config FNOSC = PRIPLL           // Oscillator Selection Bits (Primary Osc w/PLL (XT+,HS+,EC+PLL))
#pragma config FSOSCEN = ON             // Secondary Oscillator Enable (Enabled)
#pragma config IESO = ON                // Internal/External Switch Over (Enabled)
#pragma config POSCMOD = XT             // Primary Oscillator Configuration (XT osc mode)
#pragma config OSCIOFNC = OFF           // CLKO Output Signal Active on the OSCO Pin (Disabled)
#pragma config FPBDIV = DIV_2           // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/2)
#pragma config FCKSM = CSDCMD           // Clock Switching and Monitor Selection (Clock Switch Disable, FSCM Disabled)
#pragma config WDTPS = PS1048576        // Watchdog Timer Postscaler (1:1048576)
#pragma config WINDIS = OFF             // Watchdog Timer Window Enable (Watchdog Timer is in Non-Window Mode)
#pragma config FWDTEN = OFF             // Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls))
#pragma config FWDTWINSZ = WINSZ_25     // Watchdog Timer Window Size (Window Size is 25%)

// DEVCFG0
#pragma config JTAGEN = OFF             // JTAG Enable (JTAG Disabled)
#pragma config ICESEL = ICS_PGx1        // ICE/ICD Comm Channel Select (Communicate on PGEC1/PGED1)
#pragma config PWP = OFF                // Program Flash Write Protect (Disable)
#pragma config BWP = OFF                // Boot Flash Write Protect bit (Protection Disabled)
#pragma config CP = OFF                 // Code Protect (Protection Disabled)
int sineTable[4096]= { ... };

int i = 0;

void main(void) {
    RPB5R = 0b0011; //pin 14 : SDO1 (data out)
    RPA0R = 0b0011; //pin 2 : SS1 (word select)
    
    SPI1CON2bits.AUDEN = 1; //audio protocol enabled
    SPI1CON2bits.AUDMONO = 1; //MONO mode
    SPI1CON2bits.AUDMOD = 0b00; //I2S mode
    SPI1CON2bits.IGNROV = 1; // Ignore Receive Overflow bit (for Audio Data Transmissions)
    SPI1CON2bits.IGNTUR = 1; //  Ignore Transmit Underrun bit (for Audio Data Transmissions) 1 = A TUR is not a critical error and zeros are transmitted until thSPIxTXB is not empty 0 = A TUR is a critical error which stop SPI operation

    SPI1BRG = 140;
    SPI1CONbits.MSTEN = 1;
    SPI1CONbits.MCLKSEL = 0; //Clock = Fpb
    SPI1CONbits.CKP = 1; //Idle state high, active state low
    SPI1CONbits.MODE32 = 1;
    SPI1CONbits.MODE16 = 0; //32 bit
    //SPI1CONbits.STXISEL = 0b11; //quand générer l'interruption?
    SPI1CONbits.DISSDI = 1; // disable serial data in
    SPI1CONbits.ENHBUF = 1; // enable enhanced buffer
    
    SPI1CONbits.ON = 0; //ON
    SPI1CONbits.ON = 1; //ON
    
    while(1)
    {
        SPI1BUF = sineTable[i];
        while( SPI1STATbits.SPIBUSY); // wait for transfer complete
        if(i >= 4095){
            i = 0;
        }
        i++;
    } // main loop 
} 
SPI/I2S配置+代码:

// DEVCFG3
#pragma config USERID = 0xFFFF          // Enter Hexadecimal value (Enter Hexadecimal value)
#pragma config PMDL1WAY = ON            // Peripheral Module Disable Configuration (Allow only one reconfiguration)
#pragma config IOL1WAY = ON             // Peripheral Pin Select Configuration (Allow only one reconfiguration)
#pragma config FUSBIDIO = ON            // USB USID Selection (Controlled by the USB Module)
#pragma config FVBUSONIO = ON           // USB VBUS ON Selection (Controlled by USB Module)

// DEVCFG2
#pragma config FPLLIDIV = DIV_2         // PLL Input Divider (2x Divider)
#pragma config FPLLMUL = MUL_18         // PLL Multiplier (18x Multiplier)
#pragma config UPLLIDIV = DIV_12        // USB PLL Input Divider (12x Divider)
#pragma config UPLLEN = OFF             // USB PLL Enable (Disabled and Bypassed)
#pragma config FPLLODIV = DIV_1         // System PLL Output Clock Divider (PLL Divide by 1)

// DEVCFG1
#pragma config FNOSC = PRIPLL           // Oscillator Selection Bits (Primary Osc w/PLL (XT+,HS+,EC+PLL))
#pragma config FSOSCEN = ON             // Secondary Oscillator Enable (Enabled)
#pragma config IESO = ON                // Internal/External Switch Over (Enabled)
#pragma config POSCMOD = XT             // Primary Oscillator Configuration (XT osc mode)
#pragma config OSCIOFNC = OFF           // CLKO Output Signal Active on the OSCO Pin (Disabled)
#pragma config FPBDIV = DIV_2           // Peripheral Clock Divisor (Pb_Clk is Sys_Clk/2)
#pragma config FCKSM = CSDCMD           // Clock Switching and Monitor Selection (Clock Switch Disable, FSCM Disabled)
#pragma config WDTPS = PS1048576        // Watchdog Timer Postscaler (1:1048576)
#pragma config WINDIS = OFF             // Watchdog Timer Window Enable (Watchdog Timer is in Non-Window Mode)
#pragma config FWDTEN = OFF             // Watchdog Timer Enable (WDT Disabled (SWDTEN Bit Controls))
#pragma config FWDTWINSZ = WINSZ_25     // Watchdog Timer Window Size (Window Size is 25%)

// DEVCFG0
#pragma config JTAGEN = OFF             // JTAG Enable (JTAG Disabled)
#pragma config ICESEL = ICS_PGx1        // ICE/ICD Comm Channel Select (Communicate on PGEC1/PGED1)
#pragma config PWP = OFF                // Program Flash Write Protect (Disable)
#pragma config BWP = OFF                // Boot Flash Write Protect bit (Protection Disabled)
#pragma config CP = OFF                 // Code Protect (Protection Disabled)
int sineTable[4096]= { ... };

int i = 0;

void main(void) {
    RPB5R = 0b0011; //pin 14 : SDO1 (data out)
    RPA0R = 0b0011; //pin 2 : SS1 (word select)
    
    SPI1CON2bits.AUDEN = 1; //audio protocol enabled
    SPI1CON2bits.AUDMONO = 1; //MONO mode
    SPI1CON2bits.AUDMOD = 0b00; //I2S mode
    SPI1CON2bits.IGNROV = 1; // Ignore Receive Overflow bit (for Audio Data Transmissions)
    SPI1CON2bits.IGNTUR = 1; //  Ignore Transmit Underrun bit (for Audio Data Transmissions) 1 = A TUR is not a critical error and zeros are transmitted until thSPIxTXB is not empty 0 = A TUR is a critical error which stop SPI operation

    SPI1BRG = 140;
    SPI1CONbits.MSTEN = 1;
    SPI1CONbits.MCLKSEL = 0; //Clock = Fpb
    SPI1CONbits.CKP = 1; //Idle state high, active state low
    SPI1CONbits.MODE32 = 1;
    SPI1CONbits.MODE16 = 0; //32 bit
    //SPI1CONbits.STXISEL = 0b11; //quand générer l'interruption?
    SPI1CONbits.DISSDI = 1; // disable serial data in
    SPI1CONbits.ENHBUF = 1; // enable enhanced buffer
    
    SPI1CONbits.ON = 0; //ON
    SPI1CONbits.ON = 1; //ON
    
    while(1)
    {
        SPI1BUF = sineTable[i];
        while( SPI1STATbits.SPIBUSY); // wait for transfer complete
        if(i >= 4095){
            i = 0;
        }
        i++;
    } // main loop 
} 
模拟行为: 在模拟中,代码似乎工作正常,但是状态寄存器(SPI1STAT)中的所有位都是0,并且始终保持在0(包括SPIBUSY),这是奇数

目标行为: 我正在用试验板(ICSP,无开发板)上的Pickit3对PIC32进行编程。我遵循数据表中指定的PIC32MX的基本连接,并连接了DAC

我注意到:

  • SPIBUSY在我用sinetable中的第一个值填充SPI1BUF后设置
  • 我在watches窗口中没有看到缓冲区(SPI1BUF)的值发生变化,而在模拟中我看到了(但这可能是正常的idk)
  • 程序陷入while循环,因为SPIBUSY从未被清除
因此,在模拟中,它似乎工作正常,可能是因为SPI1BUSY位无论如何都不会改变(就像其他状态位一样)

对于目标,状态位似乎可以工作,但SPI1BUSY永远不会被清除

知道为什么吗?
谢谢您

再次检查FRM的Pic32 SPI。在音频模式下使用时有特殊情况