Изменение кода для счетчика

Обсуждаем контроллеры компании Atmel.
Ответить
Первый раз сказал Мяу!
Сообщения: 26
Зарегистрирован: Вт май 23, 2017 15:41:09

Сообщение mnirti »

Конечно, лучше учить поэтапно. Но у меня получается, что выполняю такие задания параллельно с чтением теории, задания такие уже задают, знаний не хватает. Ищу по кускам, но куски вместе не склеиваются. В учебниках упражнения приводятся для выполнения непосредственно в ОС, как правило. Поэтому самостоятельная практика началась с уроков того сайта, откуда был взят изначальный код.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

давай по шагам...
1) объяви переменную i для счетчика
и опиши массив (10 элементов, с кодами цифр - можешь скопировать их (коды) из соих примеров (если не подойдут потом поправим))
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Реклама
Первый раз сказал Мяу!
Сообщения: 26
Зарегистрирован: Вт май 23, 2017 15:41:09

Сообщение mnirti »

Массив знаков получился такой:

Код: Выделить всё

for (i=0; i<10; i+1) // i должна быть от нуля до 9 включительно, т. к. строго меньше 10, шаг отсчета 1
char dig [10]=  // Массив символов для индикатора
 {
	0b00000110;
	0b01011011;
	0b01001111;
	0b01100110;
	0b01101101;
	0b01111101;
	0b00000111;
	0b01111111;
	0b01101111;
	0b00111111;
       }
Добавлено after 6 minutes 12 seconds:
А может быть и так можно:

Код: Выделить всё

char dig [i=0; i<10; i+1]=   
 {
	0b00000110;
	0b01011011;
	0b01001111;
	0b01100110;
	0b01101101;
	0b01111101;
	0b00000111;
	0b01111111;
	0b01101111;
	0b00111111;
       }
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18679
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

mnirti писал(а):for (i=0; i<10; i+1)
i+1 здесь не будет давать нужного вам эффекта, т.к. результат выражения ничему не присваивается. здесь или i++ надо писать, или i+=1 или i = i + 1 иначе цикл у вас будет вечным
mnirti писал(а):char dig [10]=  // Массив символов для индикатора
 {
   0b00000110;
   0b01011011;
   0b01001111;
   0b01100110;
   0b01101101;
   0b01111101;
   0b00000111;
   0b01111111;
   0b01101111;
   0b00111111;
       }
это всё магические числа, что плохо по определению.
mnirti писал(а):char dig
так точно нельзя.

вы по какой книге язык Си изучаете? неужели там такое написано?!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Первый раз сказал Мяу!
Сообщения: 26
Зарегистрирован: Вт май 23, 2017 15:41:09

Сообщение mnirti »

Получается:

Код: Выделить всё

for (i=0; i<10; i++) // инкремента

char dig [10]=  // Массив чисел 
 {
    1<<2; // например, 4
...
	
       }
Реклама
Вымогатель припоя
Сообщения: 537
Зарегистрирован: Вт фев 09, 2010 17:52:26

Сообщение codenamehawk »

[uquote="ARV",url="/forum/viewtopic.php?p=3123245#p3123245"][/quote]это всё магические числа, что плохо по определению.[/uquote]
Чем это плохо я не знаю(если достаточно памяти), но инициализация массива делается примерно так:

Код: Выделить всё

char dig [10]=  // Массив символов для индикатора
 {
   0b00000110,
   0b01011011,
   0b01001111,
   0b01100110,
   0b01101101,
   0b01111101,
   0b00000111,
   0b01111111,
   0b01101111,
   0b00111111
       };
https://prog-cpp.ru/c-massiv/

а заодно почитайте и это http://cpp.com.ru/kr_cbook/ch5kr.html скоро понадобиться
Реклама
Друг Кота
Аватара пользователя
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

[uquote="ARV",url="/forum/viewtopic.php?p=3123245#p3123245"]
mnirti писал(а):char dig [10]=  // Массив символов для индикатора
 {
   0b00000110;
   0b01011011;
   0b01001111;
   0b01100110;
   0b01101101;
   0b01111101;
   0b00000111;
   0b01111111;
   0b01101111;
   0b00111111;
       }
это всё магические числа[/uquote] я считаю это — настройка периферии, а как без них предлагаете знакогенератор собрать?
mnirti массив лучше:
1. сделать константным - мы в нём по ходу программы ни чего менять не будем,
2. объявлять не в цикле for (почитайте про область видимости переменных)
3. если массив заполняется при объявлении — его размер можно не писать, компилятор сам сощитает ... dig[]={...};
4. элементы массива разделяются запятыми
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18679
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

codenamehawk писал(а):Чем это плохо я не знаю
жаль
Ivanoff-iv писал(а):если массив заполняется при объявлении — его размер можно не писать
можно, но не нужно, иначе сложнее контролировать его правильное заполнение.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Первый раз сказал Мяу!
Сообщения: 26
Зарегистрирован: Вт май 23, 2017 15:41:09

Сообщение mnirti »

Читаю и слушаю всех, код выходит таким:

Код: Выделить всё

#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; // Младший бит, нулевая нога на вход
	
	 const char dig [10]=  // Константный массив чисел, 
	 //объявлен в основной  функции
 {
	0b00000110,
	0b01011011,
	0b01001111,
	0b01100110,
	0b01101101,
	0b01111101,
	0b00000111,
	0b01111111,
	0b01101111,
	0b00111111
       };
	//---------------------------------

	while ((PINB&0b00000001)==1)) // Пустой цикл: кнопка не нажата
	if ((PINB&0b00000001)==1))
	{
		
	}
 
	//---------------------------------
	
	while ((PINB&0b00000001)==0)) // Цикл выполняется до тех пор, пока на нулевой ноге есть логический ноль
{
 
	for (i=0; i<10; i++) // 
	if ((PINB&0b00000001)==0))
    _delay_ms(1500);



//---------------------------------
while ((PINB&0b00000001)==0)) // Пустой цикл: кнопка нажата
if ((PINB&0b00000001)==0))
{
	
}
}

//---------------------------------
PORTD=const char dig[i]; // Вывод значений в порт D

}
Счетчик пока еще не работает. Наверное неправильно написаны пустые циклы, ко всему прочему пропадает питание после нажатия кнопки.
Друг Кота
Аватара пользователя
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Сообщение Ivanoff-iv »

9 строка: переменная не нужна (она ни где не используется).
32-36: дополнительной проверки не надо,достаточно только цикла.
40: этот цикл сделай закольцованным навсегда, без учета кнопки.
43: циклу for добавь операторные скобки и в них впиши
задержку,
пустой цикл с условием по кнопке
и вывод iтой цифры в порт.

всё дальнейшее стирай.
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Вымогатель припоя
Сообщения: 537
Зарегистрирован: Вт фев 09, 2010 17:52:26

Сообщение codenamehawk »

Что бы написать программу, надо ее себе представить.
Удобней всего это сделать на бумаге, например в графическом виде.
http://www.maksakov-sa.ru/Algol/SpPrAlg ... index.html

Программа в процессоре никогда не должна "закончиться", для этого в функции main создается
бесконечный цикл

Код: Выделить всё


int main(void)
//main start
{
//инициализация переменных и настройка железа(настройка портов на вход- выход)
	while (1)
	{
          // Тут будет основной код 
	}
}//main end
В вашем случае удобнее ввести переменную в которую считать состояние кнопки(кнопок) и в зависимости от нее делать разветвления программы.

Код: Выделить всё

unsigned char knopka;
unsigned int   perevennaja=0;
while (1)
{
  knopka = PINB;
  // если кнопка нажата делаем то
  if ((knopka & 0b00000001) == 0 )
  {
     //Если надо добавляете проверку на мах значение, с учетом того ее увеличите
     perenennaja++;
     
  } else //если кнопка не нажата делаем то
  {
     //Если надо добавляете проверку на min значение, с учетом того ее уменьшите
     peremennaja--;
  }
  //тут удобное место написать код для отображения  значения "perenennaja"
  _delay_ms(300); перед следующим опросом кнопки, пропускаем дребезг кнопки
}



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



Добавлено after 6 minutes 54 seconds:
[uquote="ARV",url="/forum/viewtopic.php?p=3123296#p3123296"]
codenamehawk писал(а):Чем это плохо я не знаю
жаль[/uquote]

Покажите как вы бы "правильно" сделали хранение символов, для отображения их на LED.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18679
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

codenamehawk писал(а):Покажите как вы бы "правильно" сделали хранение символов, для отображения их на LED
так 100500 раз уже было показано...

Код: Выделить всё

#define _A  _BV(0)
#define _B _BV(1)
#define _C _BV(2)
#define _D _BV(3)
#define _E _BV(4)
#define _F _BV(5)
#define _G _BV(6)
#define _H _BV(7)

#define _dig_0 (_A | _B | _C | _D | _E | _F)
#define _dig_1 (_B | _C)
#define _dig_2 (_A | _B | _G | _E | _D)
// и так далее все цифры и другие знаки, которые нужны

char DIG[10] = {_dig_0, _dig_1, _dig_2, /* и так далее */ _dig_9};
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Вымогатель припоя
Сообщения: 537
Зарегистрирован: Вт фев 09, 2010 17:52:26

Сообщение codenamehawk »

Код: Выделить всё

#define _A  _BV(0)
#define _B _BV(1)
#define _C _BV(2)
#define _D _BV(3)
#define _E _BV(4)
#define _F _BV(5)
#define _G _BV(6)
#define _H _BV(7)

#define _dig_0 (_A | _B | _C | _D | _E | _F)
#define _dig_1 (_B | _C)
#define _dig_2 (_A | _B | _G | _E | _D)
// и так далее все цифры и другие знаки, которые нужны
Это нужно только если кто сам создает знаки.

Намного проще один раз рассчитать в проге
http://www.getchip.net/posts/080-konver ... ndikatora/
и далее просто использовать константы.
Код получится одинаковым, а не нужной писанины меньше.
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18679
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

codenamehawk писал(а):Это нужно только если кто сам создает знаки
много раз слышал фразу "математика мне не нужна, я люблю историю и пойду учиться в на истфак" - найдите 7 отличий от вашего утверждения...

жаль, что правила хорошего тона постепенно умирают как в реальной жизни, так и в программировании. зачем пользоваться салфеткой, если можно и рукой рот вытереть? зачем избавляться от магических чисел, если "только один раз надо"?

как минимум затем, чтобы самого себя уважать не за лень, а за аккуратность.

извините за оффтоп.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Первый раз сказал Мяу!
Сообщения: 26
Зарегистрирован: Вт май 23, 2017 15:41:09

Сообщение mnirti »

Теперь код переписан так, но отладчик выдает 7 ошибок:

Код: Выделить всё

#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; // Младший бит, нулевая нога на вход
	
	 const char dig [10]=  // Константный массив чисел, 
	 //объявлен в основной  функции
 {
	0b00000110,
	0b01011011,
	0b01001111,
	0b01100110,
	0b01101101,
	0b01111101,
	0b00000111,
	0b01111111,
	0b01101111,
	0b00111111
       };
	//---------------------------------

	while ((PINB&0b00000001)==1)) // Пустой цикл: кнопка не нажата
	// if ((PINB&0b00000001)==1)) Без дополнительной проверки
	{
		
	}
 
	//---------------------------------
	
	while (1) // Бесконечный цикл
    if ((PINB&0b00000001)==0))
	
	for (i=0; i<10; i++) 
  {
    _delay_ms(1500);
  
}
  



//---------------------------------
while ((PINB&0b00000001)==0)) // Пустой цикл: кнопка нажата
if ((PINB&0b00000001)==0))
{
	
}
PORTD=const char dig[i]; // Вывод значений в порт D
}
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18679
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

вы пытаетесь протестировать интуицию остальных? или к чему эти интригующие слова про 7 ошибок? нам надо угадать, какие именно?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Мучитель микросхем
Сообщения: 453
Зарегистрирован: Ср июн 08, 2011 20:25:20

Сообщение bob1 »

[uquote="mnirti",url="/forum/viewtopic.php?p=3124650#p3124650"]while (1) // Бесконечный цикл[/uquote] скобки {} добавите для всего куска кода, где это цикл :)) , а так работает только для след. строки. И т.д для других while.....
Контактная информация:
Первый раз сказал Мяу!
Сообщения: 26
Зарегистрирован: Вт май 23, 2017 15:41:09

Сообщение mnirti »

Список ошибок, выданных компилятором, теперь новый, код немного подправлен, в циклах есть дополнительные скобки.

Код: Выделить всё

#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; // Младший бит, нулевая нога на вход
	
	const char dig [10]=  // Константный массив чисел,
	//объявлен в основной  функции
	{
		0b00000110,
		0b01011011,
		0b01001111,
		0b01100110,
		0b01101101,
		0b01111101,
		0b00000111,
		0b01111111,
		0b01101111,
		0b00111111
	};
	//---------------------------------

	while ((PINB&0b00000001)==1)) // Пустой цикл: кнопка не нажата
	// if ((PINB&0b00000001)==1)) Без дополнительной проверки
	{
		
	}
	
	//---------------------------------
	
	while (1) // Бесконечный цикл
	{
		
	
	if ((PINB&0b00000001)==0))
	
	for (i=0; i<10; i++)
	{
		_delay_ms(1500);
		
	}
	}



	//---------------------------------
	while ((PINB&0b00000001)==0)) // Пустой цикл: кнопка нажата
	{
		if ((PINB&0b00000001)==0))
	
		
	}
	PORTD=const char dig[i]; // Вывод значений в порт D
}
Вложения
Отладка.jpg
(235.26 КБ) 427 скачиваний
Вымогатель припоя
Сообщения: 537
Зарегистрирован: Вт фев 09, 2010 17:52:26

Сообщение codenamehawk »

[uquote="mnirti",url="/forum/viewtopic.php?p=3124650#p3124650"]

Код: Выделить всё

PORTD=const char dig[i]; // Вывод значений в порт D
[/uquote]
Что тут делает const char?
Почитайте про глобальные и локальные переменные.

Компилятор показывает строку с ошибкой и тип ошибки.

Добавлено after 6 minutes 35 seconds:
Комментируйте, что делает каждый блок программы.

Что делает этот блок

Код: Выделить всё

   while ((PINB&0b00000001)==1)) // Пустой цикл: кнопка не нажата
   // if ((PINB&0b00000001)==1)) Без дополнительной проверки
   {
      
   }
Первый раз сказал Мяу!
Сообщения: 26
Зарегистрирован: Вт май 23, 2017 15:41:09

Сообщение mnirti »

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

Вернуться в «AVR»