Пн мар 07, 2016 21:26:17
Вт мар 08, 2016 01:29:42
/*
/// таймер TIM2 72мгц - IR , вход CH1 + CH4
TIM2->PSC = 720;
TIM2->CCMR1|=TIM_CCMR1_CC1S_0 | TIM_CCMR1_IC2F_3; //TI1FP1+фильтр
TIM2->CCMR1 |= (TIM_CCMR1_OC2M_2|TIM_CCMR1_OC2M_1);
TIM2->CCMR2|=TIM_CCMR2_CC4S_1 | TIM_CCMR2_IC4F_3; //TI1FP2+фильтр
TIM2->CCR2 = 15800 ; // детектор тишины
TIM2->SMCR = (5<<4) | 4; //TI1FP1+Reset Mode
TIM2->CCER|= TIM_CCER_CC1E | TIM_CCER_CC4P | TIM_CCER_CC4E | TIM_CCER_CC2E;
TIM2->DIER = TIM_DIER_CC1IE | TIM_DIER_CC2IE; // прерывание от захвата и тишины
TIM2->CR1 = TIM_CR1_CEN;
*/
volatile uint32_t data_IR;
volatile char *time2_data;
_bitFlag table_simvol_bits;
_bitFlag time2_data_IR_RE;
#define IR_ZERO_L 56 // время передачи нуля
void TIM2_IRQHandler (void)
{
uint16_t tmp_H;
uint16_t tmp_L;
static uint8_t nomer_bit = 32;
static uint8_t status_bit = 0;
static uint32_t time2_data_IR;
if (TIM2->SR & TIM_SR_CC2IF)
{ TIM2->SR = 0; nomer_bit = 32;status_bit = 0; return;}
else
{
tmp_L = TIM2-> CCR4; tmp_H = (TIM2->CCR1) - tmp_L;
if (status_bit ==0 )
{ if ((tmp_H < ((uint16_t)IR_ZERO_L * 1.25)) && (tmp_L > ((uint16_t)IR_ZERO_L * 7.75))
&& (tmp_L < ((uint16_t)IR_ZERO_L * 8.25)))
{ nomer_bit = 32; time2_data_IR =0;status_bit++;}else; return; }else;
if (status_bit == 1 )
{ if (tmp_H < ((uint16_t)IR_ZERO_L * 1.25))
{ if (tmp_L < ((uint16_t)IR_ZERO_L * 1.25)) nomer_bit--;
else
{ if (tmp_L < ((uint16_t)IR_ZERO_L * 3.25))
{ nomer_bit--; time2_data_IR |= (uint32_t) 1 << nomer_bit;} else;
}
} else status_bit = 0;
if (nomer_bit == 0)
{data_IR = time2_data_IR; sTask_wake(&table_simvol_bits); status_bit++; return;} else;
}else;
if (status_bit == 2 ) // H903-L4000; (H56-L224; H900-L9627;) // (H900-L4000; H56-L228) lg
{ if ((tmp_H > ((uint16_t)IR_ZERO_L * 15.75)) && (tmp_L > ((uint16_t)IR_ZERO_L * 69))
&& (tmp_L < ((uint16_t)IR_ZERO_L * 73))) status_bit++;
else status_bit = 0; return;
}else;
if (status_bit == 3 )
{ if ((tmp_H < ((uint16_t)IR_ZERO_L * 1.25)) && (tmp_L > ((uint16_t)IR_ZERO_L * 3.75))
&& (tmp_L < ((uint16_t)IR_ZERO_L * 4.25))) status_bit++;
else status_bit = 0; return;
}else;
if (status_bit == 4 )
{ if ((tmp_H > ((uint16_t)IR_ZERO_L * 15.75)) && (tmp_L > ((uint16_t)IR_ZERO_L * 166))
&& (tmp_L < ((uint16_t)IR_ZERO_L * 176)))
{status_bit = 3; time2_data_IR_RE = 1;}
else status_bit = 0; return;
}else;
}
}
void table_simvol (void)
{
for(;;)
{
if (data_IR == 0) {time2_data = ".........."; } else;
if (( data_IR >> 16) == 0x00FF) // пульт от плеера
{
data_IR = data_IR & 0xFFFF;
if (data_IR == 0x38c7) {time2_data = "POWER"; } else;
if (data_IR == 0xd22d) {time2_data = "LCD_ON/OF"; } else;
if (data_IR == 0xda25) {time2_data = "MODE"; } else;
if (data_IR == 0x20df) {time2_data = "3D"; } else;
if (data_IR == 0x5aa5) {time2_data = "PROG"; } else;
if (data_IR == 0x50af) {time2_data = "MITE"; } else;
if (data_IR == 0x00ff) {time2_data = "REPEAT"; } else;
if (data_IR == 0x08f7) {time2_data = "A-B"; } else;
if (data_IR == 0xa25d) {time2_data = "1"; } else;
if (data_IR == 0xe817) {time2_data = "2"; } else;
if (data_IR == 0x48b7) {time2_data = "3"; } else;
if (data_IR == 0xb847) {time2_data = "TITLE"; } else;
if (data_IR == 0x28d7) {time2_data = "4"; } else;
if (data_IR == 0xe01f) {time2_data = "5"; } else;
if (data_IR == 0xb04f) {time2_data = "6"; } else;
if (data_IR == 0x1ae5) {time2_data = "ANGLE"; } else;
if (data_IR == 0xd827) {time2_data = "7"; } else;
if (data_IR == 0x926d) {time2_data = "8"; } else;
if (data_IR == 0x22dd) {time2_data = "9"; } else;
if (data_IR == 0x3ac5) {time2_data = "SUBTITLE"; } else;
if (data_IR == 0x9867) {time2_data = "+10"; } else;
if (data_IR == 0x7887) {time2_data = "0"; } else;
if (data_IR == 0x7a85) {time2_data = "MENU"; } else;
if (data_IR == 0xc837) {time2_data = "OSD"; } else;
if (data_IR == 0xf00f) {time2_data = "ZOOM"; } else;
if (data_IR == 0x728d) {time2_data = "CH+"; } else;
if (data_IR == 0x629d) {time2_data = "PBC"; } else;
if (data_IR == 0x9a65) {time2_data = "SLOW"; } else;
if (data_IR == 0x30cf) {time2_data = "<<-"; } else;
if (data_IR == 0x609f) {time2_data = "ENTER"; } else;
if (data_IR == 0xa05f) {time2_data = "->>"; } else;
if (data_IR == 0xc23d) {time2_data = "RETURN"; } else;
if (data_IR == 0xf20d) {time2_data = "AUDIO"; } else;
if (data_IR == 0xb24d) {time2_data = "CH-"; } else;
if (data_IR == 0x32cd) {time2_data = "GOTO"; } else;
if (data_IR == 0xe21d) {time2_data = "SETUP"; } else;
if (data_IR == 0x10ef) {time2_data = "VOL+"; } else;
if (data_IR == 0x42bd) {time2_data = "<<"; } else;
if (data_IR == 0x02fd) {time2_data = ">>"; } else;
if (data_IR == 0xc03f) {time2_data = "STOP"; } else;
if (data_IR == 0x0af5) {time2_data = "VOL-"; } else;
if (data_IR == 0x807f) {time2_data = "|<<"; } else;
if (data_IR == 0x40bf) {time2_data = ">>|"; } else;
if (data_IR == 0x8877) {time2_data = "PLEY"; } else;
}else;
if (( data_IR >> 16) == 0x20DF) // пульт от телека LG
{
data_IR = data_IR & 0xFFFF;
if (data_IR == 0x10ef) {time2_data = "POWER"; } else;
if (data_IR == 0x0ff0) {time2_data = "TV/RADIO"; } else;
if (data_IR == 0x9c63) {time2_data = "SUBTITLE"; } else;
if (data_IR == 0x06f9) {time2_data = "AD(PIP/*)"; } else;
if (data_IR == 0xd926) {time2_data = "TV/PC"; } else;
if (data_IR == 0xd02f) {time2_data = "INPUT"; } else;
if (data_IR == 0x8877) {time2_data = "1"; } else;
if (data_IR == 0x48b7) {time2_data = "2"; } else;
if (data_IR == 0xc837) {time2_data = "3"; } else;
if (data_IR == 0x28d7) {time2_data = "4"; } else;
if (data_IR == 0xa857) {time2_data = "5"; } else;
if (data_IR == 0x6897) {time2_data = "6"; } else;
if (data_IR == 0xe817) {time2_data = "7"; } else;
if (data_IR == 0x18e7) {time2_data = "8"; } else;
if (data_IR == 0x9867) {time2_data = "9"; } else;
if (data_IR == 0xca35) {time2_data = "LIST"; } else;
if (data_IR == 0x08f7) {time2_data = "0"; } else;
if (data_IR == 0x58a7) {time2_data = "Q.VIEW"; } else;
if (data_IR == 0x40bf) {time2_data = "VOL+"; } else;
if (data_IR == 0x7887) {time2_data = "FAV"; } else;
if (data_IR == 0x00ff) {time2_data = "CH+"; } else;
if (data_IR == 0xd52a) {time2_data = "GUIDE"; } else;
if (data_IR == 0xc03f) {time2_data = "VOL-"; } else;
if (data_IR == 0x906f) {time2_data = "MITE"; } else;
if (data_IR == 0x807f) {time2_data = "CH-"; } else;
if (data_IR == 0x4fb) {time2_data = "TEXT"; } else;
if (data_IR == 0x55aa) {time2_data = "INFO"; } else;
if (data_IR == 0x847b) {time2_data = "T.OPT"; } else;
if (data_IR == 0xc23d) {time2_data = "SETTINGS"; } else;
if (data_IR == 0x02fd) {time2_data = "TOP"; } else;
if (data_IR == 0xa25d) {time2_data = "Q.MENU"; } else;
if (data_IR == 0xe01f) {time2_data = "LEFT"; } else;
if (data_IR == 0x22dd) {time2_data = "OK"; } else;
if (data_IR == 0x609f) {time2_data = "RIGHT"; } else;
if (data_IR == 0x14eb) {time2_data = "BACK"; } else;
if (data_IR == 0x827d) {time2_data = "BOTTOM"; } else;
if (data_IR == 0xda25) {time2_data = "EXIT"; } else;
if (data_IR == 0x7e81) {time2_data = "smplink"; } else;
if (data_IR == 0xbd42) {time2_data = "RES/*"; } else;
if (data_IR == 0x8d72) {time2_data = "STOP"; } else;
if (data_IR == 0xf10e) {time2_data = "<<"; } else;
if (data_IR == 0x0df2) {time2_data = "PLEY"; } else;
if (data_IR == 0x5da2) {time2_data = "PAUSE"; } else;
if (data_IR == 0x718e) {time2_data = ">>"; } else;
if (data_IR == 0x4eb1) {time2_data = "RED"; } else;
if (data_IR == 0x8e71) {time2_data = "GREEN"; } else;
if (data_IR == 0xc639) {time2_data = "YELLOW"; } else;
if (data_IR == 0x8679) {time2_data = "BLUE"; } else;
}else;
sTask_wait (&table_simvol_bits);
}
Вт мар 08, 2016 11:12:41
Вт мар 08, 2016 13:35:17
Вт мар 08, 2016 13:46:03
AVI-crak писал(а):У меня работает, а у вас?
NEC remote power button
NC 0xF4 Инверсия комманды
C 0x0B Комманда
NA 0xF7 инверсия адреса
A 0x08 адрес
received bites | LOST Bites |
F 4 | 0 B | F X | X X
1111 0100 | 0000 1011 | 1111 01LL | LLLL LLLL
Вт мар 08, 2016 14:50:53
Ican писал(а):AVI-crak писал(а):У меня работает, а у вас?
А у меня не работает
Заполнение идет с конца, т.е. потерянные байты L находятся после стартовой посылки и паузы.
Чт мар 10, 2016 21:39:57
Чт апр 07, 2016 13:49:45
Чт апр 07, 2016 19:55:58
Пт апр 08, 2016 13:36:05
Поиграйся двумя разными пультами одновременно
Сб май 14, 2022 21:44:41
/// IK protocol NEC
/// TIMx->PSC = clock frequency of the timer / 50526
#include <stdint.h>
#include "ik_nec.h"
#include "stm32f030x6.h"
#define IK_N 0xFFU /* unnamed china */
//#define IK_N 0xDFU /* LG */
#define DECODER ((uint16_t)((~IK_N)<<8)|IK_N)
volatile uint8_t ik_out;
const uint16_t range_z[] ={
628,1167,35,66,35,66,634,1177,0,0,
76,278,76,278,2890,12759,798,1483,2890,12759,949,1764};
void TIM3_IRQHandler (void) //220
{
uint32_t tmp;
static uint8_t status = 0;
static uint8_t poz;
static uint32_t stor;
if ((TIM3->SR & (TIM_SR_CC1IF | TIM_SR_CC2IF | TIM_SR_CC3IF | TIM_SR_CC4IF))
!= (TIM_SR_CC1IF | TIM_SR_CC2IF | TIM_SR_CC3IF)) goto uno;
tmp = TIM3->CCR2;
if (tmp < range_z[status << 1]) goto uno;
if (tmp > range_z[(status << 1) + 1]) goto uno;
switch (status)
{
case 0: status = 1; poz = 32; stor = 0; tmp = 10; break;
case 1: tmp = stor << 1;
if (TIM3->CCR1 > 170) tmp |= 1;
stor = tmp; poz--; tmp = 12;
if (poz == 0)
{
/// watch raw IR code
/// stor = (~IK_N<<24)|(IK_N<<16)|(~ik_out<<8)|(ik_out)
if ((DECODER == (stor >> 16)) && ((((stor >> 8) ^ stor) & 0xFF) == 0xFF))
{
stor &= 0xFF; ik_out = stor; tmp = 14; status = 2;
}else goto uno;
}; break;
case 2: status = 3; tmp = 16; break;
case 3: status = 2; tmp = 18; ik_out = stor; break;
default: uno: status = 0; tmp = 20; break;
};
TIM3->SR = 0;
TIM3->CCR3 = range_z[tmp++];
TIM3->CCR4 = range_z[tmp];
};
void ik_tim_init(void)
{
RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
GPIOA->MODER |= _VAL2FLD(GPIO_MODER_MODER6, 2); //Alternate function mode
GPIOA->AFR[0] |= _VAL2FLD(GPIO_AFRL_AFSEL6, 1);
TIM3->PSC = 950; /// clock frequency of the timer / 50526 (509us = 51L)
TIM3->CCMR1 = _VAL2FLD(TIM_CCMR1_CC1S, 1)|
_VAL2FLD(TIM_CCMR1_CC2S, 2);
TIM3->CCER = _VAL2FLD(TIM_CCER_CC1P, 1)|
_VAL2FLD(TIM_CCER_CC2P, 0)|
_VAL2FLD(TIM_CCER_CC1E, 1)|
_VAL2FLD(TIM_CCER_CC2E, 1);
TIM3->SMCR = _VAL2FLD(TIM_SMCR_TS, 5)| // Filtered Timer Input 1 (TI1FP1)
_VAL2FLD(TIM_SMCR_SMS, 4); // Reset Mode (TRGI)
TIM3->CCMR2 = _VAL2FLD(TIM_CCMR2_OC3M,6)|
_VAL2FLD(TIM_CCMR2_OC4M,6);
TIM3->CCR3 = 949; // 1357 start P
TIM3->CCR4 = 1764;
TIM3->DIER = TIM_DIER_CC1IE;
TIM3->CR1 |= TIM_CR1_CEN;
NVIC_EnableIRQ(TIM3_IRQn);
}
/// #include "ik_nec.h"
#ifdef _ik_nec_
extern "C" {
#endif /* _ik_nec_ */
extern volatile uint8_t ik_out;
void ik_tim_init(void);
#ifdef _ik_nec_
}
#endif /* _ik_nec_ */
#define _ik_nec_
Ср дек 14, 2022 18:22:21
#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk)
//
#define GPIO_MODER_MODER6_Pos (12U)
#define GPIO_MODER_MODER6_Msk (0x3U << GPIO_MODER_MODER6_Pos) /*!< 0x00003000 */
#define GPIO_AFRL_AFSEL6_Pos (24U)
#define GPIO_AFRL_AFSEL6_Msk (0xFU << GPIO_AFRL_AFSEL6_Pos) /*!< 0x0F000000 */
//
#define TIM_SMCR_TS_Pos (4U)
#define TIM_SMCR_TS_Msk (0x7UL << TIM_SMCR_TS_Pos) /*!< 0x00000070 */
#define TIM_CCMR1_CC1S_Pos (0U)
#define TIM_CCMR1_CC1S_Msk (0x3UL << TIM_CCMR1_CC1S_Pos) /*!< 0x00000003 */
#define TIM_CCMR1_CC2S_Pos (8U)
#define TIM_CCMR1_CC2S_Msk (0x3UL << TIM_CCMR1_CC2S_Pos) /*!< 0x00000300 */
#define TIM_CCER_CC1P_Pos (1U)
#define TIM_CCER_CC1P_Msk (0x1UL << TIM_CCER_CC1P_Pos) /*!< 0x00000002 */
#define TIM_CCER_CC2P_Pos (5U)
#define TIM_CCER_CC2P_Msk (0x1UL << TIM_CCER_CC2P_Pos) /*!< 0x00000020 */
#define TIM_CCER_CC1E_Pos (0U)
#define TIM_CCER_CC1E_Msk (0x1UL << TIM_CCER_CC1E_Pos) /*!< 0x00000001 */
#define TIM_CCER_CC2E_Pos (4U)
#define TIM_CCER_CC2E_Msk (0x1UL << TIM_CCER_CC2E_Pos) /*!< 0x00000010 */
#define TIM_SMCR_SMS_Pos (0U)
#define TIM_SMCR_SMS_Msk (0x7UL << TIM_SMCR_SMS_Pos) /*!< 0x00000007 */
#define TIM_CCMR2_OC3M_Pos (4U)
#define TIM_CCMR2_OC3M_Msk (0x7UL << TIM_CCMR2_OC3M_Pos) /*!< 0x00000070 */
#define TIM_CCMR2_OC4M_Pos (12U)
#define TIM_CCMR2_OC4M_Msk (0x7UL << TIM_CCMR2_OC4M_Pos) /*!< 0x00007000 */
Ср дек 14, 2022 20:53:16
/**
* @brief Class for IR receiver
*
* @tparam _Timer GP timer instance
* @tparam _Pin Input pin
* @tparam _Decoder Decoder
*/
template <typename _Timer, typename _Pin, typename _Decoder>
class IrReceiver
{
using InputCaptureFalling = typename _Timer::InputCapture<0>;
using InputCaptureRising = typename _Timer::InputCapture<1>;
using TimeoutOCChannel = typename _Timer::OutputCompare<2>;
public:
/**
* @brief Init receiver
*
* @par Returns
* Nothing
*/
static void Init()
{
_Timer::Enable();
_Timer::SetPrescaler(_Timer::GetClockFreq() / 1000000 * 2 - 1); // 1us period
_Timer::SetPeriod(0xffff);
_Timer::SlaveMode::SelectTrigger(_Timer::SlaveMode::Trigger::FilteredTimerInput1);
_Timer::SlaveMode::EnableSlaveMode(_Timer::SlaveMode::Mode::ResetMode);
InputCaptureFalling::SetCapturePolarity(InputCaptureFalling::CapturePolarity::FallingEdge);
InputCaptureFalling::SetCaptureMode(InputCaptureFalling::CaptureMode::Direct);
InputCaptureFalling::EnableInterrupt();
InputCaptureFalling::Enable();
InputCaptureRising::SetCapturePolarity(InputCaptureRising::CapturePolarity::RisingEdge);
InputCaptureRising::SetCaptureMode(InputCaptureRising::CaptureMode::Indirect);
InputCaptureRising::EnableInterrupt();
InputCaptureRising::Enable();
TimeoutOCChannel::SetPulse(15'000);
_Pin::Port::Enable();
_Pin::template SetConfiguration<_Pin::Configuration::In>();
_Pin::template SetPullMode<_Pin::PullMode::PullUp>();
_Timer::Start();
}
/**
* @brief Timer IRQ handler (call this method in TIMx_IRQHandler)
*
* @par Returns
* Nothing
*/
static void IRQHandler()
{
static bool idleState = true;
if(InputCaptureFalling::IsInterrupt()) {
InputCaptureFalling::ClearInterruptFlag();
uint16_t width = InputCaptureFalling::GetValue();
uint16_t pulse = InputCaptureRising::GetValue();
if(idleState) {
idleState = false;
TimeoutOCChannel::EnableInterrupt();
}
else {
if(IsSimilar<_Decoder::StartWidth>(width) && IsSimilar<_Decoder::StartPulse>(pulse)) {
_Decoder::Start();
}
else if(IsSimilar<_Decoder::Width0>(width) && IsSimilar<_Decoder::Pulse0>(pulse)) {
_Decoder::Add0();
}
else if(IsSimilar<_Decoder::Width1>(width) && IsSimilar<_Decoder::Pulse1>(pulse)) {
_Decoder::Add1();
}
else {
idleState = true;
}
}
}
if (TimeoutOCChannel::IsInterrupt()) {
TimeoutOCChannel::DisableInterrupt();
TimeoutOCChannel::ClearInterruptFlag();
if(!idleState) {
idleState = true;
_Decoder::Handle();
}
}
}
private:
/**
* @brief Compare received value with decoder constant with given accuracy
*
* @tparam _TargetValue Constant
* @param value Received value
*
* @return true If value ~ _TargetValue
* @return false If value != _TargetValue
*/
template<uint16_t _TargetValue>
inline static bool IsSimilar(uint16_t value)
{
return ((_TargetValue * (100 - _Decoder::EpsilonInPercent) / 100) < value) && (value < (_TargetValue * (100 + _Decoder::EpsilonInPercent) / 100));
}
};
/**
* @brief NEC decoder
*/
class NecDecoder
{
public:
static const uint16_t StartWidth = 13500;
static const uint16_t StartPulse = 9000;
static const uint16_t Width0 = 1125;
static const uint16_t Pulse0 = 562;
static const uint16_t Width1 = 2250;
static const uint16_t Pulse1 = 562;
static const uint16_t EpsilonInPercent = 20;
/// Command
/// @todo Add commands
enum Command : uint16_t
{
NoCommand = 0
};
using Callback = std::add_pointer_t<void(Command command)>;
/**
* @brief Set the callback for command receive
*
* @param callback Callback
*
* @par Returns
* Nothing
*/
static void SetCallback(Callback callback)
{
_callback = callback;
}
/**
* @brief Start new frame
*
* @par Returns
* Nothing
*/
static void Start()
{
_frame = 0;
}
/**
* @brief Add bit 0 to frame
*
* @par Returns
* Nothing
*/
static void Add0()
{
_frame >>= 1;
}
/**
* @brief Add bit 1 to frame
*
* @par Returns
* Nothing
*/
static void Add1()
{
_frame = (_frame >> 1) | 0x80000000;
}
/**
* @brief End of frame (pause detect) handler
*
* @par Returns
* Nothing
*/
static void Handle()
{
if ((_frame & 0xff000000) != ( (~(_frame) & 0x00ff0000) << 8)) {
return;
}
if ((_frame & 0xff00) != (((~_frame) & 0x00ff) << 8)) {
return;
}
uint16_t command = ((_frame & 0xff000000) >> 16) | ((_frame & 0xff00) >> 8);
if(_callback)
_callback(static_cast<Command>(command));
}
private:
static uint32_t _frame;
static Callback _callback;
};
uint32_t NecDecoder::_frame;
NecDecoder::Callback NecDecoder::_callback;
#include <clock.h>
#include <iopins.h>
#include <timer.h>
#include <drivers/ir.h>
using namespace Zhele;
using namespace Zhele::Drivers;
using namespace Zhele::IO;
using namespace Zhele::Timers;
using namespace Zhele::Clock;
void ConfigureClock();
void ConfigureOutputPwm();
void ConfigureInputCapture();
using Receiver = IrReceiver<Timer4, Pb6, NecDecoder>;
int main()
{
ConfigureClock();
Receiver::Init();
NecDecoder::SetCallback([](NecDecoder::Command command) {
// Do smth
});
for (;;)
{
}
}
void ConfigureClock()
{
PllClock::SelectClockSource(PllClock::ClockSource::External);
PllClock::SetMultiplier(9);
Apb1Clock::SetPrescaler(Apb1Clock::Div2);
SysClock::SelectClockSource(SysClock::Pll);
}
extern "C"
{
void TIM4_IRQHandler()
{
Receiver::IRQHandler();
}
}
Чт дек 15, 2022 01:02:21
Сб янв 21, 2023 22:04:22
del
del
Сб янв 21, 2023 22:20:53
Сб янв 21, 2023 22:31:07
Вс янв 22, 2023 01:22:41
Вс янв 22, 2023 04:00:44
template<TimCh Channel>
class Remote
{
using Tim = Channel::Timer;
static constexpr uint32_t chNum = Channel::number();
static_assert(chNum <= 3);
static_assert(Tim::hasFeatures(TimFeature::SlaveCtrl), "TimFeature::SlaveCtrl is Required!");
static_assert(chNum == 1 || Tim::hasFeatures(TimFeature::Xor), "TimFeature::Xor is Required!");
.........
};
Remote<Tim3Ch2<PA7>> remote;
Вс янв 22, 2023 09:58:40
void ik_tim_init(void) {
RCC->APB2ENR |= RCC_APB2ENR_TIM1EN; // 1-й таймер
// TIM1_CH1 PA8 AF2
RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
GPIOA->MODER |= _VAL2FLD(GPIO_MODER_MODER8, 2); // Ногу в альтернативную функцию
GPIOA->AFR[1] |= _VAL2FLD(GPIO_AFRH_AFSEL8, 2); //
TIM1->PSC = 480;//340;//950;//400; //950; /// clock frequency of the timer / 50526 (509us = 51L) // TIM prescaler register
TIM1->CCMR1 = _VAL2FLD(TIM_CCMR1_CC1S, 1)|
_VAL2FLD(TIM_CCMR1_CC2S, 2);
TIM1->CCER = _VAL2FLD(TIM_CCER_CC1P, 1)|
_VAL2FLD(TIM_CCER_CC2P, 0)|
_VAL2FLD(TIM_CCER_CC1E, 1)|
_VAL2FLD(TIM_CCER_CC2E, 1);
TIM1->SMCR = _VAL2FLD(TIM_SMCR_TS, 5)| // Filtered Timer Input 1 (TI1FP1)
_VAL2FLD(TIM_SMCR_SMS, 4); // Reset Mode (TRGI)
TIM1->CCMR2 = _VAL2FLD(TIM_CCMR2_OC3M,6)|
_VAL2FLD(TIM_CCMR2_OC4M,6);
TIM1->CCR3 = 949; //949; // 1357 start P
TIM1->CCR4 = 1764;
TIM1->DIER = TIM_DIER_CC1IE;
TIM1->CR1 |= TIM_CR1_CEN;
NVIC_EnableIRQ(TIM1_CC_IRQn);
}
void TIM1_CC_IRQHandler(void) { //
uint32_t tmp;
static uint8_t status = 0;
static uint8_t poz;
static uint32_t stor;
if ((TIM1->SR & (TIM_SR_CC1IF | TIM_SR_CC2IF | TIM_SR_CC3IF | TIM_SR_CC4IF))
!= (TIM_SR_CC1IF | TIM_SR_CC2IF | TIM_SR_CC3IF)) goto uno;
tmp = TIM1->CCR2;
if (tmp < range_z[status << 1]) goto uno;
if (tmp > range_z[(status << 1) + 1]) goto uno;
switch (status) {
case 0: status = 1; poz = 32; stor = 0; tmp = 10; break;
case 1: tmp = stor << 1;
if (TIM1->CCR1 > 170) tmp |= 1;
stor = tmp; poz--; tmp = 12;
if (poz == 0) {
/// watch raw IR code
/// stor = (~IK_N<<24)|(IK_N<<16)|(~ik_out<<8)|(ik_out)
//if ((DECODER == (stor >> 16)) && ((((stor >> 8) ^ stor) & 0xFF) == 0xFF)) {
stor &= 0xFF; ik_out = stor; tmp = 14; status = 2;
//} else goto uno;
}; break;
case 2: status = 3; tmp = 16; break;
case 3: status = 2; tmp = 18; ik_out = stor; break;
default: uno: status = 0; tmp = 20; break;
};
TIM1->SR = 0;
TIM1->CCR3 = range_z[tmp++];
TIM1->CCR4 = range_z[tmp];
}
Reflector писал(а):Скомпилируется только если подставить подходящий таймер, канал и пин.