roboforum.ru

Технический форум по робототехнике.

Магический кристалл

Re: Магический кристалл

galex1981 » 15 мар 2010, 02:15

1) В Си есть подпрограммы и функции, отличаются тем что ПП не возвращают никакого значения, функции же возвращают
Код: Выделить всёРазвернуть
ПП
void select()
{
     return;
}
Функция:
int getMax(int a, int b)
{
     return (a>b)?a:b;
}


2) В главной функции на порт, к которому подключен светодиод, подать или 0 или 1 соответственно варианту подключения светодиода.

Re: Магический кристалл

GrayHunter » 15 мар 2010, 03:03

1) меня интересует аналог "rcall" и "ret" (asm) в Си. Есть такие?
2)
Подключаем к одному из выводов ШИМ светодиод, пишем программу
можно пример, пожалуйста (желательно чтобы было 4 уровня максимальной яркости, которые зависят от заряда кристалла)

Re: Магический кристалл

Angel71 » 15 мар 2010, 10:05

от прочтения самоучителя по си куча вопросов отпадёт моментально

Re: Магический кристалл

avr123.nm.ru » 15 мар 2010, 10:28

GrayHunter писал(а): ШИМ светодиод, пишем программу - можно пример
посмотрите пример на заглавной http://proavr.narod.ru - там шаг ШИМ 10 % но можно изменить, подробно про pwm ШИМ в AVR в задаче 8.

Re: Магический кристалл

GrayHunter » 15 мар 2010, 15:25

Прочитал про ШИМ - мда, буду вечером разбираться в скаченных примерах кодов, надеюсь там можно понять, как "дышать" светодиодом в нужный момент.

Насчёт подпрограмм: прочитал уже много всего, ещё больше проверил поиском, но нигде нормального объяснения аналога Си подпрограммам на asm не нашёл. Метки в данном случае не подходят, т.к. возвращаться надо будет в то место, откуда подпрограмма была вызвана, а с метками это уже не будет подпрограмма.
Единственное, что нашёл похожего - это Циклы for(;;) и while(), но тогда подпрограммами будут прерывания... а просто, как в asm, можно сделать подпрограмму?

Например, мне нужно проверить 3 ножки и вернуться - вот что на данный момент сварганил:
Код: Выделить всёРазвернуть
  Temp = 1;
   if(Temp==PORTD.0)  // получаем данные с Экрана/ножки PD0 и проверяем на перемычку
   {
      if(Temp==PORTD.1 || Temp==PORTD.2)  // получаем данные с ножек PD1 и PD2 и проверяем на замыкание сразу нескольких перемычек
      {
      goto Fast_Burning;  // если замкнуто несколько перемычек - перейти к быстрому прогоранию
      };
   Temp = 1;  // кристалл в Экране (эту строку можно убрать)
??? - вернуться в место вызова этой подпрограммы - ???
   };
  Temp = 0;  // кристалл НЕ в Экране
??? - вернуться в место вызова этой подпрограммы - ???

Интересуют моменты, где надо "вернуться в место вызова этой подпрограммы". По идее, это должно быть аналогично "ret"... Так же примерчик бы, как вызвать подпрограмму в нужном месте (asm "rcall").

Как это сделать?
Помогите, плз, а то всё застопорилось на этом.

Re: Магический кристалл

Angel71 » 15 мар 2010, 15:55

читайте внимательней книги по си. про подпрограммы galex1981 вам всё нужное уже сообщил. циклы и подпрограммы конечно имеют немного общего, но таки разные вещи.

Re: Магический кристалл

GrayHunter » 15 мар 2010, 16:14

Angel71, уже второе сообщение с упорной бесполезностью. Я читал и курс от AVR123 и Б. Керриган, Д. Ритчи Язык программирования C, но из-за маленького опыта, я не могу понять, какие в Си аналоги asm подпрограммам. Объяснения своего вопроса я, вроде, дал уже достаточно, для опытных в Си.
Поэтому прошу знающих Си написать мне код-пример подпрограммы на Си, чтобы я дальше по аналогии его использовал. :roll:

Re: Магический кристалл

