赞
踩
void LED_init(void)
{
GPIO_InitTypeDef gpio_info;
//PH0
//初始化GPIOH时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOH,ENABLE);
gpio_info.GPIO_Mode = GPIO_Mode_OUT;
gpio_info.GPIO_OType = GPIO_OType_PP;
gpio_info.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12;
gpio_info.GPIO_PuPd = GPIO_PuPd_UP;
gpio_info.GPIO_Speed = GPIO_Low_Speed;
GPIO_Init(GPIOH,&gpio_info);
}
void key1_init(void)
{
GPIO_InitTypeDef gpio_info;
EXTI_InitTypeDef exti_info;
NVIC_InitTypeDef NVIC_InitStructure;
//PA0
//初始化GPIOA的时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
//初始化中断时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
//配置按键
gpio_info.GPIO_Mode = GPIO_Mode_IN;
gpio_info.GPIO_OType = GPIO_OType_PP;
gpio_info.GPIO_Pin = GPIO_Pin_0;
gpio_info.GPIO_PuPd = GPIO_PuPd_NOPULL;
gpio_info.GPIO_Speed = GPIO_Low_Speed;
GPIO_Init(GPIOA,&gpio_info);
//配置按键的外部中断
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource0);
exti_info.EXTI_Line = EXTI_Line0;
exti_info.EXTI_LineCmd = ENABLE; //使能
exti_info.EXTI_Mode = EXTI_Mode_Interrupt;
exti_info.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_Init(&exti_info);
//配置这个外部中断的优先级
NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn; //PA0 对应的是EXTI0_IRQn
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_Init(&NVIC_InitStructure);
}
__IO uint32_t TimingDelay = 0;
//每10us执行一次
void TimingDelay_Decrement()
{
if(TimingDelay!=0)
TimingDelay--;
}
void Delay_10us(__IO uint32_t value)
{
TimingDelay = value;
while(TimingDelay!=0);
}
void Delay_ms(__IO uint32_t value)
{
Delay_10us(value*100);
}
void Delay_init(void)
{
//配置systick定时器每10us产生一次中断
SysTick_Config(SystemCoreClock/100000);
}
static void TIM_PWMOUTPUT_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
// 开启TIMx_CLK,x[2,3,4,5,12,13,14]
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* 累计 TIM_Period个后产生一个更新或者中断*/
//当定时器从0计数到8999,即为9000次,为一个定时周期
TIM_TimeBaseStructure.TIM_Period = 1000-1;
// 通用控制定时器时钟源TIMxCLK = HCLK/2=90MHz
// 设定定时器频率为=TIMxCLK/(TIM_Prescaler+1)=100KHz
TIM_TimeBaseStructure.TIM_Prescaler = 90-1;
// 采样时钟分频
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
// 计数方式
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
// 初始化定时器TIMx, x[2,3,4,5,12,13,14]
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/*PWM模式配置*/
/* PWM1 Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //配置为PWM模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 1000-1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //当定时器计数值小于CCR1_Val时为高电平
TIM_OC1Init(TIM2, &TIM_OCInitStructure); //使能通道1
/*使能通道1重载*/
TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable);
// 使能定时器
TIM_Cmd(TIM2, ENABLE);
}
void TIM_PWM_init()
{
TIMx_GPIO_Config();
TIM_PWMOUTPUT_Config();
}
void PWM_SetFrequency(uint32_t rate)
{
uint32_t temp =0;
if(rate == 0)
temp = 0;
else
temp= 1*1000000/rate;
TIM_SetCounter(TIM2,0);
TIM_SetAutoreload(TIM2, temp);
TIM_SetCompare1(TIM2,temp/2);
}
Delay_init();
TIM_PWM_init();
LED_init();
key1_init();
//中音
#define L1 523
#define L2 587
#define L3 659
#define L4 698
#define L5 784
#define L6 880
#define L7 988
//低音
#define k1 262
#define k2 294
#define k3 330
#define k4 349
#define k5 392
#define k6 440
#define k7 494
//高音
#define h1 1046
#define h2 1175
#define h3 1318
#define h4 1379
#define h5 1568
#define h6 1760
#define h7 1976
#define l0 500
#define l1 l0/2
#define l2 l1/2
#define l3 l0*2
uint16_t musicical1[][2]=
{
{h3,l1},{h4,l1},{h3,l1},{h2,l1},
{h3,l3},{L6,l3},{h2,l3},{L5,l3},
{h2,l3},{L5,l3},{h1,l3},{h3,l1},
{h4,l1},{h3,l1},{h2,l1},{h3,l3},
{h6,l3},{h4,l0},{h3,l1},{h2,l1},
{h1,l0},{h3,l1},{h3,l3},{h3,l1},
{h2,l1},{h1,l1},{h2,l1},{h3,l3},
{h6,l3},{h2,l3},{h3,l3},
};//"交换余生"31个字符
uint16_t musicical2[][2]=
{
{L1,l0},{L2,l0},{L3,l0},{L1,l0},
{L1,l0},{L2,l0},{L3,l0},{L1,l0},
{L3,l0},{L4,l0},{L5,l3},{L3,l0},
{L4,l0},{L5,l3},{L5,l1},{L6,l1},
{L5,l1},{L4,l1},{L3,l0},{L1,l0},
{L5,l1},{L6,l1},{L5,l1},{L4,l1},
{L3,l0},{L1,l0},{L1,l0},{k5,l0},
{L1,l3},{L1,l0},{k5,l0},{L1,l3},
};//"两只老虎"32个字符
uint16_t musicical3[][2]=
{
{L3,l0},{L2,l0},{L4,l0},{L3,l0},
{L1,l0},{L5,l0},{L7,l0},{h1,l0},
{L7,l0},{L1,l0},{L1,l0},{L1,l0},
{L6,l0},{L6,l1},{L6,l1},{L5,l0},
{L5,l1},{L5,l1},{L4,l0},{L3,l0},
{L2,l0},{L3,l0},{L4,l0},{L3,l0},
};//"晴天"24个字符
void play1()
{
static uint16_t timecnt = 0;
static uint16_t index = 0;
if(timecnt == 0)
PWM_SetFrequency(musicical1[index][0]);
timecnt+=10;
if(timecnt>=musicical1[index][1])
{
index++;
timecnt = 0;
}
if(index>=31)
index = 0;
}
void play2()
{
static uint16_t timecnt = 0;
static uint16_t index = 0;
if(timecnt == 0)
PWM_SetFrequency(musicical2[index][0]);
timecnt+=10;
if(timecnt>=musicical2[index][1])
{
index++;
timecnt = 0;
}
if(index>=32)
index = 0;
}
void play3()
{
static uint16_t timecnt = 0;
static uint16_t index = 0;
if(timecnt == 0)
PWM_SetFrequency(musicical3[index][0]);
timecnt+=10;
if(timecnt>=musicical3[index][1])
{
index++;
timecnt = 0;
}
if(index>=24)
index = 0;
}
extern int number;//引用外部变量 number
int main(void)
{
//函数初始化
Delay_init();
TIM_PWM_init();
LED_init();
key1_init();
//关闭所有LED灯
LED_Red_Ctrl(LED_OFF);
LED_Green_Ctrl(LED_OFF);
LED_Blue_Ctrl(LED_OFF);
while(1)
{
Delay_ms(10);
music_time = music_time + 10;
switch(number)
{
case 1:
play1();//播放第一首歌曲
break;
case 2:
play2();//播放第二首歌曲
break;
case 3:
play3();//播放第三首歌曲
break;
default:
break;
}
if(music_time%1000 ==0)//表示系统时间除以1000的余数是0,
{
//绿色LED灯一秒钟切换一次亮灭状态。
if(GREEN ==0)
{
LED_Green_Ctrl(LED_ON);
GREEN = 1;
}
else if(GREEN ==1)
{
LED_Green_Ctrl(LED_OFF);
GREEN = 0;
}
}
}
}
这样就完成一个简单的八音盒系统。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。