51单片机+315M无线射频模块发射程序

发布者:tau29最新更新时间:2015-07-02 来源: 51hei关键字:51单片机  315M  无线射频模块  发射程序 手机看文章 扫描二维码
随时随地手机看文章
用的就是那种最普通的 最便宜的 大约几块钱 的315兆的无线模块接受发射,不带解码的,433m的程序也是一样的不用修改



压缩包中的内容:


上位机以及完整程序在文件夹中,大家可自己下载
地址是:http://www.51hei.com/bbs/dpj-19033-1.html

下面是发射端的源代码:
#include

#include "string.h"
sbit LED1 = P1^1;
sbit LED2 = P1^2;
sbit W_IN = P2^2;         //电路是用11.0592MHz晶振
sbit W_OUT = P2^0;
sbit DQ =P2^1;      //DS18B20数据口
unsigned char Te=0;//温度整数部分
unsigned char Te_D=0;//温度小数部分
unsigned char T0_last;
unsigned char w_data;  //接收时用于存储两次上升沿之间的时长,发送时存储前半周
unsigned char send_busy = 0;//存储发送时后半周
unsigned char recv_timer = 0;
bit w_stat, last_w_stat;
unsigned char jiffies=0;

 


  //定义通信端口
//延时函数

void delay(unsigned int i)
{
     while(i--);
    
}
//初始化函数
Init_DS18B20(void)
{
 unsigned char x=0;
 DQ = 1;    //DQ复位
 delay(8);  //稍做延时
 DQ = 0;    //单片机将DQ拉低
 delay(50); //精确延时 大于 480us
 DQ = 1;    //拉高总线
 delay(14);
 x=DQ;      //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
 delay(20);
}
//读一个字节
ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
 {
  DQ = 0; // 给脉冲信号
  dat>>=1;
  DQ = 1; // 给脉冲信号
  if(DQ)
   dat|=0x80;
  delay(4);
 }
 return(dat);
}
//写一个字节
WriteOneChar(unsigned char dat)
{
 unsigned char i=0;
 for (i=8; i>0; i--)
 {
  DQ = 0;
  DQ = dat&0x01;
  delay(5);
  DQ = 1;
  dat>>=1;
 }
delay(4);
}
//读取温度
void ReadTemperature(void)
{
unsigned char a=0;
unsigned char b=0;
unsigned char e=0;
//unsigned char t;
unsigned char c,d;

//unsigned char t=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=ReadOneChar();   //读取温度值低位
b=ReadOneChar();   //读取温度值高位

e=a&0x0f;//小数部分
c=(e*10)/16;
d=((e*10)%16)*10/16;  
Te_D=c*10+d;    
a=a>>4;
Te=b<<4;
Te=Te|a;

}

void clock_timer(void) interrupt 1 using 1{
   
 if (send_busy){
  if(w_data){
   w_data--;
   w_stat = 0;
  }else{
   send_busy--;
   w_stat = 1;
  }
  W_OUT = w_stat;
 }else{
  w_stat = W_IN;
  if (w_stat != last_w_stat){
   last_w_stat = w_stat;
   if (w_stat){
    w_data = recv_timer;
    recv_timer = 0;
   }
  }
  if (~recv_timer)//if(recv_busy != 0xff)
   recv_timer++;
 }
 jiffies++;
 T0_last=TL0;
}[page]

void clock_init(void){
 jiffies = 0;
 TMOD=0x02;
 TH0=TL0=0x0ce;//12M,50us
// TH0=TL0=0x7a;//16M
// TH0=TL0=0x75;//16.59M
// TH0=TL0=0x72;//17M
// TH0=TL0=0x37;//24M
// TH0=TL0=0x47;//22.1844M, 100us
// TH0=TL0=0xa3;//22.1844M, 50us
 EA=1;
 ET0=1;
   
 TR0=1;
}


void clock_init_again(void){
   
 TMOD=0x02;
 TH0=0x0ce;//12M,50us
 TL0=T0_last;
// TH0=TL0=0x7a;//16M
// TH0=TL0=0x75;//16.59M
// TH0=TL0=0x72;//17M
// TH0=TL0=0x37;//24M
// TH0=TL0=0x47;//22.1844M, 100us
// TH0=TL0=0xa3;//22.1844M, 50us
 EA=1;
 ET0=1;
    jiffies=0;
 TR0=1;
}


void init_serialcomm(void)
{
    SCON  = 0x50;       //SCON: serail mode 1, 8-bit UART, enable ucvr 
    TMOD |= 0x20;       //TMOD: timer 1, mode 2, 8-bit reload 
    PCON |= 0x80;       //SMOD=1; 
    TH1   = 0x0e6;       //Baud:2400  fosc=11.0592MHz  :f4
 TL1   = 0x0e6;
    //IE   |= 0x90;       //Enable Serial Interrupt 
    TR1   = 1;          // timer 1 run
 RI=0;
 TI=1; 
}

void serial_out(char d){
 while(!TI);
 TI=0;
 SBUF=(d);
}

 

void send_string_com(char *str,int strlen)//串口程序
{   char sum;

    int k=0;
    serial_out(02);
    do
    {   sum^=*(str+k);
        serial_out(*(str + k));
        k++;
    } while(k < strlen);
 serial_out(sum);
 serial_out(03);
}

//等待指定长度的串行数据到达,超时值为每两个字节之间的间隔时间而非等待整个串的时间.
//超时单位为time_out * 100uS
bit wait_serial(unsigned char *p, unsigned char len, unsigned char time_out){
 unsigned int time=jiffies;
 unsigned char n=0;
 do{
  if (RI){
   p[n++]=SBUF;
   RI=0;
   if(n==len)
    return 0;
   time=jiffies;
  }
 }while(jiffies-time < time_out);
 return 1;
}

sys_init(){
 clock_init();
 init_serialcomm();
}

 


//=============================================================
//发送程序 开始
//=============================================================

#define PULS_0_WIDTH 8   //低电平脉宽
#define PULS_1_WIDTH 16   //高电平脉宽
#define PULS_HEAD_WIDTH 8  //前导信号脉宽
#define PULS_START_WIDTH 24  //引导信号脉宽
#define PULS_STOP_WIDTH 8  //结束码脉宽

#define PULS_HEAD_COUNTS 16  //前导信号长度


unsigned char send_buf[16];
#define send_byts send_buf[0] //剩余字节数,发送完后为0
unsigned char sending_byte;  //当前正在发送的字节
unsigned char send_byte_p;  //已发送字节数(含正在发送的字节)
unsigned char send_bit_p;  //当前正在发送的字节已发送位数(含正在发送的位)

#define SEND_PROGRESSING 0x41
#define SEND_FAILED 0x21
#define SEND_SUCCESS 0x31
unsigned char send_stat = 0; //发送程序当前状态,为0时正常
unsigned char head_counts; //前导信号计数器(包括引导信号)

void start_send(){
 send_byte_p = 0;
 send_bit_p = 0;
 send_stat = SEND_PROGRESSING;
 head_counts = 16;
}

#define START_SEND(byts) send_buf[0]=byts;send_byts=byts;start_send()

//发送前应清除send_byte_p,send_bit_p,send_stat,并设置send_byts
//发送过程中可根据send_byts的值得到剩余字节数,根据send_byte_p的值得到已发送字节数.注意,将正在发送的字节当作已发送完毕.
//发送过程中可根据send_stat的值得到发送状态.
//发送完成后,send_byts和send_bit_p的值都为0.
#define SEND_PULS(x) w_data=send_busy=(x>>1)
void send(){
//下面两行在wirless()中已经执行过了,所以无需写上
// if (send_stat != SEND_PROGRESSING)
//  return;

 if (!send_busy){
  if(send_byts || send_bit_p){
   if (head_counts){
    head_counts--;
    if(head_counts)
     SEND_PULS(PULS_HEAD_WIDTH);
    else
     SEND_PULS(PULS_START_WIDTH);
   }else{
    if (send_bit_p == 0){
     sending_byte = send_buf[send_byte_p];
     send_byte_p++;
     send_byts--;
     send_bit_p = 8;
    }
  
    if(sending_byte & 0x80){
     SEND_PULS(PULS_1_WIDTH);
    }else{
     SEND_PULS(PULS_0_WIDTH);
    }
  
    sending_byte <<= 1;
    send_bit_p--;
   }
  }else{
   SEND_PULS(PULS_STOP_WIDTH);
   send_stat = SEND_SUCCESS;
  }
 }
 return;
}
//=============================================================
//发送程序 结束
//=============================================================

//=============================================================
//接收程序 开始
//=============================================================

unsigned char recv_buf[16];
#define recv_byts recv_buf[0]  //应收到字节数,由每个包的第一个字节指定
unsigned char recving_byte;   //当前正在接收的字节
unsigned char recv_byte_p;   //已收到字节数(不含正在接收的字节)
unsigned char recv_bit_p;   //当前正在接收的字节等待接收位数(不含正在接收的位)

#define RECV_FAILED 0x31
#define RECV_SUCCESS 0x41

unsigned char recv_stat = 0;  //接收程序当前状态,为0时正常
unsigned char recv_step = 0;  //引导脉冲标志,为0时等待引导,为1时等待数据

#define TEST_PULS(puls_in, puls_type) (puls_in > puls_type - PULS_0_WIDTH / 2 && puls_in < puls_type + PULS_0_WIDTH / 2)

#define HEAD_NEED_RECIVED 8
void recv(){
 unsigned puls_width;

 if ((recv_stat == RECV_SUCCESS) || !w_data)
  return;

 puls_width = w_data;
 w_data = 0;

#if 0 //输出脉宽
 serial_out(puls_width);
// printhex(puls_width);
#endif

 if (recv_step < HEAD_NEED_RECIVED){
  if(TEST_PULS(puls_width, PULS_HEAD_WIDTH)){
   recv_step++;
  }else{
   recv_step = 0;
  }
 }else if (recv_step == HEAD_NEED_RECIVED){
  if(TEST_PULS(puls_width, PULS_START_WIDTH)){
   serial_out(0xbb);
   recv_byte_p = 0;
   recv_bit_p = 8;
   recv_stat = 0;
   recv_step++;
  }else{
   if(!TEST_PULS(puls_width, PULS_HEAD_WIDTH)){
    recv_step = 0;
   }
  }
 }else{
//serial_out(puls_width);
  recving_byte <<= 1;
  if(TEST_PULS(puls_width, PULS_0_WIDTH)){
   recving_byte &= 0xfe;
  }else if(TEST_PULS(puls_width, PULS_1_WIDTH)){
   recving_byte |= 1;
  }else{
   serial_out(puls_width);
   recv_step = 0;
   serial_out(0xaa);
   return;
  }[page]
  recv_bit_p--;
  if(recv_bit_p == 0){ //接收完一字节
   recv_bit_p = 8;
//   serial_out(recving_byte); //输出接收到的字符
   recv_buf[recv_byte_p] = recving_byte;
   recv_byte_p++;
   if(recv_byte_p == recv_byts){
    recv_step = 0;
    recv_stat = RECV_SUCCESS;
   }
  }
 }
}

//=============================================================
//接收程序 结束
//=============================================================

#define SEND_DELAY_TIME 20  //防碰撞延迟(单位:毫秒)
unsigned char send_delay = SEND_DELAY_TIME;
#define VALID_PULS_COUNT 10
unsigned char valid_puls_counts = VALID_PULS_COUNT;

//碰撞检测在该函数中实现.由于无线模块本身的限制,碰撞检测为非完全检测,只能在发送前
//检测是否有其它单元在使用信道,在发送过程中受到的碰撞干扰是无法检测到的.经测试,效果还行
void wirless(){
 if (send_stat == SEND_PROGRESSING && send_delay == 0){
  send();
  if (send_stat == SEND_SUCCESS)
   send_delay = SEND_DELAY_TIME;
 }else{
  recv();
  if (recv_step > HEAD_NEED_RECIVED) //如果检测到当前有其它单元正在发送,继续等待
   send_delay = SEND_DELAY_TIME;
  else{
   if(TEST_PULS(w_data, PULS_0_WIDTH) //如果检测到当前有其它单元正在发送,继续等待
    || TEST_PULS(w_data, PULS_1_WIDTH)
    //|| TEST_PULS(w_data, PULS_HEAD_WIDTH)
    || TEST_PULS(w_data, PULS_START_WIDTH)
    //|| TEST_PULS(w_data, PULS_STOP_WIDTH)
    ){
     if (valid_puls_counts)
      valid_puls_counts--;
     else
      send_delay = SEND_DELAY_TIME;
    }else{
     valid_puls_counts = VALID_PULS_COUNT;
    }
  }
 }
}

#define SCMD_SET_PORT 0x51
#define SCMD_GET_PORT 0x52

#define SCMD_RESET 0x61

#define SCMD_LCD_OUTSTR 0x71
#define SCMD_LCD_RESET 0x72
#define SCMD_LCD_SETXY 0x73
#define SCMD_LCD_SETLINE 0x74
#define SCMD_LCD_CLEAR 0x75


#define SRESP_GET_PORT_ERROR 0x41
#define SRESP_SET_PORT_ERROR 0x42

#define HEART_BEAT_INTERVAL 100  //心跳间隔 X / 1000   秒
unsigned int heart_beat_timer = HEART_BEAT_INTERVAL;
unsigned int last_jiffies=0;

 void main(){
    
 init_serialcomm();
 //P0=0xff;
 //P2=0x00;                                                                                                                                                                                                 ;
 sys_init();

 LED1 = 0;
 LED2 = 1;
 //send_string_com("ok",2);
 //lcd_reset();
 //lcd_power_on();
  //lcd_self_test();

 while(1){
          
       

  if (jiffies - last_jiffies >= 50){//每次中断为50us,所以要20次才为1ms
   last_jiffies = jiffies;
   heart_beat_timer--;
      
      if (send_stat == 0 ){//  碰撞测试
   
            ET0=0;
      ReadTemperature();
     
   clock_init_again();
     
   START_SEND(8);
   send_buf[1]=Te/10+0x30;
   send_buf[2]=Te%10+0x30;
   send_buf[3]='.';
   send_buf[4]=Te_D/10+0x30;
   send_buf[5]=(Te_D%10)+0x30;
            send_buf[6]='D';
   send_buf[7]='';
   //wirless();
   
         
   //send_string_com(send_buf,strlen(send_buf));
    }
   if (send_delay)
    send_delay--;
  }

      

  if (heart_beat_timer == 0){
   heart_beat_timer = HEART_BEAT_INTERVAL;
   LED1 = ~LED1;
   LED2 = ~LED2;
  }

  wirless();

  if (send_stat == SEND_FAILED){

   send_stat = 0;break;

  }else if (send_stat == SEND_SUCCESS){
   send_stat = 0;
   P2_3=~P2_3;break;
 
  }

 

 }
}

关键字:51单片机  315M  无线射频模块  发射程序 引用地址:51单片机+315M无线射频模块发射程序

上一篇:单片机制作光立方资料(基于74hc595和573)
下一篇:一个好玩的C51动态扫描小程序

推荐阅读最新更新时间:2024-03-16 14:23

MAX517与51单片机的I2C总线数据通信
1 I2C总线的特点及基本通信协议 I2C总线是Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线?串行数据线和串行时钟线?即可使连接于总线上的器件之间实现信息传送,同时可通过对器件进行软件寻址,而不是对硬件进行片选寻址的方式来节约通信线数目,从而减少了硬件所占空间。因为总线已集成在片内,所以大大缩短了设计时间,此外,在从系统中移去或增加集成电路芯片时,对总线上的其它集成芯片没有影响。 1.1 I2C总线的主要特点 I2C总线通常由两根线构成:串行数据线(SDA)和串行时钟线(SCL);总线上所有的器件都可以通过软件寻址,并保持简单的主从关系,其中主器件既可以作为发送器,又可以作为接收器;
[单片机]
MAX517与<font color='red'>51单片机</font>的I2C总线数据通信
80c51是几位单片机 80c51单片机有几个中断源
  80c51是几位单片机   80C51是一种8位微处理器,也被称为8051,由Intel公司推出。它是最早的商用单片机之一,由于它的简单易用、灵活可靠,被广泛应用于许多嵌入式系统中。在80C51系列中,最常见的型号包括AT89C51和AT89S52等。   80c51单片机寻址范围有多少   80C51单片机的寻址范围取决于其具体的型号和存储器结构。在最常见的AT89C51和AT89S52型号中,其寻址范围如下:   内部RAM寻址范围:0x00-0x7F(128字节)   内部ROM寻址范围:0x0000-0xFFFF(64KB)   特殊功能寄存器(SFR)寻址范围:0x80-0xFF(128字节)   外部扩展RAM
[单片机]
51单片机-LED模块-来回流水灯
#include reg52.h #include intrins.h #define uchar unsigned char #define uint unsigned int #define ulong unsigned long sbit LED1 = P1^0; void Delay600ms(); //@11.0592MHz void main(void) { bit flag = 0; unsigned char cnt; LED1 = 0; while(1) { if(0==flag) { for(cnt=1;cnt 8;cnt++) { Delay600ms(); P1
[单片机]
基于stc51单片机的电子时钟设计
硬件资源 焊接电路板中使用STC系列单片机,一个四位一体数码管、一个二极管,以及一些必要辅助子电路。数码管的位选端口为P3^0、P3^1、P3^2、P3^3,段选端口为P1的8个端口;调节小时、分钟端口分别为P0^0、P0^4,二极管指示灯接P2^2口。 由于使用的数码管为共阳极数码管,因此根据数码管结构图可知,P3口必须置高电平选通其中一位,P0口低电平点亮相应的断码,这和共阴极数码管0x3f代表0不一样,这里表示为0xc0,编程时应该注意。 在数码管的段码连接上,我用的是a、b、c、d、e、f、g、h所对应的管脚11、7、4、2、1、10、5、3分别接P1^0、P1^1、P1^2、P1^3、P1^4、P1^5、P1^6、
[单片机]
AT89C2051单片机对步进电机驱动器系统的设计
AT89C2051将控制脉冲从P1口的P1.4~P1.7输出,经74LS14反相后进入9014,经9014放大后控制光电开关,光电隔离后,由功率管TIP122将脉冲信号进行电压和电流放大,驱动步进电机的各相绕组。使步进电机随着不同的脉冲信号分别作正转、反转、加速、减速和停止等动作。图中L1为步进电机的一相绕组。AT89C2051选用频率22MHz的晶振,选用较高晶振的目的是为了在方式2下尽量减小AT89C2051对上位机脉冲信号周期的影响。 图中的RL1~RL4为绕组内阻,50Ω电阻是一外接电阻,起限流作用,也是一个改善回路时间常数的元件。D1~D4为续流二极管,使电机绕组产生的反电动势通过续流二极管(D1~D4)而衰减掉,
[单片机]
AT89C20<font color='red'>51单片机</font>对步进电机驱动器系统的设计
基于STC12C2051单片机的智能太阳能路灯设计
简介:太阳能路灯的应用具有重要的现实意义,尤其是靠小规模火力发电或季节性水力发电的地区,更应大力发展太阳能电力。太阳能路灯以其先进、稳定、智能、成熟的控制技术及显著的节能特性、简便的维护方式等特点得到推广。随着太阳能照明灯具产品的普及,很多应用项目存在质量和售后服务问题。 太阳能路灯的应用具有重要的现实意义,尤其是靠小规模火力发电或季节性水力发电的地区,更应大力发展太阳能电力。太阳能路灯以其先进、稳定、智能、成熟的控制技术及显著的节能特性、简便的维护方式等特点得到推广。随着太阳能照明灯具产品的普及,很多应用项目存在质量和售后服务问题。因此,需及时分析原因、规范市场,使太阳能路灯市场健康有序地发展。太阳能是地球上最为直接、普遍、
[单片机]
基于STC12C20<font color='red'>51单片机</font>的智能太阳能路灯设计
基于51单片机八路抢答器资料
(1)设计一个可供8人进行的抢答器。 (2)系统设置复位按钮,按动后,重新开始抢答。 (3)抢答器开始时数码管显示序号0,选手抢答实行优先显示,优先抢答选手的编号一直保持到主持人将系统清除为止。抢答后显示优先抢答者序号,同时发出音响。,并且不出现其他抢答者的序号。 (4)抢答器具有定时抢答功能,且一次抢答的时间有主持人设定,本抢答器的时间设定为30秒,当主持人启动“开始”开关后,定时器开始减计时,同时蜂鸣器有短暂的声响。 (5)设定的抢答时间内,选手可以抢答,这时定时器停止工作,显示器上显示选手的号码和抢答时间。并保持到主持人按复位键。 (6)当设定的时间到,而无人抢答时,本次抢答无效,扬声器报警发出声音,并禁止抢答。定时器上显示
[单片机]
基于<font color='red'>51单片机</font>八路抢答器资料
基于C8051单片机的血糖监测仪解决方案
  血糖测量的电生物化学原理是当施加一定电压于经酶反应后的血液产生的电流会随着血液中的血糖浓度的增加而增加。通过精确测量出这些微弱电流,并根据电流值和血糖浓度的关系,反算出相应的浓度。所以,确定这个关系是问题的核心。但其关系复杂,受多方面因素影响。电压强度、所使用的试条以及检测的血液量都会对其产生影响。理论上需要在所有浓度点上大量实验才能确定最终的关系。在实际操作中,只需在选择若干重要浓度点做大量实验,然后采用曲线拟合或插值等数据处理方式来确定其与电流值之间的关系。   血糖测量通常采用电化学分析中的三电极体系。三电极体系是相对于传统的两电极体系而言,包括,工作电极(WE),参比电极(RE)和对电极(CE)。参比电极用来定点位
[单片机]
基于C80<font color='red'>51单片机</font>的血糖监测仪解决方案
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved