[DemoCode下载] M051寄存器操作IO中断

[复制链接]
1352|7
 楼主| 玛尼玛尼哄 发表于 2017-5-17 22:53 | 显示全部楼层 |阅读模式
  1. /**************************************************************************//**
  2. * [url=home.php?mod=space&uid=288409]@file[/url]     main.c
  3. * [url=home.php?mod=space&uid=895143]@version[/url]  V3.00
  4. * $Revision: 3 $
  5. * $Date: 14/04/03 9:18a $
  6. * [url=home.php?mod=space&uid=247401]@brief[/url]    M051 Series GPIO Driver Sample Code
  7. *
  8. * @note
  9. * Copyright (C) 2013 Nuvoton Technology Corp. All rights reserved.
  10. ******************************************************************************/
  11. #include <stdio.h>
  12. #include "M051Series.h"


  13. #define PLLCON_SETTING      CLK_PLLCON_50MHz_HXT
  14. #define PLL_CLOCK           50000000


  15. /**
  16. * @brief       Port0/Port1 IRQ
  17. *
  18. * @param       None
  19. *
  20. * [url=home.php?mod=space&uid=266161]@return[/url]      None
  21. *
  22. * [url=home.php?mod=space&uid=1543424]@Details[/url]     The Port0/Port1 default IRQ, declared in startup_M051Series.s.
  23. */
  24. void GPIOP0P1_IRQHandler(void)
  25. {
  26.     /* To check if P1.3 interrupt occurred */
  27.     if(P1->ISRC & BIT3)
  28.     {
  29.         P1->ISRC = BIT3;
  30.         printf("P1.3 INT occurred.\n");
  31.     }
  32.     else
  33.     {
  34.         /* Un-expected interrupt. Just clear all PORT0, PORT1 interrupts */
  35.         P0->ISRC = P0->ISRC;
  36.         P1->ISRC = P1->ISRC;
  37.         printf("Un-expected interrupts.\n");
  38.     }
  39. }

  40. /**
  41. * @brief       Port2/Port3/Port4 IRQ
  42. *
  43. * @param       None
  44. *
  45. * @return      None
  46. *
  47. * @details     The Port2/Port3/Port4 default IRQ, declared in startup_M051Series.s.
  48. */
  49. void GPIOP2P3P4_IRQHandler(void)
  50. {
  51.     /* To check if P4.5 interrupt occurred */
  52.     if(P4->ISRC & BIT5)
  53.     {
  54.         P4->ISRC = BIT5;
  55.         printf("P4.5 INT occurred.\n");
  56.     }
  57.     else
  58.     {
  59.         /* Un-expected interrupt. Just clear all PORT2, PORT3 and PORT4 interrupts */
  60.         P2->ISRC = P2->ISRC;
  61.         P3->ISRC = P3->ISRC;
  62.         P4->ISRC = P4->ISRC;
  63.         printf("Un-expected interrupts.\n");
  64.     }
  65. }

  66. void SYS_Init(void)
  67. {
  68.     /*---------------------------------------------------------------------------------------------------------*/
  69.     /* Init System Clock                                                                                       */
  70.     /*---------------------------------------------------------------------------------------------------------*/

  71.     /* Enable Internal RC 22.1184MHz clock */
  72.     CLK->PWRCON |= CLK_PWRCON_OSC22M_EN_Msk;

  73.     /* Waiting for Internal RC clock ready */
  74.     while(!(CLK->CLKSTATUS & CLK_CLKSTATUS_OSC22M_STB_Msk));

  75.     /* Switch HCLK clock source to Internal RC and and HCLK source divide 1 */
  76.     CLK->CLKSEL0 &= ~CLK_CLKSEL0_HCLK_S_Msk;
  77.     CLK->CLKSEL0 |= CLK_CLKSEL0_HCLK_S_HIRC;
  78.     CLK->CLKDIV &= ~CLK_CLKDIV_HCLK_N_Msk;
  79.     CLK->CLKDIV |= CLK_CLKDIV_HCLK(1);

  80.     /* Enable external XTAL 12MHz clock */
  81.     CLK->PWRCON |= CLK_PWRCON_XTL12M_EN_Msk;

  82.     /* Waiting for external XTAL clock ready */
  83.     while(!(CLK->CLKSTATUS & CLK_CLKSTATUS_XTL12M_STB_Msk));

  84.     /* Set core clock as PLL_CLOCK from PLL */
  85.     CLK->PLLCON = PLLCON_SETTING;
  86.     while(!(CLK->CLKSTATUS & CLK_CLKSTATUS_PLL_STB_Msk));
  87.     CLK->CLKSEL0 &= (~CLK_CLKSEL0_HCLK_S_Msk);
  88.     CLK->CLKSEL0 |= CLK_CLKSEL0_HCLK_S_PLL;

  89.     /* Update System Core Clock */
  90.     /* User can use SystemCoreClockUpdate() to calculate PllClock, SystemCoreClock and CycylesPerUs automatically. */
  91.     //SystemCoreClockUpdate();
  92.     PllClock        = PLL_CLOCK;            // PLL
  93.     SystemCoreClock = PLL_CLOCK / 1;        // HCLK
  94.     CyclesPerUs     = PLL_CLOCK / 1000000;  // For SYS_SysTickDelay()

  95.     /* Enable UART module clock */
  96.     CLK->APBCLK |= CLK_APBCLK_UART0_EN_Msk;

  97.     /* Select UART module clock source */
  98.     CLK->CLKSEL1 &= ~CLK_CLKSEL1_UART_S_Msk;
  99.     CLK->CLKSEL1 |= CLK_CLKSEL1_UART_S_PLL;

  100.     /*---------------------------------------------------------------------------------------------------------*/
  101.     /* Init I/O Multi-function                                                                                 */
  102.     /*---------------------------------------------------------------------------------------------------------*/

  103.     /* Set P3 multi-function pins for UART0 RXD and TXD */
  104.     SYS->P3_MFP &= ~(SYS_MFP_P30_Msk | SYS_MFP_P31_Msk);
  105.     SYS->P3_MFP |= (SYS_MFP_P30_RXD0 | SYS_MFP_P31_TXD0);

  106. }

  107. void UART0_Init()
  108. {
  109.     /*---------------------------------------------------------------------------------------------------------*/
  110.     /* Init UART                                                                                               */
  111.     /*---------------------------------------------------------------------------------------------------------*/
  112.     /* Reset UART IP */
  113.     SYS->IPRSTC2 |=  SYS_IPRSTC2_UART0_RST_Msk;
  114.     SYS->IPRSTC2 &= ~SYS_IPRSTC2_UART0_RST_Msk;

  115.     /* Configure UART0 and set UART0 Baudrate */
  116.     UART0->BAUD = UART_BAUD_MODE2 | UART_BAUD_MODE2_DIVIDER(PLL_CLOCK, 115200);
  117.     UART0->LCR = UART_WORD_LEN_8 | UART_PARITY_NONE | UART_STOP_BIT_1;
  118. }

  119. /*---------------------------------------------------------------------------------------------------------*/
  120. /* MAIN function                                                                                           */
  121. /*---------------------------------------------------------------------------------------------------------*/
  122. int main(void)
  123. {
  124.     /* Unlock protected registers */
  125.     SYS->REGWRPROT = 0x59;
  126.     SYS->REGWRPROT = 0x16;
  127.     SYS->REGWRPROT = 0x88;

  128.     /* Init System, peripheral clock and multi-function I/O */
  129.     SYS_Init();

  130.     /* Lock protected registers */
  131.     SYS->REGWRPROT = 0x0;

  132.     /* Init UART0 for printf */
  133.     UART0_Init();

  134.     printf("\n\nCPU [url=home.php?mod=space&uid=72445]@[/url] %d Hz\n", SystemCoreClock);
  135.     printf("+------------------------------------------------+\n");
  136.     printf("|    GPIO P1.3 and P4.5 Interrupt Sample Code    |\n");
  137.     printf("+------------------------------------------------+\n\n");

  138.     /*-----------------------------------------------------------------------------------------------------*/
  139.     /* GPIO Interrupt Function Test                                                                        */
  140.     /*-----------------------------------------------------------------------------------------------------*/
  141.     printf("P1.3 and P4.5 are used to test interrupt ......\n");

  142.     /* Configure P1.3 as Input mode and enable interrupt by rising edge trigger */
  143.     P1->PMD = P1->PMD & (~GPIO_PMD_PMD3_Msk) | (GPIO_PMD_INPUT << GPIO_PMD_PMD3_Pos);
  144.     P1->IMD |= (GPIO_IMD_EDGE << 3);
  145.     P1->IEN |= (BIT3 << GPIO_IEN_IR_EN_Pos);
  146.     NVIC_EnableIRQ(GPIO_P0P1_IRQn);

  147.     /*  Configure P4.5 as Quasi-bidirection mode and enable interrupt by falling edge trigger */
  148.     P4->PMD = P1->PMD & (~GPIO_PMD_PMD5_Msk) | (GPIO_PMD_QUASI << GPIO_PMD_PMD5_Pos);
  149.     P4->IMD |= (GPIO_IMD_EDGE << 5);
  150.     P4->IEN |= (BIT5 << GPIO_IEN_IF_EN_Pos);
  151.     NVIC_EnableIRQ(GPIO_P2P3P4_IRQn);

  152.     /* Waiting for interrupts */
  153.     while(1);
  154. }

  155. /*** (C) COPYRIGHT 2013 Nuvoton Technology Corp. ***/


 楼主| 玛尼玛尼哄 发表于 2017-5-17 22:54 | 显示全部楼层
