Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
inquisitor
15 / 6 / 16
Регистрация: 22.12.2015
Сообщений: 1,751
1

Переписать функцию с Arduino на Atmega8

27.11.2018, 21:01. Просмотров 1005. Ответов 32
Метки нет (Все метки)

В Arduino есть функции на СИ
Цифровой ввод/вывод
C
1
2
3
pinMode()
digitalWrite()
digitalRead()
Аналоговый ввод/вывод
C
1
2
3
analogRead()
analogReference()
analogWrite()
Хочу аналогичные сделать на Atmega8.Прошу помочь с СИ кодом.

Добавлено через 22 минуты
C
1
pinMode(1,OUTPUT);
уверен это эквивалентная запись
C
1
DDRB =|(1<<PB0);
analogWrite(1,250) по сути это ШИМ Подаем на ножку порта,установленную ранее,как выход значение от нуля до 255.
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.11.2018, 21:01
Ответы с готовыми решениями:

помогите: atmega8 + arduino + nrf24l01
Помогите подружить Atmega8 с Arduino с помощью радио передатчика nrf24l01. Уже какой день пытаюсь...

Как прошить Atmega8 с помощью Arduino Uno
Здравствуйте, уважаемые! У меня в наличии есть плата Arduino Uno (точнее ее китайская копия),...

Разница между ATMEGA8-16AI и ATMEGA8-16AU
Кто подскажет, в чем разница между ATMEGA8-16AI и ATMEGA8-16AU. Смотрю в Платане цены между ними...

AVRISP + ARDUINO mega + Arduino mini 32Khz
Помогите пожалуйста. Собирал самостоятельно Arduino mini. По не опытности ошибся при прошивке...

Переписать JS AJAX запрос к веб-серверу на Arduino на C#
На Arduino работает Веб сервер. Он формирует html-страницу, принимает AJAX запрос и отсылает ответ....

32
tatarva87
98 / 19 / 8
Регистрация: 23.03.2018
Сообщений: 94
27.11.2018, 21:15 2
Можно сделать просто: на атмеге 8 в начале майна включаешь ножку ос2 (рв3 помоему) на выход. Запускаешь шим на таймере 2 строками
C++
1
2
ASSR=0x00;
TCCR2=0b01101110;
И потом записываешь любое число от 0 до 255 в регистр OCR2 и готово. На ножке рв3 постоянно работает шим.
Единственное - период шим сигнала определяется 0 1 и 2 битом регистра Тсср2.
1
inquisitor
15 / 6 / 16
Регистрация: 22.12.2015
Сообщений: 1,751
27.11.2018, 21:38  [ТС] 3
Получается нужно
C
1
2
3
4
5
OCR2 = 250;// Output Compare Register = 250 в нашем случае это скважность шим (0 - это 0, а FF - 100 %)
ASSR=0x00;
TCCR2=0b01101110; //Fast PWM, Clear OC2 on Compare Match, clkT2S/256 (From prescaler) (реальная частота получится 8мгц/256 = 31250 гц)
TCNT2=0x00; // Timer Value = 0
TIMSK|=0x00;//
Добавлено через 5 минут
Цитата Сообщение от tatarva87 Посмотреть сообщение
И потом записываешь любое число от 0 до 255 в регистр OCR2 и готово. На ножке рв3 постоянно работает шим.
Единственное - период шим сигнала определяется 0 1 и 2 битом регистра Тсср2.
Синтаксис
analogWrite(pin, value)

Параметры
pin: порт вход/выхода на который подаем ШИМ сигнал.
value: период рабочего цикла значение между 0 (полностью выключено) and 255 (сигнал подан постоянно).
Возвращаемое значение
нет

C
1
2
3
4
5
6
7
8
9
analogWrite(pin, value)
{
DDRB =|(1<<pin);
OCR2 = value;// Output Compare Register = 250 в нашем случае это скважность шим (0 - это 0, а FF - 100 %)
ASSR=0x00;
TCCR2=0b01101110; //Fast PWM, Clear OC2 on Compare Match, clkT2S/256 (From prescaler) (реальная частота получится 8мгц/256 = 31250 гц)
TCNT2=0x00; // Timer Value = 0
TIMSK|=0x00;//
}
Если я хочу не PB3 использовать для ШИМ а любой другой.То как тогда быть?

Добавлено через 5 минут
Синтаксис
analogRead(pin)

