打印
[菜农助学交流]

助学板把玩,第三帖.GPIO.LED.TIMER

[复制链接]
2506|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
毅如靳往|  楼主 | 2011-9-30 21:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
开学后一直很忙,实习课设接踵而来,而悲催的学校发生网络故障发生一周之久,很多事都没做成。对cortex的学习陷入了一种泥潭,有点找不到方向了。正在努力寻找中~在这里贴上我最近写的程序,无非还是GPIO的应用。
加入了按键对LED的控制,以及结合了网友的一个蜂鸣器演奏八月桂花香的音乐程序。加入了PWM控制PA12灯闪烁的功能,不过因为效果不理想所以我屏蔽了,代码还在程序中
有兴趣的可以研究研究

/***************************************************************************
* 文件名:新唐M0学习程序
* 作  者:毅如靳往
* 邮  箱:oceanking7@163.com
* 功  能:对新唐M0的各个模块进行学习
* 备  注:¥已经利用的功能¥
*                  按键
*         LED灯
*                   蜂鸣器
*                  TIMER
*                  PWM
*                  UART
****************************************************************************
* 版本信息 *
* 日    期:2011-09-20
* 待改进: 按键松手检测
*                   增加音乐程序的开关
*                   PWM程序不理想,加入音乐代码则去不成调,尝试融合
****************************************************************************/
#include <stdio.h>
#include "NUC1xx.h"
#include "DrvGPIO.h"
#include "DrvSYS.h"
#include "Drvtimer.h"
#include "DrvUART.h"
#include "DrvPWM.h"

//=====================================函数声明=============================================
void init(void);
void key_scan(void);
void delay_loop(void);
void display(void);
void init_port(void);
void didi(unsigned char);
void music(void);
void Timer0_Callback(void);
void PWM_Config(void);
void DRVPWM_PwmIRQHandler(void);

//=====================================全局变量=============================================               
uint8_t KEY1_ST,KEY2_ST;                                     //定义按键1,2的状态储存变量
uint8_t LED1_ST=0,LED2_ST=0;                                //定义LED灯1,2的状态储存变量
uint32_t tmp;
uint32_t i;

uint8_t n;
//=================================八月桂花香音乐代码=============================================               
uint8_t music_tab1[] ={   
                                //格式为: 频率常数, 节拍常数, 频率常数, 节拍常数,
                                                        0x18, 0x30, 0x1C , 0x10,   0x20, 0x40, 0x1C , 0x10,   0x18, 0x10, 0x20 , 0x10,   0x1C, 0x10, 0x18 , 0x40,   0x1C, 0x20, 0x20 , 0x20,   
                                                        0x1C, 0x20, 0x18 , 0x20,   0x20, 0x80, 0xFF , 0x20,   0x30, 0x1C, 0x10 , 0x18,   0x20, 0x15, 0x20 , 0x1C,   0x20, 0x20, 0x20 , 0x26,   
                                                        0x40, 0x20, 0x20 , 0x2B,   0x20, 0x26, 0x20 , 0x20,   0x20, 0x30, 0x80 , 0xFF,   0x20, 0x20, 0x1C , 0x10,   0x18, 0x10, 0x20 , 0x20,   
                                                        0x26, 0x20, 0x2B , 0x20,   0x30, 0x20, 0x2B , 0x40,   0x20, 0x20, 0x1C , 0x10,   0x18, 0x10, 0x20 , 0x20,   0x26, 0x20, 0x2B , 0x20,   
                                                        0x30, 0x20, 0x2B , 0x40,   0x20, 0x30, 0x1C , 0x10,   0x18, 0x20, 0x15 , 0x20,   0x1C, 0x20, 0x20 , 0x20,   0x26, 0x40, 0x20 , 0x20,   
                                                        0x2B, 0x20, 0x26 , 0x20,   0x20, 0x20, 0x30 , 0x80,   0x20, 0x30, 0x1C , 0x10,   0x20, 0x10, 0x1C , 0x10,  0x20, 0x20, 0x26 , 0x20,   
                                                        0x2B, 0x20, 0x30 , 0x20,   0x2B, 0x40, 0x20 , 0x15,   0x1F, 0x05, 0x20 , 0x10,   0x1C, 0x10, 0x20 , 0x20,   0x26, 0x20, 0x2B , 0x20,   
                                                        0x30, 0x20, 0x2B , 0x40,   0x20, 0x30, 0x1C , 0x10,   0x18, 0x20, 0x15 , 0x20,   0x1C, 0x20, 0x20 , 0x20,   0x26, 0x40, 0x20 , 0x20,   
                                                        0x2B, 0x20, 0x26 , 0x20,   0x20, 0x20, 0x30 , 0x30,   0x20, 0x30, 0x1C , 0x10,   0x18, 0x40, 0x1C , 0x20,   0x20, 0x20, 0x26 , 0x40,   
                                                        0x13, 0x60, 0x18 , 0x20,   0x15, 0x40, 0x13 , 0x40,   0x18, 0x80, 0x00
                                            };



/****************************************************************************
* 名    称:main()
* 功    能:主函数
* 说    明:
****************************************************************************/
int main (void)
{       
        UNLOCKREG();
    SYSCLK->PWRCON.XTL12M_EN = 1;                        // SYSCLK =>12Mhz       
        DrvSYS_Delay(5000);                                                 //  等待时钟就绪                                                                                           
        LOCKREG();                       
//---------------------------临时变量---------------------------------\\   


//---------------------------初始化---------------------------------\\   
        init();                                                                        //功能初始化
        init_port();                                                        //IO初始化
          
        PWM_Config();                                                          /*PWM01配置函数*/
      
        DrvPWM_Enable(DRVPWM_TIMER0, 1);                           /* Enable the PWM Timer 0 */

//---------------------------大循环----------------------------------\\   
        while(1)
        {
                key_scan();                                                        //键盘扫描
                display();                                                        //显示
                music();                                               
/*                for( i=0;i<50;i++)
                {
                    tmp = ((PWMA->CNR0)+1)*(i*2)/100-1;
                    PWMA->CMR0 = tmp;
                        DrvSYS_Delay(10000);
                }
                 i=0;          */
        }
}

/****************************************************************************
* 名    称:init()
* 功    能:功能初始化函数
* 入口参数:main()
* 出口参数:
* 说    明:
****************************************************************************/
void init(void)
{
        DrvGPIO_InitFunction(E_FUNC_UART0);
//=====================================定时器初始化=============================================               
        {
                DrvTIMER_Init();        
                /*定时器初始化函数*/
       
                DrvSYS_SelectIPClockSource(E_SYS_TMR0_CLKSRC,0);        
                /*TIMER0 时钟源选择:000 =外部12MHz 晶振 、001 =外部 32KHz 晶振 、010 = HCLK 、011 = 外部触发时钟 、1xx =内部 22MHz 振荡器 */
               
                DrvTIMER_Open(E_TMR0,100,E_PERIODIC_MODE);       
                /*设定定时器 tick 周期并且启动定时器:定时器通道 TMR0 每秒1次 周期模式*/
               
                DrvTIMER_SetTimerEvent(E_TMR0,1,(TIMER_CALLBACK) Timer0_Callback,0);       
                /* 隔1个tick执行事件,parameter3-事件处理函数指针,4-传递参数*/
               
                DrvTIMER_EnableInt(E_TMR0);                 //使能定时器中断
               
                DrvTIMER_Start(E_TMR0);                         //启动定时器
        }


//=====================================串口初始化=============================================               
        {
                STR_UART_T param;
                       
                DrvSYS_SelectIPClockSource(E_SYS_UART_CLKSRC, 0);                         //         使能UART时钟
                DrvGPIO_InitFunction(E_FUNC_UART0);                                                         //         复用功能引脚设置
               
            param.u32BaudRate        = 115200;                                                         //         波特率
            param.u8cDataBits        = DRVUART_DATABITS_8;                                 //         数据位
            param.u8cStopBits        = DRVUART_STOPBITS_1;                                 //         停止位
            param.u8cParity          = DRVUART_PARITY_NONE;                                 //         校验位
            param.u8cRxTriggerLevel  = DRVUART_FIFO_1BYTES;                                 //         FIFO存储深度 1 字节
            param.u8TimeOut                 = 0;                                                                 //         FIFO超时设定
            DrvUART_Open(UART_PORT0, ¶m);                                                         //         串口开启、结构体整体赋值          
        }                                                         

}
/****************************************************************************
* 名    称:init_port()
* 功    能:端口初始化函数
* 入口参数:main()
* 出口参数:
* 说    明:
****************************************************************************/
void init_port(void)
{
        DrvGPIO_Open(E_GPA,2, E_IO_OUTPUT);                                                  //////////////////
        DrvGPIO_Open(E_GPA,3, E_IO_OUTPUT);                                                  //     LED      //  
        DrvGPIO_Open(E_GPA,4, E_IO_OUTPUT);                                            //     配置     //
        DrvGPIO_Open(E_GPA,5, E_IO_OUTPUT);                                                  //////////////////

        DrvGPIO_SetBit(E_GPA,2);
        DrvGPIO_SetBit(E_GPA,3);
        DrvGPIO_SetBit(E_GPA,4);
        DrvGPIO_SetBit(E_GPA,5);


           /*设置PA12为输出,PA12为PWM01功能*/
    DrvGPIO_InitFunction(E_FUNC_PWM01);


        DrvGPIO_Open(E_GPB, 15, E_IO_INPUT);                                   //按键IO类型配置
        DrvGPIO_Open(E_GPB, 14, E_IO_INPUT);

        DrvGPIO_Open(E_GPB, 10, E_IO_OUTPUT);                                        //蜂鸣器IO类型配置
        DrvGPIO_ClrBit(E_GPB,10);
}


