打印
[新手园地]

GPIO控制LED灯(新手学习第一贴)更新

[复制链接]
4946|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
mcsgy|  楼主 | 2011-9-12 01:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 mcsgy 于 2011-9-14 00:40 编辑
 
/******************************************************************************
工程名称:GPIO控制流水灯
作者:   mcsgy
日期:    2011年9月11日
更新日期:2011年9月12日,2011年9月13日(加入中断控制)
参考:    Cube的《助学入门实验2 GPIO实验》
******************************************************************************/
#include "NUC1xx.h"
void DrvSYS_Delay(uint32_t us)     //系统延时程序
{
SysTick->LOAD = (us * (SystemCoreClock / 10000)) / 100;
SysTick->VAL  = (0x00);
    SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
    /* Waiting for down-count to zero */
    while((SysTick->CTRL & (1 << 16)) == 0);
}
/*****************************时钟初始化程序********************************/
void M0_Clock_Init(void)
{
  volatile uint32_t delayCnt;
  SYSCLK->PWRCON.XTL12M_EN=1;                  //使能外部12M时钟
  for(delayCnt=0;delayCnt<10000;delayCnt++);   //等待外部12M时钟就绪
  
  SYSCLK->PLLCON.PLL_SRC=0;       //PLL时钟配置
  SYSCLK->PLLCON.IN_DV=1;
  SYSCLK->PLLCON.FB_DV=46;
  SYSCLK->PLLCON.OUT_DV=3;
  SYSCLK->PLLCON.PD=0;
  SYSCLK->PLLCON.OE=0;
  
//  DrvSYS_Delay(5000);
  
                                
  SYSCLK->CLKSEL0.HCLK_S=2;       //选择PLL输出做为系统时钟48M
  for(delayCnt=0;delayCnt<10000;delayCnt++);   //等待PLL稳定这里不能用DrvSYS_Delay()来延时,
                //因为此时系统时钟还未稳定,否则会出错,比如类似于0x5000_0100没有读写权限的错误。
  SystemCoreClockUpdate();                    //系统时钟更新完毕之后,便可用DrvSYS_Delay(us)函数
  DrvSYS_Delay(5000);       //  
}
/*******************************IO口初始化子程序*********************************/
void IO_Init(void)
{
GPIOA->PMD.PMD2=1;        //将GPIOA2,3,4,5设置为推挽输出
GPIOA->PMD.PMD3=1;
GPIOA->PMD.PMD4=1;
GPIOA->PMD.PMD5=1;

GPIOB->PMD.PMD10=1;        //将GPIOB10设置为推挽输出
GPIOB->DOUT&=~(0x00000400);      //GPIOB10输出低,蜂鸣器不响
}
/***************************中断初始化程序*******************************/
void SYSINT_Init(void)
{
GPIOB->PMD.PMD14=0;        //将GPIOB14,15设置为输入
GPIOB->PMD.PMD15=0;
GPIOB->IMD&=0x3FFF;        //设置为边沿触发方式
GPIOB->DBEN|=(BIT14+BIT15);      //去抖使能
GPIOB->IEN=0;
GPIOB->IEN|=(BIT14+BIT15);     //使能为下降沿触发方式
NVIC->ISER[0]|=(BIT2+BIT3);
}
/*****************************主程序main函数***********************************/
int main (void)
{
UNLOCKREG();       //解锁寄存器
M0_Clock_Init();      //初始化时钟
IO_Init();        //初始化LED灯IO
SYSINT_Init();       //初始化外部Key1,Key2中断
{
  unsigned char i=8;
  while(i--)
  {
   GPIOA->DOUT&=~BIT2;        //依次点亮LED1,LED2,LED3,LED4并一直循环
   DrvSYS_Delay(100000);       //廷时100毫秒
   GPIOA->DOUT|=BIT2;
   GPIOA->DOUT&=~BIT3;
   DrvSYS_Delay(100000);
   GPIOA->DOUT|=BIT3;
   GPIOA->DOUT&=~BIT4;
   DrvSYS_Delay(100000);
   GPIOA->DOUT|=BIT4;
   GPIOA->DOUT&=~BIT5;
   DrvSYS_Delay(100000);
   GPIOA->DOUT|=BIT5;
  }
  }
  while(1)
  {
//   if(!((GPIOB->PIN) & BIT14))        //按键点亮LED1
//  {
//   GPIOA->DOUT&=~BIT2;
//  }
//  else
//  {
//   GPIOA->DOUT|=BIT2;
//  }
//  if(!((GPIOB->PIN) & BIT15))        //按键点亮LED2
//  {
//   GPIOA->DOUT&=~BIT3;
//  }
//  else
//  {
//   GPIOA->DOUT|=BIT3;
//  }
   
  
  }

}
/***************************INT0中断服务程序******************************/
void EINT0_IRQHandler(void)
{
GPIOB->IEN|=(~BIT14);          //关闭中断
DrvSYS_Delay(10000);         //延时去抖
if(!((GPIOB->PIN) & BIT14))        //判断按键是否按下
{
  GPIOA->DOUT^=(BIT2+BIT4);     //IO口与1异或取反
}              
GPIOB->ISRC|=BIT14;        //清中断标志
GPIOB->IEN|=BIT14;        //开启中断
}
/***************************INT1中断服务程序******************************/
void EINT1_IRQHandler(void)
{
     GPIOB->IEN|=(~BIT15);
  DrvSYS_Delay(10000);
  if(!((GPIOB->PIN) & BIT15))
  {
   GPIOA->DOUT^=(BIT2+BIT3+BIT4+BIT5);
  }
  GPIOB->ISRC|=BIT15;
  GPIOB->IEN|=BIT15;
}

GPIO流水灯.rar

1017.13 KB

相关帖子

沙发
mcsgy|  楼主 | 2011-9-12 02:01 | 只看该作者
代码拷过来没有缩进了,附件里面有。

使用特权

评论回复
板凳
tao560532| | 2011-9-12 09:30 | 只看该作者
不错,学习了,注释比我详细

使用特权

评论回复
地板
tao560532| | 2011-9-12 09:34 | 只看该作者
不过我把程序下进去好像没反应啊

使用特权

评论回复
5
mcsgy|  楼主 | 2011-9-12 16:45 | 只看该作者
可能KEIl里面的设置还要改一些,可以参考Cube的那个《助学入门实验2 GPIO实验》,我是按照那个改的。

使用特权

评论回复
6
mcsgy|  楼主 | 2011-9-12 18:59 | 只看该作者
主程序中的代码更新
/******************************************************************************
工程名称:GPIO控制流水灯
作者:          mcsgy
日期:    2011年9月11日
更新日期:2011年9月12日
参考:    Cube的《助学入门实验2 GPIO实验》
******************************************************************************/



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

    /* Waiting for down-count to zero */
    while((SysTick->CTRL & (1 << 16)) == 0);
}
void M0_Clock_Init(void)
{
         volatile uint32_t delayCnt;
         SYSCLK->PWRCON.XTL12M_EN=1;                                //使能外部12M时钟
         for(delayCnt=0;delayCnt<10000;delayCnt++);                        //等待外部12M时钟就绪
         
         SYSCLK->PLLCON.PLL_SRC=0;                                                        //PLL时钟配置
         SYSCLK->PLLCON.IN_DV=1;
         SYSCLK->PLLCON.FB_DV=46;
         SYSCLK->PLLCON.OUT_DV=3;
         SYSCLK->PLLCON.PD=0;
         SYSCLK->PLLCON.OE=0;
         
//         DrvSYS_Delay(5000);
         
                                                                          
         SYSCLK->CLKSEL0.HCLK_S=2;                                          //选择PLL输出做为系统时钟48M

         for(delayCnt=0;delayCnt<10000;delayCnt++);          //等待PLL稳定这里不能用DrvSYS_Delay()来延时,
                                                                                                   //因为此时系统时钟还未稳定,否则会出错,比如类似于0x5000_0100没有读写权限的错误。
         SystemCoreClockUpdate();                    //系统时钟更新完毕之后,便可用DrvSYS_Delay(us)函数
         DrvSYS_Delay(5000);                                                 //  
}
void IO_Init(void)
{
        GPIOA->PMD.PMD2=1;                                                         //将GPIOA2,3,4,5设置为推挽输出
        GPIOA->PMD.PMD3=1;
        GPIOA->PMD.PMD4=1;
        GPIOA->PMD.PMD5=1;
       
        GPIOB->PMD.PMD10=1;                                                         //将GPIOB10设置为推挽输出
        GPIOB->DOUT&=~(0x00000400);                                         //GPIOB10输出高,蜂鸣器不响
        GPIOB->PMD.PMD14=0;                                                         //将GPIOB14,15设置为输入
        GPIOB->PMD.PMD15=0;
}
int main (void)
{
        UNLOCKREG();
        M0_Clock_Init();
        IO_Init();
        {
                unsigned char i=8;
                while(i--)
                {
                        GPIOA->DOUT&=~BIT2;                                                  //依次点亮LED1,LED2,LED3,LED4并一直循环
                        DrvSYS_Delay(100000);                                          //廷时100毫秒
                        GPIOA->DOUT|=BIT2;
                        GPIOA->DOUT&=~BIT3;
                        DrvSYS_Delay(100000);
                        GPIOA->DOUT|=BIT3;
                        GPIOA->DOUT&=~BIT4;
                        DrvSYS_Delay(100000);
                        GPIOA->DOUT|=BIT4;
                        GPIOA->DOUT&=~BIT5;
                        DrvSYS_Delay(100000);
                        GPIOA->DOUT|=BIT5;
                }

         }
         while(1)
         {
                 if(!((GPIOB->PIN) & BIT14))                                           //按键点亮LED1
                {
                        GPIOA->DOUT&=~BIT2;       
                }
                else
                {
                        GPIOA->DOUT|=BIT2;
                }
                if(!((GPIOB->PIN) & BIT15))                                           //按键点亮LED2
                {
                        GPIOA->DOUT&=~BIT3;       
                }
                else
                {
                        GPIOA->DOUT|=BIT3;
                }
          
         
         }
       

}

使用特权

评论回复
7
mcsgy|  楼主 | 2011-9-14 17:45 | 只看该作者
自己顶一下呢

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:从零开始

6

主题

232

帖子

1

粉丝