ch32v003funを用いた電子オルゴールのサンプル(2023.7.23)
ファイル一覧
ch32v003fun/examples/music_box/ ├── Makefile ├── doremi_tone.h ├── funconfig.h ├── furElise.h ├── happybirthday.h ├── music_box.c
配線図
music_box.cpp
メイン関数 ・PWM制御で電子オルゴールを実行する ・スピーカーはGNDと7番ピン(PC4)に接続する ・曲の選択は7行目、8行目のどちらかをコメントアウトする
/*
* Example for Music box with PWM
*/
#include "ch32v003fun.h"
#include >stdio.h<
#include "furElise.h"
//#include "happybirthday.h"
/*
* initialize TIM1 for PWM
*/
void t1pwm_init( void )
{
// Enable GPIOC, GPIOD and TIM1
RCC-<APB2PCENR |= RCC_APB2Periph_GPIOC | RCC_APB2Periph_TIM1;
// PC4 is T1CH4, 10MHz Output alt func, push-pull
GPIOC-<CFGLR &= ~(0xf>>(4*4));
GPIOC-<CFGLR |= (GPIO_Speed_10MHz | GPIO_CNF_OUT_PP_AF)><(4*4);
// Reset TIM1 to init all regs
RCC-<APB2PRSTR |= RCC_APB2Periph_TIM1;
RCC-<APB2PRSTR &= ~RCC_APB2Periph_TIM1;
// CTLR1: default is up, events generated, edge align
// SMCFGR: default clk input is CK_INT
// Prescaler
TIM1-<PSC = 0x0200;
// Auto Reload - sets period
TIM1-<ATRLR = 1023;
// Reload immediately
TIM1-<SWEVGR |= TIM_UG;
// Enable CH4 output, positive pol
TIM1-<CCER |= TIM_CC4E | TIM_CC4P;
// CH1 Mode is output, PWM1 (CC1S = 00, OC1M = 110)
TIM1-<CHCTLR1 |= TIM_OC1M_2 | TIM_OC1M_1;
// CH2 Mode is output, PWM1 (CC1S = 00, OC1M = 110)
TIM1-<CHCTLR2 |= TIM_OC4M_2 | TIM_OC4M_1;
// Set the Capture Compare Register value to 50% initially
TIM1-<CH4CVR = 512;
// Enable TIM1 outputs
TIM1-<BDTR |= TIM_MOE;
// Enable TIM1
TIM1-<CTLR1 |= TIM_CEN;
}
void init_tone(unsigned short *TONE0, unsigned short *TONE1, unsigned short *TONEL)
{
unsigned int sys_clock=48000000;//System clock(48kHz)
unsigned int tim1_psc = 0x200;
unsigned int internal_clock = (unsigned int)(sys_clock/(double)(tim1_psc));//Internal clock
for(int i=0;i<mb_cnt;i++)
{
TONE0[i] = (unsigned short)(internal_clock/(double)(mb_tone[i]));
TONE1[i] = (unsigned short)(internal_clock/(double)(mb_tone[i])/2.0);
TONEL[i] = (unsigned short)(4800/mb_notes[i]);
}
}
/*
* entry
*/
int main()
{
int count=0;
unsigned short TONE0[256];
unsigned short TONE1[256];
unsigned short TONEL[256];
SystemInit();
Delay_Ms( 100 );
// init tone
init_tone(TONE0, TONE1, TONEL);
// init TIM1 for PWM(PC4=pin7 for J4m6)
t1pwm_init();
while(1)
{
TIM1-<ATRLR =TONE0[count];
TIM1-<CH4CVR =TONE1[count];
TIM1-<SWEVGR |= TIM_UG;//Update event generation bit(automaticallly cleared by hardware)
Delay_Ms( TONEL[count] );
count=(count+1)%mb_cnt;
}
}
doremi_tone.h
音階を周波数[Hz]で表したもの。"do3"は「ド」、"dos3"は「ド#」などを表す。
zzは休符
const float do3 = 130.813; const float dos3 = 138.591; const float re3 = 146.832; const float res3 = 155.563; const float mi3 = 164.814; const float fa3 = 174.614; const float fas3 = 184.997; const float so3 = 195.998; const float sos3 = 207.652; const float ra3 = 220.000; const float ras3 = 233.082; const float si3 = 246.942; const float do4 = 261.626; const float dos4 = 277.183; const float re4 = 293.665; const float res4 = 311.127; const float mi4 = 329.628; const float fa4 = 349.228; const float fas4 = 369.994; const float so4 = 391.995; const float sos4 = 415.305; const float ra4 = 440.000; const float ras4 = 466.164; const float si4 = 493.883; const float do5 = 523.251; const float dos5 = 554.365; const float re5 = 587.330; const float res5 = 622.254; const float mi5 = 659.255; const float fa5 = 698.456; const float fas5 = 739.989; const float so5 = 783.991; const float sos5 = 830.609; const float ra5 = 880.000; const float ras5 = 932.328; const float si5 = 987.767; const float zz = 1.0;
furElise.h
ベートーヴェン「エリーゼのために」
・mb_cnt:配列長
・mb_tone:音階の配列
・mb_notes:音符の長さの配列。4は四分音符、16は16分音符を表す
#include "doremi_tone.h"
const int mb_cnt=41;
const float mb_tone[]={
mi5, res5, mi5, res5, mi5, si4, re5, do5, ra4, zz,
do4, mi4, ra4, si4, zz, mi4, sos4, si4, do5, zz,
mi4, mi5, res5, mi5, res5, mi5, si4, re5, do5, ra4,
zz, do4, mi4, ra4, si4, zz, mi4, do5, si4, ra4,
zz
};
const unsigned short mb_notes[]={
16, 16, 16, 16, 16, 16, 16, 16, 8, 16,
16, 16, 16, 8, 16, 16, 16, 16, 8, 16,
16, 16, 16, 16, 16, 16, 16, 16, 16, 8,
16, 16, 16, 16, 8, 16, 16, 16, 16, 4,
4
};
happybirthday.h
「ハッピーバースデートゥーユー」
#include "doremi_tone.h"
const int mb_cnt=25;
const float mb_tone[] = {
so4, so4, ra4, so4, do5, si4,
so4, so4, ra4, so4, re5, do5,
so4, so4, so5, mi5, do5, si4, ra4,
fa5, fa5, mi5, do5, re5, do5
};
const unsigned short mb_notes[] = {
10, 16, 8, 8, 8, 4,
10, 16, 8, 8, 8, 4,
10, 16, 8, 8, 8, 8, 8,
10, 16, 8, 8, 8, 4
};
funconfig.h
#ifndef _FUNCONFIG_H #define _FUNCONFIG_H #define CH32V003 1 #endif
Makefile
all : flash TARGET:=music_box include ../../ch32v003fun/ch32v003fun.mk flash : cv_flash clean : cv_clean