реклама на сайте
подробности

 
 
> Счетчик на 2313, счетчик импульсов
Aleksandr_des
сообщение Nov 24 2008, 14:53
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 47
Регистрация: 16-06-08
Из: Челны
Пользователь №: 38 318



Прошу не закидывать камнями, это мой первый проект.
Взялся за задачу.
Счетчик на авр. В качестве камня решил взять 2313. дисплей взял тот что был в протеусе.
Импульсы приходят с частотой 1 мегагерц. Отрабатывают на прерывания. Так же будет кнопка на обнуление. Данный прибор хочу поставить на линию, счетчик готовой продукции.
Программную среду решил использовать CAVR ,брался за ИАР но не осилил жки модуль(в программировании я тоже не силен).
В общем накидал такую схемку.
Код получился такой.
Код
#include <90s2313.h>
#asm
   .equ __lcd_port=0x18;PORTB
#endasm
#include <lcd.h>
#include <delay.h>
#include <stdio.h>
char i;
interrupt [EXT_INT0] void ext_int0_isr(void)
{
}

interrupt [EXT_INT1] void ext_int1_isr(void)
{

i++;
lcd_putchar(i);
delay_ms(20);
lcd_clear();

}

void main(void)
{

PORTD=0xff;
DDRD=0x00;
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Rising Edge
// INT1: On
// INT1 Mode: Rising Edge
GIMSK=0xC0;
MCUCR=0x0F;
GIFR=0xC0;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;


// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;

// LCD module initialization
lcd_init(16);

// Global enable interrupts
#asm("sei")

while (1)
      {
    
      };
}


В общем он на жки выводит символы, 123..abc.. и т.д
А надо счет, максимальная цифра 1000 000.
Подскажите что не так?
Эскизы прикрепленных изображений
Прикрепленное изображение
 


--------------------
www.ea16.ru
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 19)
_Pasha
сообщение Nov 24 2008, 15:51
Сообщение #2


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(Aleksandr_des @ Nov 24 2008, 18:53) *
Код получился такой.
Код
/************************/
char i;
interrupt [EXT_INT0] void ext_int0_isr(void)
{
}

interrupt [EXT_INT1] void ext_int1_isr(void)
{

i++;
lcd_putchar(i);
delay_ms(20);
lcd_clear();

}

В общем он на жки выводит символы, 123..abc.. и т.д
А надо счет, максимальная цифра 1000 000.
Подскажите что не так?

Дык, все не так.
1.Для того чтоб посчитать до 10^6 надо переменную типа long
2. lcd_putchar(i); выводит char - вам же надо вывести long
Исправляйте кривизну, и удачи! smile.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Nov 24 2008, 16:32
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(_Pasha @ Nov 24 2008, 18:51) *
Дык, все не так.

Вот именно, что ВСЕ, начиная с попытки вывести на дисплейчик цифири С ЧАСТОТОЙ В МЕГАГЕРЦ в обработчике прерывания да еще ДОПОЛНИТЕЛЬНО сделав задержечку в нем-же на 20MS. Короче даже и говорить не совершенно не о чем.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Aleksandr_des
сообщение Nov 26 2008, 13:24
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 47
Регистрация: 16-06-08
Из: Челны
Пользователь №: 38 318



Переписал все.
Код
#include <90s8535.h>
#include <delay.h>
#include <stdio.h>
// Alphanumeric LCD Module functions
#asm
   .equ __lcd_port=0x15;PORTC
#endasm
#include <lcd.h>
long i;
char lcd_buffer[33];
interrupt [EXT_INT1] void ext_int1_isr(void)
{
i++;
}


void main(void)
{
GIMSK=0xC0;
MCUCR=0x0E;
GIFR=0xC0;
lcd_init(16);
#asm("sei")
while (1)
      {
      
     sprintf(lcd_buffer,i);
      lcd_puts(lcd_buffer);
      delay_ms(50);
      lcd_clear();

      };
}


Подскажите пожалуйста как перевести значение переменной long в char?


--------------------
www.ea16.ru
Go to the top of the page
 
