Дисковый номеронабиратель и семисегментник
Re: Дисковый номеронабиратель и семисегментник
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3233340#p3233340"]2. переменная off обнуляется в тексте программы при каждом нажатии на любую кнопку.[/uquote]А если кнопку не нажимаем долгое время, а "off" так и крутится постоянно - это нормально будет?
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3233340#p3233340"]опять перепутал знак "=" и "=="[/uquote]Для таких случаев приучи себя писать не "if( off == 2 )", а "if( 2 == off )".
На этапе компиляции сразу отследиться.
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3233340#p3233340"]опять перепутал знак "=" и "=="[/uquote]Для таких случаев приучи себя писать не "if( off == 2 )", а "if( 2 == off )".
На этапе компиляции сразу отследиться.
- Реклама
-
Hiperboloyd
- Первый раз сказал Мяу!
- Сообщения: 39
- Зарегистрирован: Пт авг 08, 2008 23:41:37
- Откуда: Penza
- Контактная информация:
Re: Дисковый номеронабиратель и семисегментник
[uquote="mas123",url="/forum/viewtopic.php?p=3233469#p3233469"][uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3233340#p3233340"]2. переменная off обнуляется в тексте программы при каждом нажатии на любую кнопку.[/uquote]А если кнопку не нажимаем долгое время, а "off" так и крутится постоянно - это нормально будет?[/uquote]
ну вроде я так понял что это не на что не влияет.)) или я не прав?
Добавлено after 8 hours 20 minutes 33 seconds:
Друзья, помогите пожалуйста. Стою на асфальте в лыжи обутый то ли лыжи не едут, то ли я стебанутый...
в общем, почти все работало. занимался отладкой уже на железе.... и тут как-то раз и перестало... вообще перестало..... то ли в проге где-то накосячил, то ли схему на макетке неправильно собрал...ТРИ атмеги не работают......у дочи др через 10 дней, боюсь, без вашей помощи не обойдусь....а еще плату травить....
теперь много буковок, кому лень читать ,я не обижусь, просто почти отчаялся....
1. шью китайским USBASP.
2. микруху ставлю в китайскую платочку с мин. обвязкой
3. МК пишется, верификация без ошибок. но на всех трех микрухак на PС4 почему-то всегда висит 0". Остальные подтяжки работают. если подключить кноки в соответствии со схемой, то мк на нажатие кнопок не реагирует.
3. не знаю могло ли повлиять, но несколько раз я вхерачивал питание в плату, когда был подключен разъем для программирования т.е. 5в с USB и 5в с БП.
5. пробовал сегодня записать эти же контроллеры программатором AUTOPROG, но изменений нет, купил новый МК, но еще не пробовал записать его.
6. если закоментить часть текста проги (условия где встречается PC4) и строчку "sei(); " то прога частично начинает работать.
Ну и самое интересное
7. в PROTEUS все работает как надо
что я могу делать не так? ((
схема
текст программы(коменты могут не соответствовать из-за копипаста):
#include <avr/interrupt.h>
#define F_CPU 1000000UL
#include <util/delay.h>
volatile unsigned char off=0; //для выключения всего
unsigned char flag=0; //флаг нажатой кнопки светофора
unsigned char cifra=0; //для семисегментника
unsigned char svet=0; //для светофора
unsigned char vykl=0; //для выключателя
unsigned char rozetka=0; //для розетки
unsigned char sv=0;
unsigned char mag=0;
unsigned char SEGMENTE[] =
{// gfedcba
0b11111111,
0b11000000, // 0
0b11111001, // 1
0b10100100, // 2
0b10110000, // 3
0b10011001, // 4
0b10010010, // 5
0b10000010, // 6
0b11111000, // 7
0b10000000, // 8
0b10010000, // 9
};
ISR( TIMER1_OVF_vect )
{
off++;
if (8 == off)
{
PORTD &= ~(1<<6); //Выключить розетку (Вентилятор)
}
if (15 == off)
{
PORTA |= 1<<7; //погасить семисегментник
PORTB = 0b11111111; //погасить светофор
}
if (28 == off)
{
PORTD |= 1<<7;//выключить Свет
}
}
ISR (INT2_vect)
{
_delay_ms(50);
off=0;
cifra = TCNT0; //переменной присвоить значение счетчика
if (cifra>0 && cifra<11) // если цифра >0 и <10
{
PORTA = SEGMENTE[cifra]; //вывести на семисегментник цифру
cifra=0; //обнулить переменную
}
else
{
if (11 == cifra) //если переменная равна 10
{
cifra=1; //обнулить переменную
PORTA = SEGMENTE[cifra]; //вывести на семисегментник цифру 0
}
}
PORTA &= ~(1<<7);// зажечь семисегментник
cifra=0; //обнулить переменную
TCNT0 = 0;
}
int main(void)
{
DDRA = 0b11111111; // порты на выход
PORTA = 0b11111111; // подтягиваем к 1
DDRB = 0b11111010;
PORTB = 0b11111111; //подтягивем к 1
DDRC = 0b00000000;
PORTC = 0b11111111; // подтягиваем к 1
DDRD = 0b11000100;
PORTD = 0b10111011;
GICR |= (1<<INT2); //разрешить внешние прерывания инт2
MCUCSR |=(1<<ISC2);//по спадающему фронту INT2
TCNT0 = 0; //установка таймера в ноль
TCCR0 |=(1<<CS02)|(1<<CS01)|(1<<CS00); //таймер от внеш. источника по переднему фронту для номеронабирателя
TIMSK |=(1<<TOIE1); //таймер по переполнению
TCCR1B |=(1<<CS11)|(1<<CS10); //делитель 64
sei(); //разрешить общее прерывание
while (1)
{
//-------------------------------ПЕРВЫЕ ТРИ КНОПКИ--------------------------------------------------
if (!(PINC & (1<<0))) // если PC0 = не 1 тк "!" перед условием
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<0)))
{
PORTB &= ~(1<<1); // Установить на PB1 = 0
PORTB |= 1<<3; // Установить на PB3 = 1
}
while (!(PINC & (1<<0)))
{
}
}
//----------------------------------------
if (!(PINC & (1<<2)))
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<2)))
{
PORTB |= 1<<1;
PORTB &= ~(1<<3);
}
while (!(PINC & (1<<2)))
{
}
}
//------------------------------------------
if (!(PINC & (1<<1)))
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<1)))
{
PORTB &= ~(1<<3);
PORTB &= ~(1<<1);
}
while (!(PINC & (1<<1)))
{
}
}
//-------------------------------ВТОРЫЕ ТРИ КНОПКИ--------------------------------------------------
if (!(PINC & (1<<3))) // если PC0 = не 1 тк "!" перед условием
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<3)))
{
PORTB &= ~(1<<4); // Установить на PB1 = 0
PORTB |= 1<<5; // Установить на PB3 = 1
}
while (!(PINC & (1<<3)))
{
}
}
//---------------------------------------
if (!(PINC & (1<<5)))
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<5)))
{
PORTB |= 1<<4;
PORTB &= ~(1<<5);
}
while (!(PINC & (1<<5)))
{
}
}
//----------------------------------------
if (!(PINC & (1<<4)))
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<4)))
{
PORTB &= ~(1<<4);
PORTB &= ~(1<<5);
}
while (!(PINC & (1<<4)))
{
}
}
//-------------------------------ТРЕТЬИ ТРИ КНОПКИ--------------------------------------------------
if (!(PINC & (1<<6))) // если PC6 = не 1 тк "!" перед условием
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<6)))
{
PORTB &= ~(1<<6); // Установить на PB6 = 0
PORTB |= 1<<7; // Установить на PB7 = 1
}
while ((!PINC & (1<<6)))
{
}
}
//---------------------------------------------------
if (!(PIND & (1<<0)))
{
_delay_ms(50);
off=0;
if (!(PIND & (1<<0)))
{
PORTB |= 1<<6;
PORTB &= ~(1<<7);
}
while (!(PIND & (1<<0)))
{
}
}
//-----------------------------------------------------
if (!(PINC & (1<<7)))
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<7)))
{
PORTB &= ~(1<<6);
PORTB &= ~(1<<7);
}
while (!(PINC & (1<<7)))
{
}
}
//----------------ЭЛ. ЗАМОК-----------------------------
if ((PINB & (1<<1)) && (!(PINB & (1<<3))) && (!(PINB & (1<<4))) && (!(PINB & (1<<5))) && (!(PINB & (1<<6))) && (PINB & (1<<7)))
{
PORTD |= 1<<2;
}
else
{
PORTD &= ~(1<<2);
}
//--------------------------------------
if (!(PIND & (1<<1)))
{
if (0==rozetka)
{
off=0;
_delay_ms(50);
rozetka=1;
PORTD |= 1<<6;
}
}
else
{
PORTD &= ~(1<<6);
rozetka=0;
}
//-----------------------ВЫКЛЮЧАТЕЛЬ СВЕТА-------------
if (!(PIND & (1<<3)))
{
if (0==vykl)
{
off=0;
_delay_ms(50);
vykl=1;
PORTD &= ~(1<<7);
}
}
else
{
PORTD |= 1<<7;
vykl=0;
}
//-----------------------КНОПКА СВЕТОФОРА-------------------
if (!(PIND & (1<<4)))
{
off=0;
_delay_ms(50);
if (!(PIND & (1<<4)))
{
sv++; //переменной +1
switch (sv)
{
case 1: PORTB &= ~(1<<1);PORTB &= ~(1<<4);PORTB &= ~(1<<6);PORTB |= 1<<3;PORTB |= 1<<5;PORTB |= 1<<7; break;
case 2: PORTB &= ~(1<<1);PORTB &= ~(1<<4);PORTB &= ~(1<<6);PORTB &= ~(1<<3);PORTB &= ~(1<<5);PORTB &= ~(1<<7); break;
case 3: PORTB &= ~(1<<3);PORTB &= ~(1<<5);PORTB &= ~(1<<7);PORTB |= 1<<1;PORTB |= 1<<4;PORTB |= 1<<6;sv=0;break;
default: ;
}
}
while (!(PIND & (1<<4)))
{
}
}
//----------------------КНОПКА ТЕЛЕФОНА------------------------------
if (!(PIND & (1<<5)))
{
off=0;
_delay_ms(50);
if (!(PIND & (1<<5)))
{
cifra++;
if (cifra>0 && cifra<11) // если цифра >0 и <10
{
PORTA = SEGMENTE[cifra]; //вывести на семисегментник цифру
PORTA &= ~(1<<7);// зажечь семисегментник
}
else
{
if (11==cifra) //если переменная равна 10
{
cifra=1; //обнулить переменную
PORTA = SEGMENTE[cifra]; //вывести на семисегментник цифру 0
PORTA &= ~(1<<7);// зажечь семисегментник
cifra=1;
}
}
}
while (!(PIND & (1<<5)))
{
}
}
}
}
ну вроде я так понял что это не на что не влияет.)) или я не прав?
Добавлено after 8 hours 20 minutes 33 seconds:
Друзья, помогите пожалуйста. Стою на асфальте в лыжи обутый то ли лыжи не едут, то ли я стебанутый...
в общем, почти все работало. занимался отладкой уже на железе.... и тут как-то раз и перестало... вообще перестало..... то ли в проге где-то накосячил, то ли схему на макетке неправильно собрал...ТРИ атмеги не работают......у дочи др через 10 дней, боюсь, без вашей помощи не обойдусь....а еще плату травить....
теперь много буковок, кому лень читать ,я не обижусь, просто почти отчаялся....
1. шью китайским USBASP.
2. микруху ставлю в китайскую платочку с мин. обвязкой
Спойлер

3. не знаю могло ли повлиять, но несколько раз я вхерачивал питание в плату, когда был подключен разъем для программирования т.е. 5в с USB и 5в с БП.
5. пробовал сегодня записать эти же контроллеры программатором AUTOPROG, но изменений нет, купил новый МК, но еще не пробовал записать его.
6. если закоментить часть текста проги (условия где встречается PC4) и строчку "sei(); " то прога частично начинает работать.
Ну и самое интересное
7. в PROTEUS все работает как надо
что я могу делать не так? ((
схема
Спойлер

Спойлер
#include <avr/io.h>#include <avr/interrupt.h>
#define F_CPU 1000000UL
#include <util/delay.h>
volatile unsigned char off=0; //для выключения всего
unsigned char flag=0; //флаг нажатой кнопки светофора
unsigned char cifra=0; //для семисегментника
unsigned char svet=0; //для светофора
unsigned char vykl=0; //для выключателя
unsigned char rozetka=0; //для розетки
unsigned char sv=0;
unsigned char mag=0;
unsigned char SEGMENTE[] =
{// gfedcba
0b11111111,
0b11000000, // 0
0b11111001, // 1
0b10100100, // 2
0b10110000, // 3
0b10011001, // 4
0b10010010, // 5
0b10000010, // 6
0b11111000, // 7
0b10000000, // 8
0b10010000, // 9
};
ISR( TIMER1_OVF_vect )
{
off++;
if (8 == off)
{
PORTD &= ~(1<<6); //Выключить розетку (Вентилятор)
}
if (15 == off)
{
PORTA |= 1<<7; //погасить семисегментник
PORTB = 0b11111111; //погасить светофор
}
if (28 == off)
{
PORTD |= 1<<7;//выключить Свет
}
}
ISR (INT2_vect)
{
_delay_ms(50);
off=0;
cifra = TCNT0; //переменной присвоить значение счетчика
if (cifra>0 && cifra<11) // если цифра >0 и <10
{
PORTA = SEGMENTE[cifra]; //вывести на семисегментник цифру
cifra=0; //обнулить переменную
}
else
{
if (11 == cifra) //если переменная равна 10
{
cifra=1; //обнулить переменную
PORTA = SEGMENTE[cifra]; //вывести на семисегментник цифру 0
}
}
PORTA &= ~(1<<7);// зажечь семисегментник
cifra=0; //обнулить переменную
TCNT0 = 0;
}
int main(void)
{
DDRA = 0b11111111; // порты на выход
PORTA = 0b11111111; // подтягиваем к 1
DDRB = 0b11111010;
PORTB = 0b11111111; //подтягивем к 1
DDRC = 0b00000000;
PORTC = 0b11111111; // подтягиваем к 1
DDRD = 0b11000100;
PORTD = 0b10111011;
GICR |= (1<<INT2); //разрешить внешние прерывания инт2
MCUCSR |=(1<<ISC2);//по спадающему фронту INT2
TCNT0 = 0; //установка таймера в ноль
TCCR0 |=(1<<CS02)|(1<<CS01)|(1<<CS00); //таймер от внеш. источника по переднему фронту для номеронабирателя
TIMSK |=(1<<TOIE1); //таймер по переполнению
TCCR1B |=(1<<CS11)|(1<<CS10); //делитель 64
sei(); //разрешить общее прерывание
while (1)
{
//-------------------------------ПЕРВЫЕ ТРИ КНОПКИ--------------------------------------------------
if (!(PINC & (1<<0))) // если PC0 = не 1 тк "!" перед условием
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<0)))
{
PORTB &= ~(1<<1); // Установить на PB1 = 0
PORTB |= 1<<3; // Установить на PB3 = 1
}
while (!(PINC & (1<<0)))
{
}
}
//----------------------------------------
if (!(PINC & (1<<2)))
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<2)))
{
PORTB |= 1<<1;
PORTB &= ~(1<<3);
}
while (!(PINC & (1<<2)))
{
}
}
//------------------------------------------
if (!(PINC & (1<<1)))
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<1)))
{
PORTB &= ~(1<<3);
PORTB &= ~(1<<1);
}
while (!(PINC & (1<<1)))
{
}
}
//-------------------------------ВТОРЫЕ ТРИ КНОПКИ--------------------------------------------------
if (!(PINC & (1<<3))) // если PC0 = не 1 тк "!" перед условием
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<3)))
{
PORTB &= ~(1<<4); // Установить на PB1 = 0
PORTB |= 1<<5; // Установить на PB3 = 1
}
while (!(PINC & (1<<3)))
{
}
}
//---------------------------------------
if (!(PINC & (1<<5)))
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<5)))
{
PORTB |= 1<<4;
PORTB &= ~(1<<5);
}
while (!(PINC & (1<<5)))
{
}
}
//----------------------------------------
if (!(PINC & (1<<4)))
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<4)))
{
PORTB &= ~(1<<4);
PORTB &= ~(1<<5);
}
while (!(PINC & (1<<4)))
{
}
}
//-------------------------------ТРЕТЬИ ТРИ КНОПКИ--------------------------------------------------
if (!(PINC & (1<<6))) // если PC6 = не 1 тк "!" перед условием
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<6)))
{
PORTB &= ~(1<<6); // Установить на PB6 = 0
PORTB |= 1<<7; // Установить на PB7 = 1
}
while ((!PINC & (1<<6)))
{
}
}
//---------------------------------------------------
if (!(PIND & (1<<0)))
{
_delay_ms(50);
off=0;
if (!(PIND & (1<<0)))
{
PORTB |= 1<<6;
PORTB &= ~(1<<7);
}
while (!(PIND & (1<<0)))
{
}
}
//-----------------------------------------------------
if (!(PINC & (1<<7)))
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<7)))
{
PORTB &= ~(1<<6);
PORTB &= ~(1<<7);
}
while (!(PINC & (1<<7)))
{
}
}
//----------------ЭЛ. ЗАМОК-----------------------------
if ((PINB & (1<<1)) && (!(PINB & (1<<3))) && (!(PINB & (1<<4))) && (!(PINB & (1<<5))) && (!(PINB & (1<<6))) && (PINB & (1<<7)))
{
PORTD |= 1<<2;
}
else
{
PORTD &= ~(1<<2);
}
//--------------------------------------
if (!(PIND & (1<<1)))
{
if (0==rozetka)
{
off=0;
_delay_ms(50);
rozetka=1;
PORTD |= 1<<6;
}
}
else
{
PORTD &= ~(1<<6);
rozetka=0;
}
//-----------------------ВЫКЛЮЧАТЕЛЬ СВЕТА-------------
if (!(PIND & (1<<3)))
{
if (0==vykl)
{
off=0;
_delay_ms(50);
vykl=1;
PORTD &= ~(1<<7);
}
}
else
{
PORTD |= 1<<7;
vykl=0;
}
//-----------------------КНОПКА СВЕТОФОРА-------------------
if (!(PIND & (1<<4)))
{
off=0;
_delay_ms(50);
if (!(PIND & (1<<4)))
{
sv++; //переменной +1
switch (sv)
{
case 1: PORTB &= ~(1<<1);PORTB &= ~(1<<4);PORTB &= ~(1<<6);PORTB |= 1<<3;PORTB |= 1<<5;PORTB |= 1<<7; break;
case 2: PORTB &= ~(1<<1);PORTB &= ~(1<<4);PORTB &= ~(1<<6);PORTB &= ~(1<<3);PORTB &= ~(1<<5);PORTB &= ~(1<<7); break;
case 3: PORTB &= ~(1<<3);PORTB &= ~(1<<5);PORTB &= ~(1<<7);PORTB |= 1<<1;PORTB |= 1<<4;PORTB |= 1<<6;sv=0;break;
default: ;
}
}
while (!(PIND & (1<<4)))
{
}
}
//----------------------КНОПКА ТЕЛЕФОНА------------------------------
if (!(PIND & (1<<5)))
{
off=0;
_delay_ms(50);
if (!(PIND & (1<<5)))
{
cifra++;
if (cifra>0 && cifra<11) // если цифра >0 и <10
{
PORTA = SEGMENTE[cifra]; //вывести на семисегментник цифру
PORTA &= ~(1<<7);// зажечь семисегментник
}
else
{
if (11==cifra) //если переменная равна 10
{
cifra=1; //обнулить переменную
PORTA = SEGMENTE[cifra]; //вывести на семисегментник цифру 0
PORTA &= ~(1<<7);// зажечь семисегментник
cifra=1;
}
}
}
while (!(PIND & (1<<5)))
{
}
}
}
}
Re: Дисковый номеронабиратель и семисегментник
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3237600#p3237600"]ну вроде я так понял что это не на что не влияет.)) или я не прав?[/uquote]Угу, если "не влияет" означает постоянные периодические срабатывания
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3237600#p3237600"]ТРИ атмеги не работают......[/uquote]Не вижу кварца у атмеги. Правильно ли она сконфигурирована (FUSE) на работу от внутреннего RC-генератора?
Подано ли питание не только на VCC, но и на AVCC?
Какая у тебя стоит ATMEGA? На схеме фиг разглядишь, по распиновке смахивает на DIP-40 корпус Atmaga32 или 8535.
Если Аtmega32, то на PC2-PC5 висит JTAG. Смотри FUSE-бит "JTAGEN" - по умолчанию он активен. "Default Value 0 (programmed, JTAG enabled)"
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3237600#p3237600"]6. если закоментить часть текста проги (условия где встречается PC4) и строчку "sei(); " то прога частично начинает работать.[/uquote]А если только прерывания не разрешать - начинает "частично работать"?
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3237600#p3237600"]ISR (INT2_vect)
{
_delay_ms(50);[/uquote]Как я уже говорил - не люблю повторяться. (с)
Но, на кой хрен в прерывании задержка?!
Попробовать PB0 и PB2 подтянуть резистором снаружи, всё же может внутренней подтяжки не хватать.
Это, кстати, и к PC4 относится - если подключить внешнюю подтяжку, там будет "1"? При условии, что там точно нет JTAG.
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3237600#p3237600"]вообще перестало..... то ли в проге где-то накосячил,[/uquote]Именно для таких случаев придумана "система контроля версий" или хотя бы ежедневные бекапы проекта - чтобы всегда можно было откатиться на шаг назад или до прошлого рабочего состояния.PORTA |= 1<<7; //погасить семисегментник
PORTB = 0b11111111; //погасить светофор
PORTD |= 1<<7;//выключить Свет
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3237600#p3237600"]ТРИ атмеги не работают......[/uquote]Не вижу кварца у атмеги. Правильно ли она сконфигурирована (FUSE) на работу от внутреннего RC-генератора?
Подано ли питание не только на VCC, но и на AVCC?
Какая у тебя стоит ATMEGA? На схеме фиг разглядишь, по распиновке смахивает на DIP-40 корпус Atmaga32 или 8535.
Если Аtmega32, то на PC2-PC5 висит JTAG. Смотри FUSE-бит "JTAGEN" - по умолчанию он активен. "Default Value 0 (programmed, JTAG enabled)"
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3237600#p3237600"]6. если закоментить часть текста проги (условия где встречается PC4) и строчку "sei(); " то прога частично начинает работать.[/uquote]А если только прерывания не разрешать - начинает "частично работать"?
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3237600#p3237600"]ISR (INT2_vect)
{
_delay_ms(50);[/uquote]Как я уже говорил - не люблю повторяться. (с)
Но, на кой хрен в прерывании задержка?!
Попробовать PB0 и PB2 подтянуть резистором снаружи, всё же может внутренней подтяжки не хватать.
Это, кстати, и к PC4 относится - если подключить внешнюю подтяжку, там будет "1"? При условии, что там точно нет JTAG.
-
Hiperboloyd
- Первый раз сказал Мяу!
- Сообщения: 39
- Зарегистрирован: Пт авг 08, 2008 23:41:37
- Откуда: Penza
- Контактная информация:
Re: Дисковый номеронабиратель и семисегментник
Я понял о чем Вы говорите, но не пойму что Вы этим хотите сказать. Физически же ничего не будет происходить. крутится и крутится эта переменная... что-то нажали ---> прошло время ---> "PORTB = 0b11111111" --> все погасло , мы ничего не делаем и через время произошло тоже самое,т.е. как было погашено так и осталось. Если Вы имеете ввиду что это не по фэншую, тогда надо переделывать алгоритм, чтоб как-то счетчик останавливался на время простоя, на это у меня ума не хватает). максиму что можно от меня добиться это добавить условие в прерывание типо:mas123 писал(а):Угу, если "не влияет" означает постоянные периодические срабатывания
Цитата:
PORTA |= 1<<7; //погасить семисегментник
PORTB = 0b11111111; //погасить светофор
PORTD |= 1<<7;//выключить Свет
if (<все включено>)
{<все выключить>;}
else
{}
Если так правильнее то сделаю, только скажите))
Обязательно учту на будущее!mas123 писал(а):Именно для таких случаев придумана "система контроля версий" или хотя бы ежедневные бекапы проекта - чтобы всегда можно было откатиться на шаг назад или до прошлого рабочего состояния.
Atmega16. работает от внутреннего кварцаmas123 писал(а):Не вижу кварца у атмеги. Правильно ли она сконфигурирована (FUSE) на работу от внутреннего RC-генератора?
Подано ли питание не только на VCC, но и на AVCC?
Какая у тебя стоит ATMEGA? На схеме фиг разглядишь, по распиновке смахивает на DIP-40 корпус Atmaga32 или 8535.
Если Аtmega32, то на PC2-PC5 висит JTAG. Смотри FUSE-бит "JTAGEN" - по умолчанию он активен. "Default Value 0 (programmed, JTAG enabled)"
Вы ЧЕЛОВЕК! Спасибо огромное! действительно проблемы была в FUSE, галочка JTAG... в самом начале я её убирал, и настройки сохранились, а потом начал работать на другом компе и там прога с фьюзами по умолчанию и галочка стоит((((( в общем как Вы и написали.
Убрал!mas123 писал(а):Hiperboloyd писал(а):
ISR (INT2_vect)
{
_delay_ms(50);
Как я уже говорил - не люблю повторяться. (с)
Всё вроде заработало! еще раз огромное спасибо!
если объясните первый вопрос, по поводу выключения и переменной off, как там лучше сделать - будет очень здорово), ну а если надоело ковыряться моей фигне, ничего страшного!
- Ivanoff-iv
- Друг Кота
- Сообщения: 7077
- Зарегистрирован: Пт ноя 11, 2016 05:48:09
- Откуда: Сердце Пармы
Re: Дисковый номеронабиратель и семисегментник
можно вместо: off ;
написать: off =(~off)? 1:0;
если офф не 0xff к нему прибавится 1, иначе 0.
так переменная дойдёт до 255 и там и останется. т.е. в условие сброса надо вписать 254 а не 255.
написать: off =(~off)? 1:0;
если офф не 0xff к нему прибавится 1, иначе 0.
так переменная дойдёт до 255 и там и останется. т.е. в условие сброса надо вписать 254 а не 255.
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
- Реклама
Re: Дисковый номеронабиратель и семисегментник
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3238693#p3238693"]Физически же ничего не будет происходить. крутится и крутится эта переменная...[/uquote]Если вначале включается что-то из серии "погасить по таймеру", а лишь потом обнуляется "off", то возможна ситуация мгновенного выключения включенного, т.к. таймер "сработал".
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3238693#p3238693"]тогда надо переделывать алгоритм, чтоб как-то счетчик останавливался на время простоя, на это у меня ума не хватает). максиму что можно от меня добиться это добавить условие в прерывание типо:[/uquote]Один из вариантов решения - принять какое-то значение "off" как "остановлено".
Например, если off == 255, то в прерывании эту переменную не увеличивать.
В значение 255 переводить в прерывании, когда отработают все "выключено". А то и само оно до этого значения добежит и остановится.
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3238693#p3238693"]тогда надо переделывать алгоритм, чтоб как-то счетчик останавливался на время простоя, на это у меня ума не хватает). максиму что можно от меня добиться это добавить условие в прерывание типо:[/uquote]Один из вариантов решения - принять какое-то значение "off" как "остановлено".
Например, если off == 255, то в прерывании эту переменную не увеличивать.
В значение 255 переводить в прерывании, когда отработают все "выключено". А то и само оно до этого значения добежит и остановится.
-
Hiperboloyd
- Первый раз сказал Мяу!
- Сообщения: 39
- Зарегистрирован: Пт авг 08, 2008 23:41:37
- Откуда: Penza
- Контактная информация:
Re: Дисковый номеронабиратель и семисегментник
спасибо, но это кажется сложновато для меняHiperboloyd писал(а):можно вместо: off ;
написать: off =(~off)? 1:0;
если офф не 0xff к нему прибавится 1, иначе 0.
так переменная дойдёт до 255 и там и останется. т.е. в условие сброса надо вписать 254 а не 255.
чтобы off постоянно не крутилось, можно просто добавить условие:mas123 писал(а):Один из вариантов решения - принять какое-то значение "off" как "остановлено".
Например, если off == 255, то в прерывании эту переменную не увеличивать.
В значение 255 переводить в прерывании, когда отработают все "выключено". А то и само оно до этого значения добежит и остановится.
Спойлер
ISR( TIMER1_OVF_vect ){
if ( off < 29)
{
off++;
if (8 == off)
{
PORTD &= ~(1<<6); //Выключить розетку (Вентилятор)
}
if (15 == off)
{
PORTA |= 1<<7; //погасить семисегментник
PORTB = 0b11111111; //погасить светофор
}
if (28 == off)
{
PORTD |= 1<<7;//выключить Свет
}
}
}
mas123 писал(а): возможна ситуация мгновенного выключения включенного, т.к. таймер "сработал".
-
Demiurg
- Это не хвост, это антенна
- Сообщения: 1480
- Зарегистрирован: Ср июн 25, 2008 15:19:44
- Контактная информация:
Re: Дисковый номеронабиратель и семисегментник
Вам нужно пересмотреть всю программу. Но сначала я хотел бы узнать, что вы сейчас хотите сделать. Смотрю схема у вас новая.
- Ivanoff-iv
- Друг Кота
- Сообщения: 7077
- Зарегистрирован: Пт ноя 11, 2016 05:48:09
- Откуда: Сердце Пармы
Re: Дисковый номеронабиратель и семисегментник
блин, я забыл что сайт "плюсы" съедает 
вместо off++;
off+=(~off)? 1:0;
скобки и вопрос это сокращённая запись ветвления, читается так: если в скобках истина, то выражение берётся до двоеточия, если ложно — после. ~ - инверсия побитовая (0xff обернётся в 0x00 и даст ложь, всё остальное даст истину. получаем -если офф!=255 выражение будет 1, и её прибавим к офф иначе прибавим 0.
вместо off++;
off+=(~off)? 1:0;
скобки и вопрос это сокращённая запись ветвления, читается так: если в скобках истина, то выражение берётся до двоеточия, если ложно — после. ~ - инверсия побитовая (0xff обернётся в 0x00 и даст ложь, всё остальное даст истину. получаем -если офф!=255 выражение будет 1, и её прибавим к офф иначе прибавим 0.
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Re: Дисковый номеронабиратель и семисегментник
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3239789#p3239789"]чтобы off постоянно не крутилось, можно просто добавить условие:
if ( off < 29)
...[/uquote]А теперь найди 33 разницы с моим вариантом "255 - это значение стоп".
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3239789#p3239789"]но я так понимаю это не решит проблему:[/uquote]Почему же? Решит.
При обнуление таймера после установки "включить" - "off" будет наращиваться, а когда дотикает до нужного значения - выключит.
Зато можно быть уверенным, что в момент установки "включить" таймер не сработает "вот-вот" на отключение.
if ( off < 29)
...[/uquote]А теперь найди 33 разницы с моим вариантом "255 - это значение стоп".
[uquote="Hiperboloyd",url="/forum/viewtopic.php?p=3239789#p3239789"]но я так понимаю это не решит проблему:[/uquote]Почему же? Решит.
При обнуление таймера после установки "включить" - "off" будет наращиваться, а когда дотикает до нужного значения - выключит.
Зато можно быть уверенным, что в момент установки "включить" таймер не сработает "вот-вот" на отключение.
-
Hiperboloyd
- Первый раз сказал Мяу!
- Сообщения: 39
- Зарегистрирован: Пт авг 08, 2008 23:41:37
- Откуда: Penza
- Контактная информация:
Re: Дисковый номеронабиратель и семисегментник
[uquote="Demiurg",url="/forum/viewtopic.php?p=3239794#p3239794"]Вам нужно пересмотреть всю программу. Но сначала я хотел бы узнать, что вы сейчас хотите сделать. Смотрю схема у вас новая.[/uquote]
Здравствуйте, в общем все готово, цель достигнута и моя первая программа работает в допустимых пределах(для детской игрушки). Последняя проблема возникла «все перестало работать», я выложил текст всей программы, но ребята подсказали , что дело во фьюзах. Так же Сделали некоторые замечания. Т.к. Я решил что си - это интересно, то попросил объяснить, как что исправить, вот в принципе и все))
Добавлено after 2 minutes 54 seconds:
[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3239971#p3239971"]блин, я забыл что сайт "плюсы" съедает
вместо off++;
off+=(~off)? 1:0;
скобки и вопрос это сокращённая запись ветвления, читается так: если в скобках истина, то выражение берётся до двоеточия, если ложно — после. ~ - инверсия побитовая (0xff обернётся в 0x00 и даст ложь, всё остальное даст истину. получаем -если офф!=255 выражение будет 1, и её прибавим к офф иначе прибавим 0.[/uquote]
Примерно понял, очень интересный вариант, обязательно попробую. Спасибо, Вам!
Добавлено after 4 minutes 32 seconds:
Здравствуйте, в общем все готово, цель достигнута и моя первая программа работает в допустимых пределах(для детской игрушки). Последняя проблема возникла «все перестало работать», я выложил текст всей программы, но ребята подсказали , что дело во фьюзах. Так же Сделали некоторые замечания. Т.к. Я решил что си - это интересно, то попросил объяснить, как что исправить, вот в принципе и все))
Добавлено after 2 minutes 54 seconds:
[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3239971#p3239971"]блин, я забыл что сайт "плюсы" съедает
вместо off++;
off+=(~off)? 1:0;
скобки и вопрос это сокращённая запись ветвления, читается так: если в скобках истина, то выражение берётся до двоеточия, если ложно — после. ~ - инверсия побитовая (0xff обернётся в 0x00 и даст ложь, всё остальное даст истину. получаем -если офф!=255 выражение будет 1, и её прибавим к офф иначе прибавим 0.[/uquote]
Примерно понял, очень интересный вариант, обязательно попробую. Спасибо, Вам!
Добавлено after 4 minutes 32 seconds:
Ну значит со спокойной душой травлю плату! Ещё раз большое спасибо за поддержку и Советыmas123 писал(а):Почему же? Решит.
При обнуление таймера после установки "включить" - "off" будет наращиваться, а когда дотикает до нужного значения - выключит.
Зато можно быть уверенным, что в момент установки "включить" таймер не сработает "вот-вот" на отключение.
-
Hiperboloyd
- Первый раз сказал Мяу!
- Сообщения: 39
- Зарегистрирован: Пт авг 08, 2008 23:41:37
- Откуда: Penza
- Контактная информация:
Re: Дисковый номеронабиратель и семисегментник
Спасибо ВСЕМ большое. Дочке понравилось!
замок пока не ставил - рановато. позже программа будет немного переделана и из светофора появится кодовый замок для синей двери.
выключатель зажигает свет в домики и синий LED в окне вентилятора. Розетка включает сам вентилятор. телефон - просто цифры.
Вот такая штука получилась:








замок пока не ставил - рановато. позже программа будет немного переделана и из светофора появится кодовый замок для синей двери.
выключатель зажигает свет в домики и синий LED в окне вентилятора. Розетка включает сам вентилятор. телефон - просто цифры.
Вот такая штука получилась:
Спойлер








Re: Дисковый номеронабиратель и семисегментник
Прикольно получилось)) А ты молодец. Не все тут могут похвастаться законченным устройством))
Кстати.. можно добавить ещё кучу функций.. так сказать на будущее..))
Кстати.. можно добавить ещё кучу функций.. так сказать на будущее..))
-
Hiperboloyd
- Первый раз сказал Мяу!
- Сообщения: 39
- Зарегистрирован: Пт авг 08, 2008 23:41:37
- Откуда: Penza
- Контактная информация:
Re: Дисковый номеронабиратель и семисегментник
[uquote="roman.com",url="/forum/viewtopic.php?p=3254210#p3254210"]Прикольно получилось)) А ты молодец. Не все тут могут похвастаться законченным устройством))
Кстати.. можно добавить ещё кучу функций.. так сказать на будущее..))[/uquote]
Спасибо) я думал про кучу функций, но признаться домик мне поднадоел) как дочь подрастет подключу электрозамок и думаю на этом покончить) для меня это был превосходный опыт работы с деревом и МК. ребятам за помощь я очень благодарен!
Кстати.. можно добавить ещё кучу функций.. так сказать на будущее..))[/uquote]
Спасибо) я думал про кучу функций, но признаться домик мне поднадоел) как дочь подрастет подключу электрозамок и думаю на этом покончить) для меня это был превосходный опыт работы с деревом и МК. ребятам за помощь я очень благодарен!
- Smith2011
- Прорезались зубы
- Сообщения: 210
- Зарегистрирован: Вс дек 26, 2010 23:08:53
- Откуда: Москва, Зеленоград
- Контактная информация:
Re: Дисковый номеронабиратель и семисегментник
Hiperboloyd - отлично! Я тоже делал дочке бизиборд, но он без электронных приблуд, все в кучу не стал мешать.
Хочу сделать второй бизик и как раз электронный.. Скажу спасибо за схему и програмку с подробностями
Хочу сделать второй бизик и как раз электронный.. Скажу спасибо за схему и програмку с подробностями
-
Hiperboloyd
- Первый раз сказал Мяу!
- Сообщения: 39
- Зарегистрирован: Пт авг 08, 2008 23:41:37
- Откуда: Penza
- Контактная информация:
Re: Дисковый номеронабиратель и семисегментник
[uquote="Smith2011",url="/forum/viewtopic.php?p=3264193#p3264193"]Hiperboloyd - отлично! Я тоже делал дочке бизиборд, но он без электронных приблуд, все в кучу не стал мешать.
Хочу сделать второй бизик и как раз электронный.. Скажу спасибо за схему и програмку с подробностями
[/uquote]
Вероятнее всего уже поздно! но для будущих поколений , так сказать, выложу.
Прошу прощения что так прервал всё. на работе ноут озяб. что-то восстановилось. что-то с флешек собрал, что-то дома было. в итоге не смог найти окончательный вариант и забыл/забил.
но вот что-то копался и кажется это оно. В протеусе все работает, кроме таймера автоматического выключения, но так и было, в железе всё норм.
Повторяю: Вероятно это последний вариант, но возможно и нет. Это означает что могут быть ошибки. в Протеусе вроде работает.
#include <avr/interrupt.h>
#define F_CPU 1000000UL
#include <util/delay.h>
volatile unsigned char off=0; //для выключения всего
unsigned char flag=0; //флаг нажатой кнопки светофора
unsigned char cifra=0; //для семисегментника
unsigned char cifrakn=0; //для токо чтоб кн.тел. работала не с нуля
unsigned char svet=0; //для светофора
unsigned char vykl=0; //для выключателя
unsigned char rozetka=0; //для розетки
unsigned char sv=0;
unsigned char mag=0;
unsigned char SEGMENTE[] =
{// gfedcba
0b11111111,
0b11000000, // 0
0b11111001, // 1
0b10100100, // 2
0b10110000, // 3
0b10011001, // 4
0b10010010, // 5
0b10000010, // 6
0b11111000, // 7
0b10000000, // 8
0b10010000, // 9
};
ISR( TIMER1_OVF_vect )
{
if ( off < 29)
{
off++;
if (8 == off)
{
PORTD &= ~(1<<6); //Выключить розетку (Вентилятор)
}
if (15 == off)
{
PORTA |= 1<<7; //погасить семисегментник
PORTB = 0b11111111; //погасить светофор
}
if (28 == off)
{
PORTD |= 1<<0;//выключить Свет
}
}
}
ISR (INT2_vect)
{
_delay_ms(50);
off=0;
cifra = TCNT0; //переменной присвоить значение счетчика
if (cifra>0 && cifra<11) // если цифра >0 и <10
{
PORTA = SEGMENTE[cifra]; //вывести на семисегментник цифру
cifrakn=cifra;
cifra=0; //обнулить переменную
}
else
{
if (11 == cifra) //если переменная равна 10
{
cifra=1; //обнулить переменную
PORTA = SEGMENTE[cifra]; //вывести на семисегментник цифру 0
}
}
PORTA &= ~(1<<7);// зажечь семисегментник
//cifra=0; //обнулить переменную ВРОДЕ БЕЗ ЭТОГО РАБОТАЕТ
TCNT0 = 0;
}
int main(void)
{
DDRA = 0b11111111; // порты на выход
PORTA = 0b11111111; // подтягиваем к 1
DDRB = 0b11111010;
PORTB = 0b11111111; //подтягивем к 1
DDRC = 0b00000000;
PORTC = 0b11111111; // подтягиваем к 1
DDRD = 0b11100001;
PORTD = 0b10011111;
GICR |= (1<<INT2); //разрешить внешние прерывания инт2
MCUCSR |=(1<<ISC2);//по спадающему фронту INT2
TCNT0 = 0; //установка таймера в ноль
TCCR0 |=(1<<CS02)|(1<<CS01)|(1<<CS00); //таймер от внеш. источника по переднему фронту для номеронабирателя
TIMSK |=(1<<TOIE1); //таймер по переполнению
TCCR1B |=(1<<CS11)|(1<<CS10); //делитель 64
sei(); //разрешить общее прерывание
while (1)
{
//-------------------------------ПЕРВЫЕ ТРИ КНОПКИ--------------------------------------------------
if (!(PINC & (1<<0))) // если PC0 = не 1 тк "!" перед условием
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<0)))
{
PORTB &= ~(1<<1); // Установить на PB1 = 0
PORTB |= 1<<3; // Установить на PB3 = 1
}
while (!(PINC & (1<<0)))
{
}
}
//----------------------------------------
if (!(PINC & (1<<2)))
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<2)))
{
PORTB |= 1<<1;
PORTB &= ~(1<<3);
}
while (!(PINC & (1<<2)))
{
}
}
//------------------------------------------
if (!(PINC & (1<<1)))
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<1)))
{
PORTB &= ~(1<<3);
PORTB &= ~(1<<1);
}
while (!(PINC & (1<<1)))
{
}
}
//-------------------------------ВТОРЫЕ ТРИ КНОПКИ--------------------------------------------------
if (!(PINC & (1<<3))) // если PC0 = не 1 тк "!" перед условием
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<3)))
{
PORTB &= ~(1<<4); // Установить на PB1 = 0
PORTB |= 1<<5; // Установить на PB3 = 1
}
while (!(PINC & (1<<3)))
{
}
}
//---------------------------------------
if (!(PINC & (1<<5)))
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<5)))
{
PORTB |= 1<<4;
PORTB &= ~(1<<5);
}
while (!(PINC & (1<<5)))
{
}
}
//----------------------------------------
if (!(PINC & (1<<4)))
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<4)))
{
PORTB &= ~(1<<4);
PORTB &= ~(1<<5);
}
while (!(PINC & (1<<4)))
{
}
}
//-------------------------------ТРЕТЬИ ТРИ КНОПКИ--------------------------------------------------
if (!(PINC & (1<<6))) // если PC6 = не 1 тк "!" перед условием
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<6)))
{
PORTB &= ~(1<<6); // Установить на PB6 = 0
PORTB |= 1<<7; // Установить на PB7 = 1
}
while ((!PINC & (1<<6)))
{
}
}
//---------------------------------------------------
if (!(PIND & (1<<7)))
{
_delay_ms(50);
off=0;
if (!(PIND & (1<<7)))
{
PORTB |= 1<<6;
PORTB &= ~(1<<7);
}
while (!(PIND & (1<<7)))
{
}
}
//-----------------------------------------------------
if (!(PINC & (1<<7)))
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<7)))
{
PORTB &= ~(1<<6);
PORTB &= ~(1<<7);
}
while (!(PINC & (1<<7)))
{
}
}
//----------------ЭЛ. ЗАМОК-----------------------------
if ((PINB & (1<<3)) && (!(PINB & (1<<1))) && (!(PINB & (1<<4))) && (!(PINB & (1<<5))) && (!(PINB & (1<<7))) && (PINB & (1<<6)))
{
PORTD |= 1<<5;
}
else
{
PORTD &= ~(1<<5);
}
//--------------------------------------
if (!(PIND & (1<<1)))
{
if (0==rozetka)
{
off=0;
_delay_ms(50);
rozetka=1;
PORTD |= 1<<6;
}
}
else
{
PORTD &= ~(1<<6);
rozetka=0;
}
//-----------------------ВЫКЛЮЧАТЕЛЬ СВЕТА-------------
if (!(PIND & (1<<2)))
{
if (0==vykl)
{
off=0;
_delay_ms(50);
vykl=1;
PORTD &= ~(1<<0);
}
}
else
{
PORTD |= 1<<0;
vykl=0;
}
//-----------------------КНОПКА СВЕТОФОРА-------------------
if (!(PIND & (1<<4)))
{
off=0;
_delay_ms(50);
if (!(PIND & (1<<4)))
{
sv++; //переменной +1
switch (sv)
{
case 1: PORTB &= ~(1<<1);PORTB &= ~(1<<4);PORTB &= ~(1<<6);PORTB |= 1<<3;PORTB |= 1<<5;PORTB |= 1<<7; break;
case 2: PORTB &= ~(1<<1);PORTB &= ~(1<<4);PORTB &= ~(1<<6);PORTB &= ~(1<<3);PORTB &= ~(1<<5);PORTB &= ~(1<<7); break;
case 3: PORTB &= ~(1<<3);PORTB &= ~(1<<5);PORTB &= ~(1<<7);PORTB |= 1<<1;PORTB |= 1<<4;PORTB |= 1<<6;sv=0;break;
default: ;
}
}
while (!(PIND & (1<<4)))
{
}
}
//----------------------КНОПКА ТЕЛЕФОНА------------------------------
if (!(PIND & (1<<3)))
{
off=0;
_delay_ms(50);
if (!(PIND & (1<<3)))
{
cifrakn++;
if (cifrakn>0 && cifrakn<11) // если цифра >0 и <10
{
PORTA = SEGMENTE[cifrakn]; //вывести на семисегментник цифру
PORTA &= ~(1<<7);// зажечь семисегментник
}
else
{
if (11==cifrakn) //если переменная равна 10
{
cifrakn=1; //обнулить переменную
PORTA = SEGMENTE[cifrakn]; //вывести на семисегментник цифру 0
PORTA &= ~(1<<7);// зажечь семисегментник
cifrakn=1;
}
}
}
while (!(PIND & (1<<3)))
{
}
}
}
}
Схема с небольшими пояснениями
Хочу сделать второй бизик и как раз электронный.. Скажу спасибо за схему и програмку с подробностями
Вероятнее всего уже поздно! но для будущих поколений , так сказать, выложу.
Прошу прощения что так прервал всё. на работе ноут озяб. что-то восстановилось. что-то с флешек собрал, что-то дома было. в итоге не смог найти окончательный вариант и забыл/забил.
но вот что-то копался и кажется это оно. В протеусе все работает, кроме таймера автоматического выключения, но так и было, в железе всё норм.
Повторяю: Вероятно это последний вариант, но возможно и нет. Это означает что могут быть ошибки. в Протеусе вроде работает.
Спойлер
#include <avr/io.h>#include <avr/interrupt.h>
#define F_CPU 1000000UL
#include <util/delay.h>
volatile unsigned char off=0; //для выключения всего
unsigned char flag=0; //флаг нажатой кнопки светофора
unsigned char cifra=0; //для семисегментника
unsigned char cifrakn=0; //для токо чтоб кн.тел. работала не с нуля
unsigned char svet=0; //для светофора
unsigned char vykl=0; //для выключателя
unsigned char rozetka=0; //для розетки
unsigned char sv=0;
unsigned char mag=0;
unsigned char SEGMENTE[] =
{// gfedcba
0b11111111,
0b11000000, // 0
0b11111001, // 1
0b10100100, // 2
0b10110000, // 3
0b10011001, // 4
0b10010010, // 5
0b10000010, // 6
0b11111000, // 7
0b10000000, // 8
0b10010000, // 9
};
ISR( TIMER1_OVF_vect )
{
if ( off < 29)
{
off++;
if (8 == off)
{
PORTD &= ~(1<<6); //Выключить розетку (Вентилятор)
}
if (15 == off)
{
PORTA |= 1<<7; //погасить семисегментник
PORTB = 0b11111111; //погасить светофор
}
if (28 == off)
{
PORTD |= 1<<0;//выключить Свет
}
}
}
ISR (INT2_vect)
{
_delay_ms(50);
off=0;
cifra = TCNT0; //переменной присвоить значение счетчика
if (cifra>0 && cifra<11) // если цифра >0 и <10
{
PORTA = SEGMENTE[cifra]; //вывести на семисегментник цифру
cifrakn=cifra;
cifra=0; //обнулить переменную
}
else
{
if (11 == cifra) //если переменная равна 10
{
cifra=1; //обнулить переменную
PORTA = SEGMENTE[cifra]; //вывести на семисегментник цифру 0
}
}
PORTA &= ~(1<<7);// зажечь семисегментник
//cifra=0; //обнулить переменную ВРОДЕ БЕЗ ЭТОГО РАБОТАЕТ
TCNT0 = 0;
}
int main(void)
{
DDRA = 0b11111111; // порты на выход
PORTA = 0b11111111; // подтягиваем к 1
DDRB = 0b11111010;
PORTB = 0b11111111; //подтягивем к 1
DDRC = 0b00000000;
PORTC = 0b11111111; // подтягиваем к 1
DDRD = 0b11100001;
PORTD = 0b10011111;
GICR |= (1<<INT2); //разрешить внешние прерывания инт2
MCUCSR |=(1<<ISC2);//по спадающему фронту INT2
TCNT0 = 0; //установка таймера в ноль
TCCR0 |=(1<<CS02)|(1<<CS01)|(1<<CS00); //таймер от внеш. источника по переднему фронту для номеронабирателя
TIMSK |=(1<<TOIE1); //таймер по переполнению
TCCR1B |=(1<<CS11)|(1<<CS10); //делитель 64
sei(); //разрешить общее прерывание
while (1)
{
//-------------------------------ПЕРВЫЕ ТРИ КНОПКИ--------------------------------------------------
if (!(PINC & (1<<0))) // если PC0 = не 1 тк "!" перед условием
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<0)))
{
PORTB &= ~(1<<1); // Установить на PB1 = 0
PORTB |= 1<<3; // Установить на PB3 = 1
}
while (!(PINC & (1<<0)))
{
}
}
//----------------------------------------
if (!(PINC & (1<<2)))
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<2)))
{
PORTB |= 1<<1;
PORTB &= ~(1<<3);
}
while (!(PINC & (1<<2)))
{
}
}
//------------------------------------------
if (!(PINC & (1<<1)))
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<1)))
{
PORTB &= ~(1<<3);
PORTB &= ~(1<<1);
}
while (!(PINC & (1<<1)))
{
}
}
//-------------------------------ВТОРЫЕ ТРИ КНОПКИ--------------------------------------------------
if (!(PINC & (1<<3))) // если PC0 = не 1 тк "!" перед условием
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<3)))
{
PORTB &= ~(1<<4); // Установить на PB1 = 0
PORTB |= 1<<5; // Установить на PB3 = 1
}
while (!(PINC & (1<<3)))
{
}
}
//---------------------------------------
if (!(PINC & (1<<5)))
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<5)))
{
PORTB |= 1<<4;
PORTB &= ~(1<<5);
}
while (!(PINC & (1<<5)))
{
}
}
//----------------------------------------
if (!(PINC & (1<<4)))
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<4)))
{
PORTB &= ~(1<<4);
PORTB &= ~(1<<5);
}
while (!(PINC & (1<<4)))
{
}
}
//-------------------------------ТРЕТЬИ ТРИ КНОПКИ--------------------------------------------------
if (!(PINC & (1<<6))) // если PC6 = не 1 тк "!" перед условием
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<6)))
{
PORTB &= ~(1<<6); // Установить на PB6 = 0
PORTB |= 1<<7; // Установить на PB7 = 1
}
while ((!PINC & (1<<6)))
{
}
}
//---------------------------------------------------
if (!(PIND & (1<<7)))
{
_delay_ms(50);
off=0;
if (!(PIND & (1<<7)))
{
PORTB |= 1<<6;
PORTB &= ~(1<<7);
}
while (!(PIND & (1<<7)))
{
}
}
//-----------------------------------------------------
if (!(PINC & (1<<7)))
{
_delay_ms(50);
off=0;
if (!(PINC & (1<<7)))
{
PORTB &= ~(1<<6);
PORTB &= ~(1<<7);
}
while (!(PINC & (1<<7)))
{
}
}
//----------------ЭЛ. ЗАМОК-----------------------------
if ((PINB & (1<<3)) && (!(PINB & (1<<1))) && (!(PINB & (1<<4))) && (!(PINB & (1<<5))) && (!(PINB & (1<<7))) && (PINB & (1<<6)))
{
PORTD |= 1<<5;
}
else
{
PORTD &= ~(1<<5);
}
//--------------------------------------
if (!(PIND & (1<<1)))
{
if (0==rozetka)
{
off=0;
_delay_ms(50);
rozetka=1;
PORTD |= 1<<6;
}
}
else
{
PORTD &= ~(1<<6);
rozetka=0;
}
//-----------------------ВЫКЛЮЧАТЕЛЬ СВЕТА-------------
if (!(PIND & (1<<2)))
{
if (0==vykl)
{
off=0;
_delay_ms(50);
vykl=1;
PORTD &= ~(1<<0);
}
}
else
{
PORTD |= 1<<0;
vykl=0;
}
//-----------------------КНОПКА СВЕТОФОРА-------------------
if (!(PIND & (1<<4)))
{
off=0;
_delay_ms(50);
if (!(PIND & (1<<4)))
{
sv++; //переменной +1
switch (sv)
{
case 1: PORTB &= ~(1<<1);PORTB &= ~(1<<4);PORTB &= ~(1<<6);PORTB |= 1<<3;PORTB |= 1<<5;PORTB |= 1<<7; break;
case 2: PORTB &= ~(1<<1);PORTB &= ~(1<<4);PORTB &= ~(1<<6);PORTB &= ~(1<<3);PORTB &= ~(1<<5);PORTB &= ~(1<<7); break;
case 3: PORTB &= ~(1<<3);PORTB &= ~(1<<5);PORTB &= ~(1<<7);PORTB |= 1<<1;PORTB |= 1<<4;PORTB |= 1<<6;sv=0;break;
default: ;
}
}
while (!(PIND & (1<<4)))
{
}
}
//----------------------КНОПКА ТЕЛЕФОНА------------------------------
if (!(PIND & (1<<3)))
{
off=0;
_delay_ms(50);
if (!(PIND & (1<<3)))
{
cifrakn++;
if (cifrakn>0 && cifrakn<11) // если цифра >0 и <10
{
PORTA = SEGMENTE[cifrakn]; //вывести на семисегментник цифру
PORTA &= ~(1<<7);// зажечь семисегментник
}
else
{
if (11==cifrakn) //если переменная равна 10
{
cifrakn=1; //обнулить переменную
PORTA = SEGMENTE[cifrakn]; //вывести на семисегментник цифру 0
PORTA &= ~(1<<7);// зажечь семисегментник
cifrakn=1;
}
}
}
while (!(PIND & (1<<3)))
{
}
}
}
}


