CodeVision AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение WiseLord »

rusl32 писал(а):// смотрим десятые здесь выводит одно из temper_d
rusl32 писал(а):// смотрим темп здесь уже выводит другое из temper_d
Потому как это могут оказаться данные от разных замеров из-за задержек в коде. И отличаться на те самые десятые.

Допустим в [0] - некое число А, в [1] - число B
По коду получается:

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

Замер 1
i = 0                                    A1   --
Выводим A одним способом                 --   --
пауза 2 секунды                           пауза
 выводим A другим способом                      
i = 1                                    A1   A1
Выводим B одним способом                 B1   --
пауза 2 секунды                           пауза
выводим B другим способом
                                         A1   A1
пауза 2 секунды                          B1   B1
                                          пауза
Замер 2
i = 0                                    A2   A1
Выводим A одним способом                 B1   B1
пауза 2 секунды                           пауза
 выводим A другим способом               
i = 1                                    A2   A2
Выводим B одним способом                 B2   B1
пауза 2 секунды                           пауза
выводим B другим способом
                                         A2   A2
пауза 2 секунды                          B2   B2
                                          пауза
Замер 3
i = 0                                    A3   A2
Выводим A одним способом                 B2   B2
пауза 2 секунды                           пауза
 выводим A другим способом               
i = 1                                    A3   A3
Выводим B одним способом                 B3   B2
пауза 2 секунды                           пауза
выводим B другим способом
                                         A3   A3
пауза 2 секунды                          B3   B3
То есть из-за наличия кучи пауз в самые неправильные моменты на экране показания "одним" способом и "другим" отличаются. Что и выглядит, возможно, как "прыгающие" десятые.
Выбросьте весь этот мусор из кода. Один раз посчитайте всё, выведите. И никаких пауз между разными выводами на экран. Иначе вперемешку данные от разных замеров и разных датчиков.

Самым правильным алгоритмом будет что-то вроде такого:

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

uint16_t tempTimer;
...
interrupt_... {
  if (tempTimer)
    tempTimer--;
}
....
main() {
  ...
  if (tempTimer == 0) {
    tempTimer = 750; // запускаем таймер на 750 миллисекунд,
    getDataFromSensors(); // вычитываем из датчиков последние данные в буфер
    startNewMeasure(); // запускаем новый замер, данные будут готовы через 750мс, там их снова заберём и обновим буфер
  }

  // Выводим данные
}
Всё.. Никаких задержек. Данные на дисплей будут выводиться часто, а раз в 750 мс будет "стартовать" новый цикл уменьшения tempTimer от 750мс до 0, и при достижении 0 обновлять готовые данные в некоем буфере
Реклама
rusl32
Родился
Сообщения: 17
Зарегистрирован: Вс окт 25, 2015 19:09:46

Re: CodeVision AVR в вопросах и ответах

Сообщение rusl32 »

WiseLord писал(а):
rusl32 писал(а):// смотрим десятые здесь выводит одно из temper_d
rusl32 писал(а):// смотрим темп здесь уже выводит другое из temper_d
Потому как это могут оказаться данные от разных замеров из-за задержек в коде. И отличаться на те самые десятые.


Всё.. Никаких задержек. Данные на дисплей будут выводиться часто, а раз в 750 мс будет "стартовать" новый цикл уменьшения tempTimer от 750мс до 0, и при достижении 0 обновлять готовые данные в некоем буфере

Я понимаю, что там не самый оптимальный код. Вопрос не в оптимальности. Пост выше -- это кусок кода без изъятий, другими словами выполняется как написано без переходов, строка за строкой. И никаких переходов и прерываний, во время паузы -пауза, измерений, вычислений и других действий с переменной не происходит. Вопрос почему выводимое значение переменной меняется если сама переменная не изменялась. Может есть какие подводные камни в использовании индексов переменных? Если индекс меняется в диапазоне 0-1 - с нулевым индексом глючит, если в диапазоне 1-2 всё как надо.
Реклама
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение WiseLord »

rusl32 писал(а):Вопрос почему выводимое значение переменной меняется если сама переменная не изменялась.
В том-то и прикол, что изменялась, потому что в ней данные от другого измерения.

Вот простой псевдокод:

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

while(1) {
  for (i = 0; i < 10; i++) {
    sеXY(0,0);
    printt(i);

    delay_ms(1000);

    setXY(4,0);
    print(i);
  }
}
Как думаете, что будет отображаться на экране раз в секунду:

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

0   0
1   1
2   2
...
8   8
9   9
0   0
?
А вот и нет, будет отображаться

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

1   0
2   1
3   2
...
9   8
0   9
1   0
rusl32
Родился
Сообщения: 17
Зарегистрирован: Вс окт 25, 2015 19:09:46

Re: CodeVision AVR в вопросах и ответах

Сообщение rusl32 »

