roboforum.ru

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


МикроКонтроллер AVR начинающим - общие вопросы

Программирование микроконтроллеров AVR, PIC, ARM.
Разработка и изготовление печатных плат для модулей.

Re: МикроКонтроллер AVR начинающим - общие вопросы

Сообщение thor_nsk » 12 ноя 2016, 20:21

Тема, смотрю, почти мертвая, но все же спрошу. Имею проблемы с ADC на Tiny85, а точнее не могу заставить работать. ADC проходит только раз при включении (либо это "помехи" включения МК) и все, больше значения не меняются. Игрался с делителем ADC, ручным и автозапуском ничего не получилось. Код на С прилагаю. Если кому не трудно, гляньте пожалуйста. Коротко о программе. Надо включить питание сенсора, провести АЦП, сверить полученные данные с эталоном и если все "плохо", то включить помпу на полив цветов. Затем уснуть на 24часа. Проснуться и повторить программу сначала. Все получается кроме "провести АЦП". Что я делаю не так? :(
Вложения
polivalka.c
(5.44 КиБ) Скачиваний: 40
thor_nsk
 
Сообщения: 30
Зарегистрирован: 15 июн 2016, 10:38
Откуда: Новосибирск
ФИО: Константин

Re: МикроКонтроллер AVR начинающим - общие вопросы

Сообщение Madf » 12 ноя 2016, 20:26

Если используйте "Powerdown", то после просыпания, нужно около 50мс подождать, когда всё проснётся.
Madf
 
Сообщения: 2367
Зарегистрирован: 03 янв 2012, 12:55
Откуда: Москва
прог. языки: VB6, BASCOM, ASM...

Re: МикроКонтроллер AVR начинающим - общие вопросы

Сообщение thor_nsk » 13 ноя 2016, 09:59

Я тоже поначалу грешил на энергосбережение и на функции пробуждения, думал не все включается. Поэтому для пробы сделал отдельный проект, просто АЦП в цикле. Еще была проблема мониторинга числа получаемого после АЦП. Единственный быстрый вариант смог сделать на светодиодной матрице с max 7219. Я на нее в двоичном коде выводил старший и младший байт результата АЦП. Та же песня, после подачи питания что-то появляется в регистре АЦП и потом не меняется. Либо не стартует начало преобразования, либо не срабатывает прерывание по окончанию АЦП. Код прилагаю. Я уже не знаю куда копать. Вроде все должно работать, а нифига не получается. Видимо есть какой-то нюанс который мне не известен. Помогите, пожалуйста, разобраться.
Вложения
tiny85.c
(4.73 КиБ) Скачиваний: 35
thor_nsk
 
Сообщения: 30
Зарегистрирован: 15 июн 2016, 10:38
Откуда: Новосибирск
ФИО: Константин

Re: МикроКонтроллер AVR начинающим - общие вопросы

Сообщение Madf » 13 ноя 2016, 16:12

thor_nsk писал(а):Поэтому для пробы сделал отдельный проект, просто АЦП в цикле.

И? Работает?

thor_nsk писал(а):после подачи питания что-то появляется в регистре АЦП и потом не меняется

Есть известный баг АВР, АЦП после первого использования (включения) выдает мусор - это просто надо учитывать (первое измерение холостое и/или использовать накопления измерения (точно не однократное снятие значения).

thor_nsk писал(а):Код прилагаю.

Честно, я на Си не пишу (Bascom), помочь конекртно в этом не могу, только в общей идеологии. С прямой адресацией АЦП по регистрам работал (в асме), там ничего сложного, если что-то не работает - значит: просто после просыпания, нужно обязательно заного конфигурировать весь МК (по крайней мере, я так и делал), т.к. всё равно, перед спячкой, для правильного сна/потребления, нужно МК весь переводить в "девственное состояние" (выключать все таймера, порты все на вход настраивать, отключать пулапы), ну и выводить его соответсвующи...

Вот пример куска кода как я это делал (как раз для тини85):

Код: Выделить всёРазвернуть
      Disable Timer0
      Config Pwr_mp3 = Input
      Config Tx = Input

      Enable Int0
      Waitms 50
      Powerdown                                             'Idle/Powerdown
      Disable Int0
      Waitms 50

      Config Tx = Output
      Config Pwr_mp3 = Output
      Reset Pwr_mp3                                         ' включения блока мп3
      Temp_word = Getadc(1)
      Temp_word = 0
      Enable Timer0

Здесь при включении, сразу делаю тестовый замер с АЦП, чтобы баг игнорить.
Вся схема настроена так, чтобы просыпаться по INT0 (через него же производится работа/измерение АЦП).
Madf
 
Сообщения: 2367
Зарегистрирован: 03 янв 2012, 12:55
Откуда: Москва
прог. языки: VB6, BASCOM, ASM...

Re: МикроКонтроллер AVR начинающим - общие вопросы

Сообщение thor_nsk » 14 ноя 2016, 12:04

Madf писал(а):
thor_nsk писал(а):Поэтому для пробы сделал отдельный проект, просто АЦП в цикле.

И? Работает?

В том-то и дело что не работает. В общих чертах что делаю:
1) ногу, с которой буду оцифровывать конфигурирую как вход;
2) выставляю делитель ЦАП, выбираю нужный вход, преобразование по команде, разрешаю прерывание по окончании ЦАП, включаю ЦАП
3) разрешаю прерывания
4) даю команду на старт ЦАП
И пункт 4 выполняю бесконечно, но кроме мусора, после старта МК, ничего не получаю.
На неделе попробую на меге16 поиграть с ЦАП. Может получится. Но хочется чтобы заработало на тиньке.
Просто сделал поливалку на ардуине нано, но решил что это жирно слишком. На тиньке получилось компактнее, но вот из-за проблем со стартом ЦАП пришлось использовать внешний датчик влажности с цифровым выходом. Но хочу домучить ЦАП :)
thor_nsk
 
