アクセサリーや模型にLEDを組み込むためのベースに開発しました
小型化のためLEDの制御に米粒マイコンtiny10を使用し、オルタネイトスイッチは大きいので比較的小さな種類があるモーメンタリスイッチを電源/選択スイッチとしました
とりあえず点灯パターンを6個ほど入れ込みました
操作は消灯時に短ONで点灯、点灯時長ONで消灯
点灯時に短ONで表示切り替え、長ONで消灯となります。
tiny10ピンアサイン
1:LED2
2:GND
3:LED1
4:スイッチ
5:電源(3Vから5V)
6:NC(RESET)
消費電流
消灯時:0.1μA
点灯時マイコンの消費電流:3.3V時80μA(LEDの電流を含まず)
ソース
/*
Tiny10 LEDスイッチ
2025.1.15 短押しで起動、短押しで選択、長押しで保存LEDoff
2025.1.14
消費電流
125khz 5V:0.16mA 3.3V:0.075mA
sleep:0.1uA
attiny10
NC 1:PB0/OC0A/TPIDATA RESET/PB3:6 NC
GND 2:GND VCC :5 VCC
LED 3:PB1/OC0B/TPICLK INT0 PB2:4 SW
*/
//#define F_CPU 8000000UL // 8MHz動作
//#define F_CPU 250000UL // 250khz動作
#define F_CPU 125000UL // 125khz動作
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <stdbool.h>
#include <util/delay.h>
#define SWITCH_PIN 2 //PB2 // D2ピン
#define PWM_PIN 1 //PB1 // D1ピン
#define LED2 0 //PB0 LED2
#define LED_ON TCCR0A |= (1 << COM0B1) // PWM ON切り替え
#define LED_OFF TCCR0A &= ~(1 << COM0B1) // PWM OFF切り替え
#define LED2_ON PORTB |= (1<<LED2) //ON
#define LED2_OFF PORTB &= ~(1<<LED2) //OFF
#define TON 200 //短点
#define TUU 600 //長点
bool flag = false;
//#define MCUCR _SFR_IO8(0x35)
//#define GIMSK _SFR_IO8(0x3B)
//#define PCIE 5 //ビット5 - PCIE : ピン変化割り込み許可
void pwm_init(void) {
DDRB |= (1 << PWM_PIN | 1<<LED2); // PB1,PB0を出力
TCCR0A = (1 << COM0B1) | (1 << WGM00) | (1 << WGM01); // 高速PWM、非反転
TCCR0B = (1 << CS00); // 無分周
OCR0B = 512; // デューティ50% 10bit
}
void enter_powerdown_mode(void) {
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // パワーダウンモード
sleep_enable();
sleep_cpu(); // スリープ
sleep_disable();
}
void setup_interrupt(void) {
DDRB &= ~(1 << SWITCH_PIN); // PB2を入力
PUEB |= (1 << SWITCH_PIN | 1<<3); // プルアップ有効化
EICRA = (1<<ISC01) | (0<<ISC00); //INT0ピンの下降端
EIMSK = (1<<INT0);
sei(); // 全体割り込み有効化
}
ISR(INT0_vect) {
// 割り込みハンドラ(ここでモード切り替え等を実施可能)
flag = true;
}
// 疑似乱数生成関数(16ビット)
static uint16_t seed = 1; // 初期シード値
uint16_t rand(void) {
#define RAND_A 75 // 乗数
#define RAND_C 74 // 加算定数
#define RAND_M 0x7FFF // 最大値(2^15 - 1, 15ビットマスク)
seed = (RAND_A * seed + RAND_C) & RAND_M; // 計算とマスク
return seed;
}
int _i;
void fdelay(int t){
for( _i=0;_i<t;_i++){
_delay_ms(1);
if(flag){
break;
}
}
}
void ton(){
LED_ON;
fdelay(TON);
LED_OFF;
fdelay(TON);
}
void tuu(){
LED_ON;
fdelay(TUU);
LED_OFF;
fdelay(TON);
}
int n;
uint8_t sw_wait(){
if(flag == false){
return true;
}
for(n=0;n<1000;n++){
_delay_ms(1);
if(PINB & (1<<SWITCH_PIN )){
//off
_delay_ms(50);
flag =false;
return false;
}
}
LED_OFF;
LED2_OFF;
enter_powerdown_mode();
flag =false;
return true;
}
int main(void) {
int i;
CCP = 0xd8;
// CLKPSR = (0<<CLKPS3 | 1<<CLKPS2 | 0<<CLKPS1 | 1<<CLKPS0); //250khz
CLKPSR = (0<<CLKPS3 | 1<<CLKPS2 | 1<<CLKPS1 | 0<<CLKPS0); //125khz
setup_interrupt();
pwm_init();
ACSR |= (1<<ACD); //アナログ比較器OFF
ADCSRA = 0;
PRR |= (1<<PRADC); //ADC OFF
DIDR0 |= (0x1011);
LED_ON; // PWM OFF切り替え
while (1) {
//1)常時点灯
OCR0B = 512; // デューティ50% 10bit
LED_ON; // PWM ON切り替え
while(sw_wait()){ //sw wait
LED_ON;
_delay_ms(1);
}
//2)トンツー
while(sw_wait()){
// ...---...
ton();
ton();
ton();
fdelay(TON*(3-1));
tuu();
tuu();
tuu();
fdelay(TON*(3-1));
ton();
ton();
ton();
fdelay(TON*(8));
}
//3)ぱ・すー
while(sw_wait()){
LED_ON;
for( i = 1023;i>=0;i--){
OCR0B = i; // デューティ50% 10bit
fdelay(2);
}
LED_OFF;
fdelay(200);
LED_ON;
}
//4)すー・ぱ
while(sw_wait()){
LED_ON;
for( i = 0;i<1023;i++){
OCR0B = i; // デューティ50% 10bit
fdelay(2);
}
//LED_OFF;
OCR0B = 0;
fdelay(200);
//LED_ON;
}
//5)点滅
#define T1 200
while(sw_wait()){
//LED1 on
OCR0B = 512;
LED_ON;
fdelay(T1);
LED_OFF;
//LED2 on
LED2_ON;
_delay_ms(T1);
LED2_OFF;
}
LED2_OFF;
LED_OFF;
//6)点滅乱数
#define T2 1200
while(sw_wait()){
//LED1 on
OCR0B = rand() % 1000;
LED_ON;
fdelay( rand() % T2);
LED_OFF;
fdelay( rand() % T2);
}
}
return 0;
}
-
naranavi
さんが
2025/01/18
に
編集
をしました。
(メッセージ: 初版)
ログインしてコメントを投稿する