[新手园地] GPIO控制LED灯(新手学习第一贴)更新

[复制链接]
 楼主| mcsgy 发表于 2011-9-12 01:59 | 显示全部楼层 |阅读模式
本帖最后由 mcsgy 于 2011-9-14 00:40 编辑

  1. /******************************************************************************
  2. 工程名称:GPIO控制流水灯
  3. 作者:   mcsgy
  4. 日期:    2011年9月11日
  5. 更新日期:2011年9月12日,2011年9月13日(加入中断控制)
  6. 参考:    Cube的《助学入门实验2 GPIO实验》
  7. ******************************************************************************/
  8. #include "NUC1xx.h"
  9. void DrvSYS_Delay(uint32_t us)     //系统延时程序
  10. {
  11. SysTick->LOAD = (us * (SystemCoreClock / 10000)) / 100;
  12. SysTick->VAL  = (0x00);
  13.     SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
  14.     /* Waiting for down-count to zero */
  15.     while((SysTick->CTRL & (1 << 16)) == 0);
  16. }
  17. /*****************************时钟初始化程序********************************/
  18. void M0_Clock_Init(void)
  19. {
  20.   volatile uint32_t delayCnt;
  21.   SYSCLK->PWRCON.XTL12M_EN=1;                  //使能外部12M时钟
  22.   for(delayCnt=0;delayCnt<10000;delayCnt++);   //等待外部12M时钟就绪
  23.   
  24.   SYSCLK->PLLCON.PLL_SRC=0;       //PLL时钟配置
  25.   SYSCLK->PLLCON.IN_DV=1;
  26.   SYSCLK->PLLCON.FB_DV=46;
  27.   SYSCLK->PLLCON.OUT_DV=3;
  28.   SYSCLK->PLLCON.PD=0;
  29.   SYSCLK->PLLCON.OE=0;
  30.   
  31. //  DrvSYS_Delay(5000);
  32.   
  33.                                 
  34.   SYSCLK->CLKSEL0.HCLK_S=2;       //选择PLL输出做为系统时钟48M
  35.   for(delayCnt=0;delayCnt<10000;delayCnt++);   //等待PLL稳定这里不能用DrvSYS_Delay()来延时,
  36.                 //因为此时系统时钟还未稳定,否则会出错,比如类似于0x5000_0100没有读写权限的错误。
  37.   SystemCoreClockUpdate();                    //系统时钟更新完毕之后,便可用DrvSYS_Delay(us)函数
  38.   DrvSYS_Delay(5000);       //  
  39. }
  40. /*******************************IO口初始化子程序*********************************/
  41. void IO_Init(void)
  42. {
  43. GPIOA->PMD.PMD2=1;        //将GPIOA2,3,4,5设置为推挽输出
  44. GPIOA->PMD.PMD3=1;
  45. GPIOA->PMD.PMD4=1;
  46. GPIOA->PMD.PMD5=1;

  47. GPIOB->PMD.PMD10=1;        //将GPIOB10设置为推挽输出
  48. GPIOB->DOUT&=~(0x00000400);      //GPIOB10输出低,蜂鸣器不响
  49. }
  50. /***************************中断初始化程序*******************************/
  51. void SYSINT_Init(void)
  52. {
  53. GPIOB->PMD.PMD14=0;        //将GPIOB14,15设置为输入
  54. GPIOB->PMD.PMD15=0;
  55. GPIOB->IMD&=0x3FFF;        //设置为边沿触发方式
  56. GPIOB->DBEN|=(BIT14+BIT15);      //去抖使能
  57. GPIOB->IEN=0;
  58. GPIOB->IEN|=(BIT14+BIT15);     //使能为下降沿触发方式
  59. NVIC->ISER[0]|=(BIT2+BIT3);
  60. }
  61. /*****************************主程序main函数***********************************/
  62. int main (void)
  63. {
  64. UNLOCKREG();       //解锁寄存器
  65. M0_Clock_Init();      //初始化时钟
  66. IO_Init();        //初始化LED灯IO
  67. SYSINT_Init();       //初始化外部Key1,Key2中断
  68. {
  69.   unsigned char i=8;
  70.   while(i--)
  71.   {
  72.    GPIOA->DOUT&=~BIT2;        //依次点亮LED1,LED2,LED3,LED4并一直循环
  73.    DrvSYS_Delay(100000);       //廷时100毫秒
  74.    GPIOA->DOUT|=BIT2;
  75.    GPIOA->DOUT&=~BIT3;
  76.    DrvSYS_Delay(100000);
  77.    GPIOA->DOUT|=BIT3;
  78.    GPIOA->DOUT&=~BIT4;
  79.    DrvSYS_Delay(100000);
  80.    GPIOA->DOUT|=BIT4;
  81.    GPIOA->DOUT&=~BIT5;
  82.    DrvSYS_Delay(100000);
  83.    GPIOA->DOUT|=BIT5;
  84.   }
  85.   }
  86.   while(1)
  87.   {
  88. //   if(!((GPIOB->PIN) & BIT14))        //按键点亮LED1
  89. //  {
  90. //   GPIOA->DOUT&=~BIT2;
  91. //  }
  92. //  else
  93. //  {
  94. //   GPIOA->DOUT|=BIT2;
  95. //  }
  96. //  if(!((GPIOB->PIN) & BIT15))        //按键点亮LED2
  97. //  {
  98. //   GPIOA->DOUT&=~BIT3;
  99. //  }
  100. //  else
  101. //  {
  102. //   GPIOA->DOUT|=BIT3;
  103. //  }
  104.    
  105.   
  106.   }

  107. }
  108. /***************************INT0中断服务程序******************************/
  109. void EINT0_IRQHandler(void)
  110. {
  111. GPIOB->IEN|=(~BIT14);          //关闭中断
  112. DrvSYS_Delay(10000);         //延时去抖
  113. if(!((GPIOB->PIN) & BIT14))        //判断按键是否按下
  114. {
  115.   GPIOA->DOUT^=(BIT2+BIT4);     //IO口与1异或取反
  116. }              
  117. GPIOB->ISRC|=BIT14;        //清中断标志
  118. GPIOB->IEN|=BIT14;        //开启中断
  119. }
  120. /***************************INT1中断服务程序******************************/
  121. void EINT1_IRQHandler(void)
  122. {
  123.      GPIOB->IEN|=(~BIT15);
  124.   DrvSYS_Delay(10000);
  125.   if(!((GPIOB->PIN) & BIT15))
  126.   {
  127.    GPIOA->DOUT^=(BIT2+BIT3+BIT4+BIT5);
  128.   }
  129.   GPIOB->ISRC|=BIT15;
  130.   GPIOB->IEN|=BIT15;
  131. }

本帖子中包含更多资源

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

×
 楼主| mcsgy 发表于 2011-9-12 02:01 | 显示全部楼层
代码拷过来没有缩进了,附件里面有。
tao560532 发表于 2011-9-12 09:30 | 显示全部楼层
不错,学习了,注释比我详细
tao560532 发表于 2011-9-12 09:34 | 显示全部楼层
不过我把程序下进去好像没反应啊
 楼主| mcsgy 发表于 2011-9-12 16:45 | 显示全部楼层
可能KEIl里面的设置还要改一些,可以参考Cube的那个《助学入门实验2 GPIO实验》,我是按照那个改的。
 楼主| mcsgy 发表于 2011-9-12 18:59 | 显示全部楼层
主程序中的代码更新
  1. /******************************************************************************
  2. 工程名称:GPIO控制流水灯
  3. 作者:          mcsgy
  4. 日期:    2011年9月11日
  5. 更新日期:2011年9月12日
  6. 参考:    Cube的《助学入门实验2 GPIO实验》
  7. ******************************************************************************/



  8. #include "NUC1xx.h"
  9. void DrvSYS_Delay(uint32_t us)                                        //系统延时程序
  10. {
  11.         SysTick->LOAD = (us * (SystemCoreClock / 10000)) / 100;
  12.         SysTick->VAL  = (0x00);
  13.     SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;

  14.     /* Waiting for down-count to zero */
  15.     while((SysTick->CTRL & (1 << 16)) == 0);
  16. }
  17. void M0_Clock_Init(void)
  18. {
  19.          volatile uint32_t delayCnt;
  20.          SYSCLK->PWRCON.XTL12M_EN=1;                                //使能外部12M时钟
  21.          for(delayCnt=0;delayCnt<10000;delayCnt++);                        //等待外部12M时钟就绪
  22.          
  23.          SYSCLK->PLLCON.PLL_SRC=0;                                                        //PLL时钟配置
  24.          SYSCLK->PLLCON.IN_DV=1;
  25.          SYSCLK->PLLCON.FB_DV=46;
  26.          SYSCLK->PLLCON.OUT_DV=3;
  27.          SYSCLK->PLLCON.PD=0;
  28.          SYSCLK->PLLCON.OE=0;
  29.          
  30. //         DrvSYS_Delay(5000);
  31.          
  32.                                                                           
  33.          SYSCLK->CLKSEL0.HCLK_S=2;                                          //选择PLL输出做为系统时钟48M

  34.          for(delayCnt=0;delayCnt<10000;delayCnt++);          //等待PLL稳定这里不能用DrvSYS_Delay()来延时,
  35.                                                                                                    //因为此时系统时钟还未稳定,否则会出错,比如类似于0x5000_0100没有读写权限的错误。
  36.          SystemCoreClockUpdate();                    //系统时钟更新完毕之后,便可用DrvSYS_Delay(us)函数
  37.          DrvSYS_Delay(5000);                                                 //  
  38. }
  39. void IO_Init(void)
  40. {
  41.         GPIOA->PMD.PMD2=1;                                                         //将GPIOA2,3,4,5设置为推挽输出
  42.         GPIOA->PMD.PMD3=1;
  43.         GPIOA->PMD.PMD4=1;
  44.         GPIOA->PMD.PMD5=1;
  45.        
  46.         GPIOB->PMD.PMD10=1;                                                         //将GPIOB10设置为推挽输出
  47.         GPIOB->DOUT&=~(0x00000400);                                         //GPIOB10输出高,蜂鸣器不响
  48.         GPIOB->PMD.PMD14=0;                                                         //将GPIOB14,15设置为输入
  49.         GPIOB->PMD.PMD15=0;
  50. }
  51. int main (void)
  52. {
  53.         UNLOCKREG();
  54.         M0_Clock_Init();
  55.         IO_Init();
  56.         {
  57.                 unsigned char i=8;
  58.                 while(i--)
  59.                 {
  60.                         GPIOA->DOUT&=~BIT2;                                                  //依次点亮LED1,LED2,LED3,LED4并一直循环
  61.                         DrvSYS_Delay(100000);                                          //廷时100毫秒
  62.                         GPIOA->DOUT|=BIT2;
  63.                         GPIOA->DOUT&=~BIT3;
  64.                         DrvSYS_Delay(100000);
  65.                         GPIOA->DOUT|=BIT3;
  66.                         GPIOA->DOUT&=~BIT4;
  67.                         DrvSYS_Delay(100000);
  68.                         GPIOA->DOUT|=BIT4;
  69.                         GPIOA->DOUT&=~BIT5;
  70.                         DrvSYS_Delay(100000);
  71.                         GPIOA->DOUT|=BIT5;
  72.                 }

  73.          }
  74.          while(1)
  75.          {
  76.                  if(!((GPIOB->PIN) & BIT14))                                           //按键点亮LED1
  77.                 {
  78.                         GPIOA->DOUT&=~BIT2;       
  79.                 }
  80.                 else
  81.                 {
  82.                         GPIOA->DOUT|=BIT2;
  83.                 }
  84.                 if(!((GPIOB->PIN) & BIT15))                                           //按键点亮LED2
  85.                 {
  86.                         GPIOA->DOUT&=~BIT3;       
  87.                 }
  88.                 else
  89.                 {
  90.                         GPIOA->DOUT|=BIT3;
  91.                 }
  92.           
  93.          
  94.          }
  95.        

  96. }

 楼主| mcsgy 发表于 2011-9-14 17:45 | 显示全部楼层
自己顶一下呢
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:从零开始

6

主题

232

帖子

1

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