Параметры
pin: номер порта аналогового входа с которого будет производиться считывание (0..5 для большинства плат, 0..7 для Mini и Nano и 0..15 для Mega)

Возвращаемое значение
int (0 to 1023)

А что бы получить значение ШИМ,так правильно?Или нужно PB3 и никакой др пин?

C
1
2
3
4
5
6
7
8
9
10
int value =analogRead(pin)
{
DDRB =&`(1<<pin);//на вход
 value =OCR2;// Output Compare Register = 250 в нашем случае это скважность шим (0 - это 0, а FF - 100 %)
ASSR=0x00;
TCCR2=0b01101110; //Fast PWM, Clear OC2 on Compare Match, clkT2S/256 (From prescaler) (реальная частота получится 8мгц/256 = 31250 гц)
TCNT2=0x00; // Timer Value = 0
TIMSK|=0x00;//
return value;
}
0
COKPOWEHEU
1107 / 779 / 183
Регистрация: 09.09.2017
Сообщений: 3,376
28.11.2018, 16:24 4
Цитата Сообщение от scherbakovss201 Посмотреть сообщение
pinMode(1,OUTPUT);
уверен это эквивалентная запись
DDRB =|(1<<PB0);
даже не считая того, что вторая запись просто неверная, они не эквивалентны. Вариант Ардуины гораздо более сложный и затратный.
Цитата Сообщение от scherbakovss201 Посмотреть сообщение
C++
1
2
3
4
5
6
7
8
9
analogWrite(pin, value)
{
DDRB =|(1<<pin);
OCR2 = value;// Output Compare Register = 250 в нашем случае это скважность шим (0 - это 0, а FF - 100 %)
ASSR=0x00;
TCCR2=0b01101110; //Fast PWM, Clear OC2 on Compare Match, clkT2S/256 (From prescaler) (реальная частота получится 8мгц/256 = 31250 гц)
TCNT2=0x00; // Timer Value = 0
TIMSK|=0x00;//
}
Очевидно, вы даже не пытались разобраться в коде. tatarva87 привел только инициализацию, и то не всю. Ее надо делать в самом начале main'а. А сам ШИМ должен генерироваться в прерываниях:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#define PINS_NUM 23 //столько у ATmega8 выводов общего назначения
uint8_t pwm_enable[PINS_NUM]={0}; //разрешение на генерацию ШИМ на данном выводе
uint8_t pwm_value[PINS_NUM]={0}; //величина ШИМ на данном выводе
 
void analogWrite(uint8_t pin, uint8_t value){
  pwm_enable[pin] = 1;
  pwm_value[pin] = value;
}
 
ISR(TIMER2_COMP_vect){
  static uint8_t counter = 0;
  for(uint8_t i=0; i<PINS_NUM; i++){ //перебираем все выводы и ищем те, на которых генерация разрешена
    if(pwm_enable[i]){
      if(pwm_value[i] == counter)digitalWrite(i, HIGH);
    }
  }
  coutner++;
  if(counter == 0){
    for(uint8_t i=0; i<PINS_NUM; i++){
      if(pwm_enable[i]){
        digitalWrite(i, LOW);
      }
    }
  }
}
Набросал на скорую руку, надеюсь, никому не придет в голову реализовывать такое всерьез. Зато понятно что скорость такого ШИМ не может быть высокой, что впустую отъедается куча памяти (47 байт в моем примере) и процессорного времени. Не говоря уж о жуткой неоптимальности digitalWrite(), которая еще усугубит ситуацию.
0
inquisitor
15 / 6 / 16
Регистрация: 22.12.2015
Сообщений: 1,751
28.11.2018, 18:19  [ТС] 5
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Набросал на скорую руку, надеюсь, никому не придет в голову реализовывать такое всерьез. Зато понятно что скорость такого ШИМ не может быть высокой, что впустую отъедается куча памяти (47 байт в моем примере) и процессорного времени. Не говоря уж о жуткой неоптимальности digitalWrite(), которая еще усугубит ситуацию.
Задача переписать стандартные функции с Arduino->atmega8
Цифровой ввод/вывод
C
1
2
3
pinMode()
digitalWrite()
digitalRead()
Аналоговый ввод/вывод
C
1
2
3
analogRead()
analogReference()
analogWrite()
Я вижу,что для любительских нужно действия по инициализации и установке значений повторяются,значит их можно вынести в отдельный модуль и подключить инклайдом и использовать потом в своем коде готовую ари функцию.
0
COKPOWEHEU
1107 / 779 / 183
Регистрация: 09.09.2017
Сообщений: 3,376
29.11.2018, 09:21 6
Есть ли у этой задачи практическое применение или "так задали"?
0
inquisitor
15 / 6 / 16
Регистрация: 22.12.2015
Сообщений: 1,751
29.11.2018, 11:09  [ТС] 7
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Есть ли у этой задачи практическое применение или "так задали"?
Мне нравиться arduino and atmega8.
В первом скетч создается легко с помощью функции.Вот так же хочу и в во втором МК.
0
COKPOWEHEU
1107 / 779 / 183
Регистрация: 09.09.2017
Сообщений: 3,376
29.11.2018, 12:36 8
А что мешает использовать Arduino для вашего контроллера? Ведь ардуинская среда это всего лишь avr-g++ с библиотеками. Наверняка где-то в настройках можно выбрать произвольный камень.
Но еще раз напоминаю, что производительность кода в стиле Ардуины минимум на порядок ниже нормального. И по скорости, и по объему, и по функционалу.
0
inquisitor
15 / 6 / 16
Регистрация: 22.12.2015
Сообщений: 1,751
29.11.2018, 14:57  [ТС] 9
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
А что мешает использовать Arduino для вашего контроллера? Ведь ардуинская среда это всего лишь avr-g++ с библиотеками. Наверняка где-то в настройках можно выбрать произвольный камень.
Но еще раз напоминаю, что производительность кода в стиле Ардуины минимум на порядок ниже нормального. И по скорости, и по объему, и по функционалу.
Я об этом даже не знал.
Расскажите подробнее ибо в меню выбора плат нет Atmega
0
COKPOWEHEU
1107 / 779 / 183
Регистрация: 09.09.2017
Сообщений: 3,376
29.11.2018, 15:16 10
Куда именно тыкать в среде разработки я не знаю, поскольку Ардуиной не пользовался никогда. Достаточно самодельных отладочных плат, консольного компилятора, текстового редактора и makefile'ов.
Скажем, гугл одной из первых ссылок выдал это: http://homes-smart.ru/index.php/obor...du-arduino-ide
А вообще, можете посмотреть что генерируется для "родных" проектов и воспроизвести для своего. Да хотя бы флаги для avr-g++ скопируйте.
Повторяю, весь "синтаксический сахар" Ардуины это всего лишь библиотеки для avr-g++, ими можно пользоваться и отдельно от среды разработки, из командной строки.
Подопытный у вас есть, экспериментируйте!
1
inquisitor
15 / 6 / 16
Регистрация: 22.12.2015
Сообщений: 1,751
03.12.2018, 16:34  [ТС] 11
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Вариант Ардуины гораздо более сложный и затратный.
Atmel studio6.2 ругаеться
Error 1 expected '=', ',', ';', 'asm' or '__attribute__' before 'digitalRead'

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int value  digitalRead(int pin)
{
    if(pin==0)  return PIND0;
    if(pin==1)  return PIND1;
    if(pin==2)  return PIND2;
    if(pin==3)  return PIND3;
    if(pin==4)  return PIND4;
    if(pin==5)  return PIND5;
    if(pin==6)  return PIND6;
    if(pin==7)  return PIND7;
    if(pin==8)  return PINB0;
    if(pin==9)  return PINB1;
    if(pin==10) return PINB2;
    if(pin==11) return PINB3;
    if(pin==12) return PINB4;
    if(pin==13) return PINB5;
}
Добавлено через 8 минут
Warning 1 control reaches end of non-void function [-Wreturn-type]
убрал знак равно.А как побороть варнинг?
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int  digitalRead(int pin)
{
    if(pin==0)  return PIND0;
    if(pin==1)  return PIND1;
    if(pin==2)  return PIND2;
    if(pin==3)  return PIND3;
    if(pin==4)  return PIND4;
    if(pin==5)  return PIND5;
    if(pin==6)  return PIND6;
    if(pin==7)  return PIND7;
    if(pin==8)  return PINB0;
    if(pin==9)  return PINB1;
    if(pin==10) return PINB2;
    if(pin==11) return PINB3;
    if(pin==12) return PINB4;
    if(pin==13) return PINB5;
}
0
COKPOWEHEU
1107 / 779 / 183
Регистрация: 09.09.2017
Сообщений: 3,376
03.12.2018, 17:16 12
Давайте я разверну несколько констант в вашем коде:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int  digitalRead(int pin)
{
    if(pin==0)  return 0;
    if(pin==1)  return 1;
    if(pin==2)  return 2;
    if(pin==3)  return 3;
    if(pin==4)  return 4;
    if(pin==5)  return 5;
    if(pin==6)  return 6;
    if(pin==7)  return 7;
    if(pin==8)  return 0;
    if(pin==9)  return 1;
    if(pin==10) return 2;
    if(pin==11) return 3;
    if(pin==12) return 4;
    if(pin==13) return 5;
}
Функционально он ничуть не изменился, разве что читаемость улучшилась. Вот только смысл данной функции непонятен.
Цитата Сообщение от inquisitor Посмотреть сообщение
Warning 1 control reaches end of non-void function [-Wreturn-type]
Строку с ошибкой вы назвать не удосужились, ну да ладно. Возможно, компилятору не нравится, что в качестве аргумента может быть передано 14, или 256, или -1, и при этом результат будет непредсказуемым.

Добавлено через 8 минут
Попробую отговорить от говнокода еще раз.
Вы абсолютно точно уверены, что назначение выводов может измениться во время выполнения программы? Ну то есть висит, скажем, на PD2 светодиод и вдруг раз - и переместился на PC1, уведомив (как?!) об этом программу.
Почему бы не использовать обычные макросы, разворачивающиеся на этапе компиляции, а не выполнения, как у вас, удобные в использовании (опять же, в отличии от) и с человеко-читаемыми названиями?
Arduino-style:
C
1
2
3
const int led = 9;
pinMode(led, OUTPUT);
digitalWrite(led, HIGH);
Macro-style:
C
1
2
3
#define LED C,2,1
DDR_1( LED );
PORT_ON( LED );
Ну да, нельзя передать это в функцию, но где это может пригодиться я не знаю.
0
inquisitor
15 / 6 / 16
Регистрация: 22.12.2015
Сообщений: 1,751
03.12.2018, 18:13  [ТС] 13
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Ну да, нельзя передать это в функцию, но где это может пригодиться я не знаю.
Я нашел рабочую схему+код под Arduino.Я собрал схему под catmega328p.Код откомпилировался и в протеусе все работает.
Мне нужно его в atmel studio 6.2 откомпилировать.
Я установил расширение
arduino_ide_for_atmel_studio_6.2.17.6.2502.msi
Код откомпилировал.Но протеус с его прошивкой сразу виснет и ничего не симулирует. Я бы хотел код на чистом Си под атмел переписать. Переписал сделав выше упомянутую функцию digitalRead но в протеусе не работает схема либо курсор бегает справа налева либо экран забит надписями не теми,что нужно.А по факту под атмел студио нужен код ля симуляции в протеусе енкодера,то есть считать угол поворота угла положения вала на двигателе.
0
COKPOWEHEU
1107 / 779 / 183
Регистрация: 09.09.2017
Сообщений: 3,376
04.12.2018, 11:07 14
Вот как тот код можно переделать под макросы:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <avr/io.h>
#include "../modules/pinmacro.h"
#define LCD_DATA C,1
#define LCD_RS D,6
#define LCD_E D,5
#include "../modules/lcd.h"
#define INPA B,3
#define INPB B,4
#define BTN B,0,0
 
//в моей версии библиотеки нет вывода чисел, поэтому простой вариант реализуем сейчас
void lcd_u2(uint8_t val){
  uint8_t hb = val / 10;
  val %= 10;
  if(hb == 0)lcd_data(' '); else lcd_data(hb+'0');
  lcd_data(val+'0');
}
 
int main(){
  int8_t counter = 50;
  uint8_t aState=0;
  uint8_t aLastState=0;
  lcd_init();
  lcd_cur_hide();
  DDR_0( INPA );
  DDR_0( INPB );
  DDR_0( BTN ); PORT_1( BTN );
  lcd_goto(0);
  while(1){
    lcd_goto(0);
    lcd_str_P(PSTR("Count: "));
    lcd_u2(counter);
    if( PIN_ON( BTN ))counter = 50;
    aState = (!!PIN_1( INPA ));
    if(aState != aLastState){
      if((!!PIN_1( INPB )) != aState){
        counter++;
      }else{
        counter--;
      }
      if(counter >= 100)counter = 0;
         else if(counter < 0)counter = 99;
      aLastState = aState;
    }
  }
}
Разумеется, готовые библиотеки у меня есть.
В протеусе проверил, вроде работает.
1
inquisitor
15 / 6 / 16
Регистрация: 22.12.2015
Сообщений: 1,751
04.12.2018, 13:45  [ТС] 15
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
В протеусе проверил, вроде работает.
Не работает в протеусе.Код откомпилировал в atmel studio 6 успешно.
В архиве проект протеусе 7.7+проект atmel studio(исходник+прошивка)
0
Вложения
Тип файла: rar atmega328p_4bit_lcd_v6.rar (47.8 Кб, 1 просмотров)
COKPOWEHEU
1107 / 779 / 183
Регистрация: 09.09.2017
Сообщений: 3,376
04.12.2018, 14:23 16
Жаль, вы не выложили схему (у меня протеус 7.6 и ваш формат не открывает, да и это в любом случае неудобно).
У себя пересобрал под m328 с вашими настройками, все работает. Из предположений что может пойти не так:
- питание на AVCC (оно должно быть чтобы работали порты С)
- земля на R/W (просто болтаться в воздухе нельзя)
ну и надеюсь, с выводами не ошиблись: D4 на PC1, D5-PC2, D6-PC3, D7-PC4
1
inquisitor
15 / 6 / 16
Регистрация: 22.12.2015
Сообщений: 1,751
04.12.2018, 14:50  [ТС] 17
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Жаль, вы не выложили схему (у меня протеус 7.6 и ваш формат не открывает, да и это в любом случае неудобно).
У себя пересобрал под m328 с вашими настройками, все работает. Из предположений что может пойти не так:
- питание на AVCC (оно должно быть чтобы работали порты С)
- земля на R/W (просто болтаться в воздухе нельзя)
ну и надеюсь, с выводами не ошиблись: D4 на PC1, D5-PC2, D6-PC3, D7-PC4
Приложите ваш протеус,у меня есть 7.7 и 8.6
0
COKPOWEHEU
1107 / 779 / 183
Регистрация: 09.09.2017
Сообщений: 3,376
04.12.2018, 15:04 18
Лучший ответ Сообщение было отмечено inquisitor как решение

Решение

Проверяйте
1
Вложения
Тип файла: rar encoder_lcd.rar (60.2 Кб, 1 просмотров)
inquisitor
15 / 6 / 16
Регистрация: 22.12.2015
Сообщений: 1,751
04.12.2018, 15:49  [ТС] 19
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Проверяйте
Проверил работает.
Разрешите еще вопрос.Как в протеусе смоделировать зарядку 12v батареи?
Схему и код прилагаю. Если можно подправить с выводом на дисплей.
sketch_nov30a.rar
0
COKPOWEHEU
1107 / 779 / 183
Регистрация: 09.09.2017
Сообщений: 3,376
04.12.2018, 16:04 20
Цитата Сообщение от inquisitor Посмотреть сообщение
Проверил работает.
И где была ошибка?
Цитата Сообщение от inquisitor Посмотреть сообщение
Как в протеусе смоделировать зарядку 12v батареи?
Сомневаюсь, что там реализованы аккумуляторы, но можете смоделировать через "батарейку" (cell) и переменный резистор чтобы имитировать напряжение батареи разной степени заряженности.
Схема вроде бы нормальная, а вот о качестве кода говорит уже количество goto. Хотя форматирование неплохое и комментарии есть. Я бы посоветовал вам помедитировать немного (чтобы не заразиться этими goto) над кодом и написать свой, без использования ардуинских функций. Единственная проблема, которая может у вас с этим возникнуть - analogRead(). Для его замены стоит внимательно почитать Евстифеева "Микроконтроллеры AVR семейства mega" (лучший из известных мне справочников по AVR), особенно раздел об АЦП.
То что получится выкладывайте сюда, я уверен что найду что улучшить.
1
04.12.2018, 16:04
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.12.2018, 16:04

Модуль распознавания речи + Arduino Pro mini + Arduino MP3-Sheild
Список компонентов: 1).Модуль распознавания речи.(напряжение питания от 4,5 до 5,5 Вольт DC)...

Arduino UNO. Как работать c RFID-сканнером и Arduino на одном Serial-порту?
Рас уж тут речь зашла об ардуине и многопоточности COM порта, думаю могу обратиться именно сюда за...

Arduino uno + arduino ethernet + delphi для чайников
Доброго времени суток. У меня такая задача нужно реализовать программу на Delphi которая...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru