vvvccc123 发表于 2009-12-21 01:37:57

通过AVR+FM来无线传送数据

我是想在自家楼顶上放几个传感器,由太阳能供电,测测温度风向之类,然后数据通过无线传递.我认为无线发射最容易动手实现就是FM调频发射了.因对数据传输的速度和距离都要求不高,所以尝试用AVR+FM做了下试验.

发射部分用TINY13A生成8种不同频率代表8进制数据,然后加载到FM发射电路.部分原理图如下
http://cache.amobbs.com/bbs_upload782111/files_23/ourdev_517004.gif
发射 (原文件名:2.gif)

//循环发送8种频率
ISR(TIM0_OVF_vect)
{
        unsigned char t = OCR0A;
        t+=0x10;
        if(t>0xb0)
        {
                t = 0x40;
        }
        OCR0A = t;
        OCR0B = t>>1; //1/2的占空比
}

void port_init(void)
{
        DDRB= 0x02;
}

void timer0_init(void)
{
OCR0A = 0x20;
OCR0B = OCR0A/2;
TCCR0A = 0x23; //快速PWM
TCCR0B = 0x0A; //start timer
}

void init_devices(void)
{
       port_init();
       timer0_init();
       TIMSK0 = 0x02;
}


int main(void)
{
        init_devices();
        sei();
        while(1)
        {
        }
}


接收部分拆了个CXA1691做的收音机,将其P23引出的音频引到MEGA48PA的AIN0
http://cache.amobbs.com/bbs_upload782111/files_23/ourdev_517003.gif
接收 (原文件名:1.gif)
#include <avr/io.h>
#include <avr/interrupt.h>

#include "uart.h"


volatile enum
{
        ST_STOP,
        ST_FIX
} st_flag = ST_STOP;


#define DIV_MAX_CNT 32
volatile unsigned int div_buffer;
volatile unsigned char div_cnt = 0;

SIGNAL(TIMER1_OVF_vect)
{
        st_flag = ST_STOP;
}

SIGNAL(TIMER1_CAPT_vect)
{
        TCNT1=0;

        if(ST_FIX==st_flag)
        {
                if(div_cnt<DIV_MAX_CNT)
                {
                        unsigned int icr = ICR1;
                        if(div_cnt>0 || icr<0x100)
                        {
                                div_buffer = icr;
                        }
                }
        }
        else
        {
                st_flag = ST_FIX;
        }
        TIFR1 = _BV(ICF1);
}



int main(void)
{
        CLKPR = 0x80;
        CLKPR = 0x0;


        //stop cap
        TCCR1B = 0;
        TIMSK1 = 0;

        TCCR1A = 0; //仅计数捕获
        TCNT1=0;
        ICR1 = 0;
        ACSR = _BV(ACIC); //位2 – ACIC: 模拟比较器输入捕捉使能
        TCCR1B = _BV(ICNC1) | _BV(ICES1) | /**/_BV(CS10); //输入捕捉噪声抑制器 上升沿触发 8M 1分频
        TIMSK1 = _BV(TOIE1) | _BV(ICIE1);


        init_USART();
        printf_s("build: %s %s\r\n", __DATE__, __TIME__);
        sei();

        while(1)
        {
                if(DIV_MAX_CNT==div_cnt)
                {
                        for(unsigned char i=0; i<DIV_MAX_CNT; i++)
                        {
                                printf_s("%x ", div_buffer);
                        }
                        printf_s("\r\n");
                        div_cnt = 0;
                }
        }

}


示波器在AIN0测的波型
http://cache.amobbs.com/bbs_upload782111/files_23/ourdev_517005.gif
接收波形 (原文件名:rigol.gif)

