中斷版音樂播放
/*音調的有關宏定義*/
#define proport 10000 //Tclk/(psc+1)=72000000/(7199+1)
#define L1 ((proport/131)-1)//低調 do 的周期根據Tout= ((arr+1)*(psc+1))/Tclk推出arr值就是本句define定義的值,Tout為音調頻率131Hz的倒數,Tclk=72MHz
#define L2 ((proport/147)-1)//低調 re 的周期
#define L3 ((proport/165)-1)//低調 mi 的周期
#define L4 ((proport/176)-1)//低調 fa 的周期
#define L5 ((proport/196)-1)//低調 sol的周期
#define L6 ((proport/220)-1)//低調 la 的周期
#define L7 ((proport/247)-1)//低調 si 的周期
#define M1 ((proport/262)-1)//中調 do 的周期
#define M2 ((proport/296)-1)//中調 re 的周期
#define M3 ((proport/330)-1)//中調 mi 的周期
#define M4 ((proport/349)-1)//中調 fa 的周期
#define M5 ((proport/392)-1)//中調 sol的周期
#define M6 ((proport/440)-1)//中調 la 的周期
#define M7 ((proport/494)-1)//中調 si 的周期
#define H1 ((proport/523)-1)//高調 do 的周期
#define H2 ((proport/587)-1)//高調 re 的周期
#define H3 ((proport/659)-1)//高調 mi 的周期
#define H4 ((proport/699)-1)//高調 fa 的周期
#define H5 ((proport/784)-1)//高調 sol的周期
#define H6 ((proport/880)-1)//高調 la 的周期
#define H7 ((proport/988)-1)//高調 si 的周期
#define TT 200
/*
字母加數字為音符,
數字為節拍
*/
uint16_t indexWave[] = {
// M5,50,M5,25,M5,25,
// M6,100,M5,100,H1,100,
// M7,100,M7,100,M5,50,M5,25,M5,25,
// M6,100,M5,100,H2,100,
// H1,100,H1,100,M5,50,M5,25,M5,25,
// H5,100,H3,100,H1,100,
// M7,100,M6,100,H4,50,H4,25,H4,25,
// H3,100,H1,100,H2,100,H1,100,H1,100
//兩只老虎
// L1,4,L2,4,L3,4,L1,4,
// L1,4,L2,4,L3,4,L1,4,
// L3,4,L4,4,L5,8,
// L3,4,L4,4,L5,8,
// L5,3,L6,1,L5,3,L6,1,L3,4,L1,4,
// L5,3,L6,1,L5,3,L6,1,L3,4,L1,4,
// L2,4,M5,4,L1,8,
// L2,4,M5,4,L1,8
////歡樂頌
//M3,8,M3,8,M4,8,M5,8,
//M5,8,M4,8,M3,8,M2,8,
//M1,8,M1,8,M2,8,M3,8,
//M3,12,M2,4,M2,16,
//M3,8,M3,8,M4,8,M5,8,
//M5,8,M4,8,M3,8,M2,8,
//M1,8,M1,8,M2,8,M3,8,
//M2,12,M1,4,M1,16,
//M2,8,M2,8,M3,8,M1,8,
//M2,8,M3,4,M4,4,M3,8,M1,8,
//M2,8,M3,4,M4,4,M3,8,M2,8,
//M1,8,M2,8,L5,8,M3,8,
//M3,8,M3,8,M4,8,M5,8,
//M5,8,M4,8,M3,8,M4,4,M2,4,
//M1,8,M1,8,M2,8,M3,8,
//M2,12,M1,4,M1,16,
//M2,8,M2,8,M3,8,M1,8,
//M2,8,M3,4,M4,4,M3,8,M1,8,
//M2,8,M3,4,M4,4,M3,8,M2,8,
//M1,8,M2,8,L5,8,M3,8,
//M3,8,M3,8,M4,8,M5,8,
//M5,8,M4,8,M3,8,M4,4,M2,4,
//M1,8,M1,8,M2,8,M3,8,
//M2,12,M1,4,M1,16
////最炫民族風
L6,TT/4,L3,TT/8,L5,TT/8,L6,TT/4,L6,TT/8,M1,TT/8,M1,TT/4,M2,TT/8,M1,TT/8,L6,TT/2,M1,TT/4,M1,TT/8,L5,TT/8,M1,TT/8,M2,TT/8,M3,TT/8,M5,TT/8,
M5,TT/8,M3,TT/8,M2,TT/4,M3,TT/2,M6,TT/8,M6,TT/8,M6,TT/8,M5,TT/8,M3,TT/8,M3,TT/4,M1,TT/8,L6,TT/8,L6,TT/8,L6,TT/8,M3,TT/8,
M2,TT/2,M3,TT/8,M3,TT/8,M5,TT/8,M3,TT/8,M2,TT/8,M3,TT/8,M2,TT/8,M1,TT/8,L6,TT/4,L5,TT/4,L6,TT/2,
L6,TT/4,L3,TT/8,L5,TT/8,L6,TT/4,L6,TT/8,M1,TT/8,M1,TT/4,M2,TT/8,M1,TT/8,L6,TT/2,M1,TT/4,M1,TT/8,L5,TT/8,M1,TT/8,M2,TT/8,M3,TT/8,M5,TT/8,
M5,TT/8,M3,TT/8,M2,TT/4,M3,TT/2,M6,TT/8,M6,TT/8,M6,TT/8,M5,TT/8,M3,TT/8,M3,TT/4,M1,TT/8,L6,TT/8,L6,TT/8,L6,TT/8,M3,TT/8,
M2,TT/2,M3,TT/8,M3,TT/8,M5,TT/8,M3,TT/8,M2,TT/8,M3,TT/8,M2,TT/8,M1,TT/8,L6,TT/4,L5,TT/4,L6,TT/2,
M3,TT/8,M3,TT/8,M5,TT/8,M3,TT/8,M3,TT/8,M5,TT/8,M5,TT/8,M6,TT/8,H1,TT/8,M6,TT/8,M5,TT/4,M6,TT/2,L6,TT/4,L6,TT/8,
L5,TT/8,L6,TT/4,M1,TT/4,M2,TT/8,M3,TT/16,M2,TT/16,M1,TT/8,M2,TT/8,M3,TT/2,L6,TT/8,M6,TT/8,M6,TT/8,M5,TT/8,M2,TT/8,M3,TT/16,M2,TT/16,
M1,TT/8,M2,TT/8,M3,TT/2,
M1,TT/8,L6,TT/8,L6,TT/8,M1,TT/8,M2,TT/4,L5,TT/8,L5,TT/8,M3,TT/8,M5,TT/8,M3,TT/8,M2,TT/8,M1,TT/2,L6,TT/8,M1,TT/8,M2,TT/8,M3,TT/8,M2,TT/8,M1,TT/8,
L5,TT/8,L3,TT/8,L6,TT/2,L6,TT/4,L6,TT/8,L5,TT/8,L6,TT/4,M1,TT/4,M2,TT/8,M3,TT/16,M2,TT/16,M1,TT/8,M2,TT/8,M3,TT/2,L6,TT/8,M6,TT/8,
M6,TT/8,M5,TT/8,M2,TT/8,M3,TT/16,M2,TT/16,
M1,TT/8,M2,TT/8,M3,TT/2,
M1,TT/8,L6,TT/8,L6,TT/8,M1,TT/8,M2,TT/4,L5,TT/8,L5,TT/8,M3,TT/8,M5,TT/8,M3,TT/8,M2,TT/8,M1,TT/4+TT/8,M1,TT/8,L6,TT/8,
M1,TT/8,M2,TT/8,M3,TT/8,M5,TT/8,M3,TT/8,M3,TT/8,M5,TT/8,M6,TT/2,M6,TT/2,L6,TT/4,L6,TT/8,L5,TT/8,L6,TT/4,
L6,TT/8,M1,TT/8,M2,TT/8,M3,TT/16,M2,TT/16,M1,TT/8,M2,TT/8,M3,TT/2,
M6,TT/8,M5,TT/8,M3,TT/8,M2,TT/8,M5,TT/8,M3,TT/8,M2,TT/8,M1,TT/8,M1,TT/2,
L6,TT/4,L6,TT/8,L5,TT/8,L6,TT/4,M1,TT/4,M2,TT/8,M3,TT/16,M2,TT/16,M1,TT/8,M2,TT/8,M3,TT/2,L6,TT/8,M6,TT/8,M6,TT/8,M5,TT/8,M2,TT/8,M3,TT/16,M2,TT/16,
M1,TT/8,M2,TT/8,M3,TT/2,
M1,TT/8,L6,TT/8,L6,TT/8,M1,TT/8,M2,TT/4,L5,TT/8,L5,TT/8,M3,TT/8,M5,TT/8,M3,TT/8,M2,TT/8,M1,TT/2,L6,TT/8,M1,TT/8,M2,TT/8,M3,TT/8,M2,TT/8,M1,TT/8,
L5,TT/8,L3,TT/8,L6,TT/2,L6,TT/4,L6,TT/8,L5,TT/8,L6,TT/4,M1,TT/4,M2,TT/8,M3,TT/16,M2,TT/16,M1,TT/8,M2,TT/8,M3,TT/2,L6,TT/8,M6,TT/8,
M6,TT/8,M5,TT/8,M2,TT/8,M3,TT/16,M2,TT/16,
M1,TT/8,M2,TT/8,M3,TT/2,
M1,TT/8,L6,TT/8,L6,TT/8,M1,TT/8,M2,TT/4,L5,TT/8,L5,TT/8,M3,TT/8,M5,TT/8,M3,TT/8,M2,TT/8,M1,TT/4+TT/8,M1,TT/8,L6,TT/8,
M1,TT/8,M2,TT/8,M3,TT/8,M5,TT/8,M3,TT/8,M3,TT/8,M5,TT/8,M6,TT/2,M6,TT/2
};
//計算PWM表有多少個元素其中音符和音調的節拍各占一半
uint16_t POINT_NUM = sizeof(indexWave)/sizeof(indexWave[0]);
/**
配置TIM復用輸出PWM時用到的I/O
*/
static void TIMx_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* clock enable */
RCC_APB2PeriphClockCmd(BRE_TIM_GPIO_CLK, ENABLE);
BRE_TIM_GPIO_APBxClock_FUN ( BRE_TIM_GPIO_CLK, ENABLE );
// BRE_GPIO_REMAP_FUN();
/* 配置呼吸燈用到的引腳 */
GPIO_InitStructure.GPIO_Pin = BRE_TIM_LED_PIN ;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // 復用推挽輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( BRE_TIM_LED_PORT, &GPIO_InitStructure );
}
/*
配置嵌套向量中斷控制器NVIC
*/
static void NVIC_Config_PWM(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure one bit for preemption priority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* 配置TIM3_IRQ中斷為中斷源 */
NVIC_InitStructure.NVIC_IRQChannel = BRE_TIMx_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
/**
配置TIM輸出的PWM信號的模式,如周期、極性
*/
static void TIMx_Mode_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
/* 設置TIM3CLK 時鐘 */
BRE_TIM_APBxClock_FUN ( BRE_TIM_CLK, ENABLE );
/* 基本定時器配置 */
// TIM_TimeBaseStructure.TIM_Period = (1024-1);; //當定時器從0計數到 TIM_Period+1 ,為一個定時周期
TIM_TimeBaseStructure.TIM_Prescaler =(7200-1); //設置預分頻
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1 ; //設置時鐘分頻系數:不分頻(這里用不到)
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上計數模式
TIM_TimeBaseInit(BRE_TIMx, &TIM_TimeBaseStructure);
/* PWM模式配置 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //配置為PWM模式1
TIM_OCInitStructure.TIM_OCIdleState=TIM_OCIdleState_Set; // 輸出通道空閑電平極性配置
// TIM_OCInitStructure.TIM_Pulse = 0; //設置初始PWM脈沖寬度為0
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //當定時器計數值小于CCR1_Val時為低電平
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //使能輸出
BRE_TIM_OCxInit ( BRE_TIMx, &TIM_OCInitStructure ); //使能通道
BRE_TIM_OCxPreloadConfig ( BRE_TIMx, TIM_OCPreload_Enable ); //使能預裝載
TIM_ARRPreloadConfig(BRE_TIMx, ENABLE); //使能TIM重載寄存器ARR
TIM_Cmd(BRE_TIMx, ENABLE);
//使能定時器
TIM_ITConfig(BRE_TIMx, TIM_IT_Update, ENABLE); //使能中斷
NVIC_Config_PWM(); //配置中斷優先級
}
void TIMx_Breathing_Init(void)
{
TIMx_GPIO_Config();
TIMx_Mode_Config();
}
/* 中斷服務函數 */
void BRE_TIMx_IRQHandler(void)
{
if (TIM_GetITStatus(BRE_TIMx, TIM_IT_Update) != RESET) //TIM_IT_Update
{
for(i=0; i<(POINT_NUM/2); i++) //只有一半是音符,一半是節拍
{
i++;
BRE_TIMx->ARR = indexWave[2*i];
BRE_TIMx->BRE_CCRx = indexWave[2*i];
SysTick_Delay_ms(5*indexWave[2*i+1]);//音長的時間都乘以5即一拍為500微秒
}
if (i>=(POINT_NUM/2))//當I大于等于數組音符元素時I清零重新開始播放音樂
{
i=0;
}
TIM_ClearITPendingBit (BRE_TIMx, TIM_IT_Update); //必須要清除中斷標志位
}
}
|