/****************************************************************************
* 名    称:key_scan()
* 功    能:键盘扫描函数
* 入口参数:main()
* 出口参数:
* 说    明:GPB15-----KEY1                                GPB14-------KEY2
****************************************************************************/
void key_scan(void)
{
        KEY1_ST = DrvGPIO_GetBit (E_GPB, 15);                                   //获取KEY1的值
        KEY2_ST = DrvGPIO_GetBit (E_GPB, 14);                                   //获取KEY2的值
//按键KEY1的响应动作
        if (KEY1_ST == 0)
        {
                delay_loop();                                                                         //消抖
                delay_loop();                                                                         //消抖(写两个是为了足够的消抖时间)
                 if (KEY1_ST == 0)
                {
                        if(++LED1_ST>5)        LED1_ST=0;
                        didi(1);                        //形参传递为几  则蜂鸣器响几声
                }
        }
//按键KEY2的响应动作
        if (KEY2_ST == 0)
        {
                delay_loop();
                delay_loop();
                 if (KEY2_ST == 0)
                {
                        LED2_ST=~LED2_ST;
/*                        if(LED2_ST==0)
                                music();
                        else
                                didi(1);                        */
//                        while(!KEY1_ST)                          //按键松手检测
//                        {
//                                 display();
//                        }
                }
        }

}
/****************************************************************************
* 名    称:display()
* 功    能:显示函数
* 入口参数:main()
* 出口参数:
* 说    明:
****************************************************************************/
void display(void)
{
        switch(LED1_ST)
        {
                 case 0:        DrvGPIO_SetBit(E_GPA,2);
                                DrvGPIO_SetBit(E_GPA,3);
                                DrvGPIO_SetBit(E_GPA,4);
                                DrvGPIO_SetBit(E_GPA,5);
                                break;
                 case 1:        DrvGPIO_ClrBit(E_GPA,2);
                                DrvGPIO_SetBit(E_GPA,3);
                                DrvGPIO_SetBit(E_GPA,4);
                                DrvGPIO_SetBit(E_GPA,5);
                                break;
                case 2:        DrvGPIO_ClrBit(E_GPA,3);
                                DrvGPIO_SetBit(E_GPA,2);
                                DrvGPIO_SetBit(E_GPA,4);
                                DrvGPIO_SetBit(E_GPA,5);
                                break;
                case 3:        DrvGPIO_ClrBit(E_GPA,4);
                                DrvGPIO_SetBit(E_GPA,2);
                                DrvGPIO_SetBit(E_GPA,3);
                                DrvGPIO_SetBit(E_GPA,5);
                                break;
                case 4:        DrvGPIO_ClrBit(E_GPA,5);
                                DrvGPIO_SetBit(E_GPA,2);
                                DrvGPIO_SetBit(E_GPA,3);
                                DrvGPIO_SetBit(E_GPA,4);
                                break;
                case 5:       
                                 DrvGPIO_ClrBit(E_GPA,2);
                                DrvGPIO_SetBit(E_GPA,3);
                                DrvGPIO_SetBit(E_GPA,4);
                                DrvGPIO_SetBit(E_GPA,5);
                                delay_loop();
                                DrvGPIO_ClrBit(E_GPA,3);
                                DrvGPIO_SetBit(E_GPA,2);
                                DrvGPIO_SetBit(E_GPA,4);
                                DrvGPIO_SetBit(E_GPA,5);
                                delay_loop();
                                DrvGPIO_ClrBit(E_GPA,4);
                                DrvGPIO_SetBit(E_GPA,2);
                                DrvGPIO_SetBit(E_GPA,3);
                                DrvGPIO_SetBit(E_GPA,5);
                                delay_loop();
                                DrvGPIO_ClrBit(E_GPA,5);
                                DrvGPIO_SetBit(E_GPA,2);
                                DrvGPIO_SetBit(E_GPA,3);
                                DrvGPIO_SetBit(E_GPA,4);
                                delay_loop();
                                 DrvGPIO_SetBit(E_GPA,2);
                                DrvGPIO_SetBit(E_GPA,3);
                                DrvGPIO_SetBit(E_GPA,4);
                                DrvGPIO_SetBit(E_GPA,5);
                                delay_loop();
                                break;
        }
}



