Jump to content
carlogulliani

Декодирование OOK сигнала на stm8s

Recommended Posts

Добрый день, пытаюсь разобраться с декодированием сигнала ASK/OOK на stm8s003. В OOK главную роль играют период сигнала, так, например, 0 - 400 мкс, 1 - 800 мкс. +- 10%. Поэтому основная для меня проблема считать количество микросекунд между событиями, в ардуино за это отвечает функция micros()

Включаю внутреннее тактирование 16МГц, настраиваю таймер TIM1 на частоту 1MHz (1 микросекунда), у таймера стоит прерывание по переполнению, и когда счетчик доходит до предела, я в некую переменную добавляю максимальное значение счетчика, на выводе вижу не те значения, которые ожидаю, также попробовал считать через capture compare, тоже безрезультатно

 

#include "stm8s.h"
#include "timer.h"
#include "gpio.h"

volatile uint32_t tick = 0;

//Interruption
ISR_TIM1(TIM1_OVF) {
  tick += 65535;
    TIM1_SR1 &= ~0x01;     // clear all interrupt flags
    TIM1_SR1 = 0;
    TIM1_SR2 = 0;
    TIM1_CR1 = 0;
    TIM1_CCER1 &= ~0X11; // STOP TIMER
    //TIM1_SR1 = 0;
    //PinToggle(PORTD, PIN5);
}

uint8_t flag = 0;

ISR_TIM1_CC(TIM1_CAP_COM) {
    if (TIM1_SR1 & 0x01) {
        TIM1_SR1 = 0;
        TIM1_CR1 = 0;
        TIM1_CCER1 &= ~0x11;
        if (TIM1_SR2) {
            TIM1_SR2 = 0;
            flag = 1;
        }
        else {
            flag = 0;
        }
    }
    if (TIM1_SR1 & 0x02) {
        TIM1_SR1 &= ~0x02;
    }
}


uint32_t systick() {
    return (uint32_t)(TIM1_CNTRH << 8) | TIM1_CNTRL;
}

uint32_t millis() {
    return tick + (systick() / (F_CPU / 1000));
}

uint32_t micros() {
    return tick + (systick() / (F_CPU / 1000000ul));
}

void tim1_init(void) {
    // 1MHz = 1uS
    TIM1_PSCRH = 0x00;
    TIM1_PSCRL = 0x15;

    TIM1_IER = 0x04 | 0x02 | 0x01; // Enable interrups
    TIM1_CCMR1 = 1;
    TIM1_CCMR2 = 2;
    TIM1_CCER1 = 0x20;
    TIM1_SMCR = 0x54;
}

void tim1_start() {
    TIM1_CNTRH = 0;
    TIM1_CNTRL = 0;
    TIM1_CCR2H = 0;
    TIM1_CCR2L = 0;
    TIM1_CCER1 |= 0x11;
    TIM1_CR1 = 0x01;
}

uint16_t tim1_pulse_len() {
    return ((uint16_t)(TIM1_CCR2H << 8) | TIM1_CCR2L);
}

Принимаю сигнал

 

ISR_PORTD(handlerD) {
	state = PinRead(GD0_PORT, GD0_PIN);
  uint32_t m = micros();
  if (state == HIGH) {
    lolen = m - prevtime;
    printf("//");
  }
  else {
    hilen = m - prevtime;
    printf("\\");
  }
  prevtime = m;
  if (state == HIGH)
  {
    if (flag == 0) {
      // the end of packet
      if (CheckValue(Pe, hilen) && CheckValue(Pe2, lolen)) // valid 1
      {
        printf("OK-PE\r\n");
        if (bcounter < 32)
          code1 = (code1 << 1) | 1;
        else if (bcounter < 64)
          code2 = (code2 << 1) | 1;
        bcounter++;
      }
      else if (CheckValue(Pe2, hilen) && CheckValue(Pe, lolen)) // valid 0
      {
        printf("OK-PE2\r\n");
        if (bcounter < 32)
          code1 = (code1 << 1) | 0;
        else if (bcounter < 64)
          code2 = (code2 << 1) | 0; bcounter++;
      }
      else
        bcounter = 0;
    }
    else {
      if (bcounter < 32)
          code1 = (code1 << 1) | 1;
        else if (bcounter < 64)
          code2 = (code2 << 1) | 1;
        bcounter++;
    }
  }
  //printf("bcounter: %d\r\n", bcounter);
  if (bcounter >= 65)
  {
    printf("Got: %x %x\r\n", code1, code2);
    Pe2 = lolen;
    Pe = hilen;
    flag = 1;
    bcounter = 0;
    code1 = 0;
    code2 = 0;
  }
}

 

Edited by carlogulliani

Share this post


Link to post
Share on other sites
31 minutes ago, carlogulliani said:

настраиваю таймер TIM1 на частоту 1MHz

Если таймер настроен на 1МГц, то systick() и есть время в микросекундах,  то есть в прерывании от порта просто считывайте показания таймера:

ISR_PORTD(handlerD) 

{
	state = PinRead(GD0_PORT, GD0_PIN);
	uint16_t m = systick();
	if (state == HIGH) 
	{ 
		lolen = m - prevtime;
	}
	prevtime = m;

Таймер 16-битный, все переменные uint16_t.

А зачем таймер останавливать? Пусть себе крутится.

Зачем прерывание по переполнению?

Зачем прерывание по Capture/Compare?

Переменная tick не нужна, просто вычитайте предыдущее значение из  текущего, и всё будет пучком.

Edited by Yurkin2015

Share this post


Link to post
Share on other sites
Just now, Yurkin2015 said:

Если таймер настроен на 1МГц, то systick() и есть время в микросекундах,  то есть в прерывании от порта просто считывайте показания таймера:


ISR_PORTD(handlerD) 

{
	state = PinRead(GD0_PORT, GD0_PIN);
	uint16_t m = systick();
	if (state == HIGH) 
	{ 
		lolen = m - prevtime;
	}
	prevtime = m;

Таймер 16-битный, все переменные uint16_t.

А зачем таймер останавливать? Пусть себе крутится.

Зачем прерывание по переполнению?

Зачем прерывание по Capture/Compare?

Спасибо за ваш комментарий! Прерывание по переполнению сделал для того, чтобы, когда досчитает то предельного значения (в данном случае до 65535) и обнулится, не получилось так, что при первом вызове значения, условно будут, 60000, а во втором 14000, то есть дельта тогда будет не правильно считаться. CС хотел использовать для подсчета периода сигнала, условно, когда первый раз дрыгнулась нога и флаг 0, включаю таймер, как только прошел период - считаю значения СС. Про остановку таймера, вы правы, незачем.

Share this post


Link to post
Share on other sites

Драйверы MOSFET/IGBT Infineon – силой нужно управлять!

Специалисты Infineon усовершенствовали традиционные кремниевые MOSFET и IGBT и выпустили компоненты на базе принципиально иных материалов – нитрида галлия и карбида кремния. Мы создали подборку полезных материалов, чтобы вы разобрались во всех тонкостях и стали экспертом по управлению силовыми приборами нового поколения CoolMOS, CoolGaN, CoolSiC!

Подробнее

2 minutes ago, carlogulliani said:

когда досчитает то предельного значения

 

2 minutes ago, carlogulliani said:

60000, а во втором 14000

Переполнение не помешает. Если переменные типа uint16_t, то всё прекрасно вычтется 14000 - 60000 = 19536, и получится правильный результат.

Edited by Yurkin2015

Share this post


Link to post
Share on other sites

Снижена цена на DC/DC и AC/DC преобразователи Mornsun в Компэл!

Компэл снизил цены на всю продукцию Mornsun. В ассортименте – как широко известные и популярные позиции, так и новинки. Доступны AC/DC, неизолированные DC/DC-преобразователи или импульсные стабилизаторы (семейство K78/R3), изолированные DC/DC, и новейшее поколение R4.

Подробнее

36 minutes ago, Yurkin2015 said:

 

Переполнение не помешает. Если переменные типа uint16_t, то всё прекрасно вычтется 14000 - 60000 = 19536, и получится правильный результат.

Спасибо

Share this post


Link to post
Share on other sites

Новинки гибридных конденсаторов: преимущества технологии

Гибридные конденсаторы унаследовали от полимерных конденсаторов такие достоинства как устойчивость к импульсам тока, повышенную надежность и низкое собственное сопротивление, а также высокую емкость и низкий ток утечки, как у алюминиевых электролитов. Благодаря этому гибридные конденсаторы могут с успехом заменить традиционные алюминиевые конденсаторы.

Подробнее

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Сообщения

    • Сплав Розе я покупал на радиорынке также продаётся в чипдипе, но дорого
    • Если транзистор не пробит исток - сток, проверьте защитный стабилитрон в цепи исток - затвор. Иногда просто сопротивление стоит.
    • Какой обиженный и озлобленный пользователь однако. Вместо того чтоб самому что-то создать или хотя-бы научится обходить систему, без которой невозможен доход фирм, он предлагает подход инквизиции. Молодец! По легенде гильотину испытали на ее же создателе, так что вперед - в светлое будущее. И если покупать расходники так дорого и невыносимо больно, то есть дешевые альтернативы - например вместо малоресурсных LED пользоваться лунным светом, а ночную облачность списывать на "отсутствие электроэнергии" ))))) А вместо ноута с кастрированными АКБ пользоваться по старинке тетрадкой, ручкой и калькулятором на солнечных батареях, а если и калькулятор невмоготу, то логарифмической линейкой или на крайняк счетами )))))
    • Извиняюсь что полностью цитирую - но - здесь момент я не понял, прерывистый ток - ЕС выше резонанс - получим *бестолковую *паузу и тут же - его получим только ес частота работы ниже - резонанса - так эта *бестолковая *пауза и есть разрывной ток - я правильно понял? 
    • Значит однозначно безсвинцовый припой, температура нужна хорошая. Приходилось обычным, правда с встроенным термометром, строительным феном, часто менять процессора с 360 ногами в дом/театре SONY. На дохлой плате тренируйся, китайский термометр он разный.
    • Буквально пол-суток назад заказал мультиметр - все нормально, платеж прошел, никаких дополнительных подтверждений личности не потребовалось. П.С. В порядке бреда: а с другого браузера не пробовали?

  • Двухканальный усилитель звука, 3 Вт

×
×
  • Create New...