九齐051D写的433遥控器

前言

最近一个项目需要实现433遥控器,用九齐的051D写了一个,分享出来加深下印象。

433遥控器,麻烦的是硬件电路,软件部分其实很简单,跟38K的遥控器没什么区别,都是给一个有效电平,然后433发送芯片通过板上的板载天线把433Mhz频率的信号发出。难在硬件设计这块,关于硬件用到的芯片是WF4455TD,是从别处照搬过来的电路,所以没什么可以分享的。

软件部分如下:

/* =========================================================================
 *  Project:       433遥控器
 *  File:          main.c
 *  Description:   051D
 *  
 * 
 *  Author:        
 *  Version:       V1.0
 *  Date:          2022/5/7	
 =========================================================================*/
#include <ny8.h>
#include <ny8_romaccess.h>
#include "rom.h"
#include "ny8_constant.h"

#define  u16  unsigned int
#define  u8   unsigned char

void delay_us(int);
void delay_ms(int);
/* =======================================================================*/

#define  KEY2       PORTBbits.PB5            //KEY2

#define  KEY1       PORTBbits.PB4            //KEY1

#define  KEY3       PORTBbits.PB2            //KEY3

#define  KEY4       PORTBbits.PB0            //KEY4

#define  REC        PORTBbits.PB1            //REC	高电平有效

/* =======================================================================*/
u8      send_data=0;
u8      send_data_buf=0;
u8      i=0;
u8      f_bit_done=0;           //发完1bit标志位
u8      f_stop=0;               //发完一帧停止标志位
u8      t_stop=0;               //停止时间  
u8      f_send_low=0;           //发1bit过程中 高低电平标志位
u8      t_send=0;               //发送次数  即使一直按住按键  每次响应按键也只发送3帧数据
u8      f_send_end=0;           //发下一帧包头标志位

u8      key_delay=0;
u8      f_onkey=0;              //按住按键标志位
u8      t_onkey=0;
u8      no_key=0;               //松手计时

u8		roll_code1=0;
u8		roll_code2=0;
u16     r_temp=0;
u16     r_temp1=0;
/* =======================================================================*/
void delay_us(int count)  //@16M  2T   2.5us
{
	for(;count>0;count--);
}

void delay_ms(int count) //@16M  2T
{
	int i;
    for(;count>0;count--)
    {
        for(i=0;i<=330;i++);
    }
}

void sys_init(void)
{
	PCON &= ~(1<<3);  //关闭LVR  需要在IC_CONFIG里面设置寄存器配置
}

/* =======================================================================*/

void io_init(void)
{
	IOSTB|=((1<<5)|(1<<4)|(1<<2)|(1<<0));      //B.0245输入

    IOSTB&=~(1<<1);     //B1 REC输出    空闲状态为常高电平
    IOSTB&=~(1<<3);     //B3输出    空闲口  置为输出
	BPHCON&=~((1<<5)|(1<<4)|(1<<2)|(1<<0));           //开启B 0245口上拉电阻
    KEY1=1;KEY2=1;KEY3=1;KEY4=1;REC=0;PB3=1;
}

void timer0_init(void)
{
	T0MD  &=~((1<<5)|(1<<3));                       //FINST预分频给T0且为256分频
	TMR0 = 50;
	INTE  |= (1<<0);                                //开启T0中断
	PCON1 |= (1<<0);         				        //开启T0
}

void timer1_init(void)
{
    T1CR1=0X02;                                     //当下溢发生,定时器 1 初始值从TMR1 寄存器被重新加载并继续下数
    T1CR2=0X04;                                     //32分频

    TMR1 = 255;
    INTE  |=(1<<3);                                 //开启T1中断
    T1CR1 |=0x01;                                   //开启T1
}

void pb_init(void)
{
    BWUCON=0;
    BWUCON|=((1<<5)|(1<<4)|(1<<2)|(1<<0));

    INTE  |=(1<<1);                                 //开启PB中断
}

/* =======================================================================*/

void send_rec(void)
{
    if(i>=24 && f_send_end==0)                      //总共发24位 + 1(下一帧包头)
    {
        TMR1=255;

        REC=0;

        i=0;
        f_stop=1;                                   //发完1帧  停12ms
        send_data=0;
    }

    if(f_stop==0)                                   //滚码从0000 0000开始以1为单位步进
    {
        if(i==0)                                    //给滚码数据 0000 0000 从右往左发
        {
            send_data=roll_code1;
        }
        else if(i==8)
        {
            send_data=roll_code2;                   //给滚码数据 0000 0001 从右往左发
        }
        else if(i==16)
        {
            send_data=send_data_buf;                //发各个键不同的键码
        }

        if(f_send_end==1)                           //是否发送下一帧包头
        {
            TMR1=48;                                //高电平时间为400us
            REC = 1;
            f_send_end=0;
        }
        else
        {
            if(send_data&0x01)                      //发“1”
            {
                if(f_send_low==0)                   //先发高电平
                {
                    TMR1=52;                        //高电平时间443us
                    REC = 1;
                    f_send_low=1;
                }
                else
                {
                    TMR1=145;                       //低电平时间1182us
                    REC = 0;
                    f_send_low=0;
                    f_bit_done=1;
                }
            }
            else                                    //发“0”
            {
                if(f_send_low==0)                   //先发高电平
                {
                    TMR1=152;                       //高电平时间1242us
                    REC = 1;
                    f_send_low=1;
                }
                else
                {
                    TMR1=45;                        //低电平时间385us
                    REC = 0;
                    f_send_low=0;
                    f_bit_done=1;
                }
            }

            if(f_bit_done==1)                       //发完1bit数据
            {
                f_bit_done=0;
                send_data=send_data>>1;             //移位
                i++;                                //计数
                if(i==24)
                {
                    f_send_end=1;                   //发完24bit数据 开始发下一帧包头
                }
            }
        }
    }
    else
    {
        t_stop++;                                   //两帧间隔时间 12ms
        if(t_stop>5)
        {
            f_stop=0;
            t_stop=0;
            if(t_send>=1)
            {
                t_send--;
            }
        }
    }
}



void key_scan(void)
{
    if(KEY1==0 && KEY2==1 && KEY3==1 && KEY4==1 && f_onkey==0)
    {
        key_delay++;
        if(key_delay>=5)
        {
            key_delay=0;
            if(KEY1==0 && KEY2==1 && KEY3==1 && KEY4==1 && f_onkey==0)
            {
                f_onkey=1;                      //400ms后再次允许响应
                no_key=0;                       //松手计时清零
                t_onkey=0;

                send_data_buf=0xBF;             //赋值 1011 1111 收到的是 1111 1101
                t_send=3;                       //发三次
                i=0;                            //从第一bit数据开始发起
                f_stop=0;
            }
        }
    }
    else if(KEY1==1 && KEY2==0 && KEY3==1 && KEY4==1 && f_onkey==0)
    {
        key_delay++;
        if(key_delay>=5)
        {
            key_delay=0;
            if(KEY1==1 && KEY2==0 && KEY3==1 && KEY4==1 && f_onkey==0)
            {
                f_onkey=1;
                no_key=0;                       
                t_onkey=0;

                send_data_buf=0xEF;             //赋值 1110 1111 收到的是 1111 0111
                t_send=3;
                i=0;
                f_stop=0;
            }
        }
    }
    else if(KEY1==1 && KEY2==1 && KEY3==0 && KEY4==1 && f_onkey==0)
    {
        key_delay++;
        if(key_delay>=5)
        {
            key_delay=0;
            if(KEY1==1 && KEY2==1 && KEY3==0 && KEY4==1 && f_onkey==0)
            {
                f_onkey=1;
                no_key=0;                     
                t_onkey=0;

                send_data_buf=0x8F;             //赋值 1000 1111 收到的是 1111 0001
                t_send=3;
                i=0;
                f_stop=0;
            }
        }
    }
    else if(KEY1==1 && KEY2==1 && KEY3==1 && KEY4==0 && f_onkey==0)
    {
        key_delay++;
        if(key_delay>=5)
        {
            key_delay=0;
            if(KEY1==1 && KEY2==1 && KEY3==1 && KEY4==0 && f_onkey==0)
            {
                f_onkey=1;
                no_key=0;               
                t_onkey=0;

                send_data_buf=0x7F;             //赋值 0111 1111 收到的是 1111 1110
                t_send=3;
                i=0;
                f_stop=0;
            }
        }
    }

    if(f_onkey==1)
    {
        if(KEY1==1 && KEY2==1 && KEY3==1 && KEY4==1)
        {
            no_key++;
            if(no_key>=5)
            {
                no_key=0;
                if(KEY1==1 && KEY2==1 && KEY3==1 && KEY4==1)
                {
                    f_onkey=0;
                    t_onkey=0;
                    key_delay=0;
                }
            }
        }
    }
}

/* =======================================================================*/

void isr(void) __interrupt(0)
{
    if(INTFbits.T1IF)	//定时器1中断
    {
        INTFbits.T1IF=0;

        if(t_send>=1)
        {
            send_rec();
        }

    }


    if(INTFbits.T0IF)
	{
        INTFbits.T0IF=0;
        TMR0 = 100;

        key_scan();
    }

    if(INTFbits.PBIF)   //仅作唤醒用
	{
        INTFbits.PBIF=0;
    }
}





void main(void)
{
    PCON &=~(1<<3);     //关闭LVR

    io_init();
	delay_ms(50);
	
    timer0_init();
    timer1_init();
    pb_init();
    
    //获取滚码
    r_temp = read_14bit_rom(&__rolling_code_addr);
    r_temp1 = read_14bit_rom(&__rolling_code_addr+1);
    
    roll_code1 = (u8)((r_temp&0xff00)>>8);
    roll_code2 = (u8)r_temp&0x00ff;             //低8位         0X00E的0-7位

    
    
	INTF = 0;         //清除所有中断标志
    DISI();     	  //关闭总中断
	ENI();	    	  //开启总中断
    
    while(1)
    {
        if(t_send<1 && KEY1==1 && KEY2==1 && KEY3==1 && KEY4==1)
        {
            delay_ms(200);
            if(t_send<1 && KEY1==1 && KEY2==1 && KEY3==1 && KEY4==1)
            {
                REC=0;
                SLEEP();	//睡眠
            }
        }
    }
}

4个按键,4个不同的遥控码,按下按键后,连续发送3次同样的遥控码,每次间隔12ms。
这个项目是发24位数据,头码是一段高电平+低电平。具体协议怎么定可以自己规定。
比较特殊的一个地方就是,由于发送“1”或者“0”时,高电平时间很短并且“1”和“0”总周期一样,但是波形并不互补,所以定时器的初值要根据发不同的数据而改变。因为时间要求比较高,所以用的时定时器1,因为定时器1有自动重载功能。

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值