基于杰理RTOS平台的433射频无线数传通信

        在杰理的AC7916N实现了433射频的数据发送,在杰理的AD15系列实现433射频接收,本代码用于门铃项目收发,下面请看代码。

         首先是AC7916N的433数据发送代码,发送部分的程序放在一个400us的定时器中断服务程序中,这种方式笔者并不推荐,由于笔者本人较懒,能跑的程序就不想动,后期读者可以通过信号量或事件的方式,对其进行完善,代码只供读者参考。

 send_data_433.c:

#include "send_data_433.h"
#include "wifi/wifi_connect.h"
#include "timer4.h"
#include "pc_cmd_analysis.h"

/******************************* 433Data ****************************************/
static char us_num = 0;
static char bit_num = 0;
u8 dat_433=0;
u8 SendData_433[4]={0};
u8 Send433Data[4]={0};
u8 flag_send_data = 0;
u8 send_num = 0;
u8 Cnt_SendAndLead = 0;
u8 Cnt_SendAndLead_More = 0;

#define MLOGD printf

static void send_pin_init()
{
    //设置引脚的方向为输出,并设置为低电平
    gpio_direction_output(PIN_DATA, 0);
}

static void set_pin_high()
{
    gpio_direction_output(PIN_DATA, 1);
}

static void set_pin_low()
{
    gpio_direction_output(PIN_DATA, 0);
}

void HI_433GetAddress(void)
{
    //void *cfg_handle = wifi_cfg_init();
    unsigned char mac_addr[6] = {0};

	wifi_get_mac(mac_addr);

    SendData_433[0]=mac_addr[2];
    SendData_433[1]=mac_addr[3];
    SendData_433[2]=mac_addr[4];
    SendData_433[3]=mac_addr[5];

    /*SendData_433[0]=0xf8;
    SendData_433[1]=0x1b;
    SendData_433[2]=0x31;
    SendData_433[3]=0xac;*/

#ifdef MCU_DEBUG_PRINT
    printf("WIFI_MAC:=%02X:%02X:%02X:%02X:%02X:%02X\n",
            mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);

    printf("WIFI_433data:=%02X:%02X:%02X:%02X\n",
            SendData_433[0], SendData_433[1], SendData_433[2], SendData_433[3]);
#endif
}

void Lead_Code433()                                     //引导码+同步码:高电平延时400us+低电平延时12.4ms
{
    if (us_num < 1)
        set_pin_high();
    else
        set_pin_low();

    us_num++;

    if (us_num >= 32)
    {
        us_num = 0;
        Cnt_SendAndLead++;
        return;
    }
}


void Send_Data_433(unsigned int dat)
{
    if(us_num == 0)
        dat_433 = dat;

    bit_num++;
    us_num++;
    if (dat_433 & 0x80) // dat_433第8位为1
    {
        if (bit_num < 4)
            set_pin_high();
        else if (bit_num == 4)
            set_pin_low();
    }
    else
    {
        if (bit_num == 1)
            set_pin_high();
        else if (bit_num > 1)
            set_pin_low();
    }

    if (bit_num == 4)
    {
        dat_433 = dat_433 << 1; //左移先发位
        // printf("DATA=0x%x bit_num =%d,us_num=%d\n",dat_433,bit_num,us_num);
        bit_num = 0;
    }

    if (us_num >= 32)
    {
        us_num=0;
        bit_num = 0;
        Cnt_SendAndLead++;
        if (Cnt_SendAndLead > 4)
        {
            Cnt_SendAndLead = 0;
            Cnt_SendAndLead_More++;
            if (Cnt_SendAndLead_More >= (10 * send_num)) // 20次
            {
                Cnt_SendAndLead_More = 0;
                if(!Send_433_Test_flag)//产测时是不停发送433数据的,
                    flag_send_data = 0;//定时中断停止发送
            }
        }
        return;
    }
}


void HI_SendData_433_1527(unsigned char Address0,unsigned char Address1,unsigned char Address2,unsigned char Address3)
{
    switch(Cnt_SendAndLead)
    {
    case 0:
        Lead_Code433();     //Lead_Code1527();
        break;
    case 1:
        Send_Data_433(Address0);    //Send_Data1527(Address0);
        break;
    case 2:
        Send_Data_433(Address1);    //Send_Data1527(Address1);
        break;
    case 3:
        Send_Data_433(Address2);    //Send_Data1527(Address2);
        break;
    case 4:
        Send_Data_433(Address3);    //Send_Data1527(Address3);
        break;
    }

#ifdef MCU_DEBUG_PRINT
    //printf("Send 433Data is OK\n\r");
#endif
}

void Senddata_433_task(int num)
{
    u8 i=0;

    Send433Data[0] = (SendData_433[0]& 0x0F) | (0x10);//SendData_433是wifi_cfg_get_addr1(cfg_handle, (char *)mac_addr);来的
    Send433Data[1] = SendData_433[1];
    Send433Data[2] = SendData_433[2];
    Send433Data[3] = SendData_433[3];

    for(i=0;i<4;i++)
        MLOGD("Send433Data[%d]=0x%x | SendData_433[%d]=0x%x",i,Send433Data[i],i,SendData_433[i]);
    MLOGD("\n");

    set_pin_low();

    flag_send_data = 1;

    send_num = num;

    TMR->CNT = 0;
    /*
    for(i=0;i<num;i++)
    {
        HI_SendData_433_1527(Send433Data[0],Send433Data[1],Send433Data[2],Send433Data[3]);
    }*/
}

/*
int factory_flag;
void Senddata_433_test_start(void *args)//用于产测
{
    static u8 cnt;
    unsigned int Send433Data[4]={0};
    MLOGD("Senddata_433_test_start \n");
    Send433Data[0] = (SendData_433[0]& 0x0F) | (0x10);
    Send433Data[1] = SendData_433[1];
    Send433Data[2] = SendData_433[2];
    Send433Data[3] = SendData_433[3];
    factory_flag = 0;

    while(factory_flag == 0)
    {
        HI_SendData_433_1527(Send433Data[0],Send433Data[1],Send433Data[2],Send433Data[3]);
        os_time_dly(100);//一个数10ms,100个就是延时1000ms
        if(++cnt >1)
        {
            factory_flag = 1;
            cnt =0;
        }
    }
    MLOGD("Senddata_433_test_start  is ok\n");
    //OS_TaskDelete(NULL);
}

u8 Senddata_433_test_end(void)
{
    factory_flag =1;
    MLOGD("Senddata_433_test_end \n");
    return 1;
}
*/

void HI_Send433_task(void *args)
{
	int err;
	int msg[32];   //接收消息队列buf
#ifdef  MCU_DEBUG_PRINT
    printf("HI_Send433_task is runnig \n\r");
#endif
    while(1)
    {
        printf("HI_Send433_task\n");
		//阻塞等待消息
		err = os_taskq_pend("taskq", msg, ARRAY_SIZE(msg));//在os_taskq_pend中msg[0]接收的是消息个数,即argc==msg[0],argv[0]==msg[1]
        if (err != OS_TASKQ || msg[0] != Q_USER) {
            printf("os_taskq_pend err!");
            continue;
        }
        MLOGD("HSend433 Reci!\n");
		switch (msg[1]) {
        case MESSAGE_433:
      		printf("get MESSAGE_1, data : %d\n", msg[2]);
        	MLOGD("HSend433 Data---------! \n\r");
        	Senddata_433_task(2);//50zhen
		break;
	    }
    }
}

void send_message_433(u8 messages)
{
	int err;
	int argc = 2;  //消息个数
    int argv[4];

	//发送的消息内容
  	argv[0] = messages;//在os_taskq_pend中msg[0]接收的是消息个数,即argc==msg[0],argv[0]==msg[1]
  	argv[1] = 12;
_retry1:
    err = os_taskq_post_type("send_433_data_task", Q_USER, argc, argv);
    //err = os_taskq_post("queue_task", argc, argv[0], argv[1]);//采用该接口发送信息时可变参数个数不能超过8个
    if(err == OS_Q_FULL)
    {
      os_time_dly(5);
	  printf("err == OS_Q_FULL\n");
      goto _retry1;
    }
    printf("MESSAGE_433 send succ\n");
}

/*在任务列表中添加:
{"send_433_data_task",  23,      512,   64    },
*/
void send_data_433_entrance(void)
{
	static int send433data_pid;
    send_pin_init();
    //sys_timer_add(NULL, Rf433Send_Handle,10000);//300MS
	thread_fork("send_433_data_task", 31, 1024, 128, &send433data_pid, HI_Send433_task, NULL);
}
late_initcall(send_data_433_entrance);

send_data_433.h:

#ifndef _SEND_DATA_433_H
#define _SEND_DATA_433_H

#include "app_config.h"
#include "asm/includes.h"
#include "generic/typedef.h"
#include "asm/clock.h"
#include "asm/adc_api.h"
#include "system/timer.h"
#include "asm/efuse.h"
#include "asm/p33.h"
#include "asm/power_interface.h"
#include "device/gpio.h"
#include "system/includes.h"
#include "sys_timer.h"

#define PIN_DATA  IO_PORTC_01

extern u8 Send433Data[4];
extern u8 flag_send_data;

void HI_433GetAddress(void);
void Senddata_433_test_start(void *args);
void Senddata_433_task(int num);
void HI_SendData_433_1527(unsigned char Address0,unsigned char Address1,unsigned char Address2,unsigned char Address3);
void send_message_433(u8 messages);

enum {
    MESSAGE_433      = 0x01,
};

#endif

timer5.c:

#include "timer5.h"
#include "send_data_433.h"

//用户只能选择:JL_TIMER2、JL_TIMER3、JL_TIMER4、JL_TIMER5
//PWM使用定时器2或者3映射PWM时候,不能用于定时
#define USE_TIMER_TEST1_DEMO
#ifdef  USE_TIMER_TEST1_DEMO

JL_TIMER_TypeDef *TMR = JL_TIMER5;//选择定时器5
static u8 timer_irq = IRQ_TIMER5_IDX;//选择定时器4

static const u8 timer_index[16] =  {0, 4, 1, 5, 2,  6,  3,  7,   8,   12,  9,    13,   10,   14,   11,    15};
static const u32 timer_table[16] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768};
static u32 timer_clk = 0;

#define AWINLINE   __attribute__((always_inline))

//#define TSEC SEC_USED(.volatile_ram_code) //当中断1ms一下,建议使用函数放在内部ram
#define TSEC

static AWINLINE TSEC void timer_cfg(u32 freq, u32 us)
{
    u32 clock = timer_clk;
    u8 psc = 0;
    u8 tmp = 0;
    u32 prd = 0;
    u32 ts = us / (1000 * 1000);//计算秒
    u32 tu = us % (1000 * 1000);//计算秒剩余us
    u8 i;
    float tp = 0;

    if (freq >= clock) {
        freq = clock;
    } else if (freq <= 1) {
        freq = 1;
        if (ts) {
            tp = (float)tu / (1000 * 1000);
        }
    }
    /*求prd值*/
    prd = clock / freq;
    if (prd > 65535) {
        for (psc = 0; psc < 16; psc++) {
            prd = (u32)(clock / (timer_table[psc]) / freq);
            if (prd <= 65535) {
                break;
            } else if (psc == 15) {
                prd = 65535;
                break;
            }
        }
    }
    prd = ts ? (prd * ts + tp * prd) : prd;
    psc = timer_index[psc];
    TMR->CON = 0;
    TMR->CNT = 0;
    TMR->CON |= BIT(14);
    TMR->PRD = prd;
    TMR->CON |= psc << 4; //lsb_clk分频
    TMR->CON |= BIT(0);
}
static void TSEC timer_set(u32 us)//设置时间,该函数可以在中断调用重新设置定时器值
{
    u32 freq = 1000000 / us;
    timer_cfg(freq, us);
}
static void TSEC timer_freq_set(u32 freq)//设置频率,该函数可以在中断调用重新设置定时器值
{
    timer_cfg(freq, 0);
}
static ___interrupt TSEC void timer_isr(void)//中断
{
    if (TMR->CON & BIT(15)) {
        TMR->CON |= BIT(14);
        //putchar('@');
        //todo,中断函数执行程序...
        if(flag_send_data)
        {
            HI_SendData_433_1527(Send433Data[0],Send433Data[1],Send433Data[2],Send433Data[3]);
        }
    }
}

//example test
static int timer_entrance(void)
{
    timer_clk = clk_get("timer");//先获取定时器的时钟源
    request_irq(timer_irq, 7, timer_isr, 0);//注册中断函数定和中断优先级
#if 1
    timer_set(400); //初始化400us进一次中断
#else
    //timer_freq_set(10000);//设置10K频率进中断
#endif
    return 0;
}
late_initcall(timer_entrance);
#endif

timer5.h

#ifndef _TIMER5_H
#define _TIMER5_H

#include "app_config.h"
#include "system/includes.h"
#include "device/device.h"
#include "asm/clock.h"


extern JL_TIMER_TypeDef *TMR;

#endif

接下来的部分是在AD15N系列实现的433接收部分,其处理程序是放在定时器80us中断里面处理的,笔者这样写的代码可以跑,但是不保证没有问题,所以读者并不推荐这种方式,读者可以尝试用标志位的方式。好了,就说到这里,下面请看接收端的代码:

receive_433.c:

#include "receive_433.h"
#include "key.h"

#define LOG_TAG_CONST       NORM
#define LOG_TAG             "[normal]"
#include "debug.h"
#include "msg.h"
#include "vm.h"

#define printf  log_info

unsigned int Rf_Cnt;
unsigned int Lo_Cnt;
unsigned int Hi_Cnt;

unsigned int Count_Lead;
unsigned int Count_Data_Hi;
unsigned int Count_Data_Lo;

unsigned int Recv_Bit_Cnt;
unsigned int Recv_Byte_Cnt;
unsigned char Recv_Data_Buf;
unsigned char Rf_Data[4];
unsigned int Rf_Control_Data;

unsigned char Rf_Address[4] ={0};

u8 NSong,NVolume;
u8 Timer2 =0;
u8 jk=0;
u8 Mute_flag = 0;
u8 PLAY_FLAG = 0;
u8 P13_LOCK = 0;
u8 Addr_FLAG = 0;    //Press and hold to update the address only once
u8 TIMER2_FLAG = 0;
u8 WDT_TIME =0;
u8 mutenum =0;

extern void delay(volatile u32 t);

void HI_EraseAddress(void)//往flash中写0xff  清除配对
{
    Rf_Address[0] = 0xFF;
    Rf_Address[1] = 0xFF;
    Rf_Address[2] = 0xFF;
    Rf_Address[3] = 0xFF;

    vm_write(VM_INDEX_433_ADDR, Rf_Address, sizeof(Rf_Address));
}


void timer0_handle(void)
{
    switch(Rf_Cnt)
    {
      case 0 :
              //printf("Rf_Cnt = %d\n",Rf_Cnt);                                                         //12ms引导码
	          if(!(DATA_433))                                                  //低电平累积次数
		      {
                //printf("DATA_433==0\n",Rf_Cnt);
		        Count_Lead++;
		      }
	          else                                                       //高电平判断范围
		      {
		          //printf("DATA_433==1\n",Rf_Cnt);
				if((Count_Lead >= 70) && (Count_Lead <= 200))           //5.6ms - 16ms
				   {
					  Count_Lead=0;
                      Recv_Data_Buf = 0x00;                              //初始化参数
					  Count_Data_Hi = 0;
					  Count_Data_Lo = 0;
				      Recv_Bit_Cnt  = 0;
				      Recv_Byte_Cnt = 0;
					  Rf_Cnt=1;
				   }
				else                                                     //范围不对退出
                   {
					  Count_Lead=0;
					  Rf_Cnt=0;
				   }
	          }
      break;

      case 1 :
              //printf("Rf_Cnt = %d\n",Rf_Cnt);                                                      //数据位高电平部分判断
			  if(DATA_433)                                                  //高电平累积次数
			  {
			    //printf("DATA_433 == 1\n");
			    Count_Data_Hi++;
			  }
			  else                                                       //低电平判断范围
			  {
				 if((Count_Data_Hi >= 1) && (Count_Data_Hi <= 30))       // 80us - 2.4ms
					  {
						Hi_Cnt = Count_Data_Hi;                          //存储计数,区分0跟1数据用的
						Count_Data_Hi = 0;
					    Rf_Cnt=2;
					    //printf("Rf_Cnt ==2 \n");
					  }
				 else
				      {
						Rf_Cnt=0;
						//printf("Rf_Cnt ==0 \n");
					  }
		       	}
      break;

      case 2:
             //printf("Rf_Cnt = %d\n",Rf_Cnt);
                                                                      //数据位低电平部分判断
			 if(DATA_433==0)                                                   //低电平累积次数
			 {
			   Count_Data_Lo++;
			 }
			 else                                                        //高电平判断范围
             {
				 if((Count_Data_Lo >= 1) && (Count_Data_Lo <= 30))       // 80us - 2.4ms
                    {
					    Lo_Cnt = Count_Data_Lo;                          //存储计数,区分0跟1数据用的
                        Count_Data_Lo = 0;
					    Rf_Cnt=3;
					}
				 else
					 {
						Rf_Cnt=0;
					 }
             }
      break;

  	  case 3 :
  	      //printf("Rf_Cnt = %d\n",Rf_Cnt);
			  Recv_Data_Buf <<= 1;                                      //数据移位
			  if(Hi_Cnt>Lo_Cnt)                                         //0跟1的区分,判断高低电平哪个长
			   {
				 Recv_Data_Buf|=0x01;
			   }
			  else
			   {
				 Recv_Data_Buf&=0xFE;
			   }
			   Recv_Bit_Cnt ++;

			  if(Recv_Bit_Cnt>7)                                        //每8bit整理出一个byte
			   {
			     Rf_Data[Recv_Byte_Cnt]=Recv_Data_Buf;                  //存到数组里面
				 Recv_Bit_Cnt = 0;
				 Recv_Byte_Cnt++;
				 Recv_Data_Buf = 0x00;
			   }

			   if(Recv_Byte_Cnt>3)                                     //整理出三个byte
			   {
			     Rf_Control_Data=Rf_Data[0]&0xF0;                      //提取4bit控制数据
				 Rf_Cnt = 4;                                           //进入到功能判断
                 if(LOGE)    printf("Rf_Data[0]%x  Rf_Data[1]%x Rf_Data[2]%x  Rf_Data[3]%x  Rf_Control_Data=0x%x MUTE_LONG=%bd\n\r",Rf_Data[0],Rf_Data[1],Rf_Data[2],Rf_Data[3],Rf_Control_Data,MUTE_LONG);
                 //if(LOGE)    printf("Rf_Data[0]%bd  Rf_Data[1]%bd Rf_Data[2]%bd  Rf_Control_Data  is %bd\n\r",Rf_Data[0],Rf_Data[1],Rf_Data[2],Rf_Control_Data);
			   }
			   else
			   {
				 Rf_Cnt = 1;                                           //不够3byte,继续去解码数据
			   }
      break;

      case 4 :                                                         //功能判断
              printf("Rf_Cnt = %d\n",Rf_Cnt);
              switch(Rf_Control_Data)
			  {
				case 0x10 :
                    if(LOGE)    printf("[0]:address%x   data:%x | [1]:Address:%x    data:%x    | [2]:Address:%x    data:%x  | [3]:Address:%x    data:%x  \n\r",Rf_Address[0],Rf_Data[0],Rf_Address[1],Rf_Data[1],Rf_Address[2],Rf_Data[2],Rf_Address[3],Rf_Data[3]);

                    if(MUTE_LONG >2)
                    {
                        if(Addr_FLAG ==0)
                        {
                            P13_LOCK = 1;
                            Rf_Address[0] = Rf_Data[0]&0x0F;
                            Rf_Address[1] = Rf_Data[1];
                            Rf_Address[2] = Rf_Data[2];
                            Rf_Address[3] = Rf_Data[3];
                            Addr_FLAG = 1;
                            if(LOGE)    printf("Rf_Address[0]:0x%x  Rf_Address[1]:0x%x Rf_Address[2]:0x%x  Rf_Address[3]:0x%x   Rf_Control_Data  is %d\n\r",Rf_Address[0],Rf_Address[1],Rf_Address[2],Rf_Address[3],Rf_Control_Data);
                            //KEYDOWM_SongChoose(0x1A);
                            //HI_EraseAddress();
                            //HI_SetAddress(Rf_Address[0],Rf_Address[1],Rf_Address[2],Rf_Address[3]);
                            //HI_WDT_WatchDogFeed();//喂狗
                            vm_write(VM_INDEX_433_ADDR, Rf_Address, sizeof(Rf_Address));
                            post_msg(1, MSG_PLAY_FILE1);
                            delay(1000);
                            P13_LOCK = 0;
                        }
                        break;
                    }

                    if(((Rf_Data[0] &0x0F) == Rf_Address[0]) && (Rf_Data[1] == Rf_Address[1]) && (Rf_Data[2]  == Rf_Address[2])&& (Rf_Data[3]  == Rf_Address[3]))
                    {
                        if(LOGE)    printf("Receive data AA and play mucis  %bx\n\r",Rf_Control_Data);
                        //if((PLAY_FLAG ==0)&&(mutenum ==0))
                        //{
                            //PLAY_FLAG = 1;
                            //KEYDOWM_SongChoose(NSong);
                            //KEYDOWM_VolumeChoose(NVolume);
                            post_msg(1, MSG_PLAY_FILE1);
                            post_msg(1, MSG_SET_PLAY_FLAG);//播放四次标志位置1
                            delay(100);
                            //APK_HeadSEND();
                            //APK_CyclePlayMusic();
                            Timer2 =1;
                            //if(TIMER2_FLAG < 1) set_TR2;
                            TIMER2_FLAG++;
                            if(LOGE)    printf("11111111111111111\n\r");
                            //while(PLAY_FLAG);
                            if(LOGE)    printf("22222222222222222221\n\r");
                        //}
                        break;
                    }


 /*               case 0xA0 :
                    if(P13_LONG >0)
                    {
                        Rf_Address[0] = Rf_Data[0]&0x0F;
                        Rf_Address[1] = Rf_Data[1];
                        Rf_Address[2] = Rf_Data[2];
                        if(LOGE)    printf("Rf_Address[0]:0x%x  Rf_Address[1]:0x%x Rf_Address[2]:0x%x  Rf_Control_Data  is %d\n\r",Rf_Address[0],Rf_Address[1],Rf_Address[2],Rf_Control_Data);
                        KEYDOWM_SongChoose(0x15);
                    }*/
				default:
                    break;
			  }
	  Rf_Cnt = 0;                                                     //做完操作状态回零
      break;

      default:
	  Rf_Cnt = 0;
      break;
     }
}

receive_433.h:

#ifndef _RECEIVE_433_H
#define _RECEIVE_433_H

#include "gpio.h"

#define LOGE 1

#define DATA_433    	    (JL_PORTA->IN & BIT(1))

#define PIN_433_INIT()     do{\
							JL_PORTA->PU |= BIT(1),/*开启上拉*/\
							JL_PORTA->PD &= ~BIT(1),/*关闭下拉*/\
							JL_PORTA->DIE |= BIT(1),/*输入允许*/\
							JL_PORTA->DIR |= BIT(1);/*设为输入*/\
					    	}while(0)
extern void timer0_handle(void);
extern u8 Addr_FLAG;
extern unsigned char Rf_Address[4];
extern void HI_EraseAddress(void);

#endif

至此,代码结束,写得很烂,请谅解。

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值