STM32 버저는 전자 키보드(원리+코드)를 구현합니다.

오랫동안 32를 만지지 않았습니다. 오늘은 훈련 첫날입니다. 전자 키보드 연습을 하려고 합니다.

프로그래밍 난이도는 매우 작으며 gpio 제어 핀의 높고 낮은 레벨 변환에 지나지 않습니다. 더 주목할만한 것은 주로 일부 음악 이론 지식입니다.

우리가 들을 수 있는 1 2 3 4 5 6 7 음표는 사실 고정된 주파수인데 자세한 건 잘 모르겠습니다. 바흐에게 물어보세요.

결국 바이두를 통해서 비교사진을 찾았어요

 그렇다면 이 주파수를 변환하는 방법은 무엇입니까?먼저 주파수 단위-헤르츠(hz)의 정의를 살펴보겠습니다.

헤르츠(Hertz)는 주파수의 SI 단위이며 초당 주기적인 변화의 반복 횟수를 측정한 것입니다.
헤르츠(Hertz)는 헤르츠(Hertz)로 약칭됩니다. 초당 하나의 진동(또는 진동, 파동)은 1Hz이거나 회/초, 주기/초로 쓸 수 있습니다.

(바이두백과사전에서 발췌)

이렇게 이해하면 1Hz는 1초에 1번 진동하고, 사진 속 고음 1은 1초에 880번 진동한다.

마이크로컨트롤러에서 버저가 1의 높은 음조를 울리게 하려면 초당 880번 높은 레벨과 낮은 레벨 사이를 전환해야 합니다.

각 진동은 다음과 같이 쓸 수 있습니다.

GPIO_SetBits(GPIOF,GPIO_Pin_8);
delay_us(5);
GPIO_ResetBits(GPIOF,GPIO_Pin_8);
delay_us(5);

여기 50% PWM 파가 있습니다. 이것은 주파수 변환이라는 점을 기억하십시오(블로거는 처음부터 PWM 파동과 주파수의 개념을 혼동했습니다). 듀티 사이클의 변화는 소리의 강도와 듀티 사이클을 반영합니다. 비율이 높을수록 부저 소리가 커집니다.

예를 들어 880hz의 경우 부저가 1초 동안 높은 음조 1을 울리도록 하려면 레벨을 880번 변환해야 하고 각 변환이 1초 이내에 균등하게 분배되어야 하므로 레벨을 변경해야 합니다. 1초 이내에 880개의 시간 간격으로 나눕니다. 즉, 1s/880=1136us(반올림)

여기에는 이전 10us가 포함되므로 기간은 다음과 같아야 합니다.

GPIO_SetBits(GPIOF,GPIO_Pin_8);
delay_us(5);
GPIO_ResetBits(GPIOF,GPIO_Pin_8);
delay_us(5);
delay_us(1136);

실제로 몇 초가 지나도 이 명령이 이 시간 내에 실행되는 한 부저는 높은 음의 1음을 울립니다.

다음은 함수 코드입니다.

double connect[3][7]={
   
   {880,987.76,1108.73,1174.66,1318.52,1479.98,1661.22},{440,493.88,554.37,587.33,659.33,739.99,830.61},{220,246.94,277.19,293.67,329.63,370,415.31}};
//创建二位数组存放频率数据
void yinjie(int mst, int f,int h)//第一个参数为响的时间(ms),第二个参数确定音阶
{
	int t=(int)1000000.0/connect[h-1][f-1]-10;//计算时间间隔
	int n=mst*1000;//转微秒
	while(n>0)//响的时间每次循环减去时间间隔,小于0时跳出
	{
		GPIO_SetBits(GPIOF,GPIO_Pin_8);
				delay_us(5);
		GPIO_ResetBits(GPIOF,GPIO_Pin_8);
				delay_us(5);
		delay_us(t);
		n-=t+10;
		
	}
	GPIO_ResetBits(GPIOF,GPIO_Pin_8);
			delay_ms(100);
		
		
}

gpio 초기화

void Init(){
	//gpio初始化
	GPIO_InitTypeDef  GPIO_InitStructure;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能GPIOF时钟
  
  //初始化蜂鸣器对应引脚GPIOF8
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;//BEEP对应引脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;//下拉
  GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化GPIO
	
  GPIO_ResetBits(GPIOF,GPIO_Pin_8);  //蜂鸣器对应引脚GPIOF8拉低

메인 (생일 축하 노래)

int main(void)
{
	u32 t=0;
	int i;
	Init();
	delay_init(84);

	
  while(1){
		yinjie(400,5,3);
		yinjie(400,5,3);
		yinjie(800,6,3);
		yinjie(800,5,3);
		yinjie(800,1,2);
		yinjie(800,7,3);
		
		yinjie(400,5,3);
		yinjie(400,5,3);
		yinjie(800,6,3);
		yinjie(800,5,3);
		yinjie(800,2,2);
		yinjie(800,1,2);
		
		yinjie(400,5,3);
		yinjie(400,5,3);
		yinjie(400,5,2);
		yinjie(400,3,2);
		yinjie(800,1,2);
		yinjie(800,7,3);
		yinjie(800,6,3);
		
		yinjie(400,4,2);
		yinjie(400,4,2);
		yinjie(400,3,2);
		yinjie(800,1,2);
		yinjie(800,2,2);
		yinjie(800,1,2);
	}

Acho que você gosta

Origin blog.csdn.net/qq_38830492/article/details/125461035
Recomendado
Clasificación