测试下性能而已不建议真的用链表做,容易爆内存。
struct notes //一个音符
{
uint16_t freq; //频率
uint8_t duty; //占空比
uint16_t deley; //播放时长
struct notes *next_note;//下一个音符
};
储存一个音符的结构体,
void play_ones(uint16_t freq,uint8_t dutya)
{
//寄存器写法 需要根据单片机的时钟来写。
TIM4->ARR = (uint32_t)((2000000/freq)-1);TIM4->CCR3 = (uint32_t)(((2000000/freq)-1)*((float)dutya/100));
}
播放一个音符,寄存器写法。
struct notes *notes;
定义一个音符头
void add_a_note(uint16_t freq,uint8_t duty,uint16_t deley)//添加一个音符
{
struct notes* buff;
buff = (struct notes*)malloc(sizeof(struct notes));
if (buff != NULL)
{
buff->freq = freq;
buff->duty = duty;
buff->deley = deley;
buff->next_note = NULL;
if (notes == NULL)
{
notes = buff;
}
else
{
struct notes *t = notes;
while (t->next_note != NULL)
{
t = t->next_note;
}
t->next_note = buff;
}
}
}
void delhead() //删除第一个音符 一般用户不需要调用
{
if (notes == NULL)
{
return;
}
if (notes->next_note == NULL)
{
free(notes);
notes = NULL;
}
else
{
struct notes *t = notes;
notes = notes->next_note;
free(t);
}
}
char buzzer_play_server() //放在主循环 只有有音符添加进来就会播放,播放完自动释放
{
static char busy_flag=0;
static uint32_t play_delay;
if(notes == NULL)
{
play_ones(0,0);
}else
{
if(busy_flag==0)
{
busy_flag=1;
play_delay=HAL_GetTick()+notes->deley;
play_ones(notes->freq,notes->duty);
}
if(busy_flag==1)
{
if(HAL_GetTick()>play_delay)
{
busy_flag=0;
delhead();
}
}
}
return busy_flag;
}