两位共阴数码管跟蜂鸣器不能同时正常工作
时间:10-02
整理:3721RD
点击:
程序想实现两位共阴数码管显示两位数值,数值设定大于50时候,蜂鸣器响的频率比较快,数值设定不大于50时候,蜂鸣器响的频率比较慢。蜂鸣器和数码管单独程序的时候都是正常,但是两个程序工作的时候,蜂鸣器正常工作,数码管显示不正常,现象是:十位显示正常,个位显示一闪一闪,闪的频率接近蜂鸣器的频率,如我现在要显示的是49,4显示的很正常,9却是闪一下灭掉,程序找不到那里的问题,求助各位,问题在哪里?
#include "stm32f10x.h"
#include "delay_SysTick.h"
#include "beep.h"
#include "bsp_TiMbase.h"
void BEEP_UNlock(void);
void BEEP_Lock(void);
#define led_com1_OFF GPIO_SetBits(GPIOB,GPIO_Pin_6)
#define led_com1_ON GPIO_ResetBits(GPIOB,GPIO_Pin_6)
#define led_com2_OFF GPIO_SetBits(GPIOB,GPIO_Pin_7)
#define led_com2_ON GPIO_ResetBits(GPIOB,GPIO_Pin_7)
u16 num=0;
u16 led_com2;
u16 led_com1;
volatile u32 time = 0;
volatile void Delay(uint32_t val)
{
while(val--);
}
void delay_ms(uint16_t ms)
{
TIM2->PSC=35999;
TIM2->ARR=ms*2;
TIM2->CR1|=(1<<3);
TIM2->CR1|=0x1;
while((TIM2->SR&0X1)==0);
TIM2->SR=0;
}
u8 table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x5c,0x37,0x71};
// 0 1 2 3 4 5 6 7 8 9 O N F
void RCC_Configuration(void)
{
RCC_DeInit();
RCC_HSEConfig(RCC_HSE_ON);
while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET);
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); //Enable Prefetch Buffer
FLASH_SetLatency(FLASH_Latency_2); // Flash 2 wait state
RCC_HCLKConfig(RCC_SYSCLK_Div1); // HCLK = SYSCLK
RCC_PCLK2Config(RCC_HCLK_Div1); // PCLK2 = HCLK
RCC_PCLK1Config(RCC_HCLK_Div2); // PCLK1 = HCLK/2
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); // PLLCLK = 8MHz * 9 = 72 MHz
RCC_PLLCmd(ENABLE); // Enable PLL
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); // Wait till PLL is ready
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); // Select PLL as system clock source
while(RCC_GetSYSCLKSource() != 0x08); // Wait till PLL is used as system clock source
}
void Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_All;
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
}
void LED_Display(void)
{
led_com2=num/10;
led_com1=num%10;
led_com2_OFF;
led_com1_ON;
GPIO_Write(GPIOB,table[led_com1]<<8);
led_com2_OFF;
//Delay_us(1000); // 1000 * 10us = 10ms
delay_ms(10);
led_com1_OFF;
led_com2_ON;
GPIO_Write(GPIOB,table[led_com2]<<8);
led_com1_OFF;
//Delay_us(1000);
delay_ms(10);
}
int main(void)
{
RCC_Configuration();
Init();
SysTick_Init();
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 , ENABLE);
num = 49;
while(1)
{
LED_Display();
if(num > 50)
{
BEEP_Lock();
}
else
{
BEEP_UNlock();
}
}
}
蜂鸣器程序:
#include "stm32f10x.h"
#include "delay_SysTick.h"
#include "beep.h"
#include "bsp_TiMbase.h"
void delay_ms(uint16_t ms);
void BEEP_Lock(void)
{
beep_ON;
delay_ms(300); // 10000 * 10us = 1000ms
beep_OFF;
delay_ms(300); // 10000 * 10us = 1000ms
}
void BEEP_UNlock(void)
{
beep_ON;
delay_ms(1000); // 100000 * 10us = 1000ms
beep_OFF;
delay_ms(1000); // 100000 * 10us = 1000ms
}
extern void BEEP_Lock(void);
extern void BEEP_UNlock(void);
这样LED显示肯定不正常,主要问题出在while(1)里。一般为了省IO口都会用3-8线译码器控制LED数码管,先选中1个数码管的阴极点亮1个数码管,然后再点亮第二个......利用人眼视觉暂留效应看到数码管显示的好多个数字。你这样做,那最后显示的一个数字肯定有问题,除非你的蜂鸣器占用时间很少。建议利用定时器中断,在中断程序中每隔一定时间将控制的蜂鸣器引脚拉高,然后再过段时间拉低,这样蜂鸣器可以正常响,也不影响LED(中断程序占用时间很少)
蜂鸣器不能用延时的方式驱动,你延时了 delay_ms(1000); // 100000 * 10us = 1000ms 数码管哪里还有时间显示,改为用if的方式吧
能详细一点吗?我现在没想明白if的方式该怎么用?
比如这样 void BEEP_Lock(void)
{
static unsigned int i;
i++;
if(i<=20000)//这个时间无法确定,加一个定时器最好
{
beep_ON;
}
else if(i<=40000)
{
beep_OFF;
}
else
i=0;
}
正解。LED显示原理类似放电影。
能详细一点吗?