串口输出的部分数据:
bf 129 193 1ff 268 2d3 33e 3a7 bf 129 193 1fd 269 2d1 33e 3aa bf 129 193 1ff 269 2d3 33c 3a8 bd 128 193 1fe 26a 2d3 33b 3a6
bf 12a 194 1fd 268 2d4 33e 3a8 be 12a 193 1fd 267 2d4 33d 3a7 bf 129 193 1ff 268 2d2 33e 3a8 be 129 192 1fe 268 2d2 33e 3a9
be 129 193 1fe 269 2d3 33f 3a8 bf 127 194 1fd 269 2d4 33d 3a8 bf 128 193 1ff 268 2d5 33e 3aa bf 129 195 200 26b 2d5 342 3a8
bf 129 193 1fd 268 2d2 33d 3a7 bf 128 194 1ff 267 2d5 33e 3a8 be 129 194 1fd 268 2d4 33e 3a8 be 12a 194 1ff 269 2d2 33f 3a8
be 128 194 1fe 268 2d3 33c 3a9 bf 129 195 1ff 268 2d5 33e 3a9 bf 128 193 1fc 269 2d3 33e 3a9 be 12a 194 1fd 268 2d2 33f 3a9
bf 12a 194 1fe 26a 2d3 33c 3a9 be 12a 194 1fe 269 2d2 33c 3a9 bf 129 194 1fd 268 2d1 33d 3a9 be 129 193 1ff 267 2d3 33e 3a8
be 129 192 1fe 269 2d4 33e 3a8 be 12a 192 1fe 268 2d2 33e 3a6 bd 129 194 1fc 269 2d3 33e 3a7 be 12a 194 1fe 269 2d2 33d 3a7

通过上面的数据,可以容易转换为所代表的数据

上面的步骤只是初步证实可行

CoolBird007 发表于 2009-12-21 02:07:10

沙发,AFSK,不错,我也打算做这个,不过是用电脑。

vipcff 发表于 2009-12-21 08:00:47

yushuang 发表于 2009-12-21 08:28:32

MARK

tclandmei 发表于 2009-12-21 08:48:42

【1楼】 CoolBird007
积分:89
派别:
等级:------
来自:
沙发,AFSK,不错,我也打算做这个,不过是用电脑。

科学出版社的一套书其中一本有很详细的章节讲述的。
我晚上回去看看叫什么名字!

kdtcf 发表于 2009-12-21 09:00:22

我做过一些类似的调频发射电路,频率飘逸最不好解决,可能一天就跑频几MHz呢,天线的形状方向都会影响发射频率,更好的办法是用声表面的收发电路,工作在315MHz,有现成的模块卖的,稳定度是这个电路的几十倍。

ndust 发表于 2009-12-21 09:11:20

jh

vvvccc123 发表于 2009-12-21 23:37:29

有没有人用过收发一体RDA5820,用这个来做好像不错,价格好像也不贵,不知性能如何?

yanrz 发表于 2009-12-22 22:10:19

太厉害了!!!
佩服!

yiminglei 发表于 2009-12-23 13:51:22

使用锁相环稳定频率吧。MC145151,并口输入的。

chinamanzhong 发表于 2009-12-23 22:44:46

mark

TornadoYu 发表于 2009-12-23 23:30:45

mark~~

vvvccc123 发表于 2009-12-26 20:58:50

新弄些RDA5820的模块,只需很少的外围就可组装一部FM的收发机了.不过不能同时接收和发送,只能做成半双工模式
http://cache.amobbs.com/bbs_upload782111/files_24/ourdev_519197.jpg
新的收发器 (原文件名:5820.jpg)


一些RDA5820的资料: http://bbs.eeworld.com.cn/viewthread.php?tid=73465

mega48pa上的rda5820的测试代码:


#define RDA5820_ADDR 0X22
static unsigned char chip_addr = RDA5820_ADDR;
#define TW_ACK 1
#define TW_NACK 0
typedef enum
{
        MODE_RX,
        MODE_TX,
}RDA5820_MODE;
void DelayMs(unsigned int ms)
{
        unsigned int i;
        for(i=0;i<ms;i++)
        _delay_loop_2(20 *250);
}
void twi_stop(void)
{
        TWCR = _BV(TWINT) | _BV(TWSTO) | _BV(TWEN);
}
void twi_start(void)
{
        TWCR = _BV(TWINT) | _BV(TWSTA) | _BV(TWEN);
        while((TWCR&_BV(TWINT))==0);
}
void twi_writebyte(unsigned char c)
{
        TWDR = c;
        TWCR = _BV(TWINT) | _BV(TWEN);
        while ((TWCR & _BV(TWINT)) == 0);
}
unsigned char twi_readbyte(unsigned char ack)
{
        unsigned char tmp=_BV(TWINT)|_BV(TWEN);
        if(ack)
                tmp|=_BV(TWEA);
        TWCR=tmp;
        while ((TWCR & _BV(TWINT)) == 0) ;
        return TWDR;
}

