通过HAL库实现全部代码,使用的工具有:STM32CudeMx,keil5,vscode等,我先写总结部分在分模块来写。
首先我们要实现的时钟系统要有以下功能:
1,时间显示功能
2,闹钟功能
3,音乐播放功能
4,音量调节功能,
5,提醒功能
.....................
基于以上要求,我们需要的硬件有,STM 32F103系列芯片一块,0.96OLED屏幕,无源蜂鸣器,电源模块,矩阵键盘,USB串口模块,DS1302(可有)等器件,其中OLED提供显示功能,需要在cubemx中打开I2C通信,用IIC来控制oled的显示内容,无源蜂鸣器用来播放音乐,使用pwm脉冲调制,将歌曲的简谱的音节转化成频率,定时功能和时间显示功能,提醒功能都使用STM32自带的RTC来实现。具体的技术要求和功能就这些,我水平有限,若有更好的方法和技术记得滴滴我一下,谢谢。
先来蜂鸣器部分:
music.c文件:
#include "music.h"
int music_kayqiusha[72] = {
d6, d6, d6, d7, z1, z1, z1, d6, z1, z1, d7, d6, d7, d7, d3, wu, d7, d7, d7, z1,
z2, z2, z2, d7, z2, z2, z1, d7, d6, d6, d6, d6, z3, z3, z6, z6, z5, z5, z6, z5,
z4, z4, z3, z2, z3, z3, d6, d6, wu, z4, z4, z2, z3, z3, z3, z1, d7, d3, z1, d7,
d6, d6, d6, d6, z3, z3, z4, z5, z6, z6, z6, z6};
int music_ssssa[160]={wu,wu,wu,wu,z3,z3,z3,z3,g1,g1,g1,g1,z7,z7,z7,z7,//0317
z6,z6,z6,z7,z6,z6,z5,z5,z6,z6,z6,z7,z6,z6,z5,z5,//6676566765
z6,z6,z7,z7,z7,z7,z7,z7,z7,z7,z3,z3,g1,g1,z7,z7,//6777317
z6,z6,z6,z7,z6,z6,z5,z5,z6,z6,z6,z7,z6,z6,z5,z5,//6676566765
g2,g2,g3,g3,g3,g3,g3,g3,g3,g3,g3,g3,g1,g1,g2,g2,//233312
g3,g3,g3,g3,g2,g2,g2,g2,g1,g1,g1,g1,g2,g2,z7,z7,//32127
z7,z7,z7,z7,z7,z7,z6,z6,z6,z6,z6,z6,z6,z6,g1,g1,//7661
z7,z7,z7,z7,z7,z7,g1,g1,g2,g2,g2,g2,g1,g1,g3,g3,//71213
g3,g3,g4,g3,g2,g2,g2,g3,g3,g3,g3,g3,g3,g3,g3,g3,//343233
g3,g3,g3,g3,g3,g3,g3,g3,g3,g3,g3,g3,g3,g3,g3,g3};
void bueep_srt(int arr1)
{
__HAL_TIM_SetAutoreload(&htim2, arr1);
__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_4, arr1 / 2);
}
void miusc(int n)
{
HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_4);
if (n==1)
{
int i = 0;
for (i = 0; i < 72; i++)
{
bueep_srt(music_kayqiusha[i]);
HAL_Delay(250);
}
}else if(n==2)
{
int i = 0;
for (i = 0; i < 160; i++)
{
bueep_srt(music_ssssa[i]);
HAL_Delay(100);
}
}
else{
HAL_TIM_PWM_Stop(&htim2,TIM_CHANNEL_4);
}
先看代码后面再看cubemx的具体设置,由上面的代码可以看到我定义了两个数组,里面存放了我对《喀秋莎》《生生世世爱》部分旋律的转译,bueep_str函数是对pwm进行计数重装载和改变翻转值,其中 __HAL_TIM_SetAutoreload(&htim2, arr1);是对tim2的计数值进行重装载,__HAL_TIM_SetCompare(&htim2, TIM_CHANNEL_4, arr1 / 2);是对电平翻转值进行重装,两个函数定时HAL库定义的宏函数,函数名是不可以改变的,
参数:&htin2是选中tim2的定时器,也叫句柄,arr1是数组的首地址,TIM_CHANNEL_4,是定时器通道,有4个通道,1,2,3,4随便选一个,相应参数变一下就可以arr1/2就是电平反转的值,除2代表占空比是50%,当然也可以是其它的占空比,接下来是.h文件
music.h:
#ifndef __MUSIC_H__
#define __MUSIC_H__
#include "tim.h"
#include "main.h"
#define d1 1000000/262
#define d2 1000000/294
#define d3 1000000/330
#define d4 1000000/349
#define d5 1000000/392
#define d6 1000000/440
#define d7 1000000/494
#define z1 1000000/523
#define z2 1000000/587
#define z3 1000000/659
#define z4 1000000/698
#define z5 1000000/784
#define z6 1000000/880
#define z7 1000000/988
#define g1 1000000/1047
#define g2 1000000/1175
#define g3 1000000/1319
#define g4 1000000/1397
#define g5 1000000/1568
#define g6 1000000/1760
#define g7 1000000/1976
#define wu 1000000/1
void bueep_srt(int arr1);
void miusc(int n);
#endif // __MUSIC_H__
因为在简谱音节中一般有低中高三个音域,所以我用d,z,g,来代表,如d1代表低音1,依次类推,
这里没有什么好解释的就跳过了。
还有就是.c文件里面的数组我是把一个音节分成两个音节来处理的,所以一个节拍有8个音或者16个音,看歌曲的最短音节有多长。
看cubemx的设置,直接上图:
大概设置就是这样啊,第一步就是点Timers->tim2(1,2,3,4)->clock soure->以及预分频等操作,(有点多,详情去搜STM32CubeMx创建过程的操作)做完后直接初始化,把上面的.c.h文件一写就可以播放音乐了,欧克。