程序如下所示,请问这个程序是什么时候产生中断的,怎么从main的空循环里跳出到中断服务子程序的,谢谢?
//########################################################################### // //! \addtogroup f2803x_example_list //! <h1>SPI Digital Loop Back with Interrupts(spi_loopback_interrupts)</h1> //! //! This program uses the internal loop back test mode of the peripheral. //! Other then boot mode pin configuration, no other hardware configuration //! is required. Both interrupts and the SPI FIFOs are used. //! //! A stream of data is sent and then compared to the received stream. //! The sent data looks like this: \n //! 0000 0001 \n //! 0001 0002 \n //! 0002 0003 \n //! .... \n //! FFFE FFFF \n //! FFFF 0000 \n //! etc.. \n //! This pattern is repeated forever. //! //! \b Watch \b Variables \n //! - \b sdata , Data to send //! - \b rdata , Received data //! - \b rdata_point , Used to keep track of the last position in //!the receive stream for error checking // //########################################################################### // $TI Release: F2803x C/C++ Header Files and Peripheral Examples V127 $ // $Release Date: March 30, 2013 $ //########################################################################### #include "DSP28x_Project.h"// Device Headerfile and Examples Include File // Prototype statements for functions found within this file. // interrupt void ISRTimer2(void); __interrupt void spiTxFifoIsr(void); __interrupt void spiRxFifoIsr(void); void delay_loop(void); void spi_fifo_init(void); void error(); Uint16 sdata[2];// Send data buffer Uint16 rdata[2];// Receive data buffer Uint16 rdata_point; // Keep track of where we are// in the data stream to check received data void main(void) {Uint16 i; // Step 1. Initialize System Control: // PLL, WatchDog, enable Peripheral Clocks // This example function is found in the DSP2803x_SysCtrl.c file.InitSysCtrl(); // Step 2. Initalize GPIO: // This example function is found in the DSP2803x_Gpio.c file and // illustrates how to set the GPIO to it's default state. // InitGpio(); // Skipped for this example // Setup only the GP I/O only for SPI-A functionalityInitSpiaGpio(); // Step 3. Initialize PIE vector table: // Disable and clear all CPU interruptsDINT;IER = 0x0000;IFR = 0x0000; // Initialize PIE control registers to their default state: // This function is found in the DSP2803x_PieCtrl.c file.InitPieCtrl(); // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // This will populate the entire table, even if the interrupt // is not used in this example. This is useful for debug purposes. // The shell ISR routines are found in DSP2803x_DefaultIsr.c. // This function is found in DSP2803x_PieVect.c.InitPieVectTable(); // Interrupts that are used in this example are re-mapped to // ISR functions found within this file.EALLOW; // This is needed to write to EALLOW protected registersPieVectTable.SPIRXINTA = &spiRxFifoIsr;PieVectTable.SPITXINTA = &spiTxFifoIsr;EDIS;// This is needed to disable write to EALLOW protected registers // Step 4. Initialize all the Device Peripherals: // This function is found in DSP2803x_InitPeripherals.c // InitPeripherals(); // Not required for this examplespi_fifo_init();// Initialize the SPI only // Step 5. User specific code, enable interrupts: // Initalize the send data bufferfor(i=0; i<2; i++){sdata[i] = i;}rdata_point = 0; // Enable interrupts required for this examplePieCtrlRegs.PIECTRL.bit.ENPIE = 1;// Enable the PIE blockPieCtrlRegs.PIEIER6.bit.INTx1=1;// Enable PIE Group 6, INT 1PieCtrlRegs.PIEIER6.bit.INTx2=1;// Enable PIE Group 6, INT 2IER=0x20;// Enable CPU INT6EINT;// Enable Global Interrupts // Step 6. IDLE loop. Just sit and loop forever (optional):for(;;); } // Some Useful local functions void delay_loop() {longi;for (i = 0; i < 1000000; i++) {} } void error(void) {__asm("ESTOP0"); //Test failed!! Stop!for (;;); } void spi_fifo_init() { // Initialize SPI FIFO registersSpiaRegs.SPICCR.bit.SPISWRESET=0; // Reset SPISpiaRegs.SPICCR.all=0x001F;//16-bit character, Loopback modeSpiaRegs.SPICTL.all=0x0017;//Interrupt enabled, Master/Slave XMIT enabledSpiaRegs.SPISTS.all=0x0000;SpiaRegs.SPIBRR=0x0063;// Baud rateSpiaRegs.SPIFFTX.all=0xC022;// Enable FIFO's, set TX FIFO level to 2 1100 0000 0010 0010SpiaRegs.SPIFFRX.all=0x0022;// Set RX FIFO level to 2SpiaRegs.SPIFFCT.all=0x00;SpiaRegs.SPIPRI.all=0x0010;SpiaRegs.SPICCR.bit.SPISWRESET=1; // Enable SPISpiaRegs.SPIFFTX.bit.TXFIFO=1;SpiaRegs.SPIFFRX.bit.RXFIFORESET=1; } __interrupt void spiTxFifoIsr(void) {Uint16 i;for(i=0;i<2;i++){SpiaRegs.SPITXBUF=sdata[i];// Send data} // // Increment data buffer contents by 1 for // the next transmit cycle //for(i=0;i<2;i++){sdata[i] = sdata[i] + 1;}SpiaRegs.SPIFFTX.bit.TXFFINTCLR=1; // Clear Interrupt flagPieCtrlRegs.PIEACK.all|=0x20;// Issue PIE ACK } __interrupt void spiRxFifoIsr(void) {Uint16 i;for(i=0;i<2;i++){rdata[i]=SpiaRegs.SPIRXBUF;// Read data}for(i=0;i<2;i++)// Check received data{if(rdata[i] != rdata_point+i) error();}rdata_point++;SpiaRegs.SPIFFRX.bit.RXFFOVFCLR=1; // Clear Overflow flagSpiaRegs.SPIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flagPieCtrlRegs.PIEACK.all|=0x20;// Issue PIE ack } //=========================================================================== // No more. //===========================================================================
Joey Mao:
你好,
你要明白中断的原理,中断被使能后和初始化后,根据设定的定时周期进行周期性循环,而主循环是在程序运行起来后就无限循环的。
它们在一定程度上是相互独立的。当中断周期数达到,开始执行中断程序,主循环被挂起;而中断程序执行完后主循环程序继续执行。
程序如下所示,请问这个程序是什么时候产生中断的,怎么从main的空循环里跳出到中断服务子程序的,谢谢?
//########################################################################### // //! \addtogroup f2803x_example_list //! <h1>SPI Digital Loop Back with Interrupts(spi_loopback_interrupts)</h1> //! //! This program uses the internal loop back test mode of the peripheral. //! Other then boot mode pin configuration, no other hardware configuration //! is required. Both interrupts and the SPI FIFOs are used. //! //! A stream of data is sent and then compared to the received stream. //! The sent data looks like this: \n //! 0000 0001 \n //! 0001 0002 \n //! 0002 0003 \n //! .... \n //! FFFE FFFF \n //! FFFF 0000 \n //! etc.. \n //! This pattern is repeated forever. //! //! \b Watch \b Variables \n //! - \b sdata , Data to send //! - \b rdata , Received data //! - \b rdata_point , Used to keep track of the last position in //!the receive stream for error checking // //########################################################################### // $TI Release: F2803x C/C++ Header Files and Peripheral Examples V127 $ // $Release Date: March 30, 2013 $ //########################################################################### #include "DSP28x_Project.h"// Device Headerfile and Examples Include File // Prototype statements for functions found within this file. // interrupt void ISRTimer2(void); __interrupt void spiTxFifoIsr(void); __interrupt void spiRxFifoIsr(void); void delay_loop(void); void spi_fifo_init(void); void error(); Uint16 sdata[2];// Send data buffer Uint16 rdata[2];// Receive data buffer Uint16 rdata_point; // Keep track of where we are// in the data stream to check received data void main(void) {Uint16 i; // Step 1. Initialize System Control: // PLL, WatchDog, enable Peripheral Clocks // This example function is found in the DSP2803x_SysCtrl.c file.InitSysCtrl(); // Step 2. Initalize GPIO: // This example function is found in the DSP2803x_Gpio.c file and // illustrates how to set the GPIO to it's default state. // InitGpio(); // Skipped for this example // Setup only the GP I/O only for SPI-A functionalityInitSpiaGpio(); // Step 3. Initialize PIE vector table: // Disable and clear all CPU interruptsDINT;IER = 0x0000;IFR = 0x0000; // Initialize PIE control registers to their default state: // This function is found in the DSP2803x_PieCtrl.c file.InitPieCtrl(); // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // This will populate the entire table, even if the interrupt // is not used in this example. This is useful for debug purposes. // The shell ISR routines are found in DSP2803x_DefaultIsr.c. // This function is found in DSP2803x_PieVect.c.InitPieVectTable(); // Interrupts that are used in this example are re-mapped to // ISR functions found within this file.EALLOW; // This is needed to write to EALLOW protected registersPieVectTable.SPIRXINTA = &spiRxFifoIsr;PieVectTable.SPITXINTA = &spiTxFifoIsr;EDIS;// This is needed to disable write to EALLOW protected registers // Step 4. Initialize all the Device Peripherals: // This function is found in DSP2803x_InitPeripherals.c // InitPeripherals(); // Not required for this examplespi_fifo_init();// Initialize the SPI only // Step 5. User specific code, enable interrupts: // Initalize the send data bufferfor(i=0; i<2; i++){sdata[i] = i;}rdata_point = 0; // Enable interrupts required for this examplePieCtrlRegs.PIECTRL.bit.ENPIE = 1;// Enable the PIE blockPieCtrlRegs.PIEIER6.bit.INTx1=1;// Enable PIE Group 6, INT 1PieCtrlRegs.PIEIER6.bit.INTx2=1;// Enable PIE Group 6, INT 2IER=0x20;// Enable CPU INT6EINT;// Enable Global Interrupts // Step 6. IDLE loop. Just sit and loop forever (optional):for(;;); } // Some Useful local functions void delay_loop() {longi;for (i = 0; i < 1000000; i++) {} } void error(void) {__asm("ESTOP0"); //Test failed!! Stop!for (;;); } void spi_fifo_init() { // Initialize SPI FIFO registersSpiaRegs.SPICCR.bit.SPISWRESET=0; // Reset SPISpiaRegs.SPICCR.all=0x001F;//16-bit character, Loopback modeSpiaRegs.SPICTL.all=0x0017;//Interrupt enabled, Master/Slave XMIT enabledSpiaRegs.SPISTS.all=0x0000;SpiaRegs.SPIBRR=0x0063;// Baud rateSpiaRegs.SPIFFTX.all=0xC022;// Enable FIFO's, set TX FIFO level to 2 1100 0000 0010 0010SpiaRegs.SPIFFRX.all=0x0022;// Set RX FIFO level to 2SpiaRegs.SPIFFCT.all=0x00;SpiaRegs.SPIPRI.all=0x0010;SpiaRegs.SPICCR.bit.SPISWRESET=1; // Enable SPISpiaRegs.SPIFFTX.bit.TXFIFO=1;SpiaRegs.SPIFFRX.bit.RXFIFORESET=1; } __interrupt void spiTxFifoIsr(void) {Uint16 i;for(i=0;i<2;i++){SpiaRegs.SPITXBUF=sdata[i];// Send data} // // Increment data buffer contents by 1 for // the next transmit cycle //for(i=0;i<2;i++){sdata[i] = sdata[i] + 1;}SpiaRegs.SPIFFTX.bit.TXFFINTCLR=1; // Clear Interrupt flagPieCtrlRegs.PIEACK.all|=0x20;// Issue PIE ACK } __interrupt void spiRxFifoIsr(void) {Uint16 i;for(i=0;i<2;i++){rdata[i]=SpiaRegs.SPIRXBUF;// Read data}for(i=0;i<2;i++)// Check received data{if(rdata[i] != rdata_point+i) error();}rdata_point++;SpiaRegs.SPIFFRX.bit.RXFFOVFCLR=1; // Clear Overflow flagSpiaRegs.SPIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flagPieCtrlRegs.PIEACK.all|=0x20;// Issue PIE ack } //=========================================================================== // No more. //===========================================================================
yuan michael:
回复 Joey Mao:
Joey Mao,
你好,谢谢你的回答。
中断不应该是由某一事件触发的吗?
程序如下所示,请问这个程序是什么时候产生中断的,怎么从main的空循环里跳出到中断服务子程序的,谢谢?
//########################################################################### // //! \addtogroup f2803x_example_list //! <h1>SPI Digital Loop Back with Interrupts(spi_loopback_interrupts)</h1> //! //! This program uses the internal loop back test mode of the peripheral. //! Other then boot mode pin configuration, no other hardware configuration //! is required. Both interrupts and the SPI FIFOs are used. //! //! A stream of data is sent and then compared to the received stream. //! The sent data looks like this: \n //! 0000 0001 \n //! 0001 0002 \n //! 0002 0003 \n //! .... \n //! FFFE FFFF \n //! FFFF 0000 \n //! etc.. \n //! This pattern is repeated forever. //! //! \b Watch \b Variables \n //! - \b sdata , Data to send //! - \b rdata , Received data //! - \b rdata_point , Used to keep track of the last position in //!the receive stream for error checking // //########################################################################### // $TI Release: F2803x C/C++ Header Files and Peripheral Examples V127 $ // $Release Date: March 30, 2013 $ //########################################################################### #include "DSP28x_Project.h"// Device Headerfile and Examples Include File // Prototype statements for functions found within this file. // interrupt void ISRTimer2(void); __interrupt void spiTxFifoIsr(void); __interrupt void spiRxFifoIsr(void); void delay_loop(void); void spi_fifo_init(void); void error(); Uint16 sdata[2];// Send data buffer Uint16 rdata[2];// Receive data buffer Uint16 rdata_point; // Keep track of where we are// in the data stream to check received data void main(void) {Uint16 i; // Step 1. Initialize System Control: // PLL, WatchDog, enable Peripheral Clocks // This example function is found in the DSP2803x_SysCtrl.c file.InitSysCtrl(); // Step 2. Initalize GPIO: // This example function is found in the DSP2803x_Gpio.c file and // illustrates how to set the GPIO to it's default state. // InitGpio(); // Skipped for this example // Setup only the GP I/O only for SPI-A functionalityInitSpiaGpio(); // Step 3. Initialize PIE vector table: // Disable and clear all CPU interruptsDINT;IER = 0x0000;IFR = 0x0000; // Initialize PIE control registers to their default state: // This function is found in the DSP2803x_PieCtrl.c file.InitPieCtrl(); // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // This will populate the entire table, even if the interrupt // is not used in this example. This is useful for debug purposes. // The shell ISR routines are found in DSP2803x_DefaultIsr.c. // This function is found in DSP2803x_PieVect.c.InitPieVectTable(); // Interrupts that are used in this example are re-mapped to // ISR functions found within this file.EALLOW; // This is needed to write to EALLOW protected registersPieVectTable.SPIRXINTA = &spiRxFifoIsr;PieVectTable.SPITXINTA = &spiTxFifoIsr;EDIS;// This is needed to disable write to EALLOW protected registers // Step 4. Initialize all the Device Peripherals: // This function is found in DSP2803x_InitPeripherals.c // InitPeripherals(); // Not required for this examplespi_fifo_init();// Initialize the SPI only // Step 5. User specific code, enable interrupts: // Initalize the send data bufferfor(i=0; i<2; i++){sdata[i] = i;}rdata_point = 0; // Enable interrupts required for this examplePieCtrlRegs.PIECTRL.bit.ENPIE = 1;// Enable the PIE blockPieCtrlRegs.PIEIER6.bit.INTx1=1;// Enable PIE Group 6, INT 1PieCtrlRegs.PIEIER6.bit.INTx2=1;// Enable PIE Group 6, INT 2IER=0x20;// Enable CPU INT6EINT;// Enable Global Interrupts // Step 6. IDLE loop. Just sit and loop forever (optional):for(;;); } // Some Useful local functions void delay_loop() {longi;for (i = 0; i < 1000000; i++) {} } void error(void) {__asm("ESTOP0"); //Test failed!! Stop!for (;;); } void spi_fifo_init() { // Initialize SPI FIFO registersSpiaRegs.SPICCR.bit.SPISWRESET=0; // Reset SPISpiaRegs.SPICCR.all=0x001F;//16-bit character, Loopback modeSpiaRegs.SPICTL.all=0x0017;//Interrupt enabled, Master/Slave XMIT enabledSpiaRegs.SPISTS.all=0x0000;SpiaRegs.SPIBRR=0x0063;// Baud rateSpiaRegs.SPIFFTX.all=0xC022;// Enable FIFO's, set TX FIFO level to 2 1100 0000 0010 0010SpiaRegs.SPIFFRX.all=0x0022;// Set RX FIFO level to 2SpiaRegs.SPIFFCT.all=0x00;SpiaRegs.SPIPRI.all=0x0010;SpiaRegs.SPICCR.bit.SPISWRESET=1; // Enable SPISpiaRegs.SPIFFTX.bit.TXFIFO=1;SpiaRegs.SPIFFRX.bit.RXFIFORESET=1; } __interrupt void spiTxFifoIsr(void) {Uint16 i;for(i=0;i<2;i++){SpiaRegs.SPITXBUF=sdata[i];// Send data} // // Increment data buffer contents by 1 for // the next transmit cycle //for(i=0;i<2;i++){sdata[i] = sdata[i] + 1;}SpiaRegs.SPIFFTX.bit.TXFFINTCLR=1; // Clear Interrupt flagPieCtrlRegs.PIEACK.all|=0x20;// Issue PIE ACK } __interrupt void spiRxFifoIsr(void) {Uint16 i;for(i=0;i<2;i++){rdata[i]=SpiaRegs.SPIRXBUF;// Read data}for(i=0;i<2;i++)// Check received data{if(rdata[i] != rdata_point+i) error();}rdata_point++;SpiaRegs.SPIFFRX.bit.RXFFOVFCLR=1; // Clear Overflow flagSpiaRegs.SPIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flagPieCtrlRegs.PIEACK.all|=0x20;// Issue PIE ack } //=========================================================================== // No more. //===========================================================================
yaogang Ye:
回复 Joey Mao:
你好Joey Mao,
我其实也是对这个问题困惑很久,SPI的通讯中断时怎么通过周期性时间触发的?就拿这个例子来说,在主程序里也没有涉及到设置定时器或者故障中断啊。
程序如下所示,请问这个程序是什么时候产生中断的,怎么从main的空循环里跳出到中断服务子程序的,谢谢?
//########################################################################### // //! \addtogroup f2803x_example_list //! <h1>SPI Digital Loop Back with Interrupts(spi_loopback_interrupts)</h1> //! //! This program uses the internal loop back test mode of the peripheral. //! Other then boot mode pin configuration, no other hardware configuration //! is required. Both interrupts and the SPI FIFOs are used. //! //! A stream of data is sent and then compared to the received stream. //! The sent data looks like this: \n //! 0000 0001 \n //! 0001 0002 \n //! 0002 0003 \n //! .... \n //! FFFE FFFF \n //! FFFF 0000 \n //! etc.. \n //! This pattern is repeated forever. //! //! \b Watch \b Variables \n //! - \b sdata , Data to send //! - \b rdata , Received data //! - \b rdata_point , Used to keep track of the last position in //!the receive stream for error checking // //########################################################################### // $TI Release: F2803x C/C++ Header Files and Peripheral Examples V127 $ // $Release Date: March 30, 2013 $ //########################################################################### #include "DSP28x_Project.h"// Device Headerfile and Examples Include File // Prototype statements for functions found within this file. // interrupt void ISRTimer2(void); __interrupt void spiTxFifoIsr(void); __interrupt void spiRxFifoIsr(void); void delay_loop(void); void spi_fifo_init(void); void error(); Uint16 sdata[2];// Send data buffer Uint16 rdata[2];// Receive data buffer Uint16 rdata_point; // Keep track of where we are// in the data stream to check received data void main(void) {Uint16 i; // Step 1. Initialize System Control: // PLL, WatchDog, enable Peripheral Clocks // This example function is found in the DSP2803x_SysCtrl.c file.InitSysCtrl(); // Step 2. Initalize GPIO: // This example function is found in the DSP2803x_Gpio.c file and // illustrates how to set the GPIO to it's default state. // InitGpio(); // Skipped for this example // Setup only the GP I/O only for SPI-A functionalityInitSpiaGpio(); // Step 3. Initialize PIE vector table: // Disable and clear all CPU interruptsDINT;IER = 0x0000;IFR = 0x0000; // Initialize PIE control registers to their default state: // This function is found in the DSP2803x_PieCtrl.c file.InitPieCtrl(); // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // This will populate the entire table, even if the interrupt // is not used in this example. This is useful for debug purposes. // The shell ISR routines are found in DSP2803x_DefaultIsr.c. // This function is found in DSP2803x_PieVect.c.InitPieVectTable(); // Interrupts that are used in this example are re-mapped to // ISR functions found within this file.EALLOW; // This is needed to write to EALLOW protected registersPieVectTable.SPIRXINTA = &spiRxFifoIsr;PieVectTable.SPITXINTA = &spiTxFifoIsr;EDIS;// This is needed to disable write to EALLOW protected registers // Step 4. Initialize all the Device Peripherals: // This function is found in DSP2803x_InitPeripherals.c // InitPeripherals(); // Not required for this examplespi_fifo_init();// Initialize the SPI only // Step 5. User specific code, enable interrupts: // Initalize the send data bufferfor(i=0; i<2; i++){sdata[i] = i;}rdata_point = 0; // Enable interrupts required for this examplePieCtrlRegs.PIECTRL.bit.ENPIE = 1;// Enable the PIE blockPieCtrlRegs.PIEIER6.bit.INTx1=1;// Enable PIE Group 6, INT 1PieCtrlRegs.PIEIER6.bit.INTx2=1;// Enable PIE Group 6, INT 2IER=0x20;// Enable CPU INT6EINT;// Enable Global Interrupts // Step 6. IDLE loop. Just sit and loop forever (optional):for(;;); } // Some Useful local functions void delay_loop() {longi;for (i = 0; i < 1000000; i++) {} } void error(void) {__asm("ESTOP0"); //Test failed!! Stop!for (;;); } void spi_fifo_init() { // Initialize SPI FIFO registersSpiaRegs.SPICCR.bit.SPISWRESET=0; // Reset SPISpiaRegs.SPICCR.all=0x001F;//16-bit character, Loopback modeSpiaRegs.SPICTL.all=0x0017;//Interrupt enabled, Master/Slave XMIT enabledSpiaRegs.SPISTS.all=0x0000;SpiaRegs.SPIBRR=0x0063;// Baud rateSpiaRegs.SPIFFTX.all=0xC022;// Enable FIFO's, set TX FIFO level to 2 1100 0000 0010 0010SpiaRegs.SPIFFRX.all=0x0022;// Set RX FIFO level to 2SpiaRegs.SPIFFCT.all=0x00;SpiaRegs.SPIPRI.all=0x0010;SpiaRegs.SPICCR.bit.SPISWRESET=1; // Enable SPISpiaRegs.SPIFFTX.bit.TXFIFO=1;SpiaRegs.SPIFFRX.bit.RXFIFORESET=1; } __interrupt void spiTxFifoIsr(void) {Uint16 i;for(i=0;i<2;i++){SpiaRegs.SPITXBUF=sdata[i];// Send data} // // Increment data buffer contents by 1 for // the next transmit cycle //for(i=0;i<2;i++){sdata[i] = sdata[i] + 1;}SpiaRegs.SPIFFTX.bit.TXFFINTCLR=1; // Clear Interrupt flagPieCtrlRegs.PIEACK.all|=0x20;// Issue PIE ACK } __interrupt void spiRxFifoIsr(void) {Uint16 i;for(i=0;i<2;i++){rdata[i]=SpiaRegs.SPIRXBUF;// Read data}for(i=0;i<2;i++)// Check received data{if(rdata[i] != rdata_point+i) error();}rdata_point++;SpiaRegs.SPIFFRX.bit.RXFFOVFCLR=1; // Clear Overflow flagSpiaRegs.SPIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flagPieCtrlRegs.PIEACK.all|=0x20;// Issue PIE ack } //=========================================================================== // No more. //===========================================================================
Joey Mao:
回复 yaogang Ye:
通讯中断是根据数据的接收或发送,从而使相应的中断标志位置位,而产生中断
通讯过程中接收或发送数据会产生相应的中断,在数据传输完成之后清除中断标志位,等待下一次中断
程序如下所示,请问这个程序是什么时候产生中断的,怎么从main的空循环里跳出到中断服务子程序的,谢谢?
//########################################################################### // //! \addtogroup f2803x_example_list //! <h1>SPI Digital Loop Back with Interrupts(spi_loopback_interrupts)</h1> //! //! This program uses the internal loop back test mode of the peripheral. //! Other then boot mode pin configuration, no other hardware configuration //! is required. Both interrupts and the SPI FIFOs are used. //! //! A stream of data is sent and then compared to the received stream. //! The sent data looks like this: \n //! 0000 0001 \n //! 0001 0002 \n //! 0002 0003 \n //! .... \n //! FFFE FFFF \n //! FFFF 0000 \n //! etc.. \n //! This pattern is repeated forever. //! //! \b Watch \b Variables \n //! - \b sdata , Data to send //! - \b rdata , Received data //! - \b rdata_point , Used to keep track of the last position in //!the receive stream for error checking // //########################################################################### // $TI Release: F2803x C/C++ Header Files and Peripheral Examples V127 $ // $Release Date: March 30, 2013 $ //########################################################################### #include "DSP28x_Project.h"// Device Headerfile and Examples Include File // Prototype statements for functions found within this file. // interrupt void ISRTimer2(void); __interrupt void spiTxFifoIsr(void); __interrupt void spiRxFifoIsr(void); void delay_loop(void); void spi_fifo_init(void); void error(); Uint16 sdata[2];// Send data buffer Uint16 rdata[2];// Receive data buffer Uint16 rdata_point; // Keep track of where we are// in the data stream to check received data void main(void) {Uint16 i; // Step 1. Initialize System Control: // PLL, WatchDog, enable Peripheral Clocks // This example function is found in the DSP2803x_SysCtrl.c file.InitSysCtrl(); // Step 2. Initalize GPIO: // This example function is found in the DSP2803x_Gpio.c file and // illustrates how to set the GPIO to it's default state. // InitGpio(); // Skipped for this example // Setup only the GP I/O only for SPI-A functionalityInitSpiaGpio(); // Step 3. Initialize PIE vector table: // Disable and clear all CPU interruptsDINT;IER = 0x0000;IFR = 0x0000; // Initialize PIE control registers to their default state: // This function is found in the DSP2803x_PieCtrl.c file.InitPieCtrl(); // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // This will populate the entire table, even if the interrupt // is not used in this example. This is useful for debug purposes. // The shell ISR routines are found in DSP2803x_DefaultIsr.c. // This function is found in DSP2803x_PieVect.c.InitPieVectTable(); // Interrupts that are used in this example are re-mapped to // ISR functions found within this file.EALLOW; // This is needed to write to EALLOW protected registersPieVectTable.SPIRXINTA = &spiRxFifoIsr;PieVectTable.SPITXINTA = &spiTxFifoIsr;EDIS;// This is needed to disable write to EALLOW protected registers // Step 4. Initialize all the Device Peripherals: // This function is found in DSP2803x_InitPeripherals.c // InitPeripherals(); // Not required for this examplespi_fifo_init();// Initialize the SPI only // Step 5. User specific code, enable interrupts: // Initalize the send data bufferfor(i=0; i<2; i++){sdata[i] = i;}rdata_point = 0; // Enable interrupts required for this examplePieCtrlRegs.PIECTRL.bit.ENPIE = 1;// Enable the PIE blockPieCtrlRegs.PIEIER6.bit.INTx1=1;// Enable PIE Group 6, INT 1PieCtrlRegs.PIEIER6.bit.INTx2=1;// Enable PIE Group 6, INT 2IER=0x20;// Enable CPU INT6EINT;// Enable Global Interrupts // Step 6. IDLE loop. Just sit and loop forever (optional):for(;;); } // Some Useful local functions void delay_loop() {longi;for (i = 0; i < 1000000; i++) {} } void error(void) {__asm("ESTOP0"); //Test failed!! Stop!for (;;); } void spi_fifo_init() { // Initialize SPI FIFO registersSpiaRegs.SPICCR.bit.SPISWRESET=0; // Reset SPISpiaRegs.SPICCR.all=0x001F;//16-bit character, Loopback modeSpiaRegs.SPICTL.all=0x0017;//Interrupt enabled, Master/Slave XMIT enabledSpiaRegs.SPISTS.all=0x0000;SpiaRegs.SPIBRR=0x0063;// Baud rateSpiaRegs.SPIFFTX.all=0xC022;// Enable FIFO's, set TX FIFO level to 2 1100 0000 0010 0010SpiaRegs.SPIFFRX.all=0x0022;// Set RX FIFO level to 2SpiaRegs.SPIFFCT.all=0x00;SpiaRegs.SPIPRI.all=0x0010;SpiaRegs.SPICCR.bit.SPISWRESET=1; // Enable SPISpiaRegs.SPIFFTX.bit.TXFIFO=1;SpiaRegs.SPIFFRX.bit.RXFIFORESET=1; } __interrupt void spiTxFifoIsr(void) {Uint16 i;for(i=0;i<2;i++){SpiaRegs.SPITXBUF=sdata[i];// Send data} // // Increment data buffer contents by 1 for // the next transmit cycle //for(i=0;i<2;i++){sdata[i] = sdata[i] + 1;}SpiaRegs.SPIFFTX.bit.TXFFINTCLR=1; // Clear Interrupt flagPieCtrlRegs.PIEACK.all|=0x20;// Issue PIE ACK } __interrupt void spiRxFifoIsr(void) {Uint16 i;for(i=0;i<2;i++){rdata[i]=SpiaRegs.SPIRXBUF;// Read data}for(i=0;i<2;i++)// Check received data{if(rdata[i] != rdata_point+i) error();}rdata_point++;SpiaRegs.SPIFFRX.bit.RXFFOVFCLR=1; // Clear Overflow flagSpiaRegs.SPIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flagPieCtrlRegs.PIEACK.all|=0x20;// Issue PIE ack } //=========================================================================== // No more. //===========================================================================
yaogang Ye:
回复 Joey Mao:
但是在这个例子里,SPI的接受和发送不是在第一次中断产生后,才从主程序调到中断子程序的么?那第一次中断是怎么产生的啊?
程序如下所示,请问这个程序是什么时候产生中断的,怎么从main的空循环里跳出到中断服务子程序的,谢谢?
//########################################################################### // //! \addtogroup f2803x_example_list //! <h1>SPI Digital Loop Back with Interrupts(spi_loopback_interrupts)</h1> //! //! This program uses the internal loop back test mode of the peripheral. //! Other then boot mode pin configuration, no other hardware configuration //! is required. Both interrupts and the SPI FIFOs are used. //! //! A stream of data is sent and then compared to the received stream. //! The sent data looks like this: \n //! 0000 0001 \n //! 0001 0002 \n //! 0002 0003 \n //! .... \n //! FFFE FFFF \n //! FFFF 0000 \n //! etc.. \n //! This pattern is repeated forever. //! //! \b Watch \b Variables \n //! - \b sdata , Data to send //! - \b rdata , Received data //! - \b rdata_point , Used to keep track of the last position in //!the receive stream for error checking // //########################################################################### // $TI Release: F2803x C/C++ Header Files and Peripheral Examples V127 $ // $Release Date: March 30, 2013 $ //########################################################################### #include "DSP28x_Project.h"// Device Headerfile and Examples Include File // Prototype statements for functions found within this file. // interrupt void ISRTimer2(void); __interrupt void spiTxFifoIsr(void); __interrupt void spiRxFifoIsr(void); void delay_loop(void); void spi_fifo_init(void); void error(); Uint16 sdata[2];// Send data buffer Uint16 rdata[2];// Receive data buffer Uint16 rdata_point; // Keep track of where we are// in the data stream to check received data void main(void) {Uint16 i; // Step 1. Initialize System Control: // PLL, WatchDog, enable Peripheral Clocks // This example function is found in the DSP2803x_SysCtrl.c file.InitSysCtrl(); // Step 2. Initalize GPIO: // This example function is found in the DSP2803x_Gpio.c file and // illustrates how to set the GPIO to it's default state. // InitGpio(); // Skipped for this example // Setup only the GP I/O only for SPI-A functionalityInitSpiaGpio(); // Step 3. Initialize PIE vector table: // Disable and clear all CPU interruptsDINT;IER = 0x0000;IFR = 0x0000; // Initialize PIE control registers to their default state: // This function is found in the DSP2803x_PieCtrl.c file.InitPieCtrl(); // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // This will populate the entire table, even if the interrupt // is not used in this example. This is useful for debug purposes. // The shell ISR routines are found in DSP2803x_DefaultIsr.c. // This function is found in DSP2803x_PieVect.c.InitPieVectTable(); // Interrupts that are used in this example are re-mapped to // ISR functions found within this file.EALLOW; // This is needed to write to EALLOW protected registersPieVectTable.SPIRXINTA = &spiRxFifoIsr;PieVectTable.SPITXINTA = &spiTxFifoIsr;EDIS;// This is needed to disable write to EALLOW protected registers // Step 4. Initialize all the Device Peripherals: // This function is found in DSP2803x_InitPeripherals.c // InitPeripherals(); // Not required for this examplespi_fifo_init();// Initialize the SPI only // Step 5. User specific code, enable interrupts: // Initalize the send data bufferfor(i=0; i<2; i++){sdata[i] = i;}rdata_point = 0; // Enable interrupts required for this examplePieCtrlRegs.PIECTRL.bit.ENPIE = 1;// Enable the PIE blockPieCtrlRegs.PIEIER6.bit.INTx1=1;// Enable PIE Group 6, INT 1PieCtrlRegs.PIEIER6.bit.INTx2=1;// Enable PIE Group 6, INT 2IER=0x20;// Enable CPU INT6EINT;// Enable Global Interrupts // Step 6. IDLE loop. Just sit and loop forever (optional):for(;;); } // Some Useful local functions void delay_loop() {longi;for (i = 0; i < 1000000; i++) {} } void error(void) {__asm("ESTOP0"); //Test failed!! Stop!for (;;); } void spi_fifo_init() { // Initialize SPI FIFO registersSpiaRegs.SPICCR.bit.SPISWRESET=0; // Reset SPISpiaRegs.SPICCR.all=0x001F;//16-bit character, Loopback modeSpiaRegs.SPICTL.all=0x0017;//Interrupt enabled, Master/Slave XMIT enabledSpiaRegs.SPISTS.all=0x0000;SpiaRegs.SPIBRR=0x0063;// Baud rateSpiaRegs.SPIFFTX.all=0xC022;// Enable FIFO's, set TX FIFO level to 2 1100 0000 0010 0010SpiaRegs.SPIFFRX.all=0x0022;// Set RX FIFO level to 2SpiaRegs.SPIFFCT.all=0x00;SpiaRegs.SPIPRI.all=0x0010;SpiaRegs.SPICCR.bit.SPISWRESET=1; // Enable SPISpiaRegs.SPIFFTX.bit.TXFIFO=1;SpiaRegs.SPIFFRX.bit.RXFIFORESET=1; } __interrupt void spiTxFifoIsr(void) {Uint16 i;for(i=0;i<2;i++){SpiaRegs.SPITXBUF=sdata[i];// Send data} // // Increment data buffer contents by 1 for // the next transmit cycle //for(i=0;i<2;i++){sdata[i] = sdata[i] + 1;}SpiaRegs.SPIFFTX.bit.TXFFINTCLR=1; // Clear Interrupt flagPieCtrlRegs.PIEACK.all|=0x20;// Issue PIE ACK } __interrupt void spiRxFifoIsr(void) {Uint16 i;for(i=0;i<2;i++){rdata[i]=SpiaRegs.SPIRXBUF;// Read data}for(i=0;i<2;i++)// Check received data{if(rdata[i] != rdata_point+i) error();}rdata_point++;SpiaRegs.SPIFFRX.bit.RXFFOVFCLR=1; // Clear Overflow flagSpiaRegs.SPIFFRX.bit.RXFFINTCLR=1; // Clear Interrupt flagPieCtrlRegs.PIEACK.all|=0x20;// Issue PIE ack } //=========================================================================== // No more. //===========================================================================
Joey Mao:
回复 yaogang Ye:
中断程序是独立的,在完成相关中断初始化之后,可以说这部分就处于等待状态,如果满足中断产生的条件,即有数据接收和发送,则会产生中断