为了降低DIY难度,我提供了方案二:采用现成的模块来搭建解码器,需要如下模块
1、STM8S103F单片机模块和编程器
2、433M无线接收模块
3、PL2303 USB转串口模块
另外还需要一些杜邦线用来连接这些模块,这些东西都可以在淘宝上买得到。
STM8S103F代码如下
/**
******************************************************************************
* @file Project/main.c
* @author MCD Application Team
* @version V2.1.0
* @date 18-November-2011
* @brief Main program body
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* © COPYRIGHT 2011 STMicroelectronics
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include
#include
#include "stm8s.h"
#include "stm8s_exti.h"
#include "stm8s_it.h"
#include "stm8s_gpio.h"
#include "stm8s_tim2.h"
#include "stm8s_tim4.h"
#include "stm8s_uart1.h"
/* Private defines -----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
#define LED_GPIO_PORT (GPIOB)
#define LED_GPIO_PINS (GPIO_PIN_5)
#define PULS_LEVEL_HIGH (1)
#define PULS_LEVEL_LOW (0)
#define DEBUG (1)
#define USER_CODE_NUMBER_MAX (10)
#define USER_CODE_INFO_MAGIC (0x12345678)
#define LED_ON GPIO_WriteLow(GPIOB, GPIO_PIN_5)
#define LED_OFF GPIO_WriteHigh(GPIOB, GPIO_PIN_5)
#define LED_REVERSE GPIO_WriteReverse(GPIOB, GPIO_PIN_5)
u32 code_addr;
u32 code = 0;
u32 puls_high = 0;
u32 puls_low = 0;
u8 current_puls_level=PULS_LEVEL_LOW;
u8 check_flag = 0;
u8 found_flag = 0;
s32 value = 0;
u32 last_code = 0;
u32 last_valid_code = 0;
u32 puls_width_compare = 0;
u8 bit_count = 0;
u8 learn_flag = 0;
u32 learn_led_count = 0;
u32 timeout_count = 0;
u32 time_count = 0;
u32 puls_high_time = 0;
u32 puls_low_time = 0;
u32 button_down_count = 0;
struct user_code_info
{
u32 magic;
u8 number;
u16 code[USER_CODE_NUMBER_MAX];
};
struct user_code_info user_info;
/* Private defines -----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
void Init_GPIO(void)
{
// led, PB5
GPIO_Init(GPIOB, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_FAST);
LED_OFF;
// 433M signal input, PC3, pull up, interrupt
GPIO_Init(GPIOC, GPIO_PIN_3, GPIO_MODE_IN_FL_IT);
EXTI_DeInit();
EXTI_SetExtIntSensitivity(EXTI_PORT_GPIOC, EXTI_SENSITIVITY_RISE_FALL);//falling and rising
// button
GPIO_Init(GPIOC, GPIO_PIN_4, GPIO_MODE_IN_PU_NO_IT);
// ouput gpio
GPIO_Init(GPIOC, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_FAST);
GPIO_WriteLow(GPIOC, GPIO_PIN_5);
GPIO_Init(GPIOC, GPIO_PIN_6, GPIO_MODE_OUT_PP_LOW_FAST);
GPIO_WriteLow(GPIOC, GPIO_PIN_6);
GPIO_Init(GPIOC, GPIO_PIN_7, GPIO_MODE_OUT_PP_LOW_FAST);
GPIO_WriteLow(GPIOC, GPIO_PIN_7);
GPIO_Init(GPIOD, GPIO_PIN_2, GPIO_MODE_OUT_PP_LOW_FAST);
GPIO_WriteLow(GPIOD, GPIO_PIN_2);
}
void Init_Timer4(void)
{
TIM4_ARRPreloadConfig(ENABLE);
TIM4_TimeBaseInit(TIM4_PRESCALER_8, 0xff);//
TIM4_ClearFlag(TIM4_FLAG_UPDATE);
TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);
//TIM4_Cmd(ENABLE);
}
void Init_Timer2(void)
{
TIM2_DeInit();
TIM2_TimeBaseInit(TIM2_PRESCALER_64,0xFFFF);
TIM2_ITConfig(TIM2_IT_UPDATE , ENABLE);
TIM2_SetCounter(0);
TIM2_Cmd(ENABLE);
}
void Init_Clk(void)
{
CLK_DeInit();
CLK_HSICmd(ENABLE);
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV2);
Init_Timer2();
}
#if DEBUG
void Init_UART1(void)
{
UART1_DeInit();
UART1_Init((u32)9600, UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO, UART1_SYNCMODE_CLOCK_DISABLE, UART1_MODE_TX_ENABLE);
UART1_Cmd(ENABLE);
}
void UART1_Send(uint8_t dat)
{
while(( UART1_GetFlagStatus(UART1_FLAG_TXE)==RESET));
UART1_SendData8(dat);
}
int putchar(int c)
{
UART1_Send((u8)c);
return (c);
}
#endif
void delay_ms(u32 t)
{
u32 i;
for(;t>0;t--)
for(i=0xFF;i>0;i--);
}
void Init_EEPROM(void)
{
FLASH_DeInit();
FLASH_Unlock(FLASH_MEMTYPE_DATA);
FLASH_SetProgrammingTime(FLASH_PROGRAMTIME_STANDARD);
}
void read_user_code_info(struct user_code_info *info)
{
u32 addr = FLASH_DATA_START_PHYSICAL_ADDRESS;
u8 i;
u8 *p = (u8 *)info;
for(i =0;imagic);
printf("number:%d\r\n", info->number);
for(i=0;inumber;i++)
{
printf("code[%d]:0x%04x\r\n", i, info->code[i]);
}
}
void save_new_code(struct user_code_info *info, u16 code)
{
u8 i;
for(i = 0;inumber;i++)
{
if(info->code[i] == code)
return;
}
if(info->number < USER_CODE_NUMBER_MAX)
{
info->code[info->number] = code;
info->number++;
}
else
{
for(i=1;icode[i-1] = info->code[i];
}
info->code[USER_CODE_NUMBER_MAX-1] = code;
}
write_user_code_info(&user_info);
dump_user_code_info(&user_info);
}
void my_job(u8 channel)
{
switch(channel)
{
case 1:GPIO_WriteReverse(GPIOC, GPIO_PIN_5);break;
case 2:GPIO_WriteReverse(GPIOC, GPIO_PIN_6);break;
case 3:GPIO_WriteReverse(GPIOC, GPIO_PIN_7);break;
case 4:GPIO_WriteReverse(GPIOD, GPIO_PIN_2);break;
default:break;
}
}
#if 0
void handle_code(u32 code)
{
u16 addr = code >> 8;
u8 data = code & 0xFF;
s8 channel = -1;
// PT6624 chip
if(data == 0xC0 || data == 0x30 || data == 0x0C || data == 0x03)
{
switch(data)
{
case 0xC0:channel = 1;break;
case 0x30:channel = 2;break;
case 0x0C:channel = 3;break;
case 0x03:channel = 4;break;
default: break;
}
}
else // other chip
{
switch(data&0x0F)
{
case 0x08:channel = 1;break;
case 0x04:channel = 2;break;
case 0x02:channel = 3;break;
case 0x01:channel = 4;break;
default: break;
}
}
if(learn_flag)
{
save_new_code(&user_info, addr);
learn_flag = 0;
}
else
{
u8 i;
if(user_info.number==0)
{
return;
}
else
{
for(i = 0;i < user_info.number;i++)
{
if(user_info.code[i] == addr)
{
my_job(channel);
LED_ON;
delay_ms(100);
LED_OFF;
delay_ms(300);
}
}
}
}
#if DEBUG
printf("code:0x%lx addr:0x%04x data:0x%02x chan:%d\r\n", code, addr, data, channel);
#endif
}
#else
void handle_code(u32 code)
{
u16 addr = code >> 8;
u8 data = code & 0xFF;
//printf("addr:0x%04x data:0x%02x\n", addr, data);
printf("{\"type\":\"trigger\", \"addr\":\"0x%04x\",\"data\":\"0x%02x\"}", addr, data);
LED_ON;
delay_ms(100);
LED_OFF;
delay_ms(400);
}
#endif
void main(void)
{
Init_Clk();
Init_GPIO();
Init_Timer2();
Init_Timer4();
Init_EEPROM();
#if DEBUG
Init_UART1();
#endif
read_user_code_info(&user_info);
if(user_info.magic != USER_CODE_INFO_MAGIC)
{
memset(&user_info, 0, sizeof(user_info));
user_info.magic = USER_CODE_INFO_MAGIC;
user_info.number = 0;
write_user_code_info(&user_info);
}
dump_user_code_info(&user_info);
enableInterrupts();
while (1)
{
// button
if(GPIO_ReadInputPin(GPIOC, GPIO_PIN_4)==0)
{
button_down_count++;
}
else
{
// long press, 3 seconds
if(button_down_count > 80000)
{
user_info.number = 0;
write_user_code_info(&user_info);
learn_flag = 0;
u8 i;
for(i = 0;i<5;i++)
{
LED_REVERSE;
delay_ms(80);
}
LED_OFF;
} // short press
else if(button_down_count > 10000)
{
learn_flag = !learn_flag;
}
button_down_count = 0;
}
if(check_flag)
{
if(found_flag == 0)
{
if(puls_high_time>0)
{
value = puls_low_time/puls_high_time;
if(value > 24 && value < 35)
{
found_flag =1;
code = 0;
bit_count = 0;
}
}
}
else
{
if(bit_count == 0)
{
puls_width_compare = puls_high_time+puls_low_time;
}
value = puls_high_time+puls_low_time-puls_width_compare;
if(value < 20 && value > -20)
{
code <<= 1;
if(puls_high_time > puls_low_time)
{
code |= 0x1;
}
bit_count++;
if(bit_count == 24)
{
handle_code(code);
found_flag = 0;
}
}
else
{
bit_count = 0;
found_flag = 0;
}
}
check_flag = 0;
}
if(learn_flag)
{
learn_led_count++;
if(learn_led_count == 4000)
{
LED_REVERSE;
learn_led_count = 0;
}
}
else
{
LED_OFF;
}
}
}
INTERRUPT_HANDLER(EXTI_PORTC_IRQHandler, 5)
{
//LED_REVERSE;
TIM2_Cmd(DISABLE);
time_count += TIM2_GetCounter();
if(GPIO_ReadInputPin(GPIOC, GPIO_PIN_3))
{
//LED_ON;
if(check_flag != 1)
{
puls_low_time = time_count;
check_flag = 1;
}
}
else
{
//LED_OFF;
if(check_flag != 1)
{
puls_high_time = time_count;
}
}
TIM2_SetCounter(0);
time_count = 0;
TIM2_Cmd(ENABLE);
}
INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23)
{
static u32 i=0;
i++;
if(i==25)
{
LED_OFF;
}
else if(i>=150)
{
TIM4_Cmd(DISABLE);
i=0;
last_valid_code = 0;
}
TIM4_ClearITPendingBit(TIM4_IT_UPDATE);
}
INTERRUPT_HANDLER(TIM2_UPD_OVF_BRK_IRQHandler, 13)
{
/* In order to detect unexpected events during development,
it is recommended to set a breakpoint on the following instruction.
*/
//LED_REVERSE;
time_count += 0xFFFF;
TIM2_ClearITPendingBit(TIM2_IT_UPDATE);
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval : None
*/
void assert_failed(u8* file, u32 line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
项目源代码:http://pan.baidu.com/s/1mhMXuNQ 密码:f1e5