Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.75/20: Рейтинг темы: голосов - 20, средняя оценка - 4.75
gubilon
1 / 1 / 0
Регистрация: 18.04.2015
Сообщений: 25
1

Последовательное зажигание светодиодов по кнопке (ATtiny2313, Cи)

18.04.2015, 16:23. Просмотров 4067. Ответов 58
Метки нет (Все метки)

Здравствуйте.Есть такая проблема.Написал код для подпрограммы последовательного зажигания светодиодов.Вот пример:
C
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
/*****************************************************
Version : Кнопки и светодиоды                                                 
Chip type           : ATmega16
Clock frequency     : 4,000000 MHz
*****************************************************/              
#include <mega16.h>                                      // библиотека ввода\вывода микроконтроллера
#include <delay.h>                                        // библиотека задержки
void i_miganie()
{
                                                                         PORTС.0=1;
                     delay_ms(600);
                                                                     PORTС.1=1;
                                     delay_ms(600);
                                     PORTС.2=1;
                                     delay_ms(600);
                                     PORTС.3=1;
                                     delay_ms(600);
                                     PORTС.4=1;
                                     delay_ms(600);
                                     PORTС.5=1;
                                     delay_ms(600);
                                     PORTС.6=1;
                                     delay_ms(600);
                                     PORTС.7=1;
                                     delay_ms(600);
                                     PORTС.7=0;
                                     delay_ms(600);
                                     PORTС.6=0;
                                     delay_ms(600);
                                     PORTС.5=0;
                                     delay_ms(600);
                                     PORTС.4=0;
                                     delay_ms(600);
                                     PORTС.3=0;
                                     delay_ms(600);
                                     PORTС.2=0;
                                     delay_ms(600);
                                     PORTС.1=0;
                                     delay_ms(600);
                                     PORTС.0=0;
                                     delay_ms(600);                   
}
Получился очень много кода.Как его можно сократить, а то общая программа получается очень большая.Задание такое:Обеспечить при нажатой кнопке SW1 поочередное засвечивание светодиодов LED0… LED7 на 1с в последовательности LED0, LED1,.., LED7, LED0 и т. д. При нажатой кнопке SW4 зажигание светодиодов должно происходить в обратном порядке. Кнопки подключены к порту B, а светодиоды - к порту C.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
18.04.2015, 16:23
Ответы с готовыми решениями:

Последовательное зажигание светодиодов по кнопке (ATmega8515, ASM)
Добрый день. Требуется помощь для написания программы на ассемблере под AVR ATmega8515...

Последовательное зажигание светодиодов
Собственно задание: при включении МК светодиоды не горят, через 2 с загораются 1-й, затем...

Зажигание светодиодов AT90S2313
Доброго времени суток. На AVR только начинающий Вот написал программу для циклического зажигания...

Зажигание полос светодиодов на мк AT90S8515
Здравствуйте! Задача такова:написать и отладить программу на ассемблер обрабатывающую прерывание...

Последовательное гашение светодиодов на окружности с интервалом
Помогите пожалуйста! Разработать программу, осуществляющую последовательное гашение светодиодов на...

