[范例教程] 【M0】 MG32F02A 学习笔记⑩ 中断控制

[复制链接]
1391|0
 楼主| noctor 发表于 2018-10-9 10:05 | 显示全部楼层 |阅读模式
     上回我们说到了MG32F02A的SPI0通过DMA进行数据通信。帖子详情:https://bbs.21ic.com/icview-2561898-1-1.html

      但是我一直忘了讲一个非常重要的功能,中断,中断这么方便的东西我居然现在才想起来。。。行吧,那这回就讲中断吧,但是我这块EV板上没有按键,就不做按键中断了,就拿上次的SPI0标准通信的从机接收来做中断吧,把中断的过程做到中断里面。

      首先附上从机中断代码:
  1. #include "MG32x02z_DRV.H"
  2. #include "MG32x02z_GPIO_DRV.H"
  3. #include <stdio.h>

  4. typedef uint8_t u8;
  5. typedef uint16_t u16;
  6. typedef uint32_t u32;
  7. typedef uint64_t u64;

  8. #define Dummy_Data         0xFFFFFFFF

  9. #define SPI_NSS         PB0     // SPI_NSS
  10. #define URTX URT0

  11. void SPI0_IRQHandler(void)          //此处函数名不可改动
  12. {
  13.         if(SPI_GetSingleFlagStatus(SPI0, SPI_RXF) == DRV_Happened)        // Wait RXF flag
  14.         {
  15.         uint32_t RDAT;
  16.         PE13=0;
  17.   RDAT = SPI_GetRxData(SPI0);                                         // Get received data
  18.         printf("RX:0x%02X\n",RDAT);
  19.         PE13=1;
  20.         }
  21. }

  22. void CSC_Init (void)
  23. {
  24.         CSC_PLL_TyprDef CSC_PLL_CFG;
  25.    
  26.        
  27.     UnProtectModuleReg(MEMprotect);             // Setting flash wait state
  28.     MEM_SetFlashWaitState(MEM_FWAIT_ONE);        // 50MHz> Sysclk >=25MHz
  29.     ProtectModuleReg(MEMprotect);

  30.     UnProtectModuleReg(CSCprotect);
  31.         CSC_CK_APB_Divider_Select(APB_DIV_1);        // Modify CK_APB divider        APB=CK_MAIN/1
  32.         CSC_CK_AHB_Divider_Select(AHB_DIV_1);        // Modify CK_AHB divider        AHB=APB/1

  33.        
  34.         /* CK_HS selection */
  35.         CSC_IHRCO_Select(IHRCO_12MHz);                        // IHRCO Sel 12MHz
  36.         CSC_IHRCO_Cmd(ENABLE);
  37.         while(CSC_GetSingleFlagStatus(CSC_IHRCOF) == DRV_Normal);
  38.         CSC_ClearFlag(CSC_IHRCOF);
  39.         CSC_CK_HS_Select(HS_CK_IHRCO);                        // CK_HS select IHRCO


  40.         /* PLL */
  41.         /**********************************************************/
  42.         CSC_PLL_CFG.InputDivider=PLLI_DIV_2;        // 12M/2=6M
  43.         CSC_PLL_CFG.Multiplication=PLLIx16;                // 6M*16=96M
  44.         CSC_PLL_CFG.OutputDivider=PLLO_DIV_2;        // PLLO=96M/2=48M
  45.         CSC_PLL_Config(&CSC_PLL_CFG);
  46.         CSC_PLL_Cmd(ENABLE);
  47.         while(CSC_GetSingleFlagStatus(CSC_PLLF) == DRV_Normal);
  48.         CSC_ClearFlag(CSC_PLLF);
  49.         /**********************************************************/

  50.        
  51.         /* CK_MAIN */
  52.         CSC_CK_MAIN_Select(MAIN_CK_HS);       


  53.         /* Configure ICKO function */
  54.                
  55.         /* Configure peripheral clock */
  56.         CSC_PeriphProcessClockSource_Config(CSC_SPI0_CKS, CK_APB);
  57.         CSC_PeriphProcessClockSource_Config(CSC_UART0_CKS, CK_APB);
  58.         CSC_PeriphOnModeClock_Config(CSC_ON_SPI0,ENABLE);
  59.         CSC_PeriphOnModeClock_Config(CSC_ON_UART0,ENABLE);
  60.         CSC_PeriphOnModeClock_Config(CSC_ON_PortB,ENABLE);
  61.         CSC_PeriphOnModeClock_Config(CSC_ON_PortE,ENABLE);

  62.     ProtectModuleReg(CSCprotect);
  63.    
  64. }



  65. int fputc(int ch,FILE *f)
  66. {
  67.        
  68.         URT_SetTXData(URTX,1,ch);
  69.         while(URT_GetITSingleFlagStatus(URTX,URT_IT_TC)==DRV_UnHappened);
  70.         URT_ClearITFlag(URTX,URT_IT_TC);
  71.        
  72.         return ch;
  73. }

  74. void UartSendByte(int ch)
  75. {
  76.        
  77.         URT_SetTXData(URTX,1,ch);
  78.         while(URT_GetITSingleFlagStatus(URTX,URT_IT_TC)==DRV_UnHappened);
  79.         URT_ClearITFlag(URTX,URT_IT_TC);
  80.        
  81. }


  82. void URT0_Init(void)
  83. {
  84.     URT_BRG_TypeDef  URT_BRG;
  85.     URT_Data_TypeDef DataDef;
  86.         PIN_InitTypeDef PINX_InitStruct;
  87.    
  88.         //==Set GPIO init
  89.         //PB8 PPO TX ,PB9 ODO RX
  90.         PINX_InitStruct.PINX_Mode                                 = PINX_Mode_PushPull_O;                  // Pin select Push Pull mode
  91.         PINX_InitStruct.PINX_PUResistant                 = PINX_PUResistant_Enable;          // Enable pull up resistor
  92.         PINX_InitStruct.PINX_Speed                                   = PINX_Speed_Low;                         
  93.         PINX_InitStruct.PINX_OUTDrive                         = PINX_OUTDrive_Level0;                 // Pin output driver full strength.
  94.         PINX_InitStruct.PINX_FilterDivider                   = PINX_FilterDivider_Bypass;        // Pin input deglitch filter clock divider bypass
  95.         PINX_InitStruct.PINX_Inverse                         = PINX_Inverse_Disable;                 // Pin input data not inverse
  96.         PINX_InitStruct.PINX_Alternate_Function  = PB8_AF_URT0_TX;                                // Pin AFS = URT0_TX
  97.         GPIO_PinMode_Config(PINB(8),&PINX_InitStruct);                                                          // TXD at PB8

  98.         PINX_InitStruct.PINX_Mode                                 = PINX_Mode_OpenDrain_O;                 // Pin select Open Drain mode
  99.         PINX_InitStruct.PINX_Alternate_Function  = PB9_AF_URT0_RX;                                // Pin AFS = URT0_RX
  100.         GPIO_PinMode_Config(PINB(9),&PINX_InitStruct);                                                          // RXD at PB9

  101.    
  102.     //=====Set Clock=====//
  103.     //---Set BaudRate---//
  104.     URT_BRG.URT_InteranlClockSource = URT_BDClock_PROC;
  105.     URT_BRG.URT_BaudRateMode = URT_BDMode_Separated;
  106.     URT_BRG.URT_PrescalerCounterReload = 0;                                //Set PSR
  107.     URT_BRG.URT_BaudRateCounterReload = 3;                                //Set RLR
  108.     URT_BaudRateGenerator_Config(URTX, &URT_BRG);                            //BR115200 = f(CK_URTx)/(PSR+1)/(RLR+1)/(OS_NUM+1)
  109.     URT_BaudRateGenerator_Cmd(URTX, ENABLE);                            //Enable BaudRateGenerator
  110.     //---TX/RX Clock---//
  111.     URT_TXClockSource_Select(URTX, URT_TXClock_Internal);                //URT_TX use BaudRateGenerator
  112.     URT_RXClockSource_Select(URTX, URT_RXClock_Internal);                //URT_RX use BaudRateGenerator
  113.     URT_TXOverSamplingSampleNumber_Select(URTX, 25);                //Set TX OS_NUM
  114.     URT_RXOverSamplingSampleNumber_Select(URTX, 25);                //Set RX OS_NUM
  115.     URT_RXOverSamplingMode_Select(URTX, URT_RXSMP_3TIME);
  116.     URT_TX_Cmd(URTX, ENABLE);                                            //Enable TX
  117.     URT_RX_Cmd(URTX, ENABLE);                                            //Enable RX
  118.    
  119.    

  120.     //=====Set Mode=====//
  121.     //---Set Data character config---//
  122.     DataDef.URT_TX_DataLength  = URT_DataLength_8;
  123.     DataDef.URT_RX_DataLength  = URT_DataLength_8;
  124.     DataDef.URT_TX_DataOrder   = URT_DataTyped_LSB;
  125.     DataDef.URT_RX_DataOrder   = URT_DataTyped_LSB;
  126.     DataDef.URT_TX_Parity      = URT_Parity_No;
  127.     DataDef.URT_RX_Parity      = URT_Parity_No;
  128.     DataDef.URT_TX_StopBits    = URT_StopBits_1_0;
  129.     DataDef.URT_RX_StopBits    = URT_StopBits_1_0;
  130.     DataDef.URT_TX_DataInverse = DISABLE;
  131.     DataDef.URT_RX_DataInverse = DISABLE;
  132.     URT_DataCharacter_Config(URTX, &DataDef);
  133.     //---Set Mode Select---//
  134.     URT_Mode_Select(URTX, URT_URT_mode);
  135.     //---Set DataLine Select---//
  136.     URT_DataLine_Select(URTX, URT_DataLine_2);
  137.    
  138.    
  139.     //=====Set Data Control=====//
  140.     URT_RXShadowBufferThreshold_Select(URTX, URT_RXTH_1BYTE);
  141.     URT_IdlehandleMode_Select(URTX, URT_IDLEMode_No);
  142.     URT_TXGaudTime_Select(URTX, 0);
  143.    
  144.     //=====Enable URT Interrupt=====//
  145.     //URT_IT_Cmd(URTX, URT_IT_RX, ENABLE);
  146.     //URT_ITEA_Cmd(URTX, ENABLE);
  147.     //NVIC_EnableIRQ(URT0_IRQn);

  148.     //=====Enable URT=====//
  149.     URT_Cmd(URTX, ENABLE);
  150.                
  151.         //==See MG32x02z_URT0_IRQ.c when interrupt in
  152. }


  153. void InitSPI0(void)
  154. {  
  155.    
  156.         PIN_InitTypeDef PINX_InitStruct;

  157.         //===Set CSC init====
  158.         //MG32x02z_CSC_Init.h(Configuration Wizard)
  159.         //Select CK_HS source = CK_IHRCO
  160.         //Select IHRCO = 12Mz
  161.         //Select CK_MAIN Source = CK_HS
  162.         //Configure PLL->Select APB Prescaler = CK_MAIN/1

  163.         /*=== 1. Enable CSC to SPI clock ===*/
  164.         //[A] When Use Wizard
  165.         //Configure Peripheral On Mode Clock->SPI0 = Enable and Select SPI0_PR Source = CK_APB
  166.         //Configure Peripheral On Mode Clock->Port B = Enable
  167.         //[B] When Use Driver
  168.         //          UnProtectModuleReg(CSCprotect);                                                          // Unprotect CSC module
  169.         //          CSC_PeriphOnModeClock_Config(CSC_ON_SPI0, ENABLE);                  // Enable SPI0 module clock
  170.         //          CSC_PeriphOnModeClock_Config(CSC_ON_PortB, ENABLE);                  // Enable PortB clock
  171.         //          CSC_PeriphProcessClockSource_Config(CSC_SPI0_CKS, CK_APB);  // CK_SPIx_PR = CK_APB = 12MHz
  172.         //          ProtectModuleReg(CSCprotect);                                                           // protect CSC module

  173.         /*=== 2. Default Initial SPI ===*/
  174.         SPI_DeInit(SPI0);

  175.         /*=== 3. Configure clock divider ===*/                                                // SPI clock = 1MHz
  176.         SPI_Clock_Select(SPI0, SPI_CK_SPIx_PR);                                         // CK_SPIx = CK_SPIx_PR
  177.         SPI_PreDivider_Select(SPI0, SPI_PDIV_2);                                        // PDIV outpu = CK_SPIx /2
  178.         SPI_Prescaler_Select(SPI0, SPI_PSC_3);                                                // Prescaler outpu = PDIV outpu /3
  179.         SPI_Divider_Select(SPI0, SPI_DIV_2);                                                // DIV outpu = PDIV outpu /2

  180.         /*=== 4. Configure SPI data line, mode and data size... ===*/
  181.         SPI_DataLine_Select(SPI0, SPI_Standard);                                        // SPI data line 1-line Bidirectional~ SPI0_MOSI
  182.         SPI_ModeAndNss_Select(SPI0, SPI_SlaveWithNss);                                        // Slave
  183.         SPI_NSSInputSignal_Select(SPI0,SPI_NssPin);                                        // Nss
  184.         SPI_ClockPhase_Select(SPI0, SPI_LeadingEdge);                                // CPHA = 0
  185.         SPI_ClockPolarity_Select(SPI0, SPI_Low);                                        // CPOL = 0
  186.         SPI_FirstBit_Select(SPI0, SPI_MSB);                                                 // MSB first
  187.         SPI_DataSize_Select(SPI0, SPI_8bits);                                                // Data size 8bits
  188.         SPI_SlaveModeReceivedThreshold_Select(SPI0, SPI_1Byte);     // Set SPI0 received data buffer high threshold

  189.         /*=== 5. Config SPI0 IO ===*/
  190.         PINX_InitStruct.PINX_Mode                                 = PINX_Mode_Digital_I;          // Pin select digital input mode
  191.         PINX_InitStruct.PINX_PUResistant                 = PINX_PUResistant_Enable;  // Enable pull up resistor
  192.         PINX_InitStruct.PINX_Speed                                   = PINX_Speed_Low;                         
  193.         PINX_InitStruct.PINX_OUTDrive                         = PINX_OUTDrive_Level0;         // Pin output driver full strength.
  194.         PINX_InitStruct.PINX_FilterDivider                   = PINX_FilterDivider_Bypass;// Pin input deglitch filter clock divider bypass
  195.         PINX_InitStruct.PINX_Inverse                         = PINX_Inverse_Disable;         // Pin input data not inverse
  196.         PINX_InitStruct.PINX_Alternate_Function = 2;                                                 // Pin AFS = 2

  197.         GPIO_PinMode_Config(PINB(0),&PINX_InitStruct);                                          // NSS setup at PB0
  198.         GPIO_PinMode_Config(PINB(2),&PINX_InitStruct);                                          // CLK setup at PB2
  199.         GPIO_PinMode_Config(PINB(3),&PINX_InitStruct);                                          // MOSI setup at PB3
  200.        
  201.   PINX_InitStruct.PINX_Mode                                = PINX_Mode_PushPull_O;     // Setting pusu pull mode
  202.   GPIO_PinMode_Config(PINB(1),&PINX_InitStruct);                      // MISO setup at PB1
  203.         PINX_InitStruct.PINX_Mode                                 = PINX_Mode_OpenDrain_O;         // Setting pusu pull mode
  204.         PINX_InitStruct.PINX_Alternate_Function = 0;                                                 // Pin AFS = 0
  205.         GPIO_PinMode_Config(PINE(13),&PINX_InitStruct);                                          // D4 setup at PE13
  206.         GPIO_PinMode_Config(PINE(14),&PINX_InitStruct);                                          // D4 setup at PE13
  207.         GPIO_PinMode_Config(PINE(15),&PINX_InitStruct);                                          // D6 setup at PE15

  208.         /*=== 6. Enable SPI ===*/
  209.         SPI_IT_Config(SPI0, SPI_INT_RX,ENABLE);           //增加SPI0中断接收使能
  210.         SPI_ITEA_Cmd(SPI0, ENABLE);                            //使能SPI0中断
  211.         SPI_Cmd(SPI0, ENABLE);                                                                                          // Enable SPI

  212. }



  213. int main()
  214. {
  215.         CSC_Init();
  216.         InitSPI0();       
  217.         NVIC_EnableIRQ(SPI0_IRQn);                          //使能SPI0的IRQ
  218.         URT0_Init();
  219.         printf("hello\n");
  220.     while(1)
  221.     {

  222.     }
  223. }

     从我注释的代码中可以看出,使能中断的过程并不多,就几行就行,但是为什么我要着重注释IRQHandler中断服务程序的函数名不能动呢?从startup.s中可以看出,他们默认使用了这个函数名作为服务程序,因此函数名按照startup.s来即可。
      
      

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
您需要登录后才可以回帖 登录 | 注册

本版积分规则

26

主题

82

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部