实际上如果熟记相关寄存器的功能后,用寄存器操作也是很简单的。
 楼主| 玛尼玛尼哄 发表于 2017-5-17 22:56 | 显示全部楼层
   /* Un-expected interrupt. Just clear all PORT0, PORT1 interrupts */
        P0->ISRC = P0->ISRC;
        P1->ISRC = P1->ISRC;
我们看到因为共用了中断入口,所以对应的标志位都是要清一下的
上面的程序看是读取后,赋值,实际上是因为该寄存器是写1清零。
 楼主| 玛尼玛尼哄 发表于 2017-5-17 22:57 | 显示全部楼层
这些都是要仔细看手册的说明才能知道的。不能凭空臆测
heisexingqisi 发表于 2017-5-18 20:00 | 显示全部楼层
有时候寄存器和库函数版本都要学
xixi2017 发表于 2017-5-18 21:49 | 显示全部楼层
#define PLL_CLOCK           50000000
是不是直接修改这个就可以更改时钟了,太厉害了。
bingkaiok 发表于 2017-5-18 23:27 | 显示全部楼层
不懂寄存器是不能完全看懂库函数的
huangcunxiake 发表于 2017-5-19 10:55 | 显示全部楼层
寄存器操作还是很方便的。不过移植性小了点。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

196

主题

3261

帖子

2

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