WiseLord писал(а):
rusl32 писал(а):Вопрос почему выводимое значение переменной меняется если сама переменная не изменялась.
В том-то и прикол, что изменялась, потому что в ней данные от другого измерения.
В чем прикол? Почему так? "i"внутри цикла в произвольный момент изменяется?
Только что опробовал. Тут всё корректно (постом выше). У меня другая тема.

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

while(1){
получаем массив значений измерений;
чистим дисплей;
    for(i=0,i<2,i++){
     znach[i]=как то вычисляем из массива значений с индексом [i];
     показываем что насчитали в znach[i] на i - ной строке в позиции 11;
      пауза на чтение;
      ещё раз показываем что в znach[i] на i - ной строке в позиции 3;;

   }
  пауза на чтение;
}
В результате получаю на одной строке результаты строго одного и того же измерения. И если for начинается с нуля они оказываются разными, если с 1 одинаковыми :dont_know:
Реклама
Эиком - электронные компоненты и радиодетали
kotriks
Грызет канифоль
Сообщения: 274
Зарегистрирован: Чт апр 28, 2011 15:08:58

Re: CodeVision AVR в вопросах и ответах

Сообщение kotriks »

народ как заставить код выполняться 5 раз после чего блокировать какое либо выполнения кода? делал так не получилось.

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

unsigned char i=demo;
for( i=0; i<5; i++ ) {demo==5;  }
вставляю в код для выполнения
эфект тот же ))
Реклама
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение WiseLord »

Какой код? demo это не код, это переменная. Что Вы хотите увидеть, просто вставив её как demo; в код?

Можно так, например:

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

void someFunction() {
  static uint8_t i = 0;
  if (i < 5) {
    doSomething();
    i++;
  }
}
Функцию someFunction() можно вызывать сколько угодно раз, но doSomething() выполнится не более 5 раз, после чего будет пропускаться.
Последний раз редактировалось WiseLord Сб авг 06, 2016 08:32:29, всего редактировалось 1 раз.
Реклама
kotriks
Грызет канифоль
Сообщения: 274
Зарегистрирован: Чт апр 28, 2011 15:08:58

Re: CodeVision AVR в вопросах и ответах

Сообщение kotriks »

WiseLord писал(а):Какой код? demo это не код, это переменная.

Можно так, например:

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

void someFunction() {
  static uint8_t i = 0;
  if (i < 5) {
    doSomething();
    i++;
  }
}
Функцию someFunction() можно вызывать сколько угодно раз, но doSomething() выполнится не более 5 раз, после чего будет пропускаться.
спасибо, а как это будет выглядеть со вставкой переменно а не с функцией doSomething()?
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение WiseLord »

А если по-русски? Вы же хотели код выполнять не более N раз. При чём тут переменно или постоянно?
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: CodeVision AVR в вопросах и ответах

Сообщение COKPOWEHEU »

Учитывая вот этот бред

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

for( i=0; i<5; i++ ) {demo==5;  }
вставляю в код для выполнения
автор думает, что переменную можно выполнять. Чего он пытался добиться этими кусками ведомо одному ему. Так что ждем нормальной формулировки задачи.
Аватара пользователя
WiseLord
Друг Кота
Сообщения: 4905
Зарегистрирован: Чт апр 11, 2013 11:19:59
Откуда: Минск
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение WiseLord »

Судя по последним двум страницам форума - не дождёмся. Человек просто не понимает, чего конкретно он хочет, не различает переменные динамические и статические, да и вообще разницу между функциями и переменными, как видим, не улавливает.
TovarishStan
Родился
Сообщения: 1
Зарегистрирован: Чт окт 30, 2014 16:35:04

Re: CodeVision AVR в вопросах и ответах

Сообщение TovarishStan »

Всем доброго дня!

Решил тут разработать один девайс, но для его работы требуется посчитать импульсы. Ну, выходит, частотомер сперва надо сделать.

Всё хорошо, кроме одного - измеряет частоту до 65кГц с копейками. Ясен пень, вопрос в переменной, но они у меня указаны все как long int.

Я недавно только программирую, так что, если можно, поподробнее и с деталями) Прилагаю кусок кода (в спойлере).

P.S. Думаю, это не важно, но пишу в CVAVR на Atmega8A.
Спойлер

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


#include <mega8.h>
#include <stdio.h>
#include <glcd.h>
#include <font5x7.h>

long int COUNT=0; //счётчик переполнения Таймера0 (считает вх импульсы)
long int FREQ=0; //переменная частоты
long int Counter=0;
long int TTT=0;

unsigned char RES[10];

// Прерывание Таймера0
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
COUNT++;
}

// Прерывание Таймера1
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
//TTT=(int)TCNT0;
TTT=TCNT0;
Counter=COUNT;

RES[1]=0;
       RES[0]=0;
       RES[2]=0;
       RES[3]=0;
       RES[4]=0;
       RES[5]=0;
       RES[6]=0;
       RES[7]=0;
       RES[8]=0;
       RES[9]=0; 

TCNT0=0x00;
COUNT=0;            
}

void main(void)
{
GLCDINIT_t glcd_init_data;
(настройки портов опустил)
(Настройки Таймеров опустил)
// Global enable interrupts
#asm("sei")

while (1)
      {        
       FREQ=Counter*256+TTT;
       sprintf(RES,"%10u",FREQ);

         glcd_outtextxyf(0,20,"Fruequency is");  
         glcd_outtextxy(0,30,RES);                    
      }
}

Аватара пользователя
lkote68
Прорезались зубы
Сообщения: 231
Зарегистрирован: Пн мар 30, 2009 15:58:32
Откуда: Украина Запорожье

Re: CodeVision AVR в вопросах и ответах

Сообщение lkote68 »

Привет народ.
Ежели посмотреть ассемблерный код, то можно обнаружить что:
PORTD.5 = 1; раскрывается как
SBI 0x12,5
соответственно
PORTD.5 = 0; раскрывается как
CBI 0x12,5
Кто знает где лежат макросы раскрытия?
Аватара пользователя
pyzhman
Друг Кота
Сообщения: 7016
Зарегистрирован: Вс июл 12, 2009 19:15:29
Откуда: Ижевск
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение pyzhman »

Первым читать до разделительной черты или после?
Docendo discimus
Аватара пользователя
lkote68
Прорезались зубы
Сообщения: 231
Зарегистрирован: Пн мар 30, 2009 15:58:32
Откуда: Украина Запорожье

Re: CodeVision AVR в вопросах и ответах

Сообщение lkote68 »

И до и после черты информативно :)
Аватара пользователя
COKPOWEHEU
Говорящий с текстолитом
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Re: CodeVision AVR в вопросах и ответах

Сообщение COKPOWEHEU »

lkote68 писал(а): PORTD.5 = 0; раскрывается как
CBI 0x12,5
Кто знает где лежат макросы раскрытия?
Нигде. Этим занимается компилятор и оптимизатор. Если перевести с cvavr на Си, получится

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

PORTD &=~(1<<5);
без оптимизации это выглядит как

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

in РОН, PORTD
andi РОН, 0b11011111
out PORTD, РОН
а с оптимизацией эта комбинация меняется на одну ассемблерную команду

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

cbi PORTD, 5
Аватара пользователя
lkote68
Прорезались зубы
Сообщения: 231
Зарегистрирован: Пн мар 30, 2009 15:58:32
Откуда: Украина Запорожье

Re: CodeVision AVR в вопросах и ответах

Сообщение lkote68 »

нда, но насколько я в теме codevision по идее компилятора не имеет. Он транслирует С в Аsm а потом его ассемблирует при помощи avrasm2.exe
Вот и выражение PORTD.5 = 0 это сишное предложение codevisiona. По идее его переводить на С нет необходимости. А когда залезаем в xxx.asm
то видим там вместо PORTD.5 = 0 CBI 0x12,5. Я почему спросил мне хочется как то это дело изменить и сделать доступ к пину по индексу типа PORTD[indx] иди как то так
Чтобы написать одну функцию и передавать ей пин и порт как параметр. Вот думал пойти по пути изменения этой лексемы.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: CodeVision AVR в вопросах и ответах

Сообщение ARV »

lkote68 писал(а):Он транслирует С в Аsm а потом его ассемблирует при помощи avrasm2.exe
а вот этим самым разве не компилятор занимается? ;)
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
uk8amk
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Re: CodeVision AVR в вопросах и ответах

Сообщение uk8amk »

lkote68 писал(а):мне хочется как то это дело изменить и сделать доступ к пину по индексу типа PORTD[indx] иди как то так
Чтобы написать одну функцию и передавать ей пин и порт как параметр.
Ох уж эта ардуина
https://github.com/watterott/Arduino-Li ... riteFast.h
Аватара пользователя
lkote68
Прорезались зубы
Сообщения: 231
Зарегистрирован: Пн мар 30, 2009 15:58:32
Откуда: Украина Запорожье

Re: CodeVision AVR в вопросах и ответах

Сообщение lkote68 »

Ну в принципе и Вы(ARV) и я правы "Компиля́ция — трансляция программы, составленной на исходном языке высокого уровня, в эквивалентную программу на низкоуровневом языке, близком машинному коду (абсолютный код, объектный модуль, иногда на язык ассемблера)"
Аватара пользователя
lkote68
Прорезались зубы
Сообщения: 231
Зарегистрирован: Пн мар 30, 2009 15:58:32
Откуда: Украина Запорожье

Re: CodeVision AVR в вопросах и ответах

Сообщение lkote68 »

uk8amk. Ох уж эта ардуина, зверюга однако - работает :) #define SetPortBit(port, bit) port = port|(1UL<<(bit))

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

......
SetPortBit(PORTD, 5);
......
Ответить

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