/****************************************************************************
* 名    称:delay_loop()
* 功    能:延时函数
* 入口参数:
* 出口参数:
* 说    明:
****************************************************************************/
void delay_loop(void)                         
{
        uint32_t j;
        for(j=0;j<60000;j++);               
        for(j=0;j<60000;j++);
        for(j=0;j<60000;j++);               
        for(j=0;j<60000;j++);
}


/****************************************************************************
* 名    称:didi(unsigned char n)
* 功    能:发声函数
* 入口参数:key_scan()
* 出口参数:
* 说    明:形参传递为几  则蜂鸣器响几声
****************************************************************************/
void didi(unsigned char n)
{
        for(;n>0;n--)
        {
                DrvGPIO_SetBit(E_GPB,10);                 //鸣叫
                delay_loop();
                DrvGPIO_ClrBit(E_GPB,10);
                delay_loop();                                         //静音
        }
}

/****************************************************************************
* 名    称:Timer0_Callback(void)
* 功    能:Timer0回调函数
* 入口参数:
* 出口参数:
* 说    明:
****************************************************************************/
void Timer0_Callback(void)
{

        n--;

}


/****************************************************************************
* 名    称:music(void)
* 功    能:音乐函数
* 入口参数:
* 出口参数:
* 说    明:
****************************************************************************/
void music(void)
{
        uint8_t p,m,flag;   //m为频率常数变量   
          uint8_t i=0;
        uint8_t music_on=0;
       
        music_on=LED2_ST;

        play:   
           while(music_on)   
            {   
            a: p=music_tab1[i];   
               if(p==0x00)  
                   {
                                   i=0;
                                DrvSYS_Delay(1000000);
                                goto play;
                   }     
               else if(p==0xff)
                           {
                                i=i+1;
                                DrvSYS_Delay(100000);
                                DrvTIMER_DisableInt(E_TMR0);
                                goto a;
                        }      
               else  
                   {
                                   m=music_tab1[i++];
                                n=music_tab1[i++];
                        }      
                        DrvTIMER_EnableInt(E_TMR0);                 //使能定时器中断
                        DrvTIMER_Start(E_TMR0);                                 //启动定时器
                   while(n!=0)
                   {
                           if (flag) DrvGPIO_ClrBit(E_GPB, 10);                           //蜂鸣器
                           else
                           DrvGPIO_SetBit(E_GPB, 10);
                           DrvSYS_Delay(3*m);
                           flag=~flag;
                   }
                       

                        DrvTIMER_DisableInt(E_TMR0);  
                        
            }                                  
}


/****************************************************************************
* 名    称:DRVPWM_PwmIRQHandler()
* 功    能:PWM Timer Callback function
* 入口参数:
* 出口参数:
* 说    明:
****************************************************************************/
void DRVPWM_PwmIRQHandler()
{       
/*  uint8_t E_GPA_STA=DrvGPIO_GetBit(E_GPA , 2);
   if(E_GPA_STA==1);
   {
              DrvGPIO_ClrBit(E_GPA,2);
   }
   if(E_GPA_STA==0)
   {
           DrvGPIO_SetBit(E_GPA,2);
   }
         */
        ;
}
/****************************************************************************
* 名    称:PWM_Config()
* 功    能:PWM配置函数
* 入口参数:
* 出口参数:
* 说    明:
****************************************************************************/
void PWM_Config()
{
                S_DRVPWM_TIME_DATA_T sPt;//定义一个PWM配置的结构体
        /*
            结构体如下:
            typedef struct
            {
                uint8_t          u8Mode;
                uint8_t          u8HighPulseRatio;
                uint8_t          u8ClockSelector;
                uint8_t          u8PreScale;
                uint32_t            u32Frequency;       
                uint32_t            u32Duty;
                int32_t          i32Inverter;
            }S_DRVPWM_TIME_DATA_T;
            */
                sPt.u8Mode = DRVPWM_AUTO_RELOAD_MODE;//自动重载模式
                sPt.u8HighPulseRatio=50;

        //        spt.u8ClockSelector=   
        //        spt.u8PreScale=   
                sPt.u32Frequency=400;
        //        spt.u32Duty=
                sPt.i32Inverter=0;

                /* Enable PWM clock */
        DrvPWM_Open();       

                /* Select PWM engine clock */
                DrvPWM_SelectClockSource(DRVPWM_TIMER0, DRVPWM_EXT_12M);  //设置外部12M时钟为时钟源

                /* Set PWM Timer0 Configuration */
                DrvPWM_SetTimerClk(DRVPWM_TIMER0, &sPt);


                /* Enable Output for PWM Timer0 */
            DrvPWM_SetTimerIO(DRVPWM_TIMER0, 1);


                /* Enable Interrupt Sources of PWM Timer0 and install call back function */
                DrvPWM_EnableInt(DRVPWM_TIMER0, 0, DRVPWM_PwmIRQHandler);


       
}

相关帖子

沙发
毅如靳往|  楼主 | 2011-9-30 21:46 | 只看该作者
2011.09.20.rar (1.45 MB)
工程文件
忘记添加了~

使用特权

评论回复
板凳
hotpower| | 2011-10-1 14:40 | 只看该作者
不错!

使用特权

评论回复
地板
毅如靳往|  楼主 | 2011-10-1 23:05 | 只看该作者
其实我个人觉得程序本体倒是没什么创新,希望能给各位以我编程格式的一个启发,因为我看很多人的代码都只是代码,多加注释,对自己以后的审阅也有帮助的,当然,只是建议

使用特权

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

本版积分规则

2

主题

176

帖子

1

粉丝