写在前面
??蜂鸣器分为有源蜂鸣器与无源蜂鸣器。有源蜂鸣器是带振荡源的,无源蜂鸣器则没有。有源蜂鸣器可以一通电就发声,无源蜂鸣器则需要一定频率的方波才可以发声。
Beeper编程思路
??Beeper根据应用情况不同,可能存在以下差异:
1.蜂鸣器的个数不固定。 2.蜂鸣器的端口和引脚不固定。 3.存在高低电平驱动两种方式。
构建结构
1.构建高低电平的枚举类型。
typedef enum __BEEPER_ValidLevel_ENUM
{
LowLevel = 0,
HighLevel = 1
}BEEPER_ValidLevel_ENUM;
2.构建BEEPER的硬件结构体。
typedef struct __BEEPERHardware_TypeDef_Struct
{
GPIO_TypeDef *BEEPER_GPIOx;
uint16_t BEEPER_GPIO_Pin;
}BEEPERHardware_TypeDef_Struct;
3.构建BEEPER的参数结构体。
typedef struct __BEEPERMemory_TypeDef_Struct
{
FunctionalState enable;
BEEPER_ValidLevel_ENUM level;
}BEEPERMemory_TypeDef_Struct;
4.构建BEEPER的结构体。
typedef struct __LED_TypeDef_Struct
{
BEEPERHardware_TypeDef_Struct BEEPERHardWare;
BEEPERMemory_TypeDef_Struct BEEPERMemory;
}BEEPER_TypeDef_Struct;
5.构建BEEPER的初始化结构体。
typedef struct __BEEPER_InitTypeDef_Struct
{
FunctionalState enable;
BEEPER_ValidLevel_ENUM pol;
}BEEPER_InitTypeDef_Struct;
构建宏以及变量空间
1.构建BEEPER变量空间。
BEEPER_TypeDef_Struct BEEPER_BASE[4];
2.构建BEEPER的个数。
#define BEEPER_NUM_MAX (4)
3.构建BEEPER的内存空间及对应配置。
#if(BEEPER_NUM_MAX >= 1)
#define BEEPER1 (&BEEPER_BASE[0])
#define BEEPER1_GPIO GPIOB
#define BEEPER1_GPIO_Pin GPIO_Pin_5
#endif
#if(BEEPER_NUM_MAX >= 2)
#define BEEPER2 (&BEEPER_BASE[1])
#define BEEPER2_GPIO GPIOB
#define BEEPER2_GPIO_Pin GPIO_Pin_6
#endif
#if(BEEPER_NUM_MAX >= 3)
#define BEEPER3 (&BEEPER_BASE[2])
#define BEEPER3_GPIO GPIOB
#define BEEPER3_GPIO_Pin GPIO_Pin_7
#endif
#if(BEEPER_NUM_MAX >= 4)
#define BEEPER4 (&BEEPER_BASE[3])
#define BEEPER4_GPIO GPIOB
#define BEEPER4_GPIO_Pin GPIO_Pin_8
#endif
4.构建默认参数。
#define BEEPER_VALIDLEVEL_DEFAULT LowLevel
#define BEEPER_ENABLE_DEFAULT ENABLE
具体函数
1.使用默认参数填写初始化结构体。
void BEEPER_StructInit(BEEPER_InitTypeDef_Struct* BEEPERx_InitStruct)
{
BEEPERx_InitStruct->enable = BEEPER_ENABLE_DEFAULT;
BEEPERx_InitStruct->pol = BEEPER_VALIDLEVEL_DEFAULT;
}
2.初始化具体的BEEPER。
ErrorStatus BEEPER_Init(BEEPER_TypeDef_Struct* BEEPERx,BEEPER_InitTypeDef_Struct* BEEPER_InitStruct)
{
GPIO_InitTypeDef GPIO_InitStructure;
if((BEEPERx == NULL) || (BEEPER_InitStruct == NULL))
{
return ERROR;
}
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
if(BEEPERx == BEEPER1)
{
BEEPER_BASE[0].BEEPERHardWare.BEEPER_GPIOx = BEEPER1_GPIO;
BEEPER_BASE[0].BEEPERHardWare.BEEPER_GPIO_Pin = BEEPER1_GPIO_Pin;
}
else if(BEEPERx == BEEPER2)
{
BEEPER_BASE[1].BEEPERHardWare.BEEPER_GPIOx = BEEPER2_GPIO;
BEEPER_BASE[1].BEEPERHardWare.BEEPER_GPIO_Pin = BEEPER2_GPIO_Pin;
}
else if(BEEPERx == BEEPER3)
{
BEEPER_BASE[2].BEEPERHardWare.BEEPER_GPIOx = BEEPER3_GPIO;
BEEPER_BASE[2].BEEPERHardWare.BEEPER_GPIO_Pin = BEEPER3_GPIO_Pin;
}
else if(BEEPERx == BEEPER4)
{
BEEPER_BASE[3].BEEPERHardWare.BEEPER_GPIOx = BEEPER4_GPIO;
BEEPER_BASE[3].BEEPERHardWare.BEEPER_GPIO_Pin = BEEPER4_GPIO_Pin;
}
else
{
return ERROR;
}
BEEPERx->BEEPERMemory.enable = BEEPER_InitStruct->enable;
BEEPERx->BEEPERMemory.level = BEEPER_InitStruct->pol;
GPIO_InitStructure.GPIO_Pin = BEEPERx->BEEPERHardWare.BEEPER_GPIO_Pin;
GPIO_Init(BEEPERx->BEEPERHardWare.BEEPER_GPIOx,&GPIO_InitStructure);
if(BEEPERx->BEEPERMemory.level == LowLevel)
{
GPIO_SetBits(BEEPERx->BEEPERHardWare.BEEPER_GPIOx,BEEPERx->BEEPERHardWare.BEEPER_GPIO_Pin);
}
else
{
GPIO_ResetBits(BEEPERx->BEEPERHardWare.BEEPER_GPIOx,BEEPERx->BEEPERHardWare.BEEPER_GPIO_Pin);
}
return SUCCESS;
}
3.控制BEEPER的状态。
ErrorStatus BEEPER_control(BEEPER_TypeDef_Struct* BEEPERx,uint8_t status)
{
if((BEEPERx == NULL)||(BEEPERx->BEEPERMemory.enable != ENABLE))
{
return ERROR;
}
if(status == 0)
{
if(BEEPERx->BEEPERMemory.level == LowLevel)
{
GPIO_SetBits(BEEPERx->BEEPERHardWare.BEEPER_GPIOx,BEEPERx->BEEPERHardWare.BEEPER_GPIO_Pin);
}
else
{
GPIO_ResetBits(BEEPERx->BEEPERHardWare.BEEPER_GPIOx,BEEPERx->BEEPERHardWare.BEEPER_GPIO_Pin);
}
}
else
{
if(BEEPERx->BEEPERMemory.level == LowLevel)
{
GPIO_ResetBits(BEEPERx->BEEPERHardWare.BEEPER_GPIOx,BEEPERx->BEEPERHardWare.BEEPER_GPIO_Pin);
}
else
{
GPIO_SetBits(BEEPERx->BEEPERHardWare.BEEPER_GPIOx,BEEPERx->BEEPERHardWare.BEEPER_GPIO_Pin);
}
}
return SUCCESS;
}
写在后面
??如果是无源蜂鸣器的话,需要给出一定的频率才能令其发声,可以在主函数中间隔一段时间对蜂鸣器的引脚进行电平反转达到目的,或者是封装成函数。例如可以封装一些能发出不同音节的函数。 ??在最后还是想夸赞一下模块化编程的好处,增删较为方便。上述代码仅用了四个蜂鸣器,若只用到两个,可以把蜂鸣器个数的宏定义改为2,并只配置前两个蜂鸣器的参数便可。而且若是这两个蜂鸣器的驱动方式不同,修改也很便利。 ??此外,若是将一个任务划分成不同的模块,可以将不同的模块分配给不同的人编写,提升开发效率。
|