Пример работы от ST с RC5 на STM32


Мой пульт от LG не охотно работал с TSOP17(каким-то), вместо него поставил какой-то китайский, выдранный из FM тюнера для машины.
В файле RC5_IR_Emul_Receiver.h меняем настройки порта куда вешаем TSOP

#define RC5_GPIO_PORT          GPIOA                /* Port which RC5 is connected */
#define RC5_GPIO_CLK           RCC_APB2Periph_GPIOA /* Clock of Port which RC5 is connected */
#define RC5_GPIO_PIN           GPIO_Pin_0           /* Pin which RC5 is connected */
#define RC5_EXTI_PORT_SOURCE   GPIO_PortSourceGPIOA /* RC5 EXTI Port source */
#define RC5_EXTI_PIN_SOURCE    GPIO_PinSource0      /* RC5 EXTI Pin source */
#define RC5_EXTI_IRQn          EXTI0_IRQn           /* RC5 EXTI IRQ */
#define RC5_EXTI_LINE          EXTI_Line0           /* RC5 EXTI line */
#define RC5_EXTI_IRQHandler    EXTI0_IRQHandler     /* RC5 IRQ handler */

В случае неустойчиво работы в файле RC5_IR_Emul_Receiver.с можно поэкспериментировать с временными интервалами.

#define   NOMINAL_HALF_BIT_TIME_US   889  /* Nominal half bit time in µs */
#define   MIN_HALF_BIT_TIME_US       640  /* Minimum half bit time in µs */
#define   MAX_HALF_BIT_TIME_US       1140 /* Maximum half bit time in µs */

#define   NOMINAL_FULL_BIT_TIME_US   1778 /* Nominal Full bit time in µs */
#define   MIN_FULL_BIT_TIME_US       1340 /* Minimum Full bit time in µs */
#define   MAX_FULL_BIT_TIME_US       2220 /* Maximum Full bit time in µs */


#include "RC5_IR_Emul_Receiver.h"
#include "stdio.h"
#include "sys_init.h"


extern StatusYesOrNo RC5_FrameReceived;
RC5Frame_TypeDef RC5_Frame;
uint8_t RC5_TogglePrevious = 0;
StatusYesOrNo FirstTimeIssued = YES;


void SetupUSART();

int main(void)
{

	RC5_Receiver_Init();
	SetupUSART();
    while(1)
    {
    	/* If RC5 frame has been received, then decode it */
    	     if (RC5_FrameReceived == YES)
    	     {


    	        /* Get the RC5 frame */
    	        RC5_Frame = RC5_Decode();


    	        USART_SendData(USART1,RC5_Frame.Command);


    	     }
    	     __WFI();
    }
}



/***************************************************************************//**
 * @brief Init USART1
 ******************************************************************************/
void SetupUSART()
{

      GPIO_InitTypeDef  GPIO_InitStructure;
      USART_InitTypeDef USART_InitStructure;

      /* Enable GPIOA clock                                                   */
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

      /* Configure USART1 Rx (PA10) as input floating                         */
      GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_10;
      GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN_FLOATING;
      GPIO_Init(GPIOA, &GPIO_InitStructure);

      /* Configure USART1 Tx (PA9) as alternate function push-pull            */
      GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF_PP;
      GPIO_Init(GPIOA, &GPIO_InitStructure);

      RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
      /* USART1 configured as follow:
            - BaudRate = 9600 baud
            - Word Length = 8 Bits
            - One Stop Bit
            - No parity
            - Hardware flow control disabled (RTS and CTS signals)
            - Receive and transmit enabled
            - USART Clock disabled
            - USART CPOL: Clock is active low
            - USART CPHA: Data is captured on the middle
            - USART LastBit: The clock pulse of the last data bit is not output to
                             the SCLK pin
      */
      USART_InitStructure.USART_BaudRate            = 9600;
      USART_InitStructure.USART_WordLength          = USART_WordLength_8b;
      USART_InitStructure.USART_StopBits            = USART_StopBits_1;
      USART_InitStructure.USART_Parity              = USART_Parity_No ;
      USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
      USART_InitStructure.USART_Mode                = USART_Mode_Rx | USART_Mode_Tx;
      USART_Init(USART1, &USART_InitStructure);
      USART_Cmd(USART1, ENABLE);
}



Ссылки на описание и библиотеку.
www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/CD00267896.pdf
dekar.wc3edit.net/st%20website/an3174.zip

Комментарии (18)

RSS свернуть / развернуть
А пробовал ли ктолибо запускать эту библиотеку на STM32VL Discovery?
Использую CoIDE, создал проект, вроде все настроил (еще пока что не сильно разбираюсь в регистрах stm32) и в итоге библиотека как я заметил даже на сигналы не реагирует, т.е. прерывание по изменению сигнала не вызывается… инициализируется всё и крутиться в Main цикле.
Возможно кто либо делал и сможет помочь в данном вопросе…
p\s проект если необходимо, могу выложить.
0
Хотя бы для другой среды, но конкретно под Discovery хотя бы пример или разьяснения, если есть у кого… буду очень благодарен!
p\s подцепил на Pin0 GPIOA приёмник, заметил что если прерывание назначить на 0е, то «подвисает» основной цикл(по умолчанию выводиться точка в UART, каждый разпрохождения основного цикла), а на другие — вообще 0 внимания. Пробовал и на GPIOB, другие пины — эффект 0.
А также еще заметил, что если один раз прошить прошивкой, в которой используеться __WFI(); -то потом его не прошить никак (постоянно ошибка записи\стирания), если только не нажать на reset кнопку и удерживая её стереть\прошить mcu.
0
Не пробовал. Но можно сделать несколько предположений.
Там в коде определены прерывания таймера типа RC_TIMблаблабла. Соотвествие номера прерывания и названия функции обычно в startup ассемблерном файле. Если имена в с и asm не соответствуют — то препывание не будет вызвано. Достаточно привести в соотвествие название функций прерываний в ассемблерном файле и в коде c.
Еще есть контроллер прерываний. Его тоже нужно правильно настроить.
0
Настойки порта и пина у меня так:

#define RC5_GPIO_PORT          GPIOA                /* Port which RC5 is connected */
#define RC5_GPIO_CLK           RCC_APB2Periph_GPIOA /* Clock of Port which RC5 is connected */
#define RC5_GPIO_PIN           GPIO_Pin_0           /* Pin which RC5 is connected */
#define RC5_EXTI_PORT_SOURCE   GPIO_PortSourceGPIOA /* RC5 EXTI Port source */
#define RC5_EXTI_PIN_SOURCE    GPIO_PinSource0      /* RC5 EXTI Pin source */
#define RC5_EXTI_IRQn          EXTI4_IRQn           /* RC5 EXTI IRQ */
#define RC5_EXTI_LINE          EXTI_Line4           /* RC5 EXTI line */
#define RC5_EXTI_IRQHandler    EXTI4_IRQHandler     /* RC5 IRQ handler */


А настройки таймера так:

#define RC5_TIM                TIM3                 /* Timer used for RC5 decoding */
#define RC5_TIM_CLK            RCC_APB1Periph_TIM3  /* Clock of the used timer */
#define RC5_TIM_IRQn           TIM3_IRQn            /* RC5 TIM IRQ */
#define RC5_TIM_IRQHandler     TIM3_IRQHandler      /* RC5 TIM IRQ handler */


посмотрел ASM файл, но не нашел нигде в генерируемых папках… только обджект\бин\иксмл… что явно не то.
а нет ли где либо соответствия к конкретному пину — такое то прерывание? (к примеру в даташитах атмег подобное было..)
тут же и мануалы для программирования и даташиты проглядел, не увидел ничего подобного :( или пропустил…
0
Ага… тогда я не прав, все что я написал — бред. Там все передефайнено и названия правильные в итоге получаются.
>а нет ли где либо соответствия к конкретному пину — такое то прерывание?
Это как раз есть в reference manual — главном документе. В описании регисторов External interrupt configuration register.
и секции External interrupt/event controller
0
  • avatar
  • OlegG
  • 26 сентября 2012, 16:02
#define RC5_EXTI_PIN_SOURCE GPIO_PinSource0 /* RC5 EXTI Pin source */
#define RC5_EXTI_IRQn EXTI4_IRQn /* RC5 EXTI IRQ */
#define RC5_EXTI_LINE EXTI_Line4 /* RC5 EXTI line */
#define RC5_EXTI_IRQHandler EXTI4_IRQHandler /* RC5 IRQ handler */
Как я понимаю должно быть соотвествие между GPIO_PinSource0 и EXTI4_IRQn. Либо все нужно изменить на 0 либо все на 4.
0
  • avatar
  • OlegG
  • 26 сентября 2012, 16:14
хм, а когда всё к примеру в 0 ставлю — то при первом изменении сигнала всё зависает…
0
причём не важно, rc5 посылка ли это или случайная помеха так сказать… просто импульса одного хватает на вход и всё виснет… (
0
выбор таймера тоже не влияет на это…
0
Это может означать вызов обработчика по умолчанию. А по умолчанию там глухой цикл стоит.
EXTI4_IRQHandler — и вот это изменяете? И весь код перекомпилируете?
0
тоже об этом подумал, ибо не давно статью про прерывания читал))
да, все 4ре строки меняю на 0.
значит ли это, что не назначаеться функция для обработки прерывания? хотя я ничего не менял в библиотеке, дальше настроек и добавления uart посылок в начале некоторых функций, что бы видеть текущее состояние (пробовал убирать, не помогает -> не из-за них).
0
хммм… как я понимаю по коду должна вызываться функция void RC5_MeasureFirstLowDuration(void), но она нигде не назначаеться на обработку…
0
Она дергается из прерывания, а прерывание само вызывается по дерганью ножки. Но по дерганию ножки оно не вызывается, поскольку вызываестя что то еще.
Поищите в coide файл, который содержит EXTI0_IRQHandler. Если не найдета, ищите что то подобное IRQHandler или даже просто handler. Имена функций в коде в define и в ide должны совпадать.
Он может выглядит примерно так www.coocox.org/repo/56e31cf1-9c7b-11e0-a293-001fd0c63d33/src/startup/startup_lm3s.c.htm. Но это для другого контроллера
+1
robocraft.ru/blog/ARM/653.html — вот тут написано что этот файл должен лежать в каталоге cmsis_boot
+1
  • avatar
  • OlegG
  • 26 сентября 2012, 18:58
Спасибо! Нашел таки)
да, там в конце необходимо добавить вот чего:

void RC5_TIM_IRQHandler(void)
{
   RC5_Sample_Data();
}

void RC5_EXTI_IRQHandler(void)
{
   RC5_MeasureFirstLowDuration();
}


и чуть выше этого не забыть изменить строки:

#pragma weak EXTI0_IRQHandler = RC5_EXTI_IRQHandler
#pragma weak TIM4_IRQHandler = RC5_TIM_IRQHandler


после этих изменений mcu перестаёт зависать при первом прерывании и даже чтото расшифровывает от пульта) только на все кнопки примерно так отзываеться:
Received:
-0000+0031+0063
Received:
-0000+0021+0059
Received:
-0000+0031+0063
p\s исходный текст, что в юарт пишеться таков:

if (RC5_FrameReceived == YES)
	{
		RC5_Frame = RC5_Decode();
		send("\rReceived:\r");
		ltoa_(RC5_Frame.ToggleBit,chardata,6);
		send(chardata);
		ltoa_(RC5_Frame.Address,chardata,6);
		send(chardata);
		ltoa_(RC5_Frame.Command,chardata,6);
		send(chardata);
	}


и более того, заметил, что если пальцем на принимающий пин коснуться или просто рукой провод принимающего пина потрогать, то он ТОже принимать начинает посылки…
Received:
+0001+0031+0124
Received:
+0001+0029+0063
Received:
+0001+0015+0012
Received:
+0001+0015+0125

О__О что я делаю не так…
0
после AVRок конечно сначала всё сложно сильно и замудрено кажется, но понемногу начинаю вьезжать в логику и гибкость настроек)
0
Можно переделать RC5 infrared transmitter for STM8L под STM32 и замкнуть их друг на друга.
RC5 IR transmitter using the IRTIM modulator firmware
0
  • avatar
  • x893
  • 26 сентября 2012, 19:59
второй платки то нету, чтобы передатчик еще делать… да и не сильный я программист. а уж тем более в STM — «сильно начинающий» пока что)
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.