| Форум РадиоКот https://radiokot.ru/forum/ |
|
| Изменение кода для счетчика https://radiokot.ru/forum/viewtopic.php?f=57&t=145902 |
Страница 1 из 3 |
| Автор: | mnirti [ Чт июн 08, 2017 08:57:28 ] |
| Заголовок сообщения: | Изменение кода для счетчика |
Здравствуйте. Помогите, пожалуйста. Нужно дополнить код: Код: #include <avr/io.h> #define F_CPU 8000000L #include <avr/io.h> #include <util/delay.h> //unsigned int i;??? //---------- void segchar (unsigned char seg) { switch (seg) { case 1: PORTD = 0b11111001; break; case 2: PORTD = 0b10100100; break; case 3: PORTD = 0b10110000; break; case 4: PORTD = 0b10011001; break; case 5: PORTD = 0b10010010; break; case 6: PORTD = 0b10000010; break; case 7: PORTD = 0b11111000; break; case 8: PORTD = 0b10000000; break; case 9: PORTD = 0b10010000; break; case 0: PORTD = 0b11000000; break; } } //---------- int main(void) { unsigned char i; unsigned butcount=0,butstate=0; DDRD = 0xFF; DDRB = 0x00; PORTD = 0b00000000; PORTB = 0b00000001; // Нулевой порт на вход, подано питание. while(1) { for (i=0;i<10;i++) // Начальное и конечное значения, шаг. { while(butstate==0) { if (!(PINB&0b00000001)){ if (butcount < 5) { butcount++; } else { i=0; butstate=1; } } else { if (butcount > 0) { butcount--; } else { butstate=1; } } } segchar(i); _delay_ms(1500); // Задержка 1,5 секунды butstate = 0; } } } В исходном виде он считает без нажатия кнопки и возвращается к нулю при ее нажатии. А нужно, чтобы отсчет начинался при нажатии кнопки и после остановки продолжался с той цифры, на которой отсчет был прерван, при этом не заменяя цикл for на таймер. Если правильно понимаю строка butstate = 0; после строки со значением задержки отвечает за сбрасывание в ноль при остановке. На что ее заменить, чтобы отсчет продолжался не с нуля? Как начать отсчет по нажатию кнопки при входе в программу (кнопка на нулевой ножке, при нажатии получается логический ноль)? В какую часть кода добавить эту новую строку? И нужно ли использовать переменную unsigned int i? |
|
| Автор: | codenamehawk [ Чт июн 08, 2017 09:59:52 ] |
| Заголовок сообщения: | Re: Изменение кода для счетчика |
А кто вам запретил пробовать? |
|
| Автор: | mnirti [ Чт июн 08, 2017 10:46:25 ] |
| Заголовок сообщения: | Re: Изменение кода для счетчика |
Цитата: А кто вам запретил пробовать? Так в том-то и дело, что выполняю упражнение, код во втором случае нужно изменить без привлечения таймера. |
|
| Автор: | Аlex [ Чт июн 08, 2017 11:57:31 ] |
| Заголовок сообщения: | Re: Изменение кода для счетчика |
Программа написана коряво, каким то школьником. Чтобы что-либо в ней переделать, нужно её всю переписать заново. По этому, берёте своё ТЗ и шаг за шагом, потихоньку, реализовываете его. Появятся вопросы - милости просим. PS: mnirti, когда выкладываете код, обрамляйте его соответствующим тегом (пример - первый пост этой темы, я поправил как нужно). Уже было сказано это Вам в другой теме, но Вы, по всей видимости, не любите читать... |
|
| Автор: | mnirti [ Чт июн 08, 2017 12:33:29 ] |
| Заголовок сообщения: | Re: Изменение кода для счетчика |
Аlex, исправлюсь, буду предоставлять код с тегами. Кажется, что код написан все-таки не школьником. Вот адрес самого упражнения: Спойлерhttp://narodstream.ru/avr-urok-9-oformlenie-koda-funkcii/Мне необходимо именно из этого исходного материала с циклом for сделать немного другой счетчик. Т. к. только учусь, огромная просьба помочь. |
|
| Автор: | Аlex [ Чт июн 08, 2017 13:36:15 ] |
| Заголовок сообщения: | Re: Изменение кода для счетчика |
Кнопки так не опрашивают. Даже если в коде и есть 5 опросов подряд со счётчиком - это не избавит от дребезга, т.к. они пролетят как пуля. Нет события по кнопке (нажата, отжата, ...). Если она будет постоянно нажата, будет всегда обнуление переменной "i", что приведёт к зависанию нуля на индикаторе. Кнопка просто тупо обнуляет счёт и больше не делает ничего. Она не останавливает счёт, ни запускает его, ... Так задано алгоритмом этой программы, который находится в тупике, и его немного не изменишь, только всё переписывать, согласно новому алгоритму. Помочь очень хочется, но пока нечем - конкретных вопросов нет. Вопрос, типа "Как мне переделать это, чтобы работало как я хочу ?" не катит. На него ответов много. Могу помочь только советом - начните писать программу заново и по-нормальному. Сделайте, для начала, перебор циферок на индикаторе. Затем добавьте нормальный обработчик кнопки. Когда он будет, у Вас появятся события от неё, в которых Вы уже будете добавлять код, связанный с этими событиями. |
|
| Автор: | mnirti [ Чт июн 08, 2017 14:09:34 ] |
| Заголовок сообщения: | Re: Изменение кода для счетчика |
Обработчик кнопки с избавлением от дребезга контактов такой: Код: if (PINB.0==0){ per=1; delay_ms(200);} while(per==1) { if (PINB.1==0) {per=2; delay_ms(200);} } Или обработка нажатия: Код: private void button1_Click(object sender, System.EventArgs e) { MessageBox.Show("button1 was clicked"); } И если все заново, то можно хотя бы оставить основу: Код: #include <avr/io.h>
#define F_CPU 8000000L #include <avr/io.h> #include <util/delay.h> unsigned int i; int main(void) { unsigned char butcount=0; DDRD = 0xFF; DDRB = 0x00; PORTD = 0b00000000; PORTB = 0b00000001; while (1) { for (i=0; i<10; i+1) //i++ = i+1 { //условие } } |
|
| Автор: | Аlex [ Чт июн 08, 2017 14:19:12 ] |
| Заголовок сообщения: | Re: Изменение кода для счетчика |
Ничего не понял из Вашего поста В обработчике кнопки что-то много всего лишнего. Достаточно : Код: if (PINB.0==0){ Но такой код повесит программу при удержании кнопки. Ну для начала достаточно.delay_ms(10); while(PINB.0==0); delay_ms(10); } Да, и почему PINB.0 ? В предыдущем коде у Вас опрос состояния входа было (PINB&0b00000001). Вы в CVAVR'е чтоли программу пишите ? mnirti писал(а): Или обработка нажатия: Тут вообще кусок из программы под винду mnirti писал(а): И если все заново, то можно хотя бы оставить основу: Это вопрос ? Если да, то - конечно можно |
|
| Автор: | mnirti [ Чт июн 08, 2017 15:05:11 ] |
| Заголовок сообщения: | Re: Изменение кода для счетчика |
Программу пишу в атмель студио, тренируюсь на ATmega8A, там на нулевую лапку подается 1, если кнопку нажимаю, то сразу ноль (синий значок на соединении, проверяю в протеусе). Тогда, наверное, так: Код: if ((PINB&0b00000001)==0)) { delay_ms(10); while(1); delay_ms(10); } В цикл помещаю 1, чтобы был беспрерывным. Подскажите, пожалуйста, какой нужен код, или цикл, или обработчик, который останавливает счет и возобновляет его с того значения, на котором прервали. Как такой оператор называется? Можно ли его в for поместить, или он будет в свитче в качестве default? В таймере библиотека прерываний interrupt, но в for какие-то другие нужны? Получается: сначала кнопка не нажата (логическая единица,красный значок), нажали один раз, начинается отсчет от 0 до 9 по кругу, нажали другой раз - отсчет застывает на той цифре, до которой успел дойти (0 логический), кнопка отпущена - продолжается со следующей цифры (логическая 1). По идее, при нажатии на ножке будет ноль, но нужно то, чтобы первое нажатие кнопки воспринималось программой как запуск отсчета, а не как остановка. Остановка - после второго. Иначе получается, что не успела программа начаться, как уже остановится. А может с помощью break выполнить прерывание или он годится только для перехода на следующую цифру при отсчете? |
|
| Автор: | Аlex [ Чт июн 08, 2017 15:23:20 ] |
| Заголовок сообщения: | Re: Изменение кода для счетчика |
Уууух, не думал, что всё так запущено ... mnirti писал(а): В цикл помещаю 1, чтобы был беспрерывным. Он бесконечный. А это значит, что он просто повесит программу навсегда.mnirti писал(а): который останавливает счет и возобновляет его с того значения, на котором прервали. Как такой оператор называется? Вы и вправду считаете, что есть такой оператор ? Это - целый алгоритм, который нужно реализовывать и встраивать в существующий код. Причём он будет зависеть от существующего алгоритма программы. |
|
| Автор: | mnirti [ Чт июн 08, 2017 15:40:09 ] |
| Заголовок сообщения: | Re: Изменение кода для счетчика |
Цитата: Уууух, не думал, что всё так запущено Не запущено, запускать нечего, еще учиться, и учиться... Если правильно понимаю: Код: while ((PINB&0b00000001)==0)) цикл будет сравнивать с 0, если приходит ноль, значит счет остановится. Цитата: Вы и вправду считаете, что есть такой оператор? Нет, не считаю, просто не знаю как и из каких операторов (или циклов) собрать конструкцию, которая осуществит остановку и возобновление отсчета. Ищу на форумах, в других упражнениях, но нет там такого, что могу утащить и приделать на свое задание. |
|
| Автор: | Аlex [ Чт июн 08, 2017 15:53:05 ] |
| Заголовок сообщения: | Re: Изменение кода для счетчика |
mnirti писал(а): цикл будет сравнивать с 0, если приходит ноль, значит счет остановится. Будут выполняться действия после этого оператора, пока условие в операторе (в скобках) будет равно истине.Не стесняйтесь читать - https://yandex.ru/search/?lr=213&msid=1 ... 1%81%D0%B8 Конкретно в Код: while ((PINB&0b00000001)==0)) код будет выполняться, пока на ноге PB0 будет висеть лог. ноль.
|
|
| Автор: | Ivanoff-iv [ Чт июн 08, 2017 16:18:25 ] |
| Заголовок сообщения: | Re: Изменение кода для счетчика |
сначала напиши подробно по пунктам работу тогото, что ты хочешь получить: вот например непонятно как отанавливается счетчик повторным нажатием или при отпускании или другой кнопкой; как счетчик должен себя вести если его остановили на середине интервала смежду цифрами (досчитывать потом остаток интервала или считать весь заново), и хоть это не так важно как управление, но тоже заслуживает внимания т.к. МК штука быстрая и часто в работе счетчиков применяются подсчетчики или задержки. |
|
| Автор: | mnirti [ Пт июн 09, 2017 09:15:51 ] |
| Заголовок сообщения: | Re: Изменение кода для счетчика |
Цитата: непонятно как отанавливается счетчик повторным нажатием или при отпускании или другой кнопкой В предыдущих постах было: там одна кнопка на нулевую ножку. 1. При нажатии начинается отсчет. 2. Повторное нажатие - останавливается. 3. Кнопку отпускаю, отсчет продолжается с той цифры, на которой был прерван. Алгоритм работы понимаю, что должно быть, но вот как сделать - без малейшего понятия. Код: #include <avr/io.h> #define F_CPU 8000000L #include <avr/io.h> #include <util/delay.h> unsigned int i; int main(void) { unsigned char butcount=0; DDRD = 0xFF; DDRB = 0x00; PORTD = 0b00000000; // Весь регистр на выход PORTB = 0b00000001; // Младший бит, нулевая нога на вход while ((PINB&0b00000001)==0)) // Цикл выполняется до тех пор, пока на нулевой ноге есть логический ноль { { for (i=0; i<10; i+1) //i++ = i+1 if ((PINB&0b00000001)==0)) _delay_ms(10); PORTD = ~0b00000110; _delay_ms(500); PORTD = ~0b01011011; _delay_ms(500); PORTD = ~0b01001111; _delay_ms(500); PORTD = ~0b01100110; _delay_ms(500); PORTD = ~0b01101101; _delay_ms(500); PORTD = ~0b01111101; _delay_ms(500); PORTD = ~0b00000111; _delay_ms(500); PORTD = ~0b01111111; _delay_ms(500); PORTD = ~0b01101111; _delay_ms(500); PORTD = ~0b00111111; _delay_ms(500); } } } Может быть, добавить второй while, внутрь первого, сделать цикл в цикле, или дополнительную задержку? |
|
| Автор: | Ivanoff-iv [ Пт июн 09, 2017 10:02:57 ] |
| Заголовок сообщения: | Re: Изменение кода для счетчика |
[quote]1. При нажатии начинается отсчет. 2. Повторное нажатие - останавливается. 3. Кнопку отпускаю, отсчет продолжается с той цифры, на которой был прерван. ... т.е. 1) запуск МК - счетчик стоит, показание=0 (или выкл.) 2) кнопка нажата (первый раз) - счетчик пошел 3) кнопка отпущена - ??? 4) кнопка нажата (2й раз и последующие) - счетчик останавливается 5) кнопка отпущена (после 2го и последующих) - счетчик запускается. так? тогда сначала пункты 1 и 2 1 - описываешь начальные условия 2 - ставишь пустой цикл на удержание, пока кнопка не нажата 3 - 4 и 5 прячешь в цикл FOR(i от 0 до 9), а его в бесконечный цикл - это тело счетчика тут удобно сделать массив знаков для индикатора DIG[10]=...сдесь описаны выводимые в порт сигналы для каждой цифры от 0 до 9. (посмотри где и как описать массив) в цикле просто пишешь задержку, потом пустой цикл для удержания счетчика до отпускания кнопки, потом вывод i в порт- PORTD=DIG[i]; всё.... (цикл FOR будет сам подставлять нужную цифру) |
|
| Автор: | Аlex [ Пт июн 09, 2017 12:06:05 ] |
| Заголовок сообщения: | Re: Изменение кода для счетчика |
mnirti писал(а): Алгоритм работы понимаю, что должно быть, но вот как сделать - без малейшего понятия. Значит взялись за сложную задачу.Начните изучение с самых азов. Скачайте какой-нибудь учебник по Си и потихонечку начинайте изучать, создавая сначала простые программки. Язык проще всего учить на компе. Результат виден сразу и режимы отладки имеются, что очень поможет при изучении. |
|
| Автор: | mnirti [ Пт июн 09, 2017 12:14:49 ] |
| Заголовок сообщения: | Re: Изменение кода для счетчика |
Да, в пункте 3 кнопка не нажата, то есть при запуске счетчика нажимается один раз, для остановки еще раз. Подскажите, пожалуйста, какие ошибки в структуре: Код: #include <avr/io.h> #define F_CPU 8000000L #include <avr/io.h> #include <util/delay.h> unsigned int i; int main(void) { unsigned char butcount=0; DDRD = 0xFF; DDRB = 0x00; PORTD = 0b00000000; // Весь регистр на выход PORTB = 0b00000001; // Младший бит, нулевая нога на вход while ((PINB&0b00000001)==1)) // Пустой цикл: кнопка не нажата if ((PINB&0b00000001)==1)) { } while ((PINB&0b00000001)==0)) // Цикл выполняется до тех пор, пока на нулевой ноге есть логический ноль { { for (i=0; i<10; i+1) //i++ = i+1 if ((PINB&0b00000001)==0)) _delay_ms(10); char dig [10]= // Массив чисел { PORTD = ~0b00000110; _delay_ms(500); PORTD = ~0b01011011; _delay_ms(500); PORTD = ~0b01001111; _delay_ms(500); PORTD = ~0b01100110; _delay_ms(500); PORTD = ~0b01101101; _delay_ms(500); PORTD = ~0b01111101; _delay_ms(500); PORTD = ~0b00000111; _delay_ms(500); PORTD = ~0b01111111; _delay_ms(500); PORTD = ~0b01101111; _delay_ms(500); PORTD = ~0b00111111; _delay_ms(500); } while ((PINB&0b00000001)==0)) // Пустой цикл: кнопка нажата if ((PINB&0b00000001)==0)) { } } PORTD=char dig[i]; // Вывод значений в порт D } Добавлено after 5 minutes 18 seconds: Цитата: Значит взялись за сложную задачу. Задача действительно очень сложная для меня. Но, к сожалению, приходится начинать не с простого. И изучать язык на компьютере также нет возможности, так как предстоит работать только в программе атмель и только с определенными типами микросхем. |
|
| Автор: | Аlex [ Пт июн 09, 2017 12:31:38 ] |
| Заголовок сообщения: | Re: Изменение кода для счетчика |
mnirti писал(а): Подскажите, пожалуйста, какие ошибки в структуре: А компилятор ошибку что-ли какую выдаёт ?Добавлено after 14 minutes 56 seconds: mnirti писал(а): так как предстоит работать только в программе атмель и только с определенными типами микросхем То, что потом предстоит - это дело десятое. Я сказал как проще его изучить.Никто потом не запрещает эти знания применять в области программирования под микроконтроллеры. |
|
| Автор: | mnirti [ Пт июн 09, 2017 12:37:11 ] |
| Заголовок сообщения: | Re: Изменение кода для счетчика |
Отладчик ошибки нашел в плане того, что не хватает скобок и точек с запятой. А при загрузке кода в МК и тестировании в протеусе получается, что питание на нулевую лапку изначально не подано, при нажатии кнопки часть сегментов не видна и счет останавливается сам по себе. Поэтому подозреваю, что циклы у меня неправильно записаны и/или строки не в том порядке. Программа не принимает запись массива DIG, только char dig. |
|
| Автор: | Аlex [ Пт июн 09, 2017 12:46:04 ] |
| Заголовок сообщения: | Re: Изменение кода для счетчика |
Только что обратил внимание вот на это : Цитата: Код: char dig [10]= // Массив чисел { PORTD = ~0b00000110; _delay_ms(500); PORTD = ~0b01011011; _delay_ms(500); PORTD = ~0b01001111; _delay_ms(500); PORTD = ~0b01100110; _delay_ms(500); PORTD = ~0b01101101; _delay_ms(500); PORTD = ~0b01111101; _delay_ms(500); PORTD = ~0b00000111; _delay_ms(500); PORTD = ~0b01111111; _delay_ms(500); PORTD = ~0b01101111; _delay_ms(500); PORTD = ~0b00111111; _delay_ms(500); } Ну почитайте Вы, наконец, книги по Си. Не получится у Вас ничего методом тыка... |
|
| Страница 1 из 3 | Часовой пояс: UTC + 3 часа |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|


