DDRC на Arduino (программирование по регистрам)

lisishe-fox
Offline
Зарегистрирован: 05.12.2016

Здравствуйте! У меня есть задание по учебе: писать программы на Arduino (UNO), используя регистры, т.е.не использовать сторонние функции. Зажигать светодиод на 13 пине я уже научилась: 

long int x=0;

void setup() {
  // put your setup code here, to run once:
DDRB = B100000;//заведем 13 вывод как выход в регистровом виде
Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
for(x = 0; x<50000; x++)
{
PORTB = B100000;
}
for(x = 0; x<50000; x++)
{
PORTB = B000000;
}
}

Теперь у меня стоит другая задача: снять показания с потенциометра. Обычный код я смогла обдумать: 

#define POT_PIN A0
#define LED_1 2
#define LED_2 3
#define LED_3 4
#define LED_4 5
void setup() {
  // put your setup code here, to run once:
pinMode (LED_1, OUTPUT);
pinMode (LED_2, OUTPUT);
pinMode (LED_3, OUTPUT);
pinMode (LED_4, OUTPUT);
pinMode (POT_PIN, INPUT);
Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
if (analogRead(POT_PIN)>(1024/5))
digitalWrite(LED_1, 1);
else
digitalWrite(LED_1, 0);
if (analogRead(POT_PIN)>(1024/4))
digitalWrite(LED_2, 1);
else
digitalWrite(LED_2, 0);
if (analogRead(POT_PIN)>(1024/3))
digitalWrite(LED_3, 1);
else
digitalWrite(LED_3, 0);
if (analogRead(POT_PIN)>(1024/2))
digitalWrite(LED_4, 1);
else
digitalWrite(LED_4, 0);
Serial.println(analogRead(POT_PIN));
}

т.е. если одно сопротивление - горит один диод, больше сопротивление - два диода, и так далее. Но порегистрово получить информацию с реостата не могу. Я не понимаю, как задать условие и почему у нас 8 бит, хотя выходов 6. Помогите, пожалуйста. Пока упрощенно программа выглядит так:

void setup() {
  // put your setup code here, to run once:
DDRC = B11111000;
}

void loop() {
  // put your main code here, to run repeatedly:
if ((PINC = B00000100)>256)
digitalWrite(13, 1);
else 
digitalWrite(13, 0);

}

 

gena
Offline
Зарегистрирован: 04.11.2012

   Считанный с аналогового входа (например А0) сигнал сравниваете с 1023 (максимально возможное значение, если А0 = 5 Вольт). Т.е. вычисляете, сколько это процентов от числа 1023. Включаете нужное Вам количество светодиодов.

  Например: весь диапазон входных значений - 0... 1023; число светодиодов на весь этот диапазон - 8. Если считанное значение лежит в диапазоне 1...63, то засвечиваем один светодиод. Если считали 64...127, засвечиваем два светодиода и т.д. Получаем управляемый потенциометром засвечивающийся светодиодный столбик. Надеюсь сама идея понятна?

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

Настройте АЦП, сконфигурируйте и читайте. Информация даже с примерами есть в даташите. 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

wiring_analog.c

Можно посмотреть как что делается если лень даташит читать

lisishe-fox
Offline
Зарегистрирован: 05.12.2016

Простите, не понимаю, о чем вы вообще. Как должна состоять программа в регистровом виде, чтобы при сопротивлении более 256 с реостата, загорался 13-ый диод?

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Что б совсем всё не подсказывать оставил analogRead. А зажигание светиков -пример без быдлокодинга:

void setup() {
DDRD=0xFC; // 6 светодиодов на 2...7 пин
}
void loop() {
byte leds_count =analogRead(A0)/170; //разделить на 6 частей
byte n;
while(leds_count){leds_count--;  n= (n<<1|1<<2); }
PORTD=n&0xFC; 
}

 

lisishe-fox
Offline
Зарегистрирован: 05.12.2016

У меня вопрос и состоял в том, как заменить analogRead в регистровый вариант? 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

lisishe-fox пишет:

У меня вопрос и состоял в том, как заменить analogRead в регистровый вариант? 

Тоесть ответ #3 вы не изволили рассмотреть?

lisishe-fox
Offline
Зарегистрирован: 05.12.2016

Если честно, легче не стало. Что это?

int analogRead(uint8_t pin)
{
	uint8_t low, high;

#if defined(analogPinToChannel)
#if defined(__AVR_ATmega32U4__)
	if (pin >= 18) pin -= 18; // allow for channel or pin numbers
#endif
	pin = analogPinToChannel(pin);
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
	if (pin >= 54) pin -= 54; // allow for channel or pin numbers
#elif defined(__AVR_ATmega32U4__)
	if (pin >= 18) pin -= 18; // allow for channel or pin numbers
#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
	if (pin >= 24) pin -= 24; // allow for channel or pin numbers
#else
	if (pin >= 14) pin -= 14; // allow for channel or pin numbers
#endif

#if defined(ADCSRB) && defined(MUX5)
	// the MUX5 bit of ADCSRB selects whether we're reading from channels
	// 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
	ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
#endif
  
	// set the analog reference (high two bits of ADMUX) and select the
	// channel (low 4 bits).  this also sets ADLAR (left-adjust result)
	// to 0 (the default).
#if defined(ADMUX)
#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
	ADMUX = (analog_reference << 4) | (pin & 0x07);
#else
	ADMUX = (analog_reference << 6) | (pin & 0x07);
#endif
#endif

	// without a delay, we seem to read from the wrong channel
	//delay(1);

#if defined(ADCSRA) && defined(ADCL)
	// start the conversion
	sbi(ADCSRA, ADSC);

	// ADSC is cleared when the conversion finishes
	while (bit_is_set(ADCSRA, ADSC));

	// we have to read ADCL first; doing so locks both ADCL
	// and ADCH until ADCH is read.  reading ADCL second would
	// cause the results of each conversion to be discarded,
	// as ADCL and ADCH would be locked when it completed.
	low  = ADCL;
	high = ADCH;
#else
	// we dont have an ADC, return 0
	low  = 0;
	high = 0;
#endif

	// combine the two bytes
	return (high << 8) | low;
}

 

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

Скажите девушка , как недопрограммист недопрограммисту, а вы даташит читали. Так вот вам задали на дом прочитать и разобраться в нем. А это просто проверка узнать , читали вы даташит или так в контакте провисели.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

lisishe-fox пишет:

Если честно, легче не стало. Что это?

int analogRead(uint8_t pin)
{
	uint8_t low, high;

#if defined(analogPinToChannel)
#if defined(__AVR_ATmega32U4__)
	if (pin >= 18) pin -= 18; // allow for channel or pin numbers
#endif
	pin = analogPinToChannel(pin);
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
	if (pin >= 54) pin -= 54; // allow for channel or pin numbers
#elif defined(__AVR_ATmega32U4__)
	if (pin >= 18) pin -= 18; // allow for channel or pin numbers
#elif defined(__AVR_ATmega1284__) || defined(__AVR_ATmega1284P__) || defined(__AVR_ATmega644__) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__)
	if (pin >= 24) pin -= 24; // allow for channel or pin numbers
#else
	if (pin >= 14) pin -= 14; // allow for channel or pin numbers
#endif

#if defined(ADCSRB) && defined(MUX5)
	// the MUX5 bit of ADCSRB selects whether we're reading from channels
	// 0 to 7 (MUX5 low) or 8 to 15 (MUX5 high).
	ADCSRB = (ADCSRB & ~(1 << MUX5)) | (((pin >> 3) & 0x01) << MUX5);
#endif
  
	// set the analog reference (high two bits of ADMUX) and select the
	// channel (low 4 bits).  this also sets ADLAR (left-adjust result)
	// to 0 (the default).
#if defined(ADMUX)
#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
	ADMUX = (analog_reference << 4) | (pin & 0x07);
#else
	ADMUX = (analog_reference << 6) | (pin & 0x07);
#endif
#endif

	// without a delay, we seem to read from the wrong channel
	//delay(1);

#if defined(ADCSRA) && defined(ADCL)
	// start the conversion
	sbi(ADCSRA, ADSC);

	// ADSC is cleared when the conversion finishes
	while (bit_is_set(ADCSRA, ADSC));

	// we have to read ADCL first; doing so locks both ADCL
	// and ADCH until ADCH is read.  reading ADCL second would
	// cause the results of each conversion to be discarded,
	// as ADCL and ADCH would be locked when it completed.
	low  = ADCL;
	high = ADCH;
#else
	// we dont have an ADC, return 0
	low  = 0;
	high = 0;
#endif

	// combine the two bytes
	return (high << 8) | low;
}

 

Это программа на чесном С.

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015
lisishe-fox
Offline
Зарегистрирован: 05.12.2016

Эх, видимо этот форум для избранных, очень жать :) Да, я открывала даташит, да, читала про какие-то ADMUX, 0 - если ввод, 1 - вывод. Видимо я так и должна написать в IDE: 0. И ту программу из #3 комментария. Как-то смешно получается: на паре говорят - смотрите в даташите, что тут, а объяснять, как ту информацию применять никто не хочет. 

Понятнее мне не стало :) 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

беги оттудова бегом нахрен. 

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

lisishe-fox, даташиты не для чайников пишут, предпологается что человек уже знает основы программирования и устройство микроконтроллеров. Так что либо вы прогуливали занятия, либо это не ваше, и нужно было выбирать специальность попроще..

lisishe-fox
Offline
Зарегистрирован: 05.12.2016

Прикольно, вот и договорились: в вузе мне дают микроконтроллер и говорят: изучай и программируй, на просторах инета говорят то, что говорят. :) Ладно, проще заказать программу, второй день себе мозги забиваю тем, чего нигде не объяснено :)

lisishe-fox
Offline
Зарегистрирован: 05.12.2016

Для таких же не сенсеев вроде меня в мире шибко умных Ардуинщиков:

http://forum.arduino.ua/viewtopic.php?id=1071

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

Так вы поизучать попробуйте) тут не так много человек, которые в вузе программирование вообще изучали, пишут под контроллеры же...

Господи, нигде не объяснена работа с АЦП?!

1. Есть гугл, ну так, для примера.

2. http://easyelectronics.ru/avr-uchebnyj-kurs-ispolzovanie-acp.html

3. http://www.avrki.ru/articles/content/lesson_5/

4. http://avr-start.ru/?p=590

Дальше ссылки из гугла копировать?

Хотите заказать - пишите на yaryarikyar@ya.ru ) напишу, прокомментирую, могу даже протестировать.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Ты маме своей плачся, что ничего не обьясняют.  Наерна, сложно обьяснить что-то человеку, которого на лекциях нету.  Или он там спит.  Или в ВКакашечку пырица.  Зачем тогда такую специальность выбирать?   

Хреново, что врачи у нас выпускаются точно такие же. 

andycat
andycat аватар
Offline
Зарегистрирован: 07.09.2017

lisishe-fox, вопрос не в тему:

1. Сколько времени дается в Вашем институте на написание данного занятия?

2. Были ли лекции по машинным кодам/регистрам/адресации и прочему?

 

alex_r61
Offline
Зарегистрирован: 20.06.2012

На http://www.gaw.ru/ всё расписано с апноутами, причём многие переведены на русский.

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

lisishe-fox пишет:

Прикольно, вот и договорились: в вузе мне дают микроконтроллер и говорят: изучай и программируй, на просторах инета говорят то, что говорят. :) Ладно, проще заказать программу, второй день себе мозги забиваю тем, чего нигде не объяснено :)

Вы что думаете, что в вузе дадут все что надо. Диплом это больше документ о намерии человека работать в этой отрасли. Дальше надо лет 20 самостоятельно изучать дальше. Отрасль же не стоит на месте. Считайте что вуз проводит первичный отсев балласта от тех кто учится самостоятельно. Пошли бы в иняз или приготовление пищи. Там прогресс не сильно развивается. Так что знаний в объеме вуза хватит на всю жизнь.

пс:http://www.embed.com.ua/raznoe/atsp-mikrokontrollerov-avr-na-paltsah/

http://avrprog.blogspot.com/2013/03/blog-post_13.html

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

DetSimen пишет:

Это программа на чесном С.

Неправда ваша, наш безкостыльный никада....никада не использует analogPinToChannel....

brokly
brokly аватар
Offline
Зарегистрирован: 08.02.2014

lisishe-fox пишет:

Прикольно, вот и договорились: в вузе мне дают микроконтроллер и говорят: изучай и программируй, на просторах инета говорят то, что говорят. :) Ладно, проще заказать программу, второй день себе мозги забиваю тем, чего нигде не объяснено :)

Когда я учился, инета еще не было. Все читали книжки и качали порнуху модемами.... Эх были времена....