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