Сообщения: 30
Зарегистрирован: 15 июн 2016, 10:38
Откуда: Новосибирск
ФИО: Константин

Re: МикроКонтроллер AVR начинающим - общие вопросы

Сообщение Madf » 14 ноя 2016, 14:05

Не ЦАП, а АЦП (Аналог в Цифру, не на оборот). :)
Если у вас не получается работать с АЦП через прерывание, то попробуйте обычные режимы (ручном или непрерывном), зачем вам лишний геморрой с обработкой событий, пусть оно само молотит.
Madf
 
Сообщения: 2367
Зарегистрирован: 03 янв 2012, 12:55
Откуда: Москва
прог. языки: VB6, BASCOM, ASM...

Re: МикроКонтроллер AVR начинающим - общие вопросы

Сообщение Dr.Unk » 01 дек 2016, 02:10

Приветствую.Подскажите пожалуйста, целый день пытаюсь разобраться с кодом. Задача: джойстик передает через UART данные вида (положение по осьХ, осьУ, кнопки).
На принимающей части пакет данных обрабатывается функцией sscanf(buffer, "%[^','],%[^','],%s", &strX, &strY, &key); . Кнопки отлично обрабатываются, а вот с осями проблема, .toInt() выдает некорректные результаты. Сервы не вращаются.

Код: Выделить всёРазвернуть
Передатчик
  int X = analogRead(axisX);
  int Y = analogRead(axisY);

  Serial.print(X);
  Serial.print(",");
  Serial.print(Y);
  Serial.print(",");
  Serial.println(key);
  //Serial.println('\n');


Код: Выделить всёРазвернуть
 Приемник
Servo servX;
Servo servY;
int servXPoz = 90;
int servYPoz = 0;
int valX;
int valY;
char key ;
String strX;
String strY;
  void loop() {
  int i=0;
  char buffer[12];
  if(Serial.available()){
    delay(50);
    while( Serial.available() && i< 12) {
      buffer[i++] = Serial.read();
    }
    buffer[i++]='\n';

  }
  if(i>0){
    sscanf(buffer, "%[^','],%[^','],%s", &strX, &strY, &key);
  }
  valX = strX.toInt();
  //valX = atoi(strX);
  servXPoz = map(valX, 0, 1023, 0, 180);
  servX.write(servXPoz);
  valY = strY.toInt();
  servYPoz = map(valY, 0, 1023, 0, 180);
  servY.write(servYPoz);

  moving();
}

void moving(){
  switch(key){
       case '5':
            ServPravo();
            break;

       case '4':
            ServLevo();
            break;

       case '3':
            ServCentr();
            break;
}
}

void ServPravo(){
  servXPoz = 0;
  servYPoz = 0;
  servX.write(servXPoz);
  servY.write(servYPoz);
}

void ServLevo(){
  servXPoz = 180;
  servYPoz = 0;
  servX.write(servXPoz);
  servY.write(servYPoz);
}

void ServCentr(){
  servXPoz = 90;
  servYPoz = 0;
  servX.write(servXPoz);
  servY.write(servYPoz);
}
Dr.Unk
 
Сообщения: 1
Зарегистрирован: 01 дек 2016, 01:49

Re: МикроКонтроллер AVR начинающим - общие вопросы

Сообщение Korbofos » 27 янв 2017, 18:31

Подскажите как передать массив из еprom по у указателю в функцию
Код: Выделить всёРазвернуть
eeprom char pfone_num[12];
void ip_send(char *str); 
ip_send(pfone_num); //так ничего не получается
}

CvAVR
РАБОТА, РАБОТА перейди на Федота, с Федота на его брата, а ко мне их зарплата.
Аватара пользователя
Korbofos
 
Сообщения: 300
Зарегистрирован: 15 янв 2011, 11:27
Откуда: Челябинск
прог. языки: C/C++
ФИО: Александр

Re: МикроКонтроллер AVR начинающим - общие вопросы

Сообщение loox » 28 янв 2017, 00:56

Korbofos
CVAvr:
Доступ в EEPROM, проиводится путем использования глобальных переменных с ключевым словом eeprom.
В Вашем случае удобнее использовать указатель, который будет храниться в SRAM
пример:
eeprom int data; // целая переменная, которая храниться в eeprom
void main(void)
{
int as; // целое , будет храниться в SRAM
int eeprom *pointToEeprom; // объявление указателя eeprom, сам указатель будет храниться в SRAM
data = 53; // пример прямой записи значения в eeprom
// пример, косвенная запись того же значения с использованием указателя
pointToEeprom =&data;
*pointToEeprom = 98;
as = data; //пример, непосредственное чтение из eeprom
as = *pointToEeprom; // пример, чтение с использованием указателя
}
За сим все. Спасибо loox

Добавлено спустя 2 часа 51 минуту 48 секунд:
Dr.Unk
коллега
При передаче данных между двумя устройствами, необходимо точно спроектировать протокол передачи данных:
<data><data1>,<data2>,......<признак окончания посылки>
data - byte 1 байт
data1 - int 2 байта
data2 - byte 1 байт
.....
/n - признак окончания строки
Варианты: длина посылки фиксированная, тогда при приеме можно не контролировать признак откончания строки, как в Вашем случае, и вообще его не передавать
длина строки переменная, тогда при ПРИЕМЕ необходимо проверять каждый принятый байт на признак окончания посылки.
ОЧЕНЬ ВАЖНО При передаче посылки между устройствами передаются байты. Прием данных возможен только в буфер byte или char. Обработка данных, в Вашем случае, должна начаться только после приема всей пачки данных.
Теперь о Вашей программе:
Вам будет удобнее использовать функцию приема SerialEvent, посмотрите примеры Communication - SerialEvent
С помощью этой функции вы легко организуете протокол приема данных, как при фиксированной длине , так и при ожидании признака окончания пачки данных.
При приеме используйте буфер byte (непонятно почему у Вас char)
int будет передан двумя байтами - сначала, по моему старший разряд первым,потом младший (извини не помню, проверь при тесте)
тогда int = BYTEn*256+BYTEn+1
Применяемая вами функция:
sscanf(buffer, "%[^','],%[^','],%s", &strX, &strY, &key);
работает с char а вы переслали int в виде 2-х byte в шеснадцатеричном виде.
Можно еще один Вариант - в передатчике вместо строки Serial.print(X) - напишите Serial.print(X,DEC) , тогда будете перtдавать char(ы)
Если, что то непонятно аписал, переспросите
Спасибо loox
loox
 
Сообщения: 265
Зарегистрирован: 26 мар 2008, 12:45

Пред.

Вернуться в Микроконтроллеры

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 4

Mail.ru counter