完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
一、原理图
实验所用到的 315/433 MHz 超再生模块 发送端原理图 接收端原理图 二、发送端代码 使用 NEC 协议发送数据 #include #include #define FOSC 6000000L //IRC频率 sfr P3M1 = 0xB1; sfr P3M0 = 0xB2; ***it SEND = P3 ^ 4; //数据发送引脚 ***it btn = P3 ^ 2; //发送按键 #ifndef uchar #define uchar unsigned char #endif #ifndef uint #define uint unsigned int #endif uchar tx_buff[4]; //发送缓冲区 void Delay9ms() //@6.000MHz { unsigned char i, j; i = 53; j = 132; do { while(--j); } while(--i); } void Delay4ms() //@6.000MHz { unsigned char i, j; i = 24; j = 85; do { while(--j); } while(--i); } void Delay560us() //@6.000MHz { unsigned char i, j; i = 4; j = 65; do { while(--j); } while(--i); } void Delay20us() //@6.000MHz { unsigned char i; _nop_(); _nop_(); i = 27; while(--i); } //发送逻辑1,逻辑1为2.25ms,脉冲时间560us void send_logic_1() { SEND = 1; Delay560us(); SEND = 0; Delay560us(); Delay560us(); Delay560us(); } //发送逻辑0,逻辑0为1.12ms,脉冲时间560us void send_logic_0() { SEND = 1; Delay560us(); SEND = 0; Delay560us(); } //发送指定长度的数据 void send(uchar *dat, uint len) { uchar i, j, temp; //引导码 SEND = 1; Delay9ms(); //9ms高电平 SEND = 0; Delay4ms(); //4ms低电平 //数据码 for(j = 0; j < len; j++){ temp = *dat; for(i = 0; i < 8; i++) { if((temp & 0x01) == 0x01) { send_logic_1(); } else { send_logic_0(); } temp = temp >> 1; } dat++; } //结束码 SEND = 1; Delay4ms(); //4ms高电平 SEND = 0; } void main() { INT0 = 1; IT0 = 1; //设置INT0的中断类型 (1:仅下降沿 0:上升沿和下降沿) EX0 = 1; //使能INT0中断 EA = 1; P3M1 &= 0xEF; //P3.4推挽输出 P3M0 &= 0xFF; tx_buff[0] = 0x40; tx_buff[1] = ~tx_buff[0]; //取反 tx_buff[2] = 0x56; tx_buff[3] = ~tx_buff[2]; //取反 while(1) { } } //中断服务程序 void ex_int0() interrupt 0 //INT0中断入口 { if(btn == 0) { Delay20us(); if(btn == 0) { Delay20us(); send(tx_buff, 4); } while(!btn);//等待 按起 } } 三、接收端代码 使用 NEC 协议接收数据 #include #include #ifndef FOSC #define FOSC 6000000L //IRC频率 #endif #ifndef uchar #define uchar unsigned char #endif #ifndef uint #define uint unsigned int #endif sfr P3M1 = 0xB1; sfr P3M0 = 0xB2; ***it RECEIVE = P3 ^ 2; //数据接收引脚,INT0 bit exint0; bit flag = 0; //接收标志 ***it LED = P3 ^ 3; //LED uchar recv[4]; //接收缓冲区 void Delay2ms() //@6.000MHz { unsigned char i, j; i = 12; j = 169; do { while(--j); } while(--i); } void Delay200us() //@6.000MHz { unsigned char i, j; i = 2; j = 39; do { while(--j); } while(--i); } void Init_Int0(void) { INT0 = 1; IT0 = 0; //设置INT0的中断类型 (1:仅下降沿 0:上升沿和下降沿) EX0 = 1; //使能INT0中断 } void main() { Init_Int0(); EA = 1; P3M1 &= 0xF7; //P3.3 推挽输出 P3M0 &= 0xFF; flag = 0; while(1) { if(flag) { flag = 0; LED = !LED; //接收到数据反转一次IO输出 } } } //中断服务程序 void External_INT0() interrupt 0 //INT0中断入口 { uchar i, j, N; uint k; exint0 = INT0; //保存INT0口的状态, INT0=0(下降沿); INT0=1(上升沿) EX0 = 0; //关中断 flag = 0; Delay2ms(); if(RECEIVE == 0) { EX0 = 1; flag = 0; return; } k = 100; //确认RECEIVE信号出现 while(RECEIVE && k) { //等RECEIVE变为低电平,跳过9ms的前导高电平信号。 Delay200us(); k--; } k = 100; while(!RECEIVE && k) { //等 RECEIVE 变为高电平,跳过4ms的前导低电平信号。 Delay200us(); k--; } for(i = 0; i < 4; i++) { //4组数据 for(j = 0; j < 8; j++) { //每组数据有8位 k = 100; while(RECEIVE && k) { //等RECEIVE变为低电平 Delay200us(); k--; } k = 100; N = 0; while(!RECEIVE && k) { //计算RECEIVE低电平时长 Delay200us(); N++; k--; if(N >= 30) { EX0 = 1; flag = 0; return; //0.14ms计数过长自动离开。 } } //低电平计数完毕 recv = recv >> 1; //数据最高位补“0” if(N >= 8) { recv = recv | 0x80; //数据最高位补“1” } N = 0; } } if((recv[0] == ~recv[1]) && (recv[2] == ~recv[3])){ //数据校验成功 flag = 1; } else{ flag = 0; } EX0 = 1; //开中断 } 四、接收输出波形图 |
|
|
|
只有小组成员才能发言,加入小组>>
3278 浏览 9 评论
2955 浏览 16 评论
3455 浏览 1 评论
8987 浏览 16 评论
4050 浏览 18 评论
1102浏览 3评论
570浏览 2评论
const uint16_t Tab[10]={0}; const uint16_t *p; p = Tab;//报错是怎么回事?
568浏览 2评论
用NUC131单片机UART3作为打印口,但printf没有输出东西是什么原因?
2301浏览 2评论
NUC980DK61YC启动随机性出现Err-DDR是为什么?
1857浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 04:47 , Processed in 1.128742 second(s), Total 78, Slave 58 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号