做了个PSK31 Beacon
2017-04-12 by Stavrospsk31 是业余无线电爱好者常用的通讯方式. 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米波段发射
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 more74HC4046实验(2)
在前几天复习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)
前两天没事复习了一下74HC4046的计算. 主要材料:
- 某个在线计算器, 只有VCO的计算. url: http://www.changpuak.ch/electronics/calc_03.php
- Motorola的AN1410: Configuring and Applying the MC74HC4046A Phase-Locked Loop
- Philips的Datasheet
- 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 more3.579MHz CW发射机
电路如图, 用74HC240的一个门振荡, 另外7个门并联推动IRF510. 用RS-232串口的RTS信号控制IRF510的供电, 作为电键. DTR信号控制整机供电和天线切换, 作为PTT.
实测发现一个大问题: CP2102转出来的RS-232的DTR和RTS极性是反的! 再一查, PL2303和FT232也是这样. 现在的PC基本已经不提供RS-232了, 没办法, 装个串口挡板, 用真实的串口再试试吧.
read more50M FM发射实验
电路如图, 74HC04的一个非门接成10.245M晶体振荡器, 晶体一端并联变容二极管. 用剩下的五个非门来推动2N7002, 2N7002的D极谐振在10.245M的五倍频, 51.225M频率上.
用VX-7R接收, 不管走到屋里哪个角落, 信号都挺强的. 可惜北京不允许使用50M频率, 只能在屋里大概试试了. 估计到开阔地能发射相当远的吧.
read more发V机
功能很简单, 就是发出字母V的莫尔斯电码"...-", 用来调试机器, 很好用.
原理图:
由CD4060组成约100kHz的RC振荡器, 6次二分频后得到大约600Hz的音频信号; 继续由74HC393分频得到4bit控制信号, 由两只CD4011组成的逻辑电路变换成字母V的开关信号, 最后由一只NPN管实现600Hz音频调制.
用一只8脚单片机的话, 硬件上可以更简单. 用逻辑电路的好处是不用调试, 焊好通电就能工作了.
开始由一只10440锂电池直接供电, 结果发现电池电压变化会严重影响音调, 于是增加了HT7750升压电路, 让它在固定5V电压下工作, 效果好多了.
read more继续试验外差机
分别用LA1600和分立器件实现了两个中波外差机.
效果差不多, 在阳台上能收到中国之声一个台, 别的台都收不到了. 总之和之前做的直放机没啥区别吧.
大概是输入回路的Q值太低, 弱信号全被中国之声压住了. 有空了再做FM机试试吧.
read more636收音机
说来惭愧, 玩了这么多年无线电, 以前从来没装响过一台收音机...... 后来发现, 不是收音机不行, 而是那会儿宿舍的电磁环境太差了, 用成品Philips D1875也照样一个AM台也收不到.
636估计是除了矿石机以外, 最简单的能收到台的收音机了, 电路图如下:
这个电路图实际上已经是加强版了, 原版的636是没有倍压检波的. 我这次的实验用了长磁棒和空气双联, 跟当年的成品636相比, 可以算是豪华版了. 在阳台上试了一下, 中波低端可以收到中国之声, 声音挺清楚;高端就收不到什么信号了.
636后来的版本又加上了再生, 应该能加强一些灵敏度和选择性;但是现在的电磁环境跟60年代不能相比了, 已经不适合装直放机了. 以后还是玩外差机吧.
read more