+Quote Post
Nemo2000
сообщение Nov 26 2008, 13:41
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 79
Регистрация: 8-04-05
Из: Санк-Петербург
Пользователь №: 3 972



Да не long в char вам переводить надо, а понять, что же вы хотите увидеть. Счет с частотой в 1 МГц? Даже если бы ЖКИ и позволил с такой частотой обновлять инфу, вы уверены, что что-нить на нем разобрали бы? smile.gif
Go to the top of the page
 
+Quote Post
Aleksandr_des
сообщение Nov 26 2008, 13:53
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 47
Регистрация: 16-06-08
Из: Челны
Пользователь №: 38 318



Цитата(Nemo2000 @ Nov 26 2008, 16:41) *
Да не long в char вам переводить надо, а понять, что же вы хотите увидеть. Счет с частотой в 1 МГц? Даже если бы ЖКИ и позволил с такой частотой обновлять инфу, вы уверены, что что-нить на нем разобрали бы? smile.gif

Задержка разве не позволит увидеть?, не надо же фиксировать значение в онлайне, но зато можно посмотреть какая сотня или тысяча идет. Или например в момент остановки счета.


--------------------
www.ea16.ru
Go to the top of the page
 
+Quote Post
vik0
сообщение Nov 26 2008, 14:03
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 27-07-08
Из: теплые края
Пользователь №: 39 233



Значительно лучше.

Цитата(Aleksandr_des @ Nov 26 2008, 15:53) *
Подскажите пожалуйста как перевести значение переменной long в char?

sprintf(lcd_buffer, "%ld", i);

И еще. Не
long i;
а
volatile long i;
Go to the top of the page
 
+Quote Post
Nemo2000
сообщение Nov 26 2008, 14:30
Сообщение #8


Частый гость
**

Группа: Свой
Сообщений: 79
Регистрация: 8-04-05
Из: Санк-Петербург
Пользователь №: 3 972



Цитата(Aleksandr_des @ Nov 26 2008, 17:53) *
Задержка разве не позволит увидеть?, не надо же фиксировать значение в онлайне, но зато можно посмотреть какая сотня или тысяча идет. Или например в момент остановки счета.


Сотня пролетает за 100мкс, тысяча - за 1мс... что с учетом задержки в 50мс выглядит тоже не очень понятно, впрочем дело ваше.

1. long i как уже и советовали заменить на
volatile unsigned long i (маск значение 4294967296)

2.char lsd_buffer[33]
33 из каких соображений? Если выводить только i то там максимум 10 знаков. кроме этого так же добавил бы unsigned char lsd_...

3.lsd_puts в качестве аргумента принимает char? (сам не знаю, но так написано у _Pasha)
если да то вывод написать чуть по другому
Код
for (j = 0; j < 10, j++)
{
   lsd_puts(lsd_buffer[j]);
}

как-то так.
Go to the top of the page
 
+Quote Post
vik0
сообщение Nov 26 2008, 14:46
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 27-07-08
Из: теплые края
Пользователь №: 39 233



Цитата(Nemo2000 @ Nov 26 2008, 16:30) *
добавил бы unsigned char lsd_...

Эээ.. А зачем?

Цитата
3.lsd_puts в качестве аргумента принимает char? (сам не знаю, но так написано у _Pasha)
если да то вывод написать чуть по другому
Код
for (j = 0; j < 10, j++)
{
   lsd_puts(lsd_buffer[j]);
}

как-то так.

В исходном варианте использовалась lcd_putchar(). В исправленном - lcd_puts(), которая, как я подозреваю, выводит строку целиком.
Go to the top of the page
 
+Quote Post
vvs157
сообщение Nov 26 2008, 14:58
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 526
Регистрация: 8-04-05
Пользователь №: 3 960



Цитата(Aleksandr_des @ Nov 24 2008, 17:53) *
Импульсы приходят с частотой 1 мегагерц.
Максимальная тактовая частота 2313 - 20 МГц, следовательно в обработчике прерываний можно находиться менее 16 тактов, в противном случае будет пропуск импульсов. В <16 тактов предобразование + вывод на LCD не впишется даже на асме. Вам надо использовать внутренний счетчик, или если оба внутренних заняты, ставить внешний счетчик на жесткой логике к тому же с буферной защелкой выхода
Go to the top of the page
 
