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

 
 
> Многопоточность на attiny2313
aivs
сообщение Apr 6 2013, 21:15
Сообщение #1


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

Группа: Участник
Сообщений: 114
Регистрация: 3-10-09
Пользователь №: 52 731



Продолжаю изучать программирование под avr.
Написал программу "Часы", добавил три кнопки для выставления времени, кнопки обрабатываются по прерыванию от Таймера каждые 0.1 сек, время тикает от того же таймера, все красиво и четко работает.
Затем я задействовал термодатчик ds18b20 с шиной 1ware и написал программу для показа температуры на дисплее hd44780, датчик опрашивается по прерыванию от таймера каждые 0.1 сек, прекрасно работает.
А затем я решил совместить эти две программы, чтобы часы в одной части дисплея работали, а температура в другой части. Получилось кривенько, при опросе датчика прерывания запрещены, соответственно на нажатия кнопок реакция заторможенная.
Подскажите, как бы реализовать подобие многопоточности?
Может тут подойдут конечные автоматы?
Приветствую список литературы по этому вопросу!
А может для attiny2313 вообще это не возможно сделать без тормозов?

Сообщение отредактировал aivs - Apr 6 2013, 21:16
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
aivs
сообщение Apr 7 2013, 07:38
Сообщение #2


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

Группа: Участник
Сообщений: 114
Регистрация: 3-10-09
Пользователь №: 52 731



В прерывании я опрашиваю три кнопки, и если кнопка нажата то просто инкрементирую переменную, никаких задержек, на каждое 10 прерывание прибавляется секунда.
Код
// Процедура обработки прерывания по Таймеру 1 каждую 0.1 сек. Проверяем нажатия кнопок и прибавляем секунды
ISR (TIMER1_COMPA_vect){
  // При нажатии на кнопку PD5 увеличиваем час на один
  if (bit_is_clear(PIND,5)) {   // Если кнопка PD5 нажата
    _delay_ms(25);              // Пауза на 25 мс
    if (bit_is_clear(PIND,5)) { // Если кнопка PD5 нажат
      while (bit_is_clear(PIND,5)); //Ждем отжатия клавиши
      hours++;
    }
  }

  // При нажатии на кнопку PD4 увеличиваем минуту на один
  if (bit_is_clear(PIND,4)) {   // Если кнопка PD5 нажата
    _delay_ms(25);              // Пауза на 25 мс
    if (bit_is_clear(PIND,4)) { // Если кнопка PD5 нажат
      while (bit_is_clear(PIND,4)); //Ждем отжатия клавиши
      minutes++;
    }
  }

  // При нажатии на кнопку PD3 увеличиваем секунду на один
  if (bit_is_clear(PIND,3)) {   // Если кнопка PD5 нажата
    _delay_ms(25);              // Пауза на 25 мс
    if (bit_is_clear(PIND,3)) { // Если кнопка PD5 нажат
      while (bit_is_clear(PIND,3)); //Ждем отжатия клавиши
      seconds++;
    }
  }

  // 10 прерываний в секунды, на каждое 10 прерывание прибавляем секунду
  second_timer++;
  if (second_timer == 10) {
    seconds++;
    second_timer = 0;
  }
}


Вот главный цикл:
Код
// Основная программа
void main(void) {
  // Деление частоты системного генератора на 1. 8MHz/1 = 8MHz
  CLKPR=0x80;
  CLKPR=0x00;

  // Инициализация порта B. LCD HD44780
  // DDRB  = 0b11111111;
  // PORTB = Порты инициализируются в библиотеке

  
  // Инициализация порта D
  // DDRD.0 = ввод; DDRD.1 = ввод; DDRD.2 = ввод; DDRD.3 = ввод; DDRD.4 = ввод; DDRD.5 = ввод; DDRD.6 = ввод; DDR$
  // PORTD.0 = резистор; PORTD.1 = резистор; PORTD.2 = резистор; PORTD.3 = резистор; PORTD.4 = резистор; PORTD.5 $
    DDRD=  0b00000000;  // 0 = ввод (кнопка); 1 = вывод
    PORTD= 0b11111011;  // Если DDRD.0 == 0(ввод), то в PORTD.0 == 1 (резистор подключен) или PORTD.0 == 0 (резис$
                        // отключаем на PD2 нагрузочный резистор, там сидит термодатчик
  //PORTD= 0b76543210   // Соответствие ножек битам порта

  // Инициализация таймера/счеткика T1
  TCCR1A=0x00;
  TCCR1B=0x0D;  // коэф предделителя 1/1024 и совпадение в канале А
  OCR1A=780;    // Прерывание возникает при достижении таймером числа 780

  // Инициализация прерываний от таймера
  TIMSK=0x40;   // разрешаем прерывание от таймера по совпадению в канале А
  sei();// Разрешаем прерывания

  lcd_init();// инициализация LCD
  _delay_ms(10);
  lcd_clr();// очистить LCD
  // Вечный цикл вывод информации на дисплей
  while(1) {
    cli();                      // Запрещаем прерывания
    ticking_clock();            // Ход часов
    set_time();                 // Выставляем время
    sei();                      // Разрешаем прерывания

    // Получаем температуру ****** Получать температуру нужно так чтобы не тормозить вывод информации при опросе $
    temp = temp_18b20();
    if(temp > 1000) { //если температура <0
      temp = 4096 - temp;
      temp = -temp;
    }
    lcd_gotoxy(1, 1);           // Переходим к 0 ячейки
    lcd_string("Temp=");
    itoa(temp,ch_temp,10);      // Переводим число в символы
    lcd_string(ch_temp);        // Выводим на дисплей
  }
}

Задержки с использованием _delay_us и _delay_ms содержат функции: set_time() и temp_18b20().
set_time() выводит на экран HD44780 время (много задержек _delay_ms)
temp_18b20() запрашивает и получает температуру по 1-wire& ((много задержек _delay_us)

Как понял мне нужно все задержки _delay_us и _delay_ms сделать через прерывания?

Сообщение отредактировал aivs - Apr 7 2013, 08:00
Go to the top of the page
 
+Quote Post
Xenia
сообщение Apr 7 2013, 12:23
Сообщение #3


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(aivs @ Apr 7 2013, 11:38) *
Код
  // Вечный цикл вывод информации на дисплей
  while(1) {
    cli();            // Запрещаем прерывания
    ticking_clock();                    // Ход часов
    set_time();        // Выставляем время
    sei();            // Разрешаем прерывания

    // Получаем температуру ****** Получать температуру нужно так чтобы не тормозить вывод информации при опросе $
    temp = temp_18b20();
    if(temp > 1000) { //если температура <0
      temp = 4096 - temp;
      temp = -temp;
    }
    lcd_gotoxy(1, 1);        // Переходим к 0 ячейки
    lcd_string("Temp=");
    itoa(temp,ch_temp,10);    // Переводим число в символы
    lcd_string(ch_temp);        // Выводим на дисплей
  }
}


Возможно, это дисплей время тянет, т.к. выполнение функции lcd_string() может занимать продолжительное время (проверить своё опасение не могу, т.к. ее код мне не ведом).
Самое простое - сэкономить на дисплейном выводе, если температура остается прежней. Какой смысл обновлять на нем число, если оно не изменилось?
Например, так:
Код
if(temp != oldtemp)
{ lcd_gotoxy(1, 1);        // Переходим к 0 ячейки
   lcd_string("Temp=");
   itoa(temp,ch_temp,10);    // Переводим число в символы
   lcd_string(ch_temp);    // Выводим на дисплей

  oldtemp = temp;
}

То же можно сделать и с set_time(), которая выводит время на экран. Полагаю, что время выводится не с миллисекундной точностью, а раз так, то перед его выводом на дисплей тоже можно проверить еще в бинарном виде, стоит ли новое значение вывода (скажем, если время выводится на дисплей без десятых долей секунды).
Или начало строки "Temp=" выводить только однажды (перед вечным циклом), если оно всегда на одном месте печатается, и перескакивать с помощью lcd_gotoxy(1, 6) сразу на цифровую область.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Apr 7 2013, 14:19
Сообщение #4


;
******

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



Цитата(Xenia @ Apr 7 2013, 15:23) *
Возможно, это дисплей время тянет

+1
Там в низкоуровневом чтении/записи обычно используется чтение статуса и ожидание, пока контроллер освободится. Вот туда я и помещаю system(), получаем
Код
while (HD44780_Busy()) system();

Культурненько и прозрачненько.
Go to the top of the page
 
+Quote Post
Xenia
сообщение Apr 7 2013, 14:31
Сообщение #5


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(_Pasha @ Apr 7 2013, 18:19) *
Там в низкоуровневом чтении/записи обычно используется чтение статуса и ожидание, пока контроллер освободится. Вот туда я и помещаю system(), получаем
Код
while (HD44780_Busy()) system();

Культурненько и прозрачненько.


А system() это что такое? sm.gif
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Apr 7 2013, 14:35
Сообщение #6


;
******

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



Цитата(Xenia @ Apr 7 2013, 17:31) *
А system() это что такое? sm.gif

Это несколькими постами выше.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- aivs   Многопоточность на attiny2313   Apr 6 2013, 21:15
- - ILYAUL   ЦитатаПолучилось кривенько, при опросе датчика пре...   Apr 6 2013, 21:52
- - Xenia   Цитата(aivs @ Apr 7 2013, 01:15) Получило...   Apr 6 2013, 23:39
|- - _Артём_   Цитата(Xenia @ Apr 7 2013, 02:39) что нел...   Apr 7 2013, 00:31
|- - mempfis_   ЦитатаЗадержки с использованием _delay_us и _delay...   Apr 7 2013, 12:58
- - _Pasha   Могу сказать, как делаю я. 1. Беру за основу идею,...   Apr 7 2013, 09:58
- - mempfis_   Цитата(aivs @ Apr 7 2013, 01:15) Затем я ...   Apr 7 2013, 11:12
|- - _Артём_   Цитата(mempfis_ @ Apr 7 2013, 14:12) Есть...   Apr 7 2013, 19:37
|- - mempfis_   ЦитатаПроблемы скорее нет, чем есть. Разве самому ...   Apr 8 2013, 07:31
|- - _basile   DATASHEET 2313: "The External Interrupts are ...   Apr 8 2013, 07:52
||- - _Pasha   Цитата(_basile @ Apr 8 2013, 10:52) Как т...   Apr 8 2013, 07:57
|||- - _basile   Цитата(_Pasha @ Apr 8 2013, 11:57) Вы не ...   Apr 8 2013, 08:08
|||- - _Pasha   Цитата(_basile @ Apr 8 2013, 11:08) И что...   Apr 8 2013, 08:22
||- - aivs   Цитата(_basile @ Apr 8 2013, 11:52) DATAS...   Apr 8 2013, 16:37
|- - _Артём_   Цитата(mempfis_ @ Apr 8 2013, 10:31) Не в...   Apr 8 2013, 14:36
- - aivs   Спасибо, уберу из прерывания: Код_delay_ms(25...   Apr 8 2013, 13:36
- - ARV   всем начинающим всегда рекомендую мудрить поменьше...   Apr 8 2013, 17:48
- - Xenia   Я тоже сразу заметила, что в этой программе пока д...   Apr 8 2013, 22:36
- - _Pasha   Цитата(Xenia @ Apr 9 2013, 01:36) Поэтому...   Apr 9 2013, 01:23
- - aivs   Цитата(Xenia @ Apr 9 2013, 02:36) Поэтому...   Apr 9 2013, 08:17
- - _Pasha   Цитата(aivs @ Apr 9 2013, 11:17) Нет...   Apr 9 2013, 09:14
- - mempfis_   Цитата(aivs @ Apr 9 2013, 11:17) Нет...   Apr 9 2013, 09:43
- - ARV   Цитата(mempfis_ @ Apr 9 2013, 13:43) Прос...   Apr 9 2013, 10:11
- - mempfis_   Цитата(ARV @ Apr 9 2013, 13:11) P.S. судя...   Apr 9 2013, 14:14


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

 


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


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