void iic_set_chip_addr(unsigned addr)
{
        chip_addr = addr&0xfe;
}

unsigned int iic_rd_reg16( unsigned char addr)
{
        unsigned int data;
        twi_start();
        twi_writebyte(chip_addr|TW_WRITE);
        twi_writebyte(addr);
        DelayMs(1);

        twi_start();
        twi_writebyte(chip_addr|TW_READ);
        data = twi_readbyte(TW_ACK)<<8;
        data |= twi_readbyte(TW_NACK);
        twi_stop();
        return data;
}


void iic_wr_reg16(unsigned char addr, unsigned int data)
{
        twi_start();
        twi_writebyte(chip_addr|TW_WRITE);
        twi_writebyte(addr);
        DelayMs(1);

        twi_writebyte(data>>8);
        twi_writebyte((unsigned char)data);
        twi_stop();
        DelayMs(1);               
}

void rda5820_init(void)
{
        iic_set_chip_addr(RDA5820_ADDR);
        //reset
        iic_wr_reg16(2, 0xc282);
        //enable
        iic_wr_reg16(2, 0xc281);
        iic_wr_reg16(5, 0x8c84);
        //设定上下限频率 60.0-115.0M
        iic_wr_reg16(0x53, 650);
        iic_wr_reg16(0x54, 1150);
}
void rda5820_set_mode(RDA5820_MODE mode)
{
        iic_wr_reg16(0x40, mode==MODE_TX ? 1 : 0);
        iic_wr_reg16(0x3, 0x525c); //设定频率 97.9
}
int main(void)
{
        //OC2B输出32768Hz
    DDRD|=_BV(PORTD3);
    TCCR2B = 0;
        TCCR2A = 0x23; //fast pwm
        TCNT2 = 0;
        OCR2A = F_CPU/32768-1;
        OCR2B = OCR2A>>1;
        TCCR2B = 0x9;

        //IIC
    DDRC&=~(_BV(PORTC4)|_BV(PORTC5));
    PORTC |= (_BV(PORTC4)|_BV(PORTC5)); //上拉使能
    TWBR=73;

        iic_set_chip_addr(RDA5820_ADDR);
        rda5820_init();
        rda5820_set_mode(MODE_TX);
        while(1);

}

另32768Hz的频率需要精度高一些,不然频率会有偏移且效果会差很多.这里用的是7.3728M的外部晶振分频得到

如下的LIN和RIN应互换才正确
http://cache.amobbs.com/bbs_upload782111/files_24/ourdev_519221.gif
模块的引脚图 (原文件名:pins.gif)
此模块未把RDA5820的三个IO口引出,不然可以直接以IIS接口来收发音频或作中断指示

touch_mcu 发表于 2009-12-26 21:13:01

收发一体的FM芯片应比较容易实现。

arduino 发表于 2009-12-26 21:20:42

mark

wjy6264 发表于 2009-12-27 16:56:02

mark

sino_design 发表于 2009-12-27 21:21:44

jh

jsongyan 发表于 2009-12-27 23:45:44

mark

keaiduo 发表于 2009-12-28 01:17:21

mark看着很好玩

astudent 发表于 2009-12-30 19:04:10

关注

lv998127 发表于 2009-12-30 20:17:37

印记

cinderellah 发表于 2009-12-30 21:38:58

爪~

flyingcys 发表于 2010-5-12 21:16:47

关注!

kelos3000 发表于 2010-5-30 10:57:06

ddd

luojiyin 发表于 2010-5-30 11:18:35

mark

warmonkey 发表于 2010-5-30 11:22:20

呃。。。FSK调制
如果是多个频点一个频率代表一位就是ODFM了

zbjzxc 发表于 2010-5-30 13:41:26

记号~~

cuikai12345 发表于 2010-5-30 19:57:43

mark

mlhorizon 发表于 2010-5-30 21:40:48

真巧,在另一个网站也看到这个了

http://www.edacode.com/index.php?option=com_flexicontent&view=items&id=578:avrfm

搞半天还是从这里出去的啊,对方也不厚道,都没标个原始出处,只标了vvvccc123 大名。
不知道这算不算侵权论坛。

chys01 发表于 2010-5-31 11:14:40

路过

hy317 发表于 2010-5-31 11:27:29

mark

up2dream 发表于 2010-5-31 11:32:08

MARK

guangan854214 发表于 2010-5-31 13:49:31

k

jackiezeng 发表于 2010-5-31 15:07:09

MARK

dgdjfw 发表于 2010-5-31 16:25:32

MARK

huasoft 发表于 2010-5-31 21:44:36

这样的帖子要顶

wayne1025 发表于 2010-5-31 21:49:52

学习之~~~~~~~~~

swustlx86 发表于 2010-6-1 17:10:54

MARK

bbsniua 发表于 2010-6-1 20:16:05

不错的想法!
以前做过模拟调制成声音搞遥控的!
去淘宝买个FM转发器做那个发射的估计很稳定!

chaled 发表于 2010-6-2 15:31:05

mark

smartzou 发表于 2010-6-2 15:52:07

mark

yaojiayi1252 发表于 2010-6-12 00:24:49

mark

iam35200 发表于 2010-6-12 01:30:08

不错的想法!

pj5350 发表于 2010-6-12 05:44:12

mark

wwwavr 发表于 2010-6-12 07:25:17

mark

ldj7501 发表于 2010-6-12 07:37:20

mark

lv998127 发表于 2010-6-12 08:24:43

mark

XA144F 发表于 2010-6-12 08:28:31

就是使用普通的声表面震荡器的315MHz、433MHz无线发射模块,接收的模块则基于RX3310A,串口使用4800的波特率没有问题。

lang6027 发表于 2010-6-14 10:32:28

RX3400比较简单些,功耗更低

wukaka 发表于 2010-6-19 21:50:26

马克

ly520cs 发表于 2010-6-20 02:36:36

mark

moon0213 发表于 2010-6-20 16:00:44

mark

zxttgg 发表于 2010-6-20 20:35:05

距离?

reloaded 发表于 2010-6-20 21:37:41

怎么测风向?

flyingcys 发表于 2010-9-18 11:49:26

关注!!!!

poet_lee 发表于 2010-9-18 12:55:03

mark~不错

longquan 发表于 2010-9-18 13:04:18

做一个去

longquan 发表于 2010-9-18 13:05:19

做一个去,以前见过双音多频调制的

xqingfeng 发表于 2010-9-18 13:24:47

学习一下!!!

hpdell 发表于 2010-9-18 15:57:34

好啊!!!!!!!!!!

avrwoo 发表于 2010-9-18 17:09:47

MARK

Tomas_Yung 发表于 2011-1-1 14:01:36

脚印

gyz1990 发表于 2011-1-1 16:34:23

留名

SystemARM 发表于 2011-1-1 17:12:25

MARK

zzz1367 发表于 2011-1-1 21:10:09

mark

xidxid 发表于 2011-1-2 10:17:58

回复【楼主位】vvvccc123
-----------------------------------------------------------------------

mark

kai2529 发表于 2011-1-2 23:30:49

记号

mosidao 发表于 2011-1-4 00:10:09

可惜我只会买不会做

chengyang79 发表于 2011-1-6 22:11:53

有用

kongan 发表于 2011-1-15 19:38:20

记号

BCE312 发表于 2013-12-9 23:29:57

不知道LZ还在研究这个不?交流一下。

ananyjlo 发表于 2013-12-10 05:04:15

不错,不错,收藏了!!!!!!!!

lou0908 发表于 2013-12-10 09:15:04

好想法,不错

3242543 发表于 2013-12-10 14:40:14

这个东西不错啊哈哈节约成本
页: [1]
查看完整版本: 通过AVR+FM来无线传送数据