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