цифровая электроника
вычислительная техника
встраиваемые системы

 

Простой и дешевый диммер на микроконтроллере ATtiny13

Автор: Mike(admin) от 28-09-2020, 07:55

Диммеры – это простые электронные устройства, которые используются для управления уровнем яркости освещения или интенсивностью подачи напряжения на нагрузку. Многие домовладельцы устанавливают диммеры для управления освещением, экономии на счетах за электричество или в качестве дополнительной функции своей системы умного дома.


Простой и дешевый диммер на микроконтроллере ATtiny13

Диммеры сегодня широко представлены на рынке, но стоимость некоторых может быть не для всех приемлемой. Впрочем, это несложное устройство можно сделать и самому, при этом для данной цели потребуется не так много компонентов, и все они будут недорогими.


Данный проект диммера основан на микроконтроллере ATtiny13, который очень компактен и стоит дешево. Управление диммером осуществляется с помощью трех кнопок: для повышения, понижения и включения/выключения нагрузки. Также имеются 8 светодиодов для индикации процента мощности.


Простой и дешевый диммер на микроконтроллере ATtiny13

Микроконтроллер сохраняет значения в EEPROM для восстановления значений после сброса. Из-за малого количества выводов ATtiny13 светодиоды подключаются с помощью сдвигового регистра 74HC164. Эта модель не имеет буферного регистра, поэтому для управления ей нужны два контакта. на один вывод меньше, чем у популярного 74HC595.


Обратите внимание, этот модуль не изолирован от сети. Он должен содержаться в подходящем пластиковом корпусе.


Схемы диммера на основе микроконтроллера ATtiny представлены далее.


Простой и дешевый диммер на микроконтроллере ATtiny13

Код программы диммера состоит из нескольких файлов. Main.c:



#define KEY_DN		0
#define KEY_UP		1
#define KEY_SET		2
#define KEY_NO		3

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/eeprom.h>

#include "aux_source.h"
#include "shiftreg.h"
uint8_t	dim_data;
bool deviceOn = true;
const uint16_t Dimmers[8] = { 0, 253, 369, 468, 531, 631, 850, 1000 };

int main()
{
	init_IO();
	dim_data = eeprom_read_byte(0);
	if (dim_data > 7)	dim_data = 7;
	tsr_shiftOut((1 << (dim_data + 1)) - 1);
	_delay_ms(250);
	while(1)
	{
		uint8_t  key = ReadKeys();
		if (deviceOn)
		{
			if (key != KEY_NO && key != KEY_SET)
			{
				if (key == KEY_DN)
				{
					if (dim_data > 0)	dim_data--;
				}
				else if (key == KEY_UP)
				{
					if (dim_data < 7)	dim_data++;
				}
				tsr_shiftOut((1 << (dim_data + 1)) - 1);
				eeprom_write_byte(0, dim_data);
				_delay_ms(100);
			}
		}
		if (key == KEY_SET)
		{
			deviceOn = !deviceOn;
			if (deviceOn)	tsr_shiftOut((1 << (dim_data + 1)) - 1);
			else			tsr_shiftOut(0);
			_delay_ms(800);
		}
	}
}



void sup_delay(uint16_t del)
{
	while (del--)
	{
		_delay_us(10);
	}
}

ISR(INT0_vect)
{
	if (deviceOn)
	{
		if (dim_data != 7)
		{
			sup_delay(Dimmers[dim_data]);
			PORTB |= (1 << PORTB0);
			_delay_us(30);
			PORTB &= ~(1 << PORTB0);
		}
		else
		{
			PORTB |= (1 << PORTB0);
			_delay_us(30);
			PORTB &= ~(1 << PORTB0);
		}
	}
}

Файл инициализации периферии:



#include "aux_source.h"

void init_IO()
{
	DDRB	= (1 << DDB0) | (1 << DDB3) | (1 << DDB4);
	
	PORTB	|= (1 << PORTB2);
	ADMUX	= (1 << ADLAR) | 1;
	DIDR0	= (1 << ADC1D);
	ADCSRA	= (1 << ADEN) | (1 << ADSC) | 5;
	while (!(ADCSRA & (1 << ADIF))) ;
	ADCSRA	|= (1 << ADIF);
		
	MCUCR	= 1;
	GIMSK	= (1 << INT0);
	sei();	
}


uint8_t ReadKeys()
{	
	ADCSRA	|= (1 << ADSC);
	while (!(ADCSRA & (1 << ADIF))) ;
	ADCSRA	|= (1 << ADIF);
	return ((ADCH * 3 + 80) / 256) ;
}

Библиотека сдвигового регистра:



#include "shiftReg.h"


uint8_t tsr_buff[DAT_SZ_BYTE] = { 0 };


void tsr_initIO(void)
{
	CLK_DAT_LATCH_OUT_INIT;
	CLK_OUT_LO;
	DAT_OUT_LO;
	LATCH_OUT_LO;
}

void tsr_shiftBuffer(void)
{
	uint8_t j = 0;
	
	while (j < DAT_SZ_BYTE)
	{
		tsr_shiftOut(tsr_buff[j]);
		j++;
	}
	
}

void tsr_shiftOut(uint8_t tsr_var)
{
	uint8_t i = 0b10000000;
	LATCH_OUT_LO;
	while (i != 0)
	{
		if (tsr_var & i)	DAT_OUT_HI;
		else			DAT_OUT_LO;
		CLK_DELAY;
		CLK_OUT_HI;
		CLK_DELAY;
		CLK_OUT_LO;
		CLK_DELAY;
		i	= i >> 1;
	}
}

void tsr_latchOut(void)
{
	LATCH_OUT_HI;
}

void sr_setBit(uint32_t srBuffBit, bool srBuffVal)
{
	uint8_t q = srBuffBit/8;
	uint8_t r = srBuffBit%8;
	if(srBuffVal)	tsr_buff[q] |= (1<<r);
	else					tsr_buff[q] &=~(1<<r);
}

Заголовочный файл библиотеки сдвигового регистра:



#ifndef __SHIFTREG_H__
#define __SHIFTREG_H__

#include <avr/io.h>
#include <util/delay.h>

#define CLK_DAT_LATCH_OUT_INIT		DDRB	|= (1 << DDB3) | (1 << DDB4)

#define CLK_OUT_HI	PORTB	|= (1<<PORTB3)
#define CLK_OUT_LO	PORTB	&=~(1<<PORTB3)
#define CLK_OUT_TOG PINB	|= (1<<PINB3)
#define DAT_OUT_HI	PORTB	|= (1<<PORTB4)
#define DAT_OUT_LO	PORTB	&=~(1<<PORTB4)
#define LATCH_OUT_HI
#define LATCH_OUT_LO

#define DAT_SZ_BYTE	1
#define CLK_DELAY	


#define DAT_SZ_BYTE	1


extern uint8_t tsr_buff[DAT_SZ_BYTE];


void tsr_initIO(void);
void tsr_shiftOut(uint8_t tsr_var);
void tsr_latchOut(void);
void tsr_setBit(uint32_t srBuffBit, bool srBuffVal);
void tsr_shiftBuffer(void);


#endif

Заголовочный файл инициализации периферии:



#pragma once

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "shiftreg.h"

void init_IO();
uint8_t ReadKeys();



Теги: диммер, ATtiny




Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Комментарии:

Оставить комментарий