Перейти к содержанию
    

Чтение из регистра TIM3_CNTR на STM8

:help: :help:

Всем привет, форумчане. Помогите пожалуйста начинающему нубасу. :biggrin:

 

Надо сделать декодер для RC5 протокола, в руках оказался камень stm8s105c6...Столкнулся вот с такой проблемой, по алгоритму выполнения надо считывать временные интервалы между внешними прерываниями на выводе PB7, решил использовать таймер TIM3, судя по документации на камень, у таймера есть регистры TIM3_CNTRH и TIM3_CNTRL они помечены как R/W и служат для хранения текущего значения счетчика.

 

Для получения значения использую вот такую строчку

 

unsigned short Timer_value |= ((TIM3_CNTRH << 8)|TIM3_CNTRL);

Но получаю только нулевое значение :crying:

 

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

 

 

#include "iostm8s105c6.h"

 

void InitialiseInternalSystemClock()

{

CLK_ECKR = 0; // очистка регистра внешнего тактирования

CLK_ICKR = 0; // очистка регистра внетреннего тактирования(сбрасывание делителя частоты)

CLK_ICKR_HSIEN = 1; // подключаем внутренний высокоскоростной генератор

 

while (CLK_ICKR_HSIRDY == 0) {} // ожидание устойчивой работы внетреннего высокоскоростного генератора

 

CLK_CKDIVR = 0; // максимальная частота работы генератора

CLK_PCKENR1 = 0xff; // хз как включить TIM4 => врубаем все

CLK_PCKENR2 = 0xff; // тут нет TIM4 => прост врубаем все

CLK_CCOR = 0; // отключения подачи на ножку тактового сигнала

CLK_HSITRIMR = 0; // выключить калибровку генератора

CLK_SWR = 0xe1; // HSI выбран как источник тактирования

CLK_SWCR = 0; // сброс флага переключения

CLK_SWCR_SWEN = 1; // переключиться на HSI

while (CLK_SWCR_SWBSY != 0) {} // ожидание переключения

}

 

 

unsigned char MIN_THRESHOLD_SHORT_PULSE = 889;

unsigned char MAX_THRESHOLD_SHORT_PULSE = 1333;

unsigned char MIN_THRESHOLD_LONG_PULSE =1334;

unsigned char MAX_THRESHOLD_LONG_PULSE = 2220;

 

 

unsigned short RC5_buffer = 0;

unsigned char bit_counter = 0;

unsigned char not_korr = 0;

unsigned char centre = 0;

 

unsigned short Timer_value = 0;

 

#pragma vector=0x06

__interrupt void EXTI_PB7(void) //Обработчик прерывания

{

//TIM3_CR1_CEN = 1;

not_korr = 1;

Timer_value = ((TIM3_CNTRH << 8) | TIM3_CNTRL); // ВОТ ЗДЕСЬ НИЧЕГО НЕ ПРОИСХОДИТ.

TIM3_CNTRL = 0;

TIM3_CNTRH = 0;

 

if(bit_counter == 0)

{

TIM3_CR1_CEN = 1;

RC5_buffer |= (PB_IDR_bit.IDR7 << bit_counter);

bit_counter++;

centre = 1;

}

else

{

// ОБРАБОТКА КОРОТКОГО ИМПУЛЬСА

if((Timer_value > MIN_THRESHOLD_SHORT_PULSE) && (Timer_value < MAX_THRESHOLD_SHORT_PULSE))

{

if(centre == 1)

{

centre = 0;

not_korr = 0;

}

else

{

centre = 1;

RC5_buffer |= (~PB_IDR_bit.IDR7 << bit_counter);

bit_counter++;

not_korr = 0;

}

}

// ОБРАБОТКА ДЛИННОГО ИМПУЛЬСА

if((Timer_value > MIN_THRESHOLD_LONG_PULSE) && (Timer_value < MAX_THRESHOLD_LONG_PULSE))

{

RC5_buffer |= (~PB_IDR_bit.IDR7 << bit_counter);

bit_counter++;

not_korr = 0;

}

if( not_korr == 1)

{

TIM4_CR1_CEN = 0; RC5_buffer = 0; bit_counter = 0; // Ошибка чтения

}

if(bit_counter == 14)

{

TIM4_CR1_CEN = 0;

RC5_buffer = 0;

}

TIM4_CR1_CEN = 1;

}

}

 

 

 

void PB7_Interrupt_init()

{

PB_DDR_bit.DDR7=0; //0-вход

PB_CR1_bit.C17=1; //1-подтяжка

PB_CR2_bit.C27=1; //1-прерывания разрешены

 

EXTI_CR1_bit.PBIS = 3; // 11: Rising and falling edge

}

 

void TIM3_init()

{

TIM3_PSCR = 4; // Делитель 2^4 = 16 => 1 МГц

TIM3_ARRH = 0;

TIM3_ARRL = 0;

//TIM3_IER_UIE = 1; // Включаем флаг обновления таймера (разрешить прерывания)

TIM3_CR1_CEN = 1; // включаем таймер

 

}

 

 

 

int main( void )

{

asm("sim");

InitialiseInternalSystemClock();

PB7_Interrupt_init();

TIM3_init();

asm("rim");

while (1)

{

 

}

 

return 0;

}

 

:smile3046:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для получения значения использую вот такую строчку

 

unsigned short Timer_value |= ((TIM3_CNTRH << 8)|TIM3_CNTRL);

Для считывания значения счётчика таймера надо читать его регистры в строго определённом порядке - сначала старший, затем младший. В вашем выражении это не гарантируется, компилятор вполне может прочитать сначала младший регистр. Поэтому сделайте чтение двумя отдельными командами:

Timer_value = TIM3_CNTRH << 8;
Timer_value |= TIM3_CNTRL;

Записывать новое значение, кстати, нужно тоже в такой последовательности.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...