#1 2024-10-11 21:41:14

khalimon
Учасник
Зареєстрований: 2020-02-24
Повідомлень: 26

переривання по usart atmega

Доброго дня!
Atmega8a, 8mhz, Arduino IDE
У періодичних пакетах (1 пакет на 0,8сек) на вході Rx (швидкість 9600) після певного прийнятого символу (конкретно цифра 5) необхідно порахувати довжину першого імпульсу (не важливо до якого символу він відноситься, важлива довжина саме першого імпульсу після прийнятої 5ки). Прошу знавців ткнути у потрібному напрямку.
Дякую!


#include <HardwareSerial.h>
volatile unsigned long i, dlina, ms3;
volatile bool d;
bool fl;


#define led   13    // светодиод


void setup() {
  Serial.begin(9600);
  pinMode(2, INPUT);
  pinMode(led, OUTPUT);

  Serial.attachSerialInterrupt(SerialInterrupt);
  attachInterrupt(0, isr, CHANGE);
}


void SerialInterrupt() {

if (UDR0 == '5')   d = 1;
}


void isr() {
  if (millis() - ms3 > 1000 && fl == 1) fl = 0;

  if (fl == 0 && d == 1) {
    if (digitalRead(2) == 0 ) i = micros();
    else {
      dlina = micros() - i;
       //  if (dlina > 100 && dlina < 110) digitalWrite(led, 1); else digitalWrite(led, 0);
       Serial.print("dlina "); Serial.println(dlina);
      fl = 1;
      d = 0;
      ms3 = millis();
    }
  }
}


void loop() {

}

Неактивний

#2 2024-10-12 00:01:28

dimich
Учасник
Зареєстрований: 2023-12-01
Повідомлень: 193

Re: переривання по usart atmega

khalimon пише:

У періодичних пакетах (1 пакет на 0,8сек) на вході Rx (швидкість 9600) після певного прийнятого символу (конкретно цифра 5) необхідно порахувати довжину першого імпульсу (не важливо до якого символу він відноситься, важлива довжина саме першого імпульсу після прийнятої 5ки).

Яка максимальна довжина імпульсу? Яка необхідна точність? Якщо достатньо розрізняти імпульси довжиною від 100 мкс до 950 мкс із точністю приблизно 100 мкс, то можна просто прийняти наступний байт і подивитись скільки у нього нульових бітів у кінці, як це робиться при роботі з 1-Wire через USART.

Якщо ж умови по довжині та точності інші, то після прийому '5' працювати з RX як зі звичайним GPIO піном. На atmega328p в термінах ардуіни це пін з номером 0, в термінах AVR це PD0 (PIND & 0x1). Бажано при цьому вимкнути ресивер USARTа, щоб він не сприймав імпульс як передачу наступного символа, а по закінченню імпульса увімкнути знов. Як вимірювати - можна використати ардуінівську pulseIn() або свою аналогічну імплементацію з циклічним опитуванням. Якщо вимірювання має відбуватись паралельно з виконанням іншого коду, можна зареєструвати обробник Pin Change Interrupt на цей пін і читати micros(), або запускати/зупиняти один із решти таймерів атмеги. Як обробляти ситуацію, якщо імпульс так і не надійшов, або якщо надійшов довший ніж очікувалось - то вже залежить від специфіки вашої задачі.

Остання редакція dimich (2024-10-12 00:02:24)

Неактивний

#3 2024-10-12 09:14:55

khalimon
Учасник
Зареєстрований: 2020-02-24
Повідомлень: 26

Re: переривання по usart atmega

Проектую на ардуіно нано 328р
На мекетці вхід Rx я закоротив з D2, тобто INT0.
По D2 переривання постійно робить, але імпульс вимірює лише після прийнятого символа 5. (див. скетч)
В мене вимірює, але щось не те. Ще й в буфері щось зайве гуляє..

Якщо хтось може допомогти готов віддячити в межах 500грн

Неактивний

#4 2024-10-12 10:33:17

Honey
Учасник
З Київ
Зареєстрований: 2020-09-26
Повідомлень: 429

Re: переривання по usart atmega

Можу зробити те, що ви хочете, на m8a або m328p, звертайтесь в пошту.

Неактивний

Швидке повідомлення

Введіть повідомлення і натисніть Надіслати

Підвал форуму