58
pyzhman
1151 / 509 / 74
Регистрация: 15.05.2012
Сообщений: 2,900
18.04.2015, 20:32 2
Где main? И для чего такая табуляция?
По вопросу - там в мк памяти до фига и больше, не пропадать же ей зазря.
По заданию - бегущий огонёк, а у вас червячок. Причем односторонний.
0
Voland_
1665 / 1053 / 99
Регистрация: 04.01.2010
Сообщений: 3,567
18.04.2015, 20:35 3
Цитата Сообщение от gubilon Посмотреть сообщение
общая программа получается очень большая.
42 строчки - большая программа?
...но. если по делу, то надо в цикле выставлять только один бит в переменной. И записывать эту переменную в порт, к которому подключены светодиоды.
Скажем, один бит в переменной можно вычислить выражением:
C
1
port_out = 1 << i;
где i - циклически изменяемый индекс "зажигаемого" светодиода, а port_out надо записывать сразу в порт C.
0
gubilon
1 / 1 / 0
Регистрация: 18.04.2015
Сообщений: 25
18.04.2015, 22:01  [ТС] 4
Цитата Сообщение от Voland_ Посмотреть сообщение
42 строчки - большая программа?
...но. если по делу, то надо в цикле выставлять только один бит в переменной. И записывать эту переменную в порт, к которому подключены светодиоды.
Скажем, один бит в переменной можно вычислить выражением:
C
1
port_out = 1 << i;
где i - циклически изменяемый индекс "зажигаемого" светодиода, а port_out надо записывать сразу в порт C.
Общая программа получается такая.
C
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
/*****************************************************
Version : Кнопки и светодиоды                         
Company : [url]http://c2.at.ua[/url]                           
Chip type           : ATmega16
Clock frequency     : 4,000000 MHz
*****************************************************/              
#include <mega16.h>                                      // библиотека ввода\вывода микроконтроллера
#include <delay.h>                                        // библиотека задержки
unsigned char kR, temp;                           // обьявляем переменные
void i_miganie()
{
                                     PORTС.0=1;
                                     delay_ms(600);
                                     PORTС.1=1;
                                     delay_ms(600);
                                     PORTС.2=1;
                                     delay_ms(600);
                                     PORTС.3=1;
                                     delay_ms(600);
                                     PORTС.4=1;
                                     delay_ms(600);
                                     PORTС.5=1;
                                     delay_ms(600);
                                     PORTС.6=1;
                                     delay_ms(600);
                                     PORTС.7=1;
                                     delay_ms(600);
                                     PORTС.7=0;
                                     delay_ms(600);
                                     PORTС.6=0;
                                     delay_ms(600);
                                     PORTС.5=0;
                                     delay_ms(600);
                                     PORTС.4=0;
                                     delay_ms(600);
                                     PORTС.3=0;
                                     delay_ms(600);
                                     PORTС.2=0;
                                     delay_ms(600);
                                     PORTС.1=0;
                                     delay_ms(600);
                                     PORTС.0=0;
                                     delay_ms(600);                   
}
void i_obmiganie()
{
                                     PORTС.7=1;
                                     delay_ms(600);
                                     PORTС.6=1;
                                     delay_ms(600);
                                     PORTС.5=1;
                                     delay_ms(600);
                                     PORTС.4=1;
                                     delay_ms(600);
                                     PORTС.3=1;
                                     delay_ms(600);
                                     PORTС.2=1;
                                     delay_ms(600);
                                     PORTС.1=1;
                                     delay_ms(600);
                                     PORTС.0=1;
                                     delay_ms(600);
                                     PORTС.0=0;
                                     delay_ms(600);
                                     PORTС.1=0;
                                     delay_ms(600);
                                     PORTС.2=0;
                                     delay_ms(600);
                                     PORTС.3=0;
                                     delay_ms(600);
                                     PORTС.4=0;
                                     delay_ms(600);
                                     PORTС.5=0;
                                     delay_ms(600);
                                     PORTС.6=0;
                                     delay_ms(600);
                                     PORTС.7=0;
                                     delay_ms(600);  
}
void i_chmiganie()
{
                                     PORTС.7=1;
                                     delay_ms(600);
                                     PORTС.5=1;
                                     delay_ms(600);
                                     PORTС.3=1;
                                     delay_ms(600);
                                     PORTС.1=1;
                                     delay_ms(600);
                                     PORTС.1=0;
                                     delay_ms(600);
                                     PORTС.3=0;
                                     delay_ms(600);
                                     PORTС.5=0;
                                     delay_ms(600);
                                     PORTС.7=0;
                                     delay_ms(600);  
}
void i_nechmiganie()
{
                                     PORTС.6=1;
                                     delay_ms(600);
                                     PORTС.4=1;
                                     delay_ms(600);
                                     PORTС.2=1;
                                     delay_ms(600);
                                     PORTС.0=1;
                                     delay_ms(600);
                                     PORTС.0=0;
                                     delay_ms(600);
                                     PORTС.2=0;
                                     delay_ms(600);
                                     PORTС.4=0;
                                     delay_ms(600);
                                     PORTС.6=0;
                                     delay_ms(600);  
}
void i_sbros()
{
                                     PORTС.0=0;
                                     PORTС.1=0;
                                     PORTС.2=0;
                                     PORTС.3=0;
                                     PORTС.4=0;
                                     PORTС.5=0;
                                     PORTС.6=0;
                                     PORTС.7=0;
                                                  
}
void i_check()
{
  if(PINB.0==0)
  {
  i_miganie();
  }  
  if(PINB.1==0)
  {
  i_obmiganie();
  }
  if(PINB.2==0)
  {
  i_chmiganie();
  }  
  if(PINB.3==0)
  {
  i_nechmiganie();
  }
  if(PINB.4==0)
  {
  i_sbros();
  }  
}
void main(void)                                             // Declare your global variables here
{       
PORTB=0b01111111;                                   // Port B initialization
 DDRB=0b00000000;                                 
PORTС=0b00000000;                                   // Port С initialization
 DDRС=0b111111111;
 
    while(1)     // бесконечный цикл                           
            {
                                                          
                             if (PINB.0==0)                    // ==== №1 кнопка
                               { 
                                i_miganie();
                                  } 
                              if (PINB.1==0)                   // ==== №2 кнопка
                               { 
                               i_obmiganie();                      
                                 }  
 
                               if (PINB.3==0)                 //  ====    №3  кнопка
                               { 
                               i_chmiganie();                   
                                  } 
                               if (PINB.4==0)                    // ==== №4 кнопка
                               { 
                                i_nechmiganie();
                                  } 
                               if (PINB.5==0)                    // ==== №5 кнопка
                               { 
                                i_sbros();
                                  } 
                   
               
            };                                                         // закрываем бесконечный цикл
 
  }
Кроме кнопок отвечающих за порядок мигания,там есть кнопки отвечающие за сброс и какие диоды будут мигать.При этом еще нужно организовать проверку кнопок,чтоб при нажатии сразу сбрасывалось.Вообщем до конца не понял как сделать.Можно,если не сложно еще раз объяснить,если возможно с примером,а то не понял задумку с портами
0
18.04.2015, 22:01
MS24
11 / 11 / 2
Регистрация: 22.02.2012
Сообщений: 115
Завершенные тесты: 1
21.04.2015, 08:59 5
Цитата Сообщение от gubilon Посмотреть сообщение
Общая программа получается такая.
Эх... когда - то и я писал такие программы =))
C
1
2
3
4
5
6
7
8
9
10
11
12
void i_miganie()
{
   int i;
   char port_out = 0;
 
   for (i =0; i<8;++i)
  {
      port_out = 1 << i;
      PORTC = port_out;
      delay_ms(600);
  }
}
Добавлено через 2 минуты
Ну а вообще тратить целый порт нецелесообразно, обычно для таких целей применяют сдвиговые регистры( hc595 - самый популярный ) или LED драйверы.
0
gubilon
1 / 1 / 0
Регистрация: 18.04.2015
Сообщений: 25
21.04.2015, 09:16  [ТС] 6
Да,код намного меньше.А как можно организовать проверку кнопок так,чтоб при нажатии другой, он сразу выходил или хотя бы по завершению программы.Потому что сталкивался с проблемой,что нужно держать кнопку и ждать,когда на неё попадет.
0
MS24
11 / 11 / 2
Регистрация: 22.02.2012
Сообщений: 115
Завершенные тесты: 1
21.04.2015, 10:57 7
Цитата Сообщение от gubilon Посмотреть сообщение
А как можно организовать проверку кнопок так,чтоб при нажатии другой, он сразу выходил
Ну тут я Вам могу предложить 2 варианта:
1) Использовать внешние прерывания.
2) Использовать прерывание по таймеру. ( я бы предпочел этот )
Завести глобальную переменную, и в прерывании инициализировать ее значением нажатой кнопки.
А уже непосредственно в функции добавить проверку:
Если нажата кнопка не соответсвующая данной функции - выйти.
0
gubilon
1 / 1 / 0
Регистрация: 18.04.2015
Сообщений: 25
21.04.2015, 13:33  [ТС] 8
Только сейчас понял.Неправильно задал вопрос.Нужно чтоб диоды загорались например сначала VD1,потом VD1 и VD2 и так далее.И с конечного,восьмого диода начали тухнуть,поэтому так много строк.У тебя же один по идее будет гореть только
0
Витальич
1274 / 1184 / 174
Регистрация: 02.12.2013
Сообщений: 4,886
21.04.2015, 15:08 9
Да простит меня MS24
C
1
2
3
4
5
6
7
8
9
10
11
12
13
void i_miganie()
{
 unsigned char arrLed[]= {b00000001,b00000011,b00000111,итд}
   int i;
   char port_out = 0;
 
   for (i =0; i<8;++i)
  {
      port_out = arrLed[i] 
      PORTC = port_out;
      delay_ms(600);
  }
}
В окурат как Вы желаете.
Массив arrLed сами только допишите.
0
gubilon
1 / 1 / 0
Регистрация: 18.04.2015
Сообщений: 25
21.04.2015, 15:13  [ТС] 10
Спасибо большое)Буду осуществлять)
0
MS24
11 / 11 / 2
Регистрация: 22.02.2012
Сообщений: 115
Завершенные тесты: 1
21.04.2015, 15:38 11
Цитата Сообщение от Витальич Посмотреть сообщение
Да простит меня MS24
А за что прощать?
Кстати таким вариантом ты можешь в массив любое значение задать, и зажигать любые светодиоды какие захочешь с каждой итерацией цикла.
Например можешь сделать несколько массивов ( убывающий и возрастающий ) и передавать просто указатель функции на эти массивы.
0
Витальич
21.04.2015, 15:43
  #12

Не по теме:

Цитата Сообщение от MS24 Посмотреть сообщение
А за что прощать?
За частичный плагиат, влом было писать, а тут Ваш код прямо и просился под контрл Цэ, контрл Вэ

0
MS24
11 / 11 / 2
Регистрация: 22.02.2012
Сообщений: 115
Завершенные тесты: 1
21.04.2015, 15:44 13
Цитата Сообщение от Витальич Посмотреть сообщение
За частичный плагиат, влом было писать, а тут Ваш код прямо и просился под контрл Цэ, контрл Вэ
А! Я уж подумал мож накосячил че =)
0
gubilon
1 / 1 / 0
Регистрация: 18.04.2015
Сообщений: 25
21.04.2015, 15:51  [ТС] 14
Цитата Сообщение от MS24 Посмотреть сообщение
А за что прощать?
Кстати таким вариантом ты можешь в массив любое значение задать, и зажигать любые светодиоды какие захочешь с каждой итерацией цикла.
Например можешь сделать несколько массивов ( убывающий и возрастающий ) и передавать просто указатель функции на эти массивы.
То есть массивы задать в начале?
0
MS24
11 / 11 / 2
Регистрация: 22.02.2012
Сообщений: 115
Завершенные тесты: 1
21.04.2015, 15:54 15
Цитата Сообщение от gubilon Посмотреть сообщение
То есть массивы задать в начале?
В начале - это понятие не явно говорящее о местоположении массива. Я имел ввиду задать массивы глобально ( вроде как в с глобальные переменные считаются нормальным явлением ). Главное что бы они были доступны твоей функции
0
Витальич
1274 / 1184 / 174
Регистрация: 02.12.2013
Сообщений: 4,886
21.04.2015, 15:59 16
Цитата Сообщение от gubilon Посмотреть сообщение
То есть массивы задать в начале?
Я бы рекомендовал ознакомится с разделом об области видимости и временем жизни переменных в любой книге по СИ.
В Вашем случаи можно создавать и в начале программы до main и внутри функции i_miganie, пока для Вас будет не принципиально, работать будет по любому.
0
gubilon
1 / 1 / 0
Регистрация: 18.04.2015
Сообщений: 25
21.04.2015, 16:59  [ТС] 17
Это написал всё.Не понимаю,как сделать прерывание по таймеру.Я как понял,что за обычное прерывание отвечает функция break,как принудительный выход из цикла.У меня задача в том,чтоб они горели,пока не нажму другую кнопку.Но как я понял,чтоб такое было то нужно в цикле прерывание поставить на выход в функцию проверки кнопок,а там уже в зависимости от нажатой кнопки прерывание к нужной функции.А как делается такое с таймером?И получиться ли функцией break выйти полностью из цикла?
0
Витальич
1274 / 1184 / 174
Регистрация: 02.12.2013
Сообщений: 4,886
21.04.2015, 17:37 18
C
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
/* массив вариантов вкл. светотодиодов на порте С */
unsigned char arrLed[]= {b00000001,b00000011,b00000111,итд}
 
/* Установка параметров таймера */
void Timer0Init();
 
/* Опрос кнопок */
unsigned char KeyGet(); 
 
/* Прерывание таймера */
ISR( TIMER0_OVF_vect )
{
 static unsigned char count = 0;
 PORTC = arrLed[count];
 count++;
 if(count >= 8)
 {
   count = 0;
 }
}
 
void main(0)
{
 Timer0Init();
 StartTimer();
 
 while(1)
 {
    if(KeyGet() == 1)
    {
      // действия по нажатой кнопки
    }
 }
}
Настраиваем прерывание таймера на частоту изменения вкл/выкл светодиодов. В функции прерывания таймера ISR( TIMER0_OVF_vect ) происходит изменение состояние (вкл/выкл) светодиодов.
Основная программа постоянно опрашивает кнопки, когда обнаружит нажатую кнопку изменяет порядок вкл/выкл светодиодов. Для этого достаточно переписать данные в arrLed[]
1
gubilon
1 / 1 / 0
Регистрация: 18.04.2015
Сообщений: 25
21.04.2015, 18:57  [ТС] 19
Получается вверху мы задаём нужное нам количество массивов мигания светодиодов?
Цитата Сообщение от Витальич Посмотреть сообщение
/* Опрос кнопок */ unsigned char KeyGet();
, а что тут прописывается?
0
Витальич
1274 / 1184 / 174
Регистрация: 02.12.2013
Сообщений: 4,886
21.04.2015, 19:58 20
Цитата Сообщение от gubilon Посмотреть сообщение
а что тут прописывается?
Опрос кнопок
Можно почти как у Вас
C
1
2
3
4
5
6
7
unsigned char KeyGet()
{
unsigned char tmp;
if (PINB.0==0){tmp = 01;}
if (PINB.1==0){tmp = 02;}
return tmp;
}
В протеусе и иногда в железе работать будет
Но лучше воспользоватся поиском по форуму и найти темы про опрос кнопок. Менее недели назад я приводил простой пример.
0
21.04.2015, 19:58
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.04.2015, 19:58

Последовательное плавное управление яркостью светодиодов
Нужно написать программку на Atmega48 в CodevisionAVR Используя PORTD 0 1 2 С начало загорается...

Переключение четырех светодиодов (сдвиг) по кнопке
Добрый день. Требуется помощь в написании кода на Assembler. Задание следующее: Переключение...

Последовательное зажигание Пяти светодиодов
Всем привет! Загорелся идеей собрать световой меч, на пяти светодиодах, их суну в пластиковую пвх...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru