>

psk31 是业余无线电爱好者常用的通讯方式. psk31 的原理就不介绍了, 见链接: 哈罗 CQ 火腿社区 - HAM 软件、HAM 网站 - PSK31 簡介 BV3FG - Powered by phpwind

psk31 的调制如何具体实现呢? HAM 们常用的方式是用 digipan 等软件把要发送的消息调制到几百 Hz 的音频信号上, 再利用发射机的 SSB 模式把这个音频信号发射出去, 这里 SSB 实际上起了上变频的作用.

也可以把整个调制过程都放在 MCU 里进行, 直接从 MCU 的 DAC 输出调制好的音频信号.

ka7oei 则提供了一个偏硬件的直接调制方案, 见下图:

左下的振荡器振荡在所需频率的 4 倍上, 由计数器 74HC4017 接成四分频, 从 0 和 2 两脚输出一对相位相反的载波信号. MCU 的 PB2 通过 74HC00 选择相位. PA3 输出的 PWM 信号经低通滤波后, 再经 U2, Q4 调节 Q3 的漏极电压, 实现在输出 0 时将输出信号幅度逐渐降到零的瞬间切换相位. 这个方案很简洁, 我决定就拿这个图稍微改动一下. MCU 么, 用最简单的 ATTiny13 就好了.

首先得在 PC 上软件模拟一下. 程序很简单, 找个 psk31 的码表, 一般是类似这样:

const uint16_t VARICODE_TABLE[] = {
    0x8000,    /* ASCII = ' '    1                             */
    0xFF80,    /* ASCII = '!'    111111111                     */
    0xAF80,    /* ASCII = '"'    101011111                     */
    0xFA80,    /* ASCII = '#'    111110101                     */
...
    0xA000,    /* ASCII = 't'    101                           */
    0xDC00,    /* ASCII = 'u'    110111                        */
    0xF600,    /* ASCII = 'v'    1111011                       */
    0xD600,    /* ASCII = 'w'    1101011                       */
    0xDF00,    /* ASCII = 'x'    11011111                      */
    0xBA00,    /* ASCII = 'y'    1011101                       */
    0xEA80,    /* ASCII = 'z'    111010101                     */
};

存储格式是从高位到低位, 后面补零. 注意这个码表是从空格开始, 到小写 z 就结束了, 也就是 ASCII 码从 32 到 122 这 91 个字符, 这样能省下不少宝贵的 flash 空间. 毕竟 ATTiny13 的 flash 空间只有可怜的 1024 字节, 如果把完整的码表放进来, 一下子 512 字节就没有了. 发送一个字符的函数可以写成这样:

void psk31_tx(char c)
{
    uint16_t varc;
    for(varc = VARICODE_TABLE[c - ' ']; varc; varc <<= 1) {
        if(varc & 0x8000)
            printf("1");
        else
            printf("0");
    }
    printf("00");
}

然后随便找个字符串, 比如 Hello, world.

char msg[] = "Hello, world.";
char *p = msg;
while(*p) {
     psk31_tx(*p);
     p++;
}

编译运行, 就能看到效果了.

在 MCU 上实现时要稍微复杂一点. 发送 1 好办, 保持满幅输出不变, 挨过 32ms 时间就完事. 发送 0 就复杂一些, 需要按余弦函数把输出幅度逐渐减小为零, 切换相位, 再把幅度逐渐增加到最大. 把 printf("1") 和 printf("0") 分别换成这两个操作就行. 但是这样就破坏了可移植性. 解决办法就是函数指针, 把 psk31_tx 函数写成这样:

void psk31_tx(char c, void (*tx0)(void), void (*tx1)(void))
{
    unsigned short varc;
    for(varc = varicode_table[(c - ' ')]; varc; varc <<= 1) {
        if(varc & 0x8000)
            (*tx1)();
        else
            (*tx0)();
    }
    (*tx0)();
    (*tx0)();
}

把发送 1 和 0 的操作写成两个回调函数传给 psk31_tx(), 这样就完美了.

之后设计电路, 如图:

振荡这里用一只 74AHC1G00 加上 14.318M 的晶振就行了, 通过调节 KV1471 的偏压来微调频率. 四分频用了更常用的 74HC74, 两级二分频, 从第二级的 Q 和 / Q 脚输出一对相位相反的载波信号. 切换相位用一只模拟开关 74LVC1G3157 来实现. 其余部分基本保持 ka7oei 的设计不变.

成品照片:

末级电源电压这里只用到 5V, 实测连续发送 1 时在 50 欧假负载上可以得到 40mW / +16dBm 的功率. 如果把末级供电电压提到 12V, 同时把 MMBT2222 和 2N7002 换成封装大一点的管子, 估计能做到 1W 上下, 再大就得加后级了.

ATTiny13 的一大缺点是不能接晶振, 于是把它的 RC 时钟设到 4.8M, 通过 OSCCAL 寄存器微调到 4.096M 左右, 然后 8 分频作为定时器 0 的时钟源, 定时器 0 输出 PWM 的同时也提供了 4.096M / 8 / 256 = 2kHz 的时基信号. 余弦波形表用了 64 个点, 从而得到 2k / 64 = 31.25Hz. 输出 1 时只要什么都不做, 等定时器 0 中断 64 次就行了.

ATTiny13 的另一大缺点... 就是 RAM 只有可怜的 64 字节. 实测发现即使发送 "Hello, world." 也一样爆栈, 只好不用回调机制, 同时把 "Hello, world." 也放到 flash, 才总算是发送成功.

用 IC-R71E 接收, Digipan 和 MultiPSK 解调的效果图如下:

Digipan

MultiPSK

感觉 Multipsk 的解调效果要好一些, 可能是 Digipan 那边有些参数没设置好.

在这个 Beacon 的基础上可以玩出很多花样来, 看你怎么发挥了.


试了一下BH1417用于6米波段发射

2016-04-14 by Stavros

BH1417是WFM发射IC, 以0.2MHz为间隔, 在87.7~88.9MHz和106.7~107.9MHz频段各有7个频点. 频率基准是7.6MHz的晶振, 先4分频得到1.9MHz, 然后一路50分频得38kHz作为立体声副载波, 另一路19分频得到100kHz给PLL作为参考. 如果把7.6M晶振换成3.579M, 则106.7~107.9MHz这7个频点就变成了50.255~50.820MHz, 全都落在6米业余波段以内.

试着搭了一块板, 果然可以工作, 用VX-7R在7个频点都能准确地收到信号. 但是前级增益低了就几乎没声, 前级增益高了又全是噪声; 如果把VX-7R强行设置成WFM模式, 则一切正常. 估计是BH1417的前端预加重/限幅模块过于强大了.

6米好玩, 等北京的6米解禁了要好好搞搞.

read more

74HC4046实验(2)

2015-10-09 by Stavros

在前几天复习HC4046计算的基础上又试了一下, 用atmega48的timer0将16M主时钟先256预分频再125分频, Toggle模式, 得到250Hz 50%占空比的方波作为参考频率; HC4046的VCO输出接到atmega48的T1口, 用timer1作为÷N分频器.

实测各种RC参数, 用HC4046的鉴相器2可以锁定在60kHz~165kHz, 800kHz~2.4MHz, 差不多有三倍的频率覆盖率, 给各种简单接收机做个本振应该是够了. 用鉴相器1只能锁定在120kHz~165kHz, 不过输出波形似乎稍微干净些.

有空再试试用DDS输出作为HC4046的参考频率. 这里DDS的频率不用很高, 在AVR的定时器中断里更新相位累加字就可以了. 这样应该就能做到1Hz级别的精密步进了.

read more

复习74HC4046的相关计算(1)

2015-09-22 by Stavros

前两天没事复习了一下74HC4046的计算. 主要材料:

  1. 某个在线计算器, 只有VCO的计算. url: http://www.changpuak.ch/electronics/calc_03.php
  2. Motorola的AN1410: Configuring and Applying the MC74HC4046A Phase-Locked Loop
  3. Philips的Datasheet
  4. Texas Instruments的Application Report SCHA003B: CMOS Phase-Locked-Loop Applications Using the CD54/74HC/HCT4046A and CD54/74HC/HCT7046A

根据Philips的datasheet, 取$R_1$ = 10k, $R_2$ = 10k, $C$ = 500p, $V_\rm{CC}$ = 5.0V …

read more

3.579MHz CW发射机

2015-01-15 by Stavros

电路如图, 用74HC240的一个门振荡, 另外7个门并联推动IRF510. 用RS-232串口的RTS信号控制IRF510的供电, 作为电键. DTR信号控制整机供电和天线切换, 作为PTT.

实测发现一个大问题: CP2102转出来的RS-232的DTR和RTS极性是反的! 再一查, PL2303和FT232也是这样. 现在的PC基本已经不提供RS-232了, 没办法, 装个串口挡板, 用真实的串口再试试吧.

read more

50M FM发射实验

2013-07-17 by Stavros

电路如图, 74HC04的一个非门接成10.245M晶体振荡器, 晶体一端并联变容二极管. 用剩下的五个非门来推动2N7002, 2N7002的D极谐振在10.245M的五倍频, 51.225M频率上.

用VX-7R接收, 不管走到屋里哪个角落, 信号都挺强的. 可惜北京不允许使用50M频率, 只能在屋里大概试试了. 估计到开阔地能发射相当远的吧.

read more

发V机

2013-06-11 by Stavros

功能很简单, 就是发出字母V的莫尔斯电码"...-", 用来调试机器, 很好用.

原理图:

由CD4060组成约100kHz的RC振荡器, 6次二分频后得到大约600Hz的音频信号; 继续由74HC393分频得到4bit控制信号, 由两只CD4011组成的逻辑电路变换成字母V的开关信号, 最后由一只NPN管实现600Hz音频调制.

用一只8脚单片机的话, 硬件上可以更简单. 用逻辑电路的好处是不用调试, 焊好通电就能工作了.

开始由一只10440锂电池直接供电, 结果发现电池电压变化会严重影响音调, 于是增加了HT7750升压电路, 让它在固定5V电压下工作, 效果好多了.

read more

继续试验外差机

2013-05-23 by Stavros

分别用LA1600和分立器件实现了两个中波外差机.

效果差不多, 在阳台上能收到中国之声一个台, 别的台都收不到了. 总之和之前做的直放机没啥区别吧.

大概是输入回路的Q值太低, 弱信号全被中国之声压住了. 有空了再做FM机试试吧.

read more

636收音机

2013-04-22 by Stavros

说来惭愧, 玩了这么多年无线电, 以前从来没装响过一台收音机...... 后来发现, 不是收音机不行, 而是那会儿宿舍的电磁环境太差了, 用成品Philips D1875也照样一个AM台也收不到.

636估计是除了矿石机以外, 最简单的能收到台的收音机了, 电路图如下:

这个电路图实际上已经是加强版了, 原版的636是没有倍压检波的. 我这次的实验用了长磁棒和空气双联, 跟当年的成品636相比, 可以算是豪华版了. 在阳台上试了一下, 中波低端可以收到中国之声, 声音挺清楚;高端就收不到什么信号了.

636后来的版本又加上了再生, 应该能加强一些灵敏度和选择性;但是现在的电磁环境跟60年代不能相比了, 已经不适合装直放机了. 以后还是玩外差机吧.

read more

改造AM中周

2010-01-18 by Stavros

FCZ 的许多无线电制作资料上都用了他们自制的线圈, 这些线圈估计是很难买到的. 幸好查到了它们的绕制数据:

型号 频率(MHz) 谐振电容(pF) 电感(μH) 空载Q值 4~6脚匝数 3~1脚匝数 3~2脚匝数
FCZ3.5 3.5 220 9.4 70 7 20 10
FCZ7 7 120 4.6 80 5 14 7
FCZ14 14 70 1.85 75 4 12 6
FCZ21 21 40 …
read more