您的位置:首页 > 其它

DIY个人智能家庭网关——硬件篇之433M无线接收解码器(二)

2017-02-26 23:19 501 查看
为了降低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.
*
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/

/* Includes ------------------------------------------------------------------*/
#include <stdio.h>
#include <string.h>
#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;i<sizeof(struct user_code_info);i++)
{
*p = FLASH_ReadByte(addr+i);
p++;
}
}

void write_user_code_info(struct user_code_info *info)
{
u32 addr = FLASH_DATA_START_PHYSICAL_ADDRESS;
u8 i;
u8 *p = (u8 *)info;

for(i =0;i<sizeof(struct user_code_info);i++)
{
FLASH_ProgramByte(addr+i, *p);
p++;
}
}

void dump_user_code_info(struct user_code_info *info)
{
u8 i;

printf("magic:0x%lx\r\n", info->magic);
printf("number:%d\r\n", info->number);

for(i=0;i<info->number;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;i<info->number;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;i<USER_CODE_NUMBER_MAX;i++)
{
info->code[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****/


从代码中可以看到,解码成功后,把数据格式化成JSON,然后通过printf输出到串口,这样路由器就可以从USB串口读取到解码数据了。

项目源代码:http://pan.baidu.com/s/1mhMXuNQ 密码:f1e5
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: