Помогите разработать элементарный выключатель на Tiny13
- Сообщения: 21
- Зарегистрирован: Сб июн 23, 2012 11:19:11
Добрый день, в вытяжке прогорел контроллер управляющий симистором, маркировка затерта думаю был PIC, имеется в наличии контроллер attiny13 и твердотельное реле MOC3041, ищу помощи в прошивке, устройство должно быть однокнопочным с не фиксированной кнопкой, если возможно сделать еще плавное затухание
. Проэкты которые есть в интернетах не совсем подходят или излишне усложнены. А "програмить" по прежнему руки не доходят научится, имею ввиду такие простые задачи.
- Реклама
вот есть готовое, автоматическое включение http://arv.radioliga.com/content/view/218/44/
Ставим плюсы: )
- Сообщения: 21
- Зарегистрирован: Сб июн 23, 2012 11:19:11
Спасибо конечно немного не те задачи, да и автоматизация не нужна вовсе.
плавное затухание не получится с MOC3041, нужен MOC без zero-cross
- Сообщения: 21
- Зарегистрирован: Сб июн 23, 2012 11:19:11
По этому и прошу помощи с элементарной базой и прошивкой.zero648 писал(а):плавное затухание не получится с MOC3041, нужен MOC без zero-cross
- Реклама
- Сообщения: 21
- Зарегистрирован: Сб июн 23, 2012 11:19:11
Не могу откомпилировать данный код :
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "main.h"
/// массив, из которого выбираются значения фазы
PROGMEM uint8_t stepping[MAX_STEP] = {170,160,150,140,100,50,10};
/// текущее значение заданной фазы регулятора
volatile uint8_t phase = 255;
/// счетчик программной фазы
volatile uint8_t counter = 0;
/// счетчик полупериодов сети для таймера автоотключения
volatile uint8_t timer;
/// флаг активности таймера автоотключения
volatile uint8_t timer_on;
/// счетчик секунд таймера автоотключения
volatile uint8_t sec;
/// счетчик минут таймера автоотключения
volatile uint8_t min;
/// текущее состояние светодиодов
volatile uint8_t current_led;
/// флаг для выключения
volatile uint8_t stop_all = 0;
/** Отключение всего немедленно
*/
static void all_off_now(void){
stop_all = 1;
}
/** Обработчик прерывания от таймера, ведущего отсчет фазы.
* Реализует импульсное управление симистором.
*/
ISR(VECTOR){
counter++; // считаем фазу
if((counter > phase)) // сравниваем ее с заданным значением
OUT_PORT |= OUT_PIN; // включаем выход, если надо
else {
OUT_PORT &= ~OUT_PIN; // а если не надо - выключаем
}
if(!counter) // если достигнут предел фазы, то
stop_timer(); // останавливаем таймер
}
/** Обработчик внешнего запроса прерывания.
* Выполняет синхрогнизацию фазорегулятора.
*/
ISR(INT0_vect){
OUT_PORT &= ~OUT_PIN; // выключаем выходной сигнал
start_timer(); // запускаем таймер фазы
// далее начинается работа таймера автоотключения
if(timer_on){ // если таймер автоотключения активирован,
if(!--timer){ // то считаем тики синхронизации
timer = F_PWR * 2; // каждую 1 секунду
OUT_PORT ^= current_led; // мигаем текущим светододом
if(sec) // и ведем подсчет времени
sec--;
else {
sec = 60;
if(min)
min--;
else {
sei(); // когда заданное время истекло
all_off_now(); // все отключаем немедленно
}
}
}
} else {
// включаем светодиод
OUT_PORT = (OUT_PORT & (~ALL_LEDS)) | current_led;
}
}
/** Инициализация всей периферии
*
*/
static void init_all(void){
// настройка внешнего прерывания INT0
MCUCR = _BV(ISC00); // любое изменение вызывает прерывание
GIMSK = _BV(INT0);
// настройка 8-битного таймера
config_timer();
// настройка портов
DDR = OUT_PIN | ALL_LEDS;
OUT_PORT = BTN_PIN;
}
/** Ожидание нажатия кнопки.
* Функция выполняет задержку на указанный интервал, прерывая его сразу по нажатию кнопки
* @param timeout_10ms интервал ожидания в шагах по 10 мс
* @return ноль, если истек интервал, а кнопка не нажималась, единица, если было нажатие кнопки
*/
static uint8_t wait_button_pressed(uint16_t timeout_10ms){
for(; timeout_10ms; timeout_10ms--){
if(!(PIN & BTN_PIN)) return 1; // если кнопка нажата - выход немедленно
_delay_us(MS10_US); // ожидание дискретное - по 10 мс
}
return 0;
}
/** Ожидание отпускания кнопки.
* Функция выполняет задержку на указанный интервал, прерывая его сразу по отпусканию кнопки
* @param timeout_10ms интервал ожидания в шагах по 10 мс
* @return ноль, если истек интервал, а кнопка не отпущена, единица, если было отпускание кнопки
*/
static uint8_t wait_button_released(uint16_t timeout_10ms){
for(; timeout_10ms; timeout_10ms--){
if(PIN & BTN_PIN) return 1; // если кнопка отпущена - выход немедленно
_delay_us(MS10_US); // ожидание дискретное - по 10 мс
}
return 0;
}
/** Активирует таймер автоотключения.
* Функция ожидает отпускания кнопки в течение 6 секунд. Если отпускания так и не было,
* происходит пересброс программы. т.е. полное отключение.
*/
static void set_timer(void){
// устанавливаем интервал ожидания
min = OFF_MIN;
sec = 0;
// число тиков для 1 секунды
timer = F_PWR * 2;
// активируем таймер автоотключения
timer_on = 1;
// ждем 6 секунд
if(!wait_button_released(T_STANDBY))
// ежели не дождались отпускания кнопки - перезагрузка
all_off_now();
}
/** Отработка алгоритма бриза.
* Функция в течение заданного интервала производит изменение фазы, при этом контролирует
* состояние кнопки. Если кнопка нажата кратко - функция завершается немедленно. Если
* кнопка нажата не менее 2 секунд - активируется таймер автоотключения, но функция продолжает
* работу.
* @param first начальное значение фазы
* @param steps количество шагов по 100 мс
* @return ноль, если цикл не отработал до конца (выход по кнопке), единица, если цикл
* отработал до конца
*/
static uint8_t do_breeze(uint8_t first, uint8_t steps){
// задаем начальную фазу
phase = first;
// цикл по длительности
for(; steps; steps--){
if(stop_all) return 0; // если пора отключаться - немедленный выход
if(wait_button_pressed(10)){ // задержка с ожиданием кнопки
_delay_ms(10); // задержка для подавления дребезга
if(wait_button_released(T_AUTOOFF))// если кнопку отпустили,
return 0; // сразу же выход
else{ // если кнопку давили долго,
set_timer(); // то запускаем таймер автоотклюения
continue; // и продолжаем работу
}
}
}
return 1;
}
/** Генератор псевдослучайной последовательности байтов
* @return псевдослучайный байт
*/
static uint8_t rnd(void){
extern void _exit();
extern uint8_t __ctors_end;
static void *tmp; // вспомогательный указатель - начальное значение роли не играет
// в качестве псевдослучайной последовательности просто загружаем байт за
// байтом коды самой программы в определенном диапазоне адресов
if((tmp > (void*)_exit) || (tmp < (void*)&__ctors_end))
tmp = (void*)&__ctors_end;
return pgm_read_byte(tmp++);
}
/** Начало любой программы бриза.
*
* @param led нужное состояние светодиодов
*/
static void begin_program(uint8_t led){
timer_on = 0; // сбрасываем таймер автоотключения
current_led = led; // и задаем нужный светодиод
}
int __attribute__((OS_main)) main(void){
// инициализация всей периферии
init_all();
sei();
// основной цикл
while(1){
stop_all = 0; // убираем флаг автоотключения
phase = 255; // делаем максимум фазы, чтобы выключить все,
// даже если кнопка все еще нажата
begin_program(0); // готовимся к запуску нулевой программы - все отключено
wait_button_released(60000); // ждем отпускания кнопки
// выключенное состояние
while(do_breeze(255,100)); // ждем в отключенном состоянии нажатия кнопки
// первая программа - планое нарастание и резкий спад
begin_program(LED1);
while(do_breeze(pgm_read_byte(&stepping[0]),100)){
for(uint8_t i = 0; i < (MAX_STEP-3); i++){
if(!do_breeze(pgm_read_byte(&stepping),20))
goto next1;
}
if(!do_breeze(pgm_read_byte(&stepping[MAX_STEP-1]),20))
break;
}
next1:
// вторая программа - самая слабая скорость
begin_program(LED2);
while(do_breeze(pgm_read_byte(&stepping[0]),200));
// третья программа - случайная
begin_program(ALL_LEDS);
uint8_t idx = 0;
while(do_breeze(pgm_read_byte(&stepping[idx]),30)){
idx = rnd() & 0x05;
}
}
}
что бы использывать в своих целях, повыкусывать не нужное. Использую AVR Studio 4 + WinAVR-20100110.
Ошибка
c:/winavr-20100110/lib/gcc/../../avr/include/util/delay.h:85:3: warning: #warning "F_CPU not defined for <util/delay.h>"
c:/winavr-20100110/lib/gcc/../../avr/include/util/delay.h:90:3: warning: #warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed"
../hex.c:24:18: error: main.h: No such file or directory
Спойлер
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include "main.h"
/// массив, из которого выбираются значения фазы
PROGMEM uint8_t stepping[MAX_STEP] = {170,160,150,140,100,50,10};
/// текущее значение заданной фазы регулятора
volatile uint8_t phase = 255;
/// счетчик программной фазы
volatile uint8_t counter = 0;
/// счетчик полупериодов сети для таймера автоотключения
volatile uint8_t timer;
/// флаг активности таймера автоотключения
volatile uint8_t timer_on;
/// счетчик секунд таймера автоотключения
volatile uint8_t sec;
/// счетчик минут таймера автоотключения
volatile uint8_t min;
/// текущее состояние светодиодов
volatile uint8_t current_led;
/// флаг для выключения
volatile uint8_t stop_all = 0;
/** Отключение всего немедленно
*/
static void all_off_now(void){
stop_all = 1;
}
/** Обработчик прерывания от таймера, ведущего отсчет фазы.
* Реализует импульсное управление симистором.
*/
ISR(VECTOR){
counter++; // считаем фазу
if((counter > phase)) // сравниваем ее с заданным значением
OUT_PORT |= OUT_PIN; // включаем выход, если надо
else {
OUT_PORT &= ~OUT_PIN; // а если не надо - выключаем
}
if(!counter) // если достигнут предел фазы, то
stop_timer(); // останавливаем таймер
}
/** Обработчик внешнего запроса прерывания.
* Выполняет синхрогнизацию фазорегулятора.
*/
ISR(INT0_vect){
OUT_PORT &= ~OUT_PIN; // выключаем выходной сигнал
start_timer(); // запускаем таймер фазы
// далее начинается работа таймера автоотключения
if(timer_on){ // если таймер автоотключения активирован,
if(!--timer){ // то считаем тики синхронизации
timer = F_PWR * 2; // каждую 1 секунду
OUT_PORT ^= current_led; // мигаем текущим светододом
if(sec) // и ведем подсчет времени
sec--;
else {
sec = 60;
if(min)
min--;
else {
sei(); // когда заданное время истекло
all_off_now(); // все отключаем немедленно
}
}
}
} else {
// включаем светодиод
OUT_PORT = (OUT_PORT & (~ALL_LEDS)) | current_led;
}
}
/** Инициализация всей периферии
*
*/
static void init_all(void){
// настройка внешнего прерывания INT0
MCUCR = _BV(ISC00); // любое изменение вызывает прерывание
GIMSK = _BV(INT0);
// настройка 8-битного таймера
config_timer();
// настройка портов
DDR = OUT_PIN | ALL_LEDS;
OUT_PORT = BTN_PIN;
}
/** Ожидание нажатия кнопки.
* Функция выполняет задержку на указанный интервал, прерывая его сразу по нажатию кнопки
* @param timeout_10ms интервал ожидания в шагах по 10 мс
* @return ноль, если истек интервал, а кнопка не нажималась, единица, если было нажатие кнопки
*/
static uint8_t wait_button_pressed(uint16_t timeout_10ms){
for(; timeout_10ms; timeout_10ms--){
if(!(PIN & BTN_PIN)) return 1; // если кнопка нажата - выход немедленно
_delay_us(MS10_US); // ожидание дискретное - по 10 мс
}
return 0;
}
/** Ожидание отпускания кнопки.
* Функция выполняет задержку на указанный интервал, прерывая его сразу по отпусканию кнопки
* @param timeout_10ms интервал ожидания в шагах по 10 мс
* @return ноль, если истек интервал, а кнопка не отпущена, единица, если было отпускание кнопки
*/
static uint8_t wait_button_released(uint16_t timeout_10ms){
for(; timeout_10ms; timeout_10ms--){
if(PIN & BTN_PIN) return 1; // если кнопка отпущена - выход немедленно
_delay_us(MS10_US); // ожидание дискретное - по 10 мс
}
return 0;
}
/** Активирует таймер автоотключения.
* Функция ожидает отпускания кнопки в течение 6 секунд. Если отпускания так и не было,
* происходит пересброс программы. т.е. полное отключение.
*/
static void set_timer(void){
// устанавливаем интервал ожидания
min = OFF_MIN;
sec = 0;
// число тиков для 1 секунды
timer = F_PWR * 2;
// активируем таймер автоотключения
timer_on = 1;
// ждем 6 секунд
if(!wait_button_released(T_STANDBY))
// ежели не дождались отпускания кнопки - перезагрузка
all_off_now();
}
/** Отработка алгоритма бриза.
* Функция в течение заданного интервала производит изменение фазы, при этом контролирует
* состояние кнопки. Если кнопка нажата кратко - функция завершается немедленно. Если
* кнопка нажата не менее 2 секунд - активируется таймер автоотключения, но функция продолжает
* работу.
* @param first начальное значение фазы
* @param steps количество шагов по 100 мс
* @return ноль, если цикл не отработал до конца (выход по кнопке), единица, если цикл
* отработал до конца
*/
static uint8_t do_breeze(uint8_t first, uint8_t steps){
// задаем начальную фазу
phase = first;
// цикл по длительности
for(; steps; steps--){
if(stop_all) return 0; // если пора отключаться - немедленный выход
if(wait_button_pressed(10)){ // задержка с ожиданием кнопки
_delay_ms(10); // задержка для подавления дребезга
if(wait_button_released(T_AUTOOFF))// если кнопку отпустили,
return 0; // сразу же выход
else{ // если кнопку давили долго,
set_timer(); // то запускаем таймер автоотклюения
continue; // и продолжаем работу
}
}
}
return 1;
}
/** Генератор псевдослучайной последовательности байтов
* @return псевдослучайный байт
*/
static uint8_t rnd(void){
extern void _exit();
extern uint8_t __ctors_end;
static void *tmp; // вспомогательный указатель - начальное значение роли не играет
// в качестве псевдослучайной последовательности просто загружаем байт за
// байтом коды самой программы в определенном диапазоне адресов
if((tmp > (void*)_exit) || (tmp < (void*)&__ctors_end))
tmp = (void*)&__ctors_end;
return pgm_read_byte(tmp++);
}
/** Начало любой программы бриза.
*
* @param led нужное состояние светодиодов
*/
static void begin_program(uint8_t led){
timer_on = 0; // сбрасываем таймер автоотключения
current_led = led; // и задаем нужный светодиод
}
int __attribute__((OS_main)) main(void){
// инициализация всей периферии
init_all();
sei();
// основной цикл
while(1){
stop_all = 0; // убираем флаг автоотключения
phase = 255; // делаем максимум фазы, чтобы выключить все,
// даже если кнопка все еще нажата
begin_program(0); // готовимся к запуску нулевой программы - все отключено
wait_button_released(60000); // ждем отпускания кнопки
// выключенное состояние
while(do_breeze(255,100)); // ждем в отключенном состоянии нажатия кнопки
// первая программа - планое нарастание и резкий спад
begin_program(LED1);
while(do_breeze(pgm_read_byte(&stepping[0]),100)){
for(uint8_t i = 0; i < (MAX_STEP-3); i++){
if(!do_breeze(pgm_read_byte(&stepping),20))
goto next1;
}
if(!do_breeze(pgm_read_byte(&stepping[MAX_STEP-1]),20))
break;
}
next1:
// вторая программа - самая слабая скорость
begin_program(LED2);
while(do_breeze(pgm_read_byte(&stepping[0]),200));
// третья программа - случайная
begin_program(ALL_LEDS);
uint8_t idx = 0;
while(do_breeze(pgm_read_byte(&stepping[idx]),30)){
idx = rnd() & 0x05;
}
}
}
что бы использывать в своих целях, повыкусывать не нужное. Использую AVR Studio 4 + WinAVR-20100110.
Ошибка
c:/winavr-20100110/lib/gcc/../../avr/include/util/delay.h:85:3: warning: #warning "F_CPU not defined for <util/delay.h>"
c:/winavr-20100110/lib/gcc/../../avr/include/util/delay.h:90:3: warning: #warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed"
../hex.c:24:18: error: main.h: No such file or directory
Ошибки переводить пробовали?SICBOY писал(а):Не могу откомпилировать данный код :
c:/winavr-20100110/lib/gcc/../../avr/include/util/delay.h:85:3: warning: #warning "F_CPU not defined for <util/delay.h>"
c:/winavr-20100110/lib/gcc/../../avr/include/util/delay.h:90:3: warning: #warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed"
../hex.c:24:18: error: main.h: No such file or directory
Ставим плюсы: )
- Сообщения: 21
- Зарегистрирован: Сб июн 23, 2012 11:19:11
Ну...да в проэкте не указал частоту , но указав все равно не компилирует
c:/winavr-20100110/lib/gcc/../../avr/include/util/delay.h:90:3: warning: #warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed"
c:/winavr-20100110/lib/gcc/../../avr/include/util/delay.h:90:3: warning: #warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed"
вы приводите не полный список сообщений. при #warning`ах проект компилируется. обратите внимание на строчку
../hex.c:24:18: error: main.h: No such file or directory
Ставим плюсы: )


