- /***************************************************************************
- * 文件名:新唐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);
-
- }