ZCDライブラリ。これもシンプルなので説明の必要がないかな。
【サンプルコード】
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include "avr8_zcd.h" Zcd zcd0(ZCD0); void func(Zcd::STATUS status) { if (status & Zcd::STATUS_CROSSIF) { /* cross */; } } int main(void) { zcd0.begin(); zcd0.callback(func); zcd0.intctrl(Zcd::INTMODE_BOTH); while (1) Zcd::poll(); return 0; } |
【ライブラリ】
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
/* avr8_zcd.h - ZCD Driver for Microchip AVR8 Series Copyright (c) 2025 Sasapea's Lab. All right reserved. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. */ #pragma once #include "avr8_config.h" #if defined(ZCD3) #define ZCD_MAX_CH 4 #elif defined(ZCD2) #define ZCD_MAX_CH 3 #elif defined(ZCD1) #define ZCD_MAX_CH 2 #elif defined(ZCD0) #define ZCD_MAX_CH 1 #else #define ZCD_MAX_CH 0 #endif #if ZCD_MAX_CH class Zcd { public: /* Interrupt Mode select */ typedef enum { INTMODE_NONE = ZCD_INTMODE_NONE_gc, /* No interrupt */ INTMODE_RISING = ZCD_INTMODE_RISING_gc, /* Interrupt on rising input signal */ INTMODE_FALLING = ZCD_INTMODE_FALLING_gc, /* Interrupt on falling input signal */ INTMODE_BOTH = ZCD_INTMODE_BOTH_gc, /* Interrupt on both rising and falling input signal */ } INTMODE; /* ZCD.STATUS bit masks and bit positions */ typedef enum { STATUS_CROSSIF = ZCD_CROSSIF_bm, /* ZCD Interrupt Flag bit mask. */ STATUS_STATE = ZCD_STATE_bm, /* ZCD State bit mask. */ } STATUS; /* ZCD State select */ typedef enum { STATE_LOW = ZCD_STATE_LOW_gc, /* Output is 0 */ STATE_HIGH = ZCD_STATE_HIGH_gc, /* Output is 1 */ } STATE; typedef void (*callback_t)(STATUS status); #if defined(ZCD0) Zcd(ZCD_t& zcd) : _zcd(&zcd), _ch((&zcd - &ZCD0) / sizeof(zcd) + 0), _callback(0) #elif defined(ZCD1) Zcd(ZCD_t& zcd) : _zcd(&zcd), _ch((&zcd - &ZCD1) / sizeof(zcd) + 1), _callback(0) #elif defined(ZCD2) Zcd(ZCD_t& zcd) : _zcd(&zcd), _ch((&zcd - &ZCD2) / sizeof(zcd) + 2), _callback(0) #elif defined(ZCD3) Zcd(ZCD_t& zcd) : _zcd(&zcd), _ch((&zcd - &ZCD3) / sizeof(zcd) + 3), _callback(0) #endif { _instances[_ch] = this; } /* virtual */ ~Zcd(void) { end(); _instances[_ch] = 0; } void begin(bool invert = false) { end(); _zcd->CTRLA = (invert ? ZCD_INVERT_bm : 0) | ZCD_ENABLE_bm; } void end(void) { _zcd->CTRLA = 0; } void runstdby(bool enable = true) { _zcd->CTRLA = (_zcd->CTRLA & ~ZCD_RUNSTDBY_bm) | (enable ? ZCD_RUNSTDBY_bm : 0); } void output(bool enable = true) { _zcd->CTRLA = (_zcd->CTRLA & ~ZCD_OUTEN_bm) | (enable ? ZCD_OUTEN_bm : 0); } void callback(callback_t func) { _callback = func; } void intctrl(INTMODE mode) { _zcd->STATUS = _zcd->STATUS; #if CONFIG_ZCD_ISR _zcd->INTCTRL = mode; #endif } static STATUS status(void) { return (STATUS)_zcd->STATUS; } static void poll(void) { #if !CONFIG_ZCD_ISR for (uint8_t i = 0; i < ZCD_MAX_CH; ++i) { Zcd* zcd = _instances[i]; if (zcd) zcd->isr(); } #endif } protected: static Zcd* _instances[ZCD_MAX_CH]; ZCD_t* _zcd; uint8_t _ch; callback_t _callback; #if CONFIG_ZCD_ISR friend void zcd_isr(uint8_t ch); #endif void isr(void) { uint8_t flags = _zcd->STATUS = _zcd->STATUS; if (_callback) _callback((STATUS)flags); } }; #endif |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
/* avr8_zcd.cpp - ZCD Driver for Microchip AVR8 Series Copyright (c) 2025 Sasapea's Lab. All right reserved. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. */ #include "avr8_zcd.h" #if ZCD_MAX_CH Zcd* Zcd::_instances[]; #if CONFIG_ZCD_ISR inline void zcd_isr(uint8_t ch) { Zcd::_instances[ch]->isr(); } #if defined(ZCD0_ZCD_vect) ISR(ZCD0_ZCD_vect) { zcd_isr(0); } #endif #if defined(ZCD1_ZCD_vect) ISR(ZCD1_ZCD_vect) { zcd_isr(1); } #endif #if defined(ZCD2_ZCD_vect) ISR(ZCD2_ZCD_vect) { zcd_isr(2); } #endif #if defined(ZCD3_ZCD_vect) ISR(ZCD3_ZCD_vect) { zcd_isr(3); } #endif #endif #endif |