+Quote Post
Nemo2000
сообщение Nov 26 2008, 15:12
Сообщение #11


Частый гость
**

Группа: Свой
Сообщений: 79
Регистрация: 8-04-05
Из: Санк-Петербург
Пользователь №: 3 972



Цитата(vik0 @ Nov 26 2008, 18:46) *
Эээ.. А зачем?

я так думаю (с) smile.gif коды символов - они беззнаковые, посему на мой взгляд, так будет правильнее, на истину в последней инстанции не претендую smile.gif
Цитата
В исходном варианте использовалась lcd_putchar(). В исправленном - lcd_puts(), которая, как я подозреваю, выводит строку целиком.

Не заметил. Виноват, исправлюсь smile.gif
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Nov 26 2008, 15:35
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата
И еще. Не
long i;
а
volatile long i;


Попутно спрошу а почему именно volatile?
И обязательно-ли для всех переменных что используються в прерываниях использовать этот квалификатор?
Go to the top of the page
 
+Quote Post
Aesthete Animus
сообщение Nov 26 2008, 17:59
Сообщение #13


Местный
***

Группа: Свой
Сообщений: 222
Регистрация: 9-06-07
Пользователь №: 28 317



Цитата(mempfis_ @ Nov 26 2008, 18:35) *
Попутно спрошу а почему именно volatile?

"volatile" дает компилятору понять, что переменная может измениться неизвестным для него (компилятора) образом.

Например, есть такая ситтуация.
Код
int i;

ISR (SOME_SIGNAL_vect)
{
    i = 0xFF;
}

int main(void)
{
    ...
    i = 0; // Читаем переменную из памяти
    
    some_wait(); // Чего то ждем

    some_routine(i); // Какая-та функция, использующая i
    ...
}

Если во время some_wait будет вызвано прерывание, то i изменится. Но компилятор оптимизирует обращения к переменным и после операции "i = 0" значение i уже находится в регистрах, так что повторного чтения i перед вызовом some_routine не происходит, в результате some_routine будет вызвано со старым i.

Что бы такого не происходило, используют volatile. Это указывает компилятору, что обращение к переменной оптимизировать не надо.

Цитата(mempfis_ @ Nov 26 2008, 18:35) *
И обязательно-ли для всех переменных что используються в прерываниях использовать этот квалификатор?

Как Вы наверное понимаете, необходимость объявлять как volatile, с прерыванием связана косвено.
Go to the top of the page
 
+Quote Post
vik0
сообщение Nov 26 2008, 18:09
Сообщение #14


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 27-07-08
Из: теплые края
Пользователь №: 39 233



Цитата(mempfis_ @ Nov 26 2008, 17:35) *
Попутно спрошу а почему именно volatile?

Если по-простому, то это - информация для компилятора, указывающая на то, что значение переменной может быть изменено в любой момент.
Цитата
И обязательно-ли для всех переменных что используються в прерываниях использовать этот квалификатор?

Да, если переменная используется где-либо еще.
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Nov 27 2008, 08:50
Сообщение #15


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Спасибо за ответ . Суть понял - volatile указывает компилятору что значения переменной нужно постоянно брать из оперативной памяти и сохранять туда-же при изменениях (т.е. постоянно обновлять их при использовании).
Объявил в своей программе часть глобальных переменных, которые исп. в разных подпрограммах, как volatile. В одних случаях код вообще не меняется, а в других появляются сообщения типа:
Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement
когда пытаюсь передать volatile глобальную переменную как параметр функции.
Почему компилятор считает что эта глобальная переменная "в соответствии с volatile-доступом неопределена в этом выражении"?
Пользуюсь IAR5.10A.
Go to the top of the page
 
+Quote Post
vik0
сообщение Nov 27 2008, 08:57
Сообщение #16


Местный
***

Группа: Свой
Сообщений: 381
Регистрация: 27-07-08
Из: теплые края
Пользователь №: 39 233



Цитата(mempfis_ @ Nov 27 2008, 10:50) *
В одних случаях код вообще не меняется,

А вы оптимизацию включите smile.gif
Цитата
а в других появляются сообщения типа:
Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement
когда пытаюсь передать volatile глобальную переменную как параметр функции.

Кусок кода привели бы...
Цитата
Почему компилятор считает что эта глобальная переменная "в соответствии с volatile-доступом неопределена в этом выражении"?

Нет. "порядок доступа к volatile переменным не определен в данном выражении"
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Nov 27 2008, 10:28
Сообщение #17


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата
А вы оптимизацию включите

Подобное предупреждение выскакивает при любых уровнях оптимизации

Цитата
Кусок кода привели бы...


Полный код привести не могу (он очень большой)
Работает он приблизительно так как приведено ниже (только проверок внутри State1, State2 больше):

Код
#define time1 10
#define time2 20
unsigned int timer;

#define state1 0
#define state2 1

//прерывание от ТС1 по совпадению с автосбросом
#pragma vector=TIMER1_COMPA_vect
__interrupt void TIMER1_COMPA_IRQ(void)
{
  //сканирование кнопки
  Button_Scun();
}

void GoToState1(unsigned int t)
{
SaveLog(t);
timer = 0;
state = state1;
}

void GoToState2(unsigned int t)
{
SaveLog(t);
timer = 0;
state = state2;
}

void State1(void)
{
timer++;
if(timer > time1) GoToState2(timer);
}

void State2(void)
{
timer++;
if(timer > time2) GoToState1(timer);
}

void main(void)
{
state = state1;
timer=0;

for(;;)
{
__watchdog_reset();
__enable_interrupt();
__sleep();

switch(state)
{
case state_1: State1();
break;

case state_2: State2();
break;
}

}

}



Цитата
Нет. "порядок доступа к volatile переменным не определен в данном выражении"

Сорри быстро и невнимательно прочитал smile.gif
Go to the top of the page
 
+Quote Post
Aesthete Animus
сообщение Nov 27 2008, 17:35
Сообщение #18


Местный
***

Группа: Свой
Сообщений: 222
Регистрация: 9-06-07
Пользователь №: 28 317



Цитата(mempfis_ @ Nov 27 2008, 13:28) *
Подобное предупреждение выскакивает при любых уровнях оптимизации
Полный код привести не могу (он очень большой)
Работает он приблизительно так как приведено ниже (только проверок внутри State1, State2 больше)

Извините, но из того куска кода, что Вы показали, я (видимо не я один) не понял, как он должен работать и уж тем более что в нем не работает. Тем более не ясно, как это вообще связано с volatile.
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Nov 28 2008, 08:32
Сообщение #19


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



Цитата(Aesthete Animus @ Nov 27 2008, 21:35) *
Извините, но из того куска кода, что Вы показали, я (видимо не я один) не понял, как он должен работать и уж тем более что в нем не работает. Тем более не ясно, как это вообще связано с volatile.

Изначально я просто поинтересовался в чём суть volatile и вы и vik0 всё доступно разъяснилиsmile.gif Код у меня рабочий но привести его не могу из-за размеров (ну ещё из-за того что это коммерческий проект smile.gif). В моём коде используется много глобальных переменных (без volatile). Некоторые из них спокойно переносят присваивание им квалификатора volatile, а для некоторых появляется ошибка приведённая выше (а именно у тех которые передаются как параметры в функции). Но в любом случае hex-файл прошивки получается один в один что с volatile что без smile.gif
Спасибо всем ответившим на мой вопрос.
Думаю стоит помоч топикстартеру с реализацией его идеи.
Go to the top of the page
 
+Quote Post
mempfis_
сообщение Nov 28 2008, 08:32
Сообщение #20


Профессионал
*****

Группа: Свой
Сообщений: 1 001
Регистрация: 27-06-06
Пользователь №: 18 409



""

Сообщение отредактировал mempfis_ - Nov 28 2008, 08:36
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 22:25
Рейтинг@Mail.ru


Страница сгенерированна за 0.01585 секунд с 7
ELECTRONIX ©2004-2016