著者:米田 聡
「Interface」「CQ ham radio」「トランジスタ技術」などの雑誌を出版するCQ出版社の電子部品セット「イノシシ撃退機部品セットVer.1」を組み立て、ソフトウエアに一工夫を加えてイノシシ撃退機を作ります。今回は完成したハードウエア向けにソフトウエアを作成します。
シェルスクリプトマガジン Vol.92は以下のリンク先でご購入できます。![]()
![]()
図18 PWM機能の初期化
(略)
#define PWM_PIN 20
(略)
#define PWM_SLICE_NUM pwm_gpio_to_slice_num(PWM_PIN)
(略)
void pwm_gpio_init() {
(略)
gpio_set_function(PWM_PIN, GPIO_FUNC_PWM);
pwm_set_wrap(PWM_SLICE_NUM, 4095);
pwm_set_clkdiv(PWM_SLICE_NUM, 2);
pwm_set_irq_enabled(PWM_SLICE_NUM, true);
irq_set_exclusive_handler(PWM_IRQ_WRAP, on_pwm_wrap);
irq_set_enabled(PWM_IRQ_WRAP, true);
(略)
}
(略)
図20 割り込みハンドラ
void on_pwm_wrap() {
pwm_clear_irq(PWM_SLICE_NUM);
(略)
uint16_t duty = convert_flash_data_to_duty(spi_rx_buf[flash_data_index], spi_rx_buf[flash_data_index + 1]);
pwm_set_chan_level(PWM_SLICE_NUM, PWM_CHAN_A, duty);
flash_data_index += 2;
if (flash_data_index >= 256) {
flash_data_index = 0;
}
(略)
}
図21 ダブルバッファを使用する修正
■34~37行目の修正コード
#ifdef FLASH_DATA_TO_DUTY
// ダブルバッファ化
uint8_t spi_rx_buf[2][256];
volatile uint32_t flash_data_index = 0;
#endif
■45~54行目の修正コード
// バッファ選択
volatile uint32_t buf_flip = 0;
void on_pwm_wrap() {
pwm_clear_irq(PWM_SLICE_NUM);
#ifdef FLASH_DATA_TO_DUTY
uint16_t duty = convert_flash_data_to_duty(spi_rx_buf[buf_flip][flash_data_index], spi_rx_buf[buf_flip][flash_data_index + 1]);
pwm_set_chan_level(PWM_SLICE_NUM, PWM_CHAN_A, duty);
flash_data_index += 2;
if (flash_data_index >= 256) {
// バッファ切り替え
buf_flip ^= 1;
flash_data_index = 0;
}
}
■87~105行目の修正コード
void play_sound() {
// バッファ切り替え(ローカル)
int flip = 0;
flash_data_index = 0;
buf_flip = 0;
pwm_set_enabled(PWM_SLICE_NUM, true); //mu0918
for(uint32_t address = 0; address < FLASH_SIZE; address += 256) {
gpio_put(PICO_DEFAULT_SPI_SSEL_PIN, 0); // Set the CS pin to active LOW
// Send the read command
uint8_t spi_tx_buf[] = {0x03, (address >> 16) & 0xFF, (address >> 8) & 0xFF, address & 0xFF};
spi_write_blocking(spi, spi_tx_buf, 4);
// Read the data
spi_read_blocking(spi, 0, spi_rx_buf[flip], 256);
// バッファ切り替え
flip ^= 1;
gpio_put(PICO_DEFAULT_SPI_SSEL_PIN, 1); // Set the CS pin to non-active HIGH
}
pwm_set_enabled(PWM_SLICE_NUM, false); //mu0918
}