无源蜂鸣器的使用
1、之前一节,我们讲了RC522的使用,在刷卡的同时,灯快速闪烁,但是一般刷卡机在刷卡的同时,会发出滴的一声,所以今天我们用无源蜂鸣器实现这一功能。
2、因为是无源蜂鸣器,内部没有震荡源,我们要用pwm使其发出声音,之前有讲过pwm如何产生。假设无源蜂鸣器连接PB0,
我们让PB0 产生一个pwm信号。
3、定时器Tim2 的配置,产生一个频率1K HZ,占空比35%的方波。
gpio配置
static void pwm_channel_gpio_config(void)
{
// rcu_periph_clock_enable(RCU_GPIOA);
rcu_periph_clock_enable(RCU_GPIOB);
rcu_periph_clock_enable(RCU_AF);
/*Configure PA6 PA7 PB0 PB1(TIMER2 CH0 CH1 CH2) as alternate function*/
// gpio_init(GPIOA,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_6);
// gpio_init(GPIOA,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_7);
gpio_init(GPIOB,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_0);
// gpio_init(GPIOB,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_1);
}
timer2的配置:
static void timer2_config(void)
{
/* -----------------------------------------------------------------------
TIMER2 configuration: generate 3 PWM signals with 3 different duty cycles:
TIMER2CLK = SystemCoreClock / 108 = 1MHz
108M/(107+1)/(999+1) = 1000HZ
TIMER2 channel0 duty cycle = (250/ 1000)* 100 = 25%
TIMER2 channel1 duty cycle = (500/ 1000)* 100 = 50%
TIMER2 channel2 duty cycle = (750/ 1000)* 100 = 75%
----------------------------------------------------------------------- */
timer_oc_parameter_struct timer_ocintpara;
timer_parameter_struct timer_initpara;
rcu_periph_clock_enable(RCU_TIMER2);
timer_deinit(TIMER2);
/* TIMER2 configuration */
timer_initpara.prescaler = 107;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = 499;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER2,&timer_initpara);
/* CH0,CH1 and CH2 configuration in PWM mode */
timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_LOW;
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
// timer_channel_output_config(TIMER2,TIMER_CH_0,&timer_ocintpara);
// timer_channel_output_config(TIMER2,TIMER_CH_1,&timer_ocintpara);
timer_channel_output_config(TIMER2,TIMER_CH_2,&timer_ocintpara);
// /* CH0 configuration in PWM mode0,duty cycle 25% */
// timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_0,249);
// timer_channel_output_mode_config(TIMER2,TIMER_CH_0,TIMER_OC_MODE_PWM0);
// timer_channel_output_shadow_config(TIMER2,TIMER_CH_0,TIMER_OC_SHADOW_DISABLE);
// /* CH1 configuration in PWM mode0,duty cycle 50% */
// timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_1,499);
// timer_channel_output_mode_config(TIMER2,TIMER_CH_1,TIMER_OC_MODE_PWM0);
// timer_channel_output_shadow_config(TIMER2,TIMER_CH_1,TIMER_OC_SHADOW_DISABLE);
/* CH2 configuration in PWM mode0,duty cycle 75% */
timer_channel_output_pulse_value_config(TIMER2,TIMER_CH_2,349); //设置占空比
timer_channel_output_mode_config(TIMER2,TIMER_CH_2,TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(TIMER2,TIMER_CH_2,TIMER_OC_SHADOW_DISABLE);
// nvic_irq_enable(TIMER2_IRQn, 0, 2);
// timer_interrupt_enable(TIMER2, TIMER_INT_UP);
/* auto-reload preload enable */
timer_auto_reload_shadow_enable(TIMER2);
/* auto-reload preload enable */
timer_disable(TIMER2);
}
然后我们在适当的位置调用pwm_config函数,即可产生pwm波形。
// 使用通用定时器TIM2 产生PWM
void pwm_config(void)
{
pwm_channel_gpio_config();
timer2_config();
}
4、在识别到卡片时候,我们使能time2 ,这时候蜂鸣器响,然后一定时间后,disable_timer,蜂鸣器即可停止响叫,但是因为我的蜂鸣器为低电平触发,而pwm在停止的时候不一定为高电平或者低电平状态,所以在停止pwm的时候,我们将pb0拉高。
具体代码如下:
void RC522_task(void * pvParameters)
{
//RC522 Config
PCD_Init();
uint8_t card_type[2] = {0};
uint8_t card_id[4] = {0};
for( ;; )
{
vTaskDelay(100);
if (0 == PCD_Request(0x26,card_type))
{
uint16_t type = (card_type[0]<<8 | card_type[1]);
if (type == 0x0400)
{
if (PCD_Anticoll(card_id) == 0)
{
if (((card_id[0]<<24) |(card_id[1] << 16) | (card_id[2] << 8) | card_id[3]) == 0x7a2e7989)
{
//printf("get card\r\n");
/* 获得互斥量: 上锁 */
xSemaphoreTake(xMutex, portMAX_DELAY);
if (get_card_flag == 0)
{
led_freq = 25;
led_num = 0;
get_card_flag = 1;
}
/* 释放互斥量: 开锁 */
xSemaphoreGive(xMutex);
}
}
}
}
}
}
void Led_task(void * pvParameters)
{
for( ;; )
{
/* 获得互斥量: 上锁 */
xSemaphoreTake(xMutex, portMAX_DELAY);
if (get_card_flag == 1)
{
if (led_num == 20 )
{
led_num = 0;
get_card_flag = 0;
led_freq = 500;
}
else if(led_num == 2)
{
gpio_init(GPIOB,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_0);
timer_enable(TIMER2);
}
else if (led_num == 4)
{
timer_disable(TIMER2);
gpio_init(GPIOB,GPIO_MODE_OUT_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_0);
gpio_bit_set(GPIOB, GPIO_PIN_0);
}
led_num++;
}
/* 释放互斥量: 开锁 */
xSemaphoreGive(xMutex);
gpio_bit_set(GPIOB, GPIO_PIN_4);
vTaskDelay(led_freq);
gpio_bit_reset(GPIOB, GPIO_PIN_4);
vTaskDelay(led_freq);
}
}
5、视频如下:
蜂鸣器刷卡