Angel71 » 15 мар 2010, 16:19

:) вы просите медвежью услугу,а не помощь. :pardon: эт без меня
:wink: я же вам настоятельно рекомендую взять и начать изучать язык с самого начала. хотя бы азы, порешайте немного задачек и избавите себя от множества ошибок при написании программы и необходимости задавать подобные вопросы.

Re: Магический кристалл

GrayHunter » 15 мар 2010, 16:22

Привожу аналогичный пример на asm:

чтобы вызвать подпрограмму:
Код: Выделить всёРазвернуть
rcall Название_подпрограммы

Сама попрограмма:
Код: Выделить всёРазвернуть
Название_подпрограммы:
код_подпрограммы
ret   ; конец подпрограммы. При этом продолжится выполнение программы, вызвавшей данную подпрограмму, с места вызова. Т.е., с команды, следующей за командой rcall

Вот такое же нужно на Си.
Или на Си это нереально? :shock:

Re: Магический кристалл

Angel71 » 15 мар 2010, 16:26

8) не смешно :) перечитайте эту страницу еще раз внимательно.

Re: Магический кристалл

GrayHunter » 15 мар 2010, 17:28

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

Хочется верить, что в Си всё же есть подпрограммы (или аналоги), и здесь кто-то знает, как ими пользоваться. Подожду помощи :roll:

Добавлено спустя 50 минут 26 секунд:
Нашёл аналогичную тему, но там всё-таки подсказали. :good:

Значит вот мой пример, чтобы я понял, правильно я понял:
Код: Выделить всёРазвернуть
#include <mega8.h>
#include <delay.h>

unsigned char Temp;

qwerty1()  // функция "do"
{
  Temp = 1;
   if(Temp==PIND.0)
   {
      if(Temp==PIND.1 || Temp==PIND.2)
      {
      goto Fast_Burning;
      };
   return;
   };
  Temp = 0;
  return;
}
while (1 != 1);

void main(void)

  DDRB = 0b00000001;
  DDRD = 0b00000000;
  PORTD = 0b00000111;
   
again:
qwerty1();  // вызываем "подпрограмму" "qwerty1"
if(Temp==1)
{
PORTD.0 = 1;   
goto again;
};
PORTD.0 = 0;   
goto again;       

Fast_Burning:
PORTD.0 = 1;
delay_ms(60);  // задержка
PORTD.0 = 0;
delay_ms(60);  // задержка
goto again;
}

Эта программа должна работать так:
- Если ножка PD0 соединена с землёй, и если ни одна из ножек PD1 и PD2 не соединены с землёй, то подать напряжение на ножку PB0.
- Если ни одна из ножек (PD0, PD1, PD2) не соединены с землёй, то убрать напряжение с ножки PB0.
- Если ножка PD0 соединена с землёй, а так же если хотя бы одна из ножек PD1 и PD2 соединены с землёй, то "поморгать" (метка: Fast_Burning).

Правильно ли я всё сделал? (если нет - пожалуйста, поправьте)
Последний раз редактировалось GrayHunter 15 мар 2010, 20:05, всего редактировалось 2 раз(а).

Re: Магический кристалл

yak-40 » 15 мар 2010, 17:51

При чтении ножки надо писАть не PORTD.1 PORTD.2 а PIND.1 PIND.2

Re: Магический кристалл

GrayHunter » 15 мар 2010, 18:01

Спасибо. Только на чтение или и на запись тоже?
// поправил и там и там.

Пытаюсь скомпилить код в CVAVR - пишет 2 ошибки:
экрана 3.png
экрана 3.png (7.01 КиБ) Просмотров: 1971


Где я делаю неправильно?

Re: Магический кристалл

yak-40 » 15 мар 2010, 18:06

Только на чтение. На вывод PORTD.1

По поводу первой ошибки: goto из одной функции в другую не прыгает.
По поводу второй: в main мешает зайти вот этот бесконечный цикл while (1 != 1);

Re: Магический кристалл

blindman » 15 мар 2010, 18:16

Ужас. Это что за компилятор такой который не ругается на while за пределами функции?


Rambler\'s Top100 Mail.ru counter