兰湾http://st.avros.net/2017-08-10T00:00:00+08:00再战RF功率计2017-08-10T00:00:00+08:002017-08-10T00:00:00+08:00Stavrostag:st.avros.net,2017-08-10:/articles/rf_power_meter_v2.html<p>目标是实现从1mW以下到几瓦射频功率的测量。</p>
<p><a href="/images2/2017/rf_power_meter.jpg"><img src="/images2/2017/rf_power_meter.jpg" width="480" /></a></p>
<p>原理图很简单,6个300欧电阻并联成50欧假负载,二极管检波、分压后由MCP3421进行AD转换,STM32F030控制OLED屏显示。供电用一节5号电池,BL8530升压到3.3V。</p>
<p><a href="/images2/2017/rf_power_meter_sch.jpg"><img src="/images2/2017/rf_power_meter_sch.jpg" width="480" /></a></p>
<p>主要的麻烦在于检波二极管。2015年试过一次,用2SC1622、2N5551之类高反压三极管的BC结检波,结果发现输入频率50MHz时测得结果严重偏小,输入144M、430M时就完全测不到了,换成1N60则一切正常。可见结电容稍微大一点都不行。但是1N60的耐压只有40V,这样用单只1N60时能测到的最大功率为 \frac{(40\rm V / 2\sqrt{2})^2}{50\Omega}=4\rm W , 两只串联时也只有16W,还是稍嫌小了点儿。如果有耐压上百伏的锗二极管就能测到几十瓦的功率了。</p>
<p>调试过程略麻烦。MCP3421测得的是22k分压电阻上的电压, 乘以(492/22)后可得二极管检波后的峰值电压, 再加上二极管压降Vf即得输入电压峰值.</p>
<p>问题是小信号输入时二极管完全是非线性的, 因此需要对若干已知输入电压Vin, 算出二极管压降VD和电流I.</p>
<p>根据二极管模型 I\approx I_Se …</p><p>目标是实现从1mW以下到几瓦射频功率的测量。</p>
<p><a href="/images2/2017/rf_power_meter.jpg"><img src="/images2/2017/rf_power_meter.jpg" width="480" /></a></p>
<p>原理图很简单,6个300欧电阻并联成50欧假负载,二极管检波、分压后由MCP3421进行AD转换,STM32F030控制OLED屏显示。供电用一节5号电池,BL8530升压到3.3V。</p>
<p><a href="/images2/2017/rf_power_meter_sch.jpg"><img src="/images2/2017/rf_power_meter_sch.jpg" width="480" /></a></p>
<p>主要的麻烦在于检波二极管。2015年试过一次,用2SC1622、2N5551之类高反压三极管的BC结检波,结果发现输入频率50MHz时测得结果严重偏小,输入144M、430M时就完全测不到了,换成1N60则一切正常。可见结电容稍微大一点都不行。但是1N60的耐压只有40V,这样用单只1N60时能测到的最大功率为 \frac{(40\rm V / 2\sqrt{2})^2}{50\Omega}=4\rm W , 两只串联时也只有16W,还是稍嫌小了点儿。如果有耐压上百伏的锗二极管就能测到几十瓦的功率了。</p>
<p>调试过程略麻烦。MCP3421测得的是22k分压电阻上的电压, 乘以(492/22)后可得二极管检波后的峰值电压, 再加上二极管压降Vf即得输入电压峰值.</p>
<p>问题是小信号输入时二极管完全是非线性的, 因此需要对若干已知输入电压Vin, 算出二极管压降VD和电流I.</p>
<p>根据二极管模型 I\approx I_Se^{V_D/nV_T} , 可得 V_D\approx nV_T{\rm ln}\frac{I}{I_S}=nV_T{\rm ln}I-nV_T{\rm ln}I_S , 其中n, Vt, Is都是常数. 之后就简单了, 用若干组实测数据, 拟合出Vd和I的关系式为V_D=0.0294{\rm ln}I + 0.5005, R^2=0.9941 . 从R平方值来看拟合得还可以.</p>
<p>下表左边两列是根据输入电压计算的功率和dBm值, 右边两列是用ADC转换结果换算的功率和dBm值. 精度似乎不错, 除了第一组数据以外, 最多只差0.1dBm, -10dBm的下限已经远超预期了.</p>
<p><a href="/images2/2017/rf_power_meter_tab.jpg"><img src="/images2/2017/rf_power_meter_tab.jpg" width="480" /></a></p>
<p>如果需要准确测量更小的输入功率呢? 可以把检波二极管换成更灵敏的1SS86(反向耐压只有可怜的3V), 或者直接上对数放大器AD8307/AD8310之类.</p>
<p>最后还有个坑: 一开始MCU选了STM32F030F4, 结果大概是因为浮点运算比较多, 最后编译完居然有30k多, STM32F030F4的16k Flash根本不够用. 保险起见, 换成了64k Flash的STM32F030C8.</p>二维码显示模块2017-07-02T00:00:00+08:002017-07-02T00:00:00+08:00Stavrostag:st.avros.net,2017-07-02:/articles/qrcode.html<p>做了个小模块, 可以把字符串从PC传到模块上存储, 并以二维码显示出来.</p>
<p><a href="/images2/2017/qrcode.jpg"><img src="/images2/2017/qrcode.jpg" width="480" /></a></p>
<p>原理图如下, MCU用了48脚的stm32f103, 配1.44寸128x128的TFT屏, 存储么, 24C512和W25Q16各上一片. 其实只要24C512就足够了...</p>
<p><a href="/images2/2017/qrcode_sch.jpg"><img src="/images2/2017/qrcode_sch.jpg" width="480" /></a></p>
<p>USB接口用了HID协议, 从stm32的官方USB例程改改就行, 好处是PC端不需要装驱动了. 程序太长就不贴上来了.</p>
<p>默认例程收发都是以8字节为单位, 这里先改成64字节, 但是64字节的数据包还是不够长, 所以需要做简单的分包处理. 思路也简单, 把第一字节的最高位和次高位作为首包和尾包的标志位, 接收时如果发现是首包, 就把接收指针指向接收缓冲区的起始位置; 然后把后面的63字节依次从USB端点复制到接收缓冲区, 之后接收指针增加63. 如果发现是尾包, 就设一个"接收完成"的标志变量为真.</p>
<p>主程序这边, 得到完整的数据后再调用libqrencode库, 把字符串转换成二维码显示出来, 最后设置"接收完成"的标志变量为假.</p>
<p>PC端程序用python实现, 因为有pywinusb库, 所以很简单, 贴上来:</p>
<div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">pywinusb.hid</span> <span class="kn">as</span> <span class="nn">hid</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="c1"># 从设备接收数据</span>
<span class="k">def</span> <span class="nf">sample_handler</span><span class="p">(</span><span class="n">data</span><span class="p">):</span>
<span class="n">data …</span></pre></div><p>做了个小模块, 可以把字符串从PC传到模块上存储, 并以二维码显示出来.</p>
<p><a href="/images2/2017/qrcode.jpg"><img src="/images2/2017/qrcode.jpg" width="480" /></a></p>
<p>原理图如下, MCU用了48脚的stm32f103, 配1.44寸128x128的TFT屏, 存储么, 24C512和W25Q16各上一片. 其实只要24C512就足够了...</p>
<p><a href="/images2/2017/qrcode_sch.jpg"><img src="/images2/2017/qrcode_sch.jpg" width="480" /></a></p>
<p>USB接口用了HID协议, 从stm32的官方USB例程改改就行, 好处是PC端不需要装驱动了. 程序太长就不贴上来了.</p>
<p>默认例程收发都是以8字节为单位, 这里先改成64字节, 但是64字节的数据包还是不够长, 所以需要做简单的分包处理. 思路也简单, 把第一字节的最高位和次高位作为首包和尾包的标志位, 接收时如果发现是首包, 就把接收指针指向接收缓冲区的起始位置; 然后把后面的63字节依次从USB端点复制到接收缓冲区, 之后接收指针增加63. 如果发现是尾包, 就设一个"接收完成"的标志变量为真.</p>
<p>主程序这边, 得到完整的数据后再调用libqrencode库, 把字符串转换成二维码显示出来, 最后设置"接收完成"的标志变量为假.</p>
<p>PC端程序用python实现, 因为有pywinusb库, 所以很简单, 贴上来:</p>
<div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">pywinusb.hid</span> <span class="kn">as</span> <span class="nn">hid</span>
<span class="kn">import</span> <span class="nn">time</span>
<span class="c1"># 从设备接收数据</span>
<span class="k">def</span> <span class="nf">sample_handler</span><span class="p">(</span><span class="n">data</span><span class="p">):</span>
<span class="n">data</span> <span class="o">=</span> <span class="p">[</span><span class="nb">chr</span><span class="p">(</span><span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="n">data</span><span class="p">]</span>
<span class="n">data</span> <span class="o">=</span> <span class="s1">''</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">data</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<span class="k">print</span><span class="p">(</span><span class="n">data</span><span class="p">)</span>
<span class="c1"># 向设备发送数据</span>
<span class="k">def</span> <span class="nf">hid_send</span><span class="p">(</span><span class="nb">buffer</span><span class="p">):</span>
<span class="nb">buffer</span> <span class="o">=</span> <span class="p">[</span><span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">buffer</span><span class="p">]</span>
<span class="n">header</span> <span class="o">=</span> <span class="mh">0x80</span> <span class="c1"># 首包标志 </span>
<span class="k">while</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&</span><span class="n">gt</span><span class="p">;</span> <span class="n">packetsize</span><span class="p">:</span>
<span class="n">msg</span> <span class="o">=</span> <span class="p">[</span><span class="mh">0x00</span><span class="p">]</span> <span class="o">+</span> <span class="p">[</span><span class="n">header</span><span class="p">]</span> <span class="o">+</span> <span class="nb">buffer</span><span class="p">[:</span><span class="n">packetsize</span><span class="p">]</span>
<span class="k">print</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<span class="n">out_report</span><span class="o">.</span><span class="n">set_raw_data</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<span class="n">header</span> <span class="o">=</span> <span class="mh">0x00</span>
<span class="n">out_report</span><span class="o">.</span><span class="n">send</span><span class="p">()</span>
<span class="k">print</span><span class="p">(</span><span class="s1">'#'</span><span class="p">)</span>
<span class="nb">buffer</span> <span class="o">=</span> <span class="nb">buffer</span><span class="p">[</span><span class="n">packetsize</span><span class="p">:]</span> <span class="c1"># buffer向后跳packetsize个位置</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.1</span><span class="p">)</span>
<span class="n">header</span> <span class="o">+=</span> <span class="mh">0x40</span> <span class="c1"># 尾包标志</span>
<span class="k">while</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&</span><span class="n">lt</span><span class="p">;</span> <span class="n">packetsize</span><span class="p">:</span>
<span class="nb">buffer</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="c1"># 剩余数据不足, 补齐64字节</span>
<span class="n">msg</span> <span class="o">=</span> <span class="p">[</span><span class="mh">0x00</span><span class="p">]</span> <span class="o">+</span> <span class="p">[</span><span class="n">header</span><span class="p">]</span> <span class="o">+</span> <span class="nb">buffer</span>
<span class="n">out_report</span><span class="o">.</span><span class="n">set_raw_data</span><span class="p">(</span><span class="n">msg</span><span class="p">)</span>
<span class="n">out_report</span><span class="o">.</span><span class="n">send</span><span class="p">()</span>
<span class="k">print</span><span class="p">(</span><span class="s1">'#'</span><span class="p">)</span>
<span class="n">time</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="mf">0.1</span><span class="p">)</span>
<span class="c1"># 主程序</span>
<span class="n">flt</span> <span class="o">=</span> <span class="n">hid</span><span class="o">.</span><span class="n">HidDeviceFilter</span><span class="p">(</span><span class="n">vendor_id</span> <span class="o">=</span> <span class="mh">0x8589</span><span class="p">)</span> <span class="c1"># 按vendor_id查找设备</span>
<span class="n">devices</span> <span class="o">=</span> <span class="n">flt</span><span class="o">.</span><span class="n">get_devices</span><span class="p">()</span>
<span class="k">if</span> <span class="n">devices</span><span class="p">:</span>
<span class="n">device</span> <span class="o">=</span> <span class="n">devices</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="k">print</span><span class="p">(</span><span class="n">device</span><span class="p">)</span>
<span class="k">else</span><span class="p">:</span>
<span class="nb">exit</span><span class="p">()</span>
<span class="n">device</span><span class="o">.</span><span class="n">open</span><span class="p">()</span>
<span class="n">device</span><span class="o">.</span><span class="n">set_raw_data_handler</span><span class="p">(</span><span class="n">sample_handler</span><span class="p">)</span>
<span class="n">out_report</span> <span class="o">=</span> <span class="n">device</span><span class="o">.</span><span class="n">find_output_reports</span><span class="p">()[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">packetsize</span> <span class="o">=</span> <span class="mi">63</span> <span class="c1"># 每次发送63字节</span>
<span class="k">while</span> <span class="bp">True</span><span class="p">:</span>
<span class="nb">str</span> <span class="o">=</span> <span class="nb">input</span><span class="p">()</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">'utf8'</span><span class="p">)</span> <span class="c1"># 汉字按utf-8处理</span>
<span class="n">hid_send</span><span class="p">(</span><span class="nb">str</span><span class="p">)</span>
<span class="n">device</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>
<p>之后问题来了, 发现最多只能生成61x61的二维码.</p>
<p>分析原因, 估计是因为libqrencode库返回的qrcode结构体是用malloc分配内存的, 根据我在前面《写了个取剩余可用堆内存的函数》里的分析, arm-none-eabi-gcc里的malloc分配的内存数量上限只能是2的整数次幂; 偏偏libqrencode库内部还多次使用了malloc, 这样20k ram的stm32f103c8一不小心就只能分配到最多4096字节内存了, 如果要生成65x65的二维码就会分配失败.</p>
<p>解决办法只能是换64脚的stm32f103rc或stm32f103re, 它们的内存分别是48k和64k; 128x128的屏幕能显示的最大二维码是125x125, 总共15625个点, 这样只要能成功分配到16k内存就行了, 估计有戏.</p>
<p>附带的好处是, 这俩的flash空间分别有256k和512k, 但是现在程序空间只用了20k多, 这样可以把多余的空间用来存二维码, 24c512和w25q16都可以省掉了.</p>
<p>ps. @Tariel推荐了一个代替*alloc的内存管理库: The BGET Memory Allocator, 也许用它能解决得更漂亮一点.</p>
<p>--------------------更新-------------------------</p>
<p>用bget代替malloc的结果, 可以生成69x69的二维码了... 确实是改善了一点点.</p>写了个取剩余可用堆内存的函数2017-06-29T00:00:00+08:002017-06-29T00:00:00+08:00Stavrostag:st.avros.net,2017-06-29:/articles/get_free_heap_mem.html<p>原理就是二分查找, 不断malloc, 找到一个malloc(n)成功, malloc(n+1)失败的位置</p>
<p>如果堆空间不连续, 返回的应该是最大连续空间.</p>
<p>程序如下, get_free_mem()中调用__get_free_mem()时指定上下界.</p>
<div class="highlight"><pre><span></span>static size_t __get_free_mem(size_t start, size_t end)
{
unsigned char *p;
size_t size = (start + end) / 2;
if(start == end - 1)
return start - 1;
p = malloc(size);
if(p != NULL) { // malloc succeeded
free(p);
return __get_free_mem(size …</pre></div><p>原理就是二分查找, 不断malloc, 找到一个malloc(n)成功, malloc(n+1)失败的位置</p>
<p>如果堆空间不连续, 返回的应该是最大连续空间.</p>
<p>程序如下, get_free_mem()中调用__get_free_mem()时指定上下界.</p>
<div class="highlight"><pre><span></span>static size_t __get_free_mem(size_t start, size_t end)
{
unsigned char *p;
size_t size = (start + end) / 2;
if(start == end - 1)
return start - 1;
p = malloc(size);
if(p != NULL) { // malloc succeeded
free(p);
return __get_free_mem(size + 1, end);
}
else { // malloc failed
return __get_free_mem(start, size);
}
}
size_t get_free_mem(void)
{
return __get_free_mem(0, 65536UL);
}
</pre></div>
<p>主要问题有两个, 一是在64k范围时要递归十几次, 4G范围时得递归30多次. 如果调用位置比较深总担心要爆栈, 得改成非递归的;</p>
<p>二是stm32的syscall.c里的_sbrk()实现是判断heap_end加上incr是否超过asm("SP"), 其中heap_end是静态变量, 第一次调用时取_end的值. 这样有个问题就是把bss段和当前未用的栈空间都给算到堆空间了, 似乎不太合适. 是否应该跳过bss段, 以及把整个栈空间都去掉? </p>
<p>实测: 在PC上用32位gcc编译, 结果是1.8G左右的内存. 在512M内存的树莓派上是345M左右, 都还算合理.</p>
<p>在48k RAM的STM32F103RCT6上则比较有趣, make完size的结果是.data+.bss一共10256字节, 49152-10256=38896, 再去掉已用掉的栈空间, 应该是38k不到的样子. 但是get_free_mem的结果总是32768. </p>
<p>如果先malloc(16000), get_free_mem的结果就变成了16384. 继续malloc, 结果逐渐减小为8192, 4096. 估计是arm-none-eabi-gcc的malloc内部实现上做了限制, 只取可用堆空间里最大的2的整数次幂.</p>
<p>如果先这样:</p>
<div class="highlight"><pre><span></span>p = malloc(12000);
q = malloc(12000);
r = malloc(11300);
s = malloc(11000);
</pre></div>
<p>这样可以成功分配到46300字节, 看来确实是把bss都算进来了. 然后, 果然hardfault了...</p>
<p>上面两点有空再改吧.</p>
<p>----------------更新--------------------</p>
<p>上面的说法有误,arm-none-eabi-size -A main_rom.elf的结果, .bss是1860, ._user_heap_stack是8192. 而arm-none-eabi-size -B main_rom.elf的结果, bss是10052,应该是把上面两者都算作bss了。</p>
<p>_user_heap_stack这部分作为堆空间是没有问题的,它应该只是在编译时起到检查静态空间是否越界的作用。</p>
<p>--------------------再更新---------------------</p>
<p>非递归版本的__get_free_mem函数如下... 脑子短路了,这个感觉比递归的还简单...</p>
<div class="highlight"><pre><span></span>static size_t __get_free_mem2(size_t start, size_t end)
{
unsigned char *p;
while(start &lt; end - 1) {
size_t size = (start + end) / 2;
if(size == 0)
return 0;
p = malloc(size);
if(p != NULL) { // malloc succeeded
free(p);
start = size;
}
else { // malloc failed
end = size - 1;
}
}
return start;
}
</pre></div>卡片手电加强版2017-06-28T00:00:00+08:002017-06-28T00:00:00+08:00Stavrostag:st.avros.net,2017-06-28:/articles/handy_v3.html<p>之前做过一个卡片手电,链接:卡片手电,感觉亮度不太够;但是如果加大亮度,电池续航时间又嫌太短。所以有必要做成高低两档亮度。</p>
<p>原理图如下:</p>
<p><a href="/images2/2017/handy_v3.png"><img src="/images2/2017/handy_v3.png" width="480" /></a></p>
<p>这次改用升压恒流的方式。升压IC不一定要用MP1540,只要是能从单锂电升压到13~14V的boost IC都可以。LED用了四只0.5W的5730,取样电阻R308串联在LED回路中,因此低亮度档的电流为1.25V/39R=32mA,相应的功率大约是0.4W。当需要高亮度时按下SW302,此时Q301导通,R305、R306与R308并联,总电阻为8.58R,此时的电流是146mA,总功率约1.9W。电池正负极连接J302、J303,MicroUSB口通过U301对电池充电。LTC4054比较贵,可以用国产的TP4054等型号完美代替。ps. D301负极对地漏了个滤波电容,10u的贴片电容就可以。</p>
<p>升压恒流方式的优点是输出电流较小,因此取样电阻的功耗也较小;但当LED有一只断路时,boost输出电压会持续升高直到击穿,因此需要增加一只16V的稳压二极管D303,把输出电压限制在VFB+16V的位置。有些专门的LED升压驱动IC,比如MP3202,已经内置了保护电路。</p>
<p>实物如下 …</p><p>之前做过一个卡片手电,链接:卡片手电,感觉亮度不太够;但是如果加大亮度,电池续航时间又嫌太短。所以有必要做成高低两档亮度。</p>
<p>原理图如下:</p>
<p><a href="/images2/2017/handy_v3.png"><img src="/images2/2017/handy_v3.png" width="480" /></a></p>
<p>这次改用升压恒流的方式。升压IC不一定要用MP1540,只要是能从单锂电升压到13~14V的boost IC都可以。LED用了四只0.5W的5730,取样电阻R308串联在LED回路中,因此低亮度档的电流为1.25V/39R=32mA,相应的功率大约是0.4W。当需要高亮度时按下SW302,此时Q301导通,R305、R306与R308并联,总电阻为8.58R,此时的电流是146mA,总功率约1.9W。电池正负极连接J302、J303,MicroUSB口通过U301对电池充电。LTC4054比较贵,可以用国产的TP4054等型号完美代替。ps. D301负极对地漏了个滤波电容,10u的贴片电容就可以。</p>
<p>升压恒流方式的优点是输出电流较小,因此取样电阻的功耗也较小;但当LED有一只断路时,boost输出电压会持续升高直到击穿,因此需要增加一只16V的稳压二极管D303,把输出电压限制在VFB+16V的位置。有些专门的LED升压驱动IC,比如MP3202,已经内置了保护电路。</p>
<p>实物如下,PCB用502粘在随便一张什么卡上就行了。焊上电池,胶布缠好,完工!</p>
<p><a href="/images2/2017/handy_v3.jpg"><img src="/images2/2017/handy_v3.jpg" width="480" /></a> </p>可级联的USB-UARTx2转换器2017-06-27T00:00:00+08:002017-06-27T00:00:00+08:00Stavrostag:st.avros.net,2017-06-27:/articles/usb_uartx2.html<p>各种DIY实验时经常需要不止一个串口,有时需要三四个;再加上下载器之类,PC提供的USB口多半不够,所以还得来个USB HUB。这堆东西肯定会把桌面弄得很乱。如果把USB HUB和USB转UART做到一起,不就简洁多了?
于是动手,原理图和实物如下:</p>
<p><a href="/images2/2017/usb-uartx2.png"><img src="/images2/2017/usb-uartx2.png" width="480" /></a></p>
<p><a href="/images2/2017/usb-uartx2.jpg"><img src="/images2/2017/usb-uartx2.jpg" width="480" /></a></p>
<p>USB HUB IC选用GL850G,可以转出四个下级USB口。其中两个USB口接沁恒的CH340E,转为TTL串口;一个USB口用母座引出,可以用来接下载器之类。如果两个串口还不够,可以两套串一起用,这样就有四个串口了。</p>
<p>CH340E是沁恒新出的小体积USB-UART转换器,实测波特率可以到2Mbps;但是不怎么好焊,感觉引脚不太沾锡,与同样MSOP-10封装的XTR111、AD9833相比差远了。大概沁恒的封装工艺还需要加强。</p>
<p>ps. 刚看到沁恒又出了SOP8封装的CH330N,有空试试。</p><p>各种DIY实验时经常需要不止一个串口,有时需要三四个;再加上下载器之类,PC提供的USB口多半不够,所以还得来个USB HUB。这堆东西肯定会把桌面弄得很乱。如果把USB HUB和USB转UART做到一起,不就简洁多了?
于是动手,原理图和实物如下:</p>
<p><a href="/images2/2017/usb-uartx2.png"><img src="/images2/2017/usb-uartx2.png" width="480" /></a></p>
<p><a href="/images2/2017/usb-uartx2.jpg"><img src="/images2/2017/usb-uartx2.jpg" width="480" /></a></p>
<p>USB HUB IC选用GL850G,可以转出四个下级USB口。其中两个USB口接沁恒的CH340E,转为TTL串口;一个USB口用母座引出,可以用来接下载器之类。如果两个串口还不够,可以两套串一起用,这样就有四个串口了。</p>
<p>CH340E是沁恒新出的小体积USB-UART转换器,实测波特率可以到2Mbps;但是不怎么好焊,感觉引脚不太沾锡,与同样MSOP-10封装的XTR111、AD9833相比差远了。大概沁恒的封装工艺还需要加强。</p>
<p>ps. 刚看到沁恒又出了SOP8封装的CH330N,有空试试。</p>CH341T GPIO实验2017-04-17T00:00:00+08:002017-04-17T00:00:00+08:00Stavrostag:st.avros.net,2017-04-17:/articles/ch341t_gpio.html<p>沁恒的CH341A是个多功能的USB总线转发器. 淘宝搜CH341A会搜出一大堆用它做的EEPROM/FLASH编程器, 而它的实际功能还要强大得多, 可以从USB提供异步串口、打印口、EPP/MEM并口、I2C、SPI等接口. 此外CH341A在EPP/MEM并口状态下还可以用沁恒提供的API直接操作引脚, 除了8位并口的8个脚以外, 若干状态引脚也能操作, 总共可以得到16个左右的GPIO. (其中有个别引脚只能输入或者只能输出. )</p>
<p>这东西的主要缺点就是封装是SOP28宽体, 体积实在大了点. 它的两个小兄弟, CH341T和CH341H都是SSOP20封装, 苗条了很多, 前者只提供异步串口和I2C, 后者只提供SPI.</p>
<p>CH341A配置不同功能是靠SDA的不同接法实现的, SDA/SCL悬空时连接PC会识别成异步串口, SDA拉低会识别成转EPP/MEM并口和I2C/SPI串口, SDA和SCL短接会识别成USB打印机. CH341T也提供了SDA和SCL引脚, 如果SDA接地, 能不能也把它的若干状态引脚当GPIO用呢?</p>
<p>做了块小板, 实际测试, 果然可以! PC直接把它识别成了CH341A.</p>
<p>接下来要实测哪些引脚可以使用. 这里要吐槽一下沁恒的API, 只提供了ch341dll.h, ch341dll.dll和ch341dll.lib; 试了各种办法想把ch341dll.lib转成mingw环境下的.a或者.o, 均失败. 没想到直接gcc …</p><p>沁恒的CH341A是个多功能的USB总线转发器. 淘宝搜CH341A会搜出一大堆用它做的EEPROM/FLASH编程器, 而它的实际功能还要强大得多, 可以从USB提供异步串口、打印口、EPP/MEM并口、I2C、SPI等接口. 此外CH341A在EPP/MEM并口状态下还可以用沁恒提供的API直接操作引脚, 除了8位并口的8个脚以外, 若干状态引脚也能操作, 总共可以得到16个左右的GPIO. (其中有个别引脚只能输入或者只能输出. )</p>
<p>这东西的主要缺点就是封装是SOP28宽体, 体积实在大了点. 它的两个小兄弟, CH341T和CH341H都是SSOP20封装, 苗条了很多, 前者只提供异步串口和I2C, 后者只提供SPI.</p>
<p>CH341A配置不同功能是靠SDA的不同接法实现的, SDA/SCL悬空时连接PC会识别成异步串口, SDA拉低会识别成转EPP/MEM并口和I2C/SPI串口, SDA和SCL短接会识别成USB打印机. CH341T也提供了SDA和SCL引脚, 如果SDA接地, 能不能也把它的若干状态引脚当GPIO用呢?</p>
<p>做了块小板, 实际测试, 果然可以! PC直接把它识别成了CH341A.</p>
<p>接下来要实测哪些引脚可以使用. 这里要吐槽一下沁恒的API, 只提供了ch341dll.h, ch341dll.dll和ch341dll.lib; 试了各种办法想把ch341dll.lib转成mingw环境下的.a或者.o, 均失败. 没想到直接gcc ch341dll.dll main.o -o main.exe, 居然成功了.</p>
<p>先试验输入状态, 程序如下:</p>
<div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt; </span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;stdlib.h&gt; </span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;windows.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">"ch341dll.h"</span><span class="cp"></span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">HANDLE</span> <span class="n">hdlCh341</span><span class="p">;</span>
<span class="n">hdlCh341</span> <span class="o">=</span> <span class="n">CH341OpenDeviceEx</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"%lu</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="kt">long</span><span class="p">)</span><span class="n">hdlCh341</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"%lu</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">CH341GetVersion</span><span class="p">());</span>
<span class="n">CH341ResetDevice</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="n">CH341SetOutput</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mh">0xffffffff</span><span class="p">,</span> <span class="mh">0x00000000</span><span class="p">,</span> <span class="mh">0x00000000</span><span class="p">);</span>
<span class="k">while</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">unsigned</span> <span class="kt">long</span> <span class="n">status</span><span class="p">;</span>
<span class="n">CH341GetInput</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">&</span><span class="n">amp</span><span class="p">;</span><span class="n">status</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"%08lx</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">status</span><span class="p">);</span>
<span class="n">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>运行, 屏幕上不断输出0000efff.</p>
<p>之后用杜邦线把模块的各个引脚逐个与地短接, 观察屏幕上的输出.</p>
<p>短接5脚INT#/4脚RXD/3脚TXD/2脚ROV#/19脚TEN#/14脚SLP#到地时, 屏幕上的输出分别变为0000ebff, 0000edff, 0000eeff, 0000afff, 0000cfff, 0000ef7f. 说明这6个脚可以作为输入脚使用.</p>
<p>再试验输出状态, 程序如下:</p>
<div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt; </span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;stdlib.h&gt; </span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">&lt;windows.h&gt;</span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">"ch341dll.h"</span><span class="cp"></span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">HANDLE</span> <span class="n">hdlCh341</span><span class="p">;</span>
<span class="n">hdlCh341</span> <span class="o">=</span> <span class="n">CH341OpenDeviceEx</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"%lu</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="p">(</span><span class="kt">unsigned</span> <span class="kt">long</span><span class="p">)</span><span class="n">hdlCh341</span><span class="p">);</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"%lu</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">CH341GetVersion</span><span class="p">());</span>
<span class="n">CH341ResetDevice</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="n">CH341SetOutput</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mh">0xffffffff</span><span class="p">,</span> <span class="mh">0xffffffff</span><span class="p">,</span> <span class="mh">0x00000000</span><span class="p">);</span>
<span class="k">while</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="n">CH341SetOutput</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="n">b11111</span><span class="p">,</span> <span class="mh">0xffffffff</span><span class="p">,</span> <span class="mh">0xffffffff</span><span class="p">);</span>
<span class="n">CH341SetOutput</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="n">b11111</span><span class="p">,</span> <span class="mh">0xffffffff</span><span class="p">,</span> <span class="mh">0x0</span><span class="p">);</span> <span class="p">}</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>
<p>之后用示波器观察各个引脚的波形, 结果发现除了上面的6个脚以外, 18脚TNOW/17脚RDY#/16脚SCL/15脚SDA也都有方波输出. 可见除了ACT#之外的10个脚都可以作为输出脚使用. 就是方波频率低了点, 只有1kHz左右.</p>
<p>这么看来CH341T的潜力还挺大, 6个脚输入输出两用, 另外4个只输出, 足够实现很多功能了. 速度慢点, 做点简单的控制是没有问题的.</p>
<p>更新: 今天想到, 可能某些管脚其实是没有内部上拉, 所以作为输入时拉到地没反应? 于是再在输入状态下把18~15这四个管脚分别上拉, 果然当SDA上拉时屏幕上的输出变成了0080efff. 可见SDA也能作为输入使用. 所以应该是7个双向GPIO, 3个只能输出.</p>做了个PSK31 Beacon2017-04-12T00:00:00+08:002017-04-12T00:00:00+08:00Stavrostag:st.avros.net,2017-04-12:/articles/psk31_beacon.html<p>psk31 是业余无线电爱好者常用的通讯方式. psk31 的原理就不介绍了, 见链接:
<a href="https://www.hellocq.net/forum/simple/?t88551.html">哈罗 CQ 火腿社区 - HAM 软件、HAM 网站 - PSK31 簡介 BV3FG - Powered by phpwind</a></p>
<p>psk31 的调制如何具体实现呢? HAM 们常用的方式是用 digipan 等软件把要发送的消息调制到几百 Hz 的音频信号上, 再利用发射机的 SSB 模式把这个音频信号发射出去, 这里 SSB 实际上起了上变频的作用.</p>
<p>也可以把整个调制过程都放在 MCU 里进行, 直接从 MCU 的 DAC 输出调制好的音频信号.</p>
<p>ka7oei 则提供了一个偏硬件的直接调制方案, 见下图:</p>
<p><a href="/images2/2017/psk31_beacon_1.png"><img src="/images2/2017/psk31_beacon_1.png" width="480" /></a> </p>
<p>左下的振荡器振荡在所需频率的 4 倍上, 由计数器 74HC4017 接成四分频, 从 …</p><p>psk31 是业余无线电爱好者常用的通讯方式. psk31 的原理就不介绍了, 见链接:
<a href="https://www.hellocq.net/forum/simple/?t88551.html">哈罗 CQ 火腿社区 - HAM 软件、HAM 网站 - PSK31 簡介 BV3FG - Powered by phpwind</a></p>
<p>psk31 的调制如何具体实现呢? HAM 们常用的方式是用 digipan 等软件把要发送的消息调制到几百 Hz 的音频信号上, 再利用发射机的 SSB 模式把这个音频信号发射出去, 这里 SSB 实际上起了上变频的作用.</p>
<p>也可以把整个调制过程都放在 MCU 里进行, 直接从 MCU 的 DAC 输出调制好的音频信号.</p>
<p>ka7oei 则提供了一个偏硬件的直接调制方案, 见下图:</p>
<p><a href="/images2/2017/psk31_beacon_1.png"><img src="/images2/2017/psk31_beacon_1.png" width="480" /></a> </p>
<p>左下的振荡器振荡在所需频率的 4 倍上, 由计数器 74HC4017 接成四分频, 从 0 和 2 两脚输出一对相位相反的载波信号. MCU 的 PB2 通过 74HC00 选择相位. PA3 输出的 PWM 信号经低通滤波后, 再经 U2, Q4 调节 Q3 的漏极电压, 实现在输出 0 时将输出信号幅度逐渐降到零的瞬间切换相位. 这个方案很简洁, 我决定就拿这个图稍微改动一下. MCU 么, 用最简单的 ATTiny13 就好了.</p>
<p>首先得在 PC 上软件模拟一下. 程序很简单, 找个 psk31 的码表, 一般是类似这样:</p>
<div class="highlight"><pre><span></span>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 */
};
</pre></div>
<p>存储格式是从高位到低位, 后面补零. 注意这个码表是从空格开始, 到小写 z 就结束了, 也就是 ASCII 码从 32 到 122 这 91 个字符, 这样能省下不少宝贵的 flash 空间. 毕竟 ATTiny13 的 flash 空间只有可怜的 1024 字节, 如果把完整的码表放进来, 一下子 512 字节就没有了.
发送一个字符的函数可以写成这样:</p>
<div class="highlight"><pre><span></span>void psk31_tx(char c)
{
uint16_t varc;
for(varc = VARICODE_TABLE[c - ' ']; varc; varc &lt;&lt;= 1) {
if(varc &amp; 0x8000)
printf("1");
else
printf("0");
}
printf("00");
}
</pre></div>
<p>然后随便找个字符串, 比如 Hello, world.</p>
<div class="highlight"><pre><span></span>char msg[] = "Hello, world.";
char *p = msg;
while(*p) {
psk31_tx(*p);
p++;
}
</pre></div>
<p>编译运行, 就能看到效果了.</p>
<p>在 MCU 上实现时要稍微复杂一点. 发送 1 好办, 保持满幅输出不变, 挨过 32ms 时间就完事. 发送 0 就复杂一些, 需要按余弦函数把输出幅度逐渐减小为零, 切换相位, 再把幅度逐渐增加到最大. 把 printf("1") 和 printf("0") 分别换成这两个操作就行. 但是这样就破坏了可移植性. 解决办法就是函数指针, 把 psk31_tx 函数写成这样:</p>
<div class="highlight"><pre><span></span>void psk31_tx(char c, void (*tx0)(void), void (*tx1)(void))
{
unsigned short varc;
for(varc = varicode_table[(c - ' ')]; varc; varc &lt;&lt;= 1) {
if(varc &amp; 0x8000)
(*tx1)();
else
(*tx0)();
}
(*tx0)();
(*tx0)();
}
</pre></div>
<p>把发送 1 和 0 的操作写成两个回调函数传给 psk31_tx(), 这样就完美了.</p>
<p>之后设计电路, 如图:</p>
<p><a href="/images2/2017/psk31_beacon_2.png"><img src="/images2/2017/psk31_beacon_2.png" width="480" /></a> </p>
<p>振荡这里用一只 74AHC1G00 加上 14.318M 的晶振就行了, 通过调节 KV1471 的偏压来微调频率. 四分频用了更常用的 74HC74, 两级二分频, 从第二级的 Q 和 / Q 脚输出一对相位相反的载波信号. 切换相位用一只模拟开关 74LVC1G3157 来实现. 其余部分基本保持 ka7oei 的设计不变.</p>
<p>成品照片:</p>
<p><a href="/images2/2017/psk31_beacon_3.jpg"><img src="/images2/2017/psk31_beacon_3.jpg" width="480" /></a> </p>
<p>末级电源电压这里只用到 5V, 实测连续发送 1 时在 50 欧假负载上可以得到 40mW / +16dBm 的功率. 如果把末级供电电压提到 12V, 同时把 MMBT2222 和 2N7002 换成封装大一点的管子, 估计能做到 1W 上下, 再大就得加后级了.</p>
<p>ATTiny13 的一大缺点是不能接晶振, 于是把它的 RC 时钟设到 4.8M, 通过 OSCCAL 寄存器微调到 4.096M 左右, 然后 8 分频作为定时器 0 的时钟源, 定时器 0 输出 PWM 的同时也提供了 4.096M / 8 / 256 = 2kHz 的时基信号. 余弦波形表用了 64 个点, 从而得到 2k / 64 = 31.25Hz. 输出 1 时只要什么都不做, 等定时器 0 中断 64 次就行了.</p>
<p>ATTiny13 的另一大缺点... 就是 RAM 只有可怜的 64 字节. 实测发现即使发送 "Hello, world." 也一样爆栈, 只好不用回调机制, 同时把 "Hello, world." 也放到 flash, 才总算是发送成功.</p>
<p>用 IC-R71E 接收, Digipan 和 MultiPSK 解调的效果图如下:</p>
<p>Digipan</p>
<p><a href="/images2/2017/psk31_beacon_4.png"><img src="/images2/2017/psk31_beacon_4.png" width="480" /></a> </p>
<p>MultiPSK</p>
<p><a href="/images2/2017/psk31_beacon_5.png"><img src="/images2/2017/psk31_beacon_5.png" width="480" /></a> </p>
<p>感觉 Multipsk 的解调效果要好一些, 可能是 Digipan 那边有些参数没设置好.</p>
<p>在这个 Beacon 的基础上可以玩出很多花样来, 看你怎么发挥了.</p>带电压电流指示的USB充电器2016-12-31T00:00:00+08:002016-12-31T00:00:00+08:00Stavrostag:st.avros.net,2016-12-31:/articles/usb_charger_new.html<p>以前做过一个带输出电流指示的USB充电器, 电流指示用的是10段式LED光条, 用着挺好, 就是感觉10段式光条显示电流还是太粗略了. 最近玩了几个OLED屏, 感觉显示效果不错, 于是做了个直接显示电压电流数值的USB充电器.</p>
<p>原理图如下, Buck IC用的是AOZ1050, 同步整流降压, 号称效率95%, 不过最大输出电流只有2A. 输入电压范围是4.5到16V, 当然输出5V时输入电压得高于5V才行, 我用的是12V. (需要更大电流的话, 可以考虑TPS54331/MP1584/MP2303之类, 可以到3A; AOSMD的AOZ1014或AOZ1094可以到5A, 他家还有更大电流的产品, 不过不知道好不好买.) 0.05欧电阻R1和运放U5, PMOS Q1组成高端电流检测, R1两端电压放大22倍后进单片机的ADC通道0, 输出电压则直接分一半进ADC通道1. 单片机用了20脚的STM32F030F4P6, 16K/4K的FLASH/RAM已经足够了. 显示屏用了一片0.91寸128x32分辨率的OLED. LDO U3为单片机和OLED屏供电, 注意它的输入电压, 常用的XC6206之类只允许5V输入, 12V进去肯定是要冒烟的.</p>
<p><a href="/images2/2016/usb_charger_new.png" title="USB充电器"><img src="/images2/2016/usb_charger_new.png" width="500px"/></a> </p>
<p>实物照片:</p>
<p><a href="/images2/2016/usb_charger_new.jpg" title="USB充电器"><img src="/images2/2016/usb_charger_new.jpg" width="500px"/></a> </p>
<p>注意, 电流好象超了? 其实是测得不准, 测量发现运放两输入端电压差几十mV, 看样子是自激了. 果然这个高端电流检测的原型电路不能直接抄来就用, 得在PMOS栅极加电阻 …</p><p>以前做过一个带输出电流指示的USB充电器, 电流指示用的是10段式LED光条, 用着挺好, 就是感觉10段式光条显示电流还是太粗略了. 最近玩了几个OLED屏, 感觉显示效果不错, 于是做了个直接显示电压电流数值的USB充电器.</p>
<p>原理图如下, Buck IC用的是AOZ1050, 同步整流降压, 号称效率95%, 不过最大输出电流只有2A. 输入电压范围是4.5到16V, 当然输出5V时输入电压得高于5V才行, 我用的是12V. (需要更大电流的话, 可以考虑TPS54331/MP1584/MP2303之类, 可以到3A; AOSMD的AOZ1014或AOZ1094可以到5A, 他家还有更大电流的产品, 不过不知道好不好买.) 0.05欧电阻R1和运放U5, PMOS Q1组成高端电流检测, R1两端电压放大22倍后进单片机的ADC通道0, 输出电压则直接分一半进ADC通道1. 单片机用了20脚的STM32F030F4P6, 16K/4K的FLASH/RAM已经足够了. 显示屏用了一片0.91寸128x32分辨率的OLED. LDO U3为单片机和OLED屏供电, 注意它的输入电压, 常用的XC6206之类只允许5V输入, 12V进去肯定是要冒烟的.</p>
<p><a href="/images2/2016/usb_charger_new.png" title="USB充电器"><img src="/images2/2016/usb_charger_new.png" width="500px"/></a> </p>
<p>实物照片:</p>
<p><a href="/images2/2016/usb_charger_new.jpg" title="USB充电器"><img src="/images2/2016/usb_charger_new.jpg" width="500px"/></a> </p>
<p>注意, 电流好象超了? 其实是测得不准, 测量发现运放两输入端电压差几十mV, 看样子是自激了. 果然这个高端电流检测的原型电路不能直接抄来就用, 得在PMOS栅极加电阻, 运放2/6脚之间加个小电容才能用. 下次再改吧.</p>
<p>再ps. 原理图里C2 1u太大了, 10~22nF就可以了.</p>试着用ATmega169做了个钟2016-12-26T00:00:00+08:002016-12-26T00:00:00+08:00Stavrostag:st.avros.net,2016-12-26:/articles/m169_clock.html<p>之前试过M328在Powerdown模式/WDT中断唤醒时工作电流不到1uA. AVR 8位单片机里带LCD控制器的不多, 查了一下似乎就只有64脚的M169/329/649和100脚的M3290/M6490这几种. 前段时间搞了几个m169和4位8字的笔段式LCD, 于是考虑做个钟, 用CR2032供电, 看看它的低功耗性能如何. </p>
<p>WDT中断的时钟源是RC振荡器, 定时精度太差了, 做钟肯定是不行的; 幸好M169也支持T2定时器的异步模式, 可以用32.768KHz的晶振作为时钟源, 由T2中断唤醒. 以及M169的省电模式下LCD控制器仍然保持运行, 感觉都是很贴心的设计. 缺点就是... 体积太大了, 64脚还是0.8的间距, 封装面积是14*14=196mm2, 还不如用别的MCU配一片HT1621呢. ps. 这东西有9*9和7*7的两种QFN封装, 但是没见到哪有卖的.</p>
<p>原理图很简单, 就不贴了. 实物照片:</p>
<p><a href="/images2/2016/m169_clock.jpg" title="M169钟"><img src="/images2/2016/m169_clock.jpg" width="500px"/></a> </p>
<p>实测工作电流大概20uA, CR2032的标称容量有200mAh多点, 算下来能工作一年多. 希望明年这会儿它还能走.</p><p>之前试过M328在Powerdown模式/WDT中断唤醒时工作电流不到1uA. AVR 8位单片机里带LCD控制器的不多, 查了一下似乎就只有64脚的M169/329/649和100脚的M3290/M6490这几种. 前段时间搞了几个m169和4位8字的笔段式LCD, 于是考虑做个钟, 用CR2032供电, 看看它的低功耗性能如何. </p>
<p>WDT中断的时钟源是RC振荡器, 定时精度太差了, 做钟肯定是不行的; 幸好M169也支持T2定时器的异步模式, 可以用32.768KHz的晶振作为时钟源, 由T2中断唤醒. 以及M169的省电模式下LCD控制器仍然保持运行, 感觉都是很贴心的设计. 缺点就是... 体积太大了, 64脚还是0.8的间距, 封装面积是14*14=196mm2, 还不如用别的MCU配一片HT1621呢. ps. 这东西有9*9和7*7的两种QFN封装, 但是没见到哪有卖的.</p>
<p>原理图很简单, 就不贴了. 实物照片:</p>
<p><a href="/images2/2016/m169_clock.jpg" title="M169钟"><img src="/images2/2016/m169_clock.jpg" width="500px"/></a> </p>
<p>实测工作电流大概20uA, CR2032的标称容量有200mAh多点, 算下来能工作一年多. 希望明年这会儿它还能走.</p>USB-485隔离转换器2016-12-22T00:00:00+08:002016-12-22T00:00:00+08:00Stavrostag:st.avros.net,2016-12-22:/articles/usb_485_new.html<p>调试各种设备经常用到RS-485总线, 但是现在的PC连232也基本没有了, 只剩USB能用, 因此需要搞个USB-485的转换器. 做法也简单, 先用CP2102/PL2303/CH340/FT232之类IC把USB转成TTL电平的串口信号, 再从TTL转成485. (顺便点评一下: PL2303太差劲, FT232国内盗版太多, 用原厂驱动会烧, CP2102好用但是只有QFN封装不好焊, 国产的CH340最好用.)</p>
<p>这里有个问题, 485收发器都需要提供收/发方向信号(也有自动切换方向的, 比如MAX13487, 但是要用的时候总是买不到), 由MCU直接控制很容易, 但从USB转出来的串口信号没法判断方向. 网上的通行做法是把485的DI脚直接接地, 串口TXD信号用晶体管反相后驱动485的DE/RE脚. 这样在接收状态时, TXD空闲为高电平, 反相后把485的DE/RE拉低, 于是485方向为接收, 没问题; 发送0时TXD为低电平, 反相后485的DE/RE脚拉高, DI脚接地, 于是485输出0, 也没问题. 发送1时TXD和空闲时一样是高电平, 485的DE/RE拉低, 方向为接收, 此时485的A/B脚是高阻状态, 靠A的上拉和B的下拉电阻输出1. 这样确实能通讯, 短距离工作也一切正常, 但是总觉得不太可靠.</p>
<p>偶然发现国产芯片 …</p><p>调试各种设备经常用到RS-485总线, 但是现在的PC连232也基本没有了, 只剩USB能用, 因此需要搞个USB-485的转换器. 做法也简单, 先用CP2102/PL2303/CH340/FT232之类IC把USB转成TTL电平的串口信号, 再从TTL转成485. (顺便点评一下: PL2303太差劲, FT232国内盗版太多, 用原厂驱动会烧, CP2102好用但是只有QFN封装不好焊, 国产的CH340最好用.)</p>
<p>这里有个问题, 485收发器都需要提供收/发方向信号(也有自动切换方向的, 比如MAX13487, 但是要用的时候总是买不到), 由MCU直接控制很容易, 但从USB转出来的串口信号没法判断方向. 网上的通行做法是把485的DI脚直接接地, 串口TXD信号用晶体管反相后驱动485的DE/RE脚. 这样在接收状态时, TXD空闲为高电平, 反相后把485的DE/RE拉低, 于是485方向为接收, 没问题; 发送0时TXD为低电平, 反相后485的DE/RE脚拉高, DI脚接地, 于是485输出0, 也没问题. 发送1时TXD和空闲时一样是高电平, 485的DE/RE拉低, 方向为接收, 此时485的A/B脚是高阻状态, 靠A的上拉和B的下拉电阻输出1. 这样确实能通讯, 短距离工作也一切正常, 但是总觉得不太可靠.</p>
<p>偶然发现国产芯片: 江苏沁恒的CH341居然有个TNOW脚指示串口发送状态, 这样就不需要上面的笨办法了; 而且datasheet里还给了用它转换485的例子. 于是马上照做了一个, 果然好用, 目前115200波特率收发测试正常, 有空再试更高的波特率.</p>
<p>原理图如下, 485驱动器用了ADI的ADM2483, 磁耦合隔离, 很好用. 不过它两边都要供电, 所以得再加个金升阳的隔离电源B0505S. 如果用自带供电的ADM2587, 这个隔离电源也可以省掉, 不过ADM2587实在太贵了. USB端加了TVS保护, 485端以后考虑也加一个.</p>
<p><a href="/images2/2016/usb_485_new.png" title="USB转485"><img src="/images2/2016/usb_485_new.png" width="500px"/></a> </p>
<p>ps. 沁恒的CH340最近出了免12M晶振的新版本CH340B/C, 实测750kbps好用, 1.5Mbps时发几百字节偶尔丢一字节数据, 总之已经很不错了. CH341也赶紧出个免晶振的版本吧.</p>Allegro导出bom和坐标文件, 用于嘉立创的SMT下单2016-12-16T00:00:00+08:002016-12-16T00:00:00+08:00Stavrostag:st.avros.net,2016-12-16:/articles/allegro_bom_coord.html<p>截图就不用贴了吧?</p>
<ol>
<li>
<p>Allegro 菜单点 Tools, Reports </p>
<ul>
<li>从 Available Reports 里找 Placed Component Report, 双击让它跑到下面框里. </li>
<li>选中 Write Report, 点 Report. 此时会在. brd 所在目录下生成一个 pcp_rep.rpt</li>
</ul>
</li>
<li>
<p>Excel, 文件, 打开, 类型选” 所有文件”, 找到刚生成的 pcp_rep.rpt. </p>
<ul>
<li>出现” 文本导入向导”, 直接点下一步. </li>
<li>分隔符号这里把” 逗号” 选上, 然后点下一步. </li>
<li>列数据格式, 选” 文本”, 然后点完成.</li>
</ul>
</li>
<li>
<p>表格出来了, 前四行没用, 删掉. 表头要按 JLC 的格式修改, 具体如下:</p>
<ul>
<li>REFDES …</li></ul></li></ol><p>截图就不用贴了吧?</p>
<ol>
<li>
<p>Allegro 菜单点 Tools, Reports </p>
<ul>
<li>从 Available Reports 里找 Placed Component Report, 双击让它跑到下面框里. </li>
<li>选中 Write Report, 点 Report. 此时会在. brd 所在目录下生成一个 pcp_rep.rpt</li>
</ul>
</li>
<li>
<p>Excel, 文件, 打开, 类型选” 所有文件”, 找到刚生成的 pcp_rep.rpt. </p>
<ul>
<li>出现” 文本导入向导”, 直接点下一步. </li>
<li>分隔符号这里把” 逗号” 选上, 然后点下一步. </li>
<li>列数据格式, 选” 文本”, 然后点完成.</li>
</ul>
</li>
<li>
<p>表格出来了, 前四行没用, 删掉. 表头要按 JLC 的格式修改, 具体如下:</p>
<ul>
<li>REFDES, 改成 Designator.</li>
<li>COMP_DEVICE_TYPE, 这列可以删掉.</li>
<li>COMP_VALUE, 改成 Comment.</li>
<li>COMP_TOL, 这列可以删掉.</li>
<li>SYM_NAME, 改成Footprint. 下面的封装如果和JLC的不一样也要改. 比如我用的封装名称都是公制, RESC2012, CAPC1608之类, 要改成相应的英制RESC0805, CAPC0603. 没有前缀也可以, 但是在excel可能就变成805/603了, 不影响下单. SOP类的器件最好改成SOIC-8, SOIC-14这样, 等等, 总之以JLC给的参考文件为准. 选中这一列, 几次查找替换命令就解决了. </li>
<li>SYM_X, SYM_Y, 这两个改成 Mid X 和 Mid Y, 底下的单位需要是毫米, mil 不行.</li>
<li>SYM_ROTATE, 改成 Rotation.</li>
<li>SYM_MIRROR, 改成 Layer. 底下的 YES 全部替换成 B, NO 替换成 T.</li>
</ul>
</li>
<li>
<p>保存成XLS或XLSX格式, 完事! BOM和坐标文件都用这一个就可以了.</p>
</li>
</ol>
<p>请继续往下看----</p>
<p>写了个python脚本, 一键即可完成上述格式转换. 部分内容请自行按需修改. python3的, 如果你用python2的话可能得再改改</p>
<div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">csv</span>
<span class="n">csvfile</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'pcp_rep.rpt'</span><span class="p">)</span>
<span class="n">reader</span> <span class="o">=</span> <span class="n">csv</span><span class="o">.</span><span class="n">reader</span><span class="p">(</span><span class="n">csvfile</span><span class="p">)</span>
<span class="n">csvfile2</span> <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s1">'pcp_rep_jlc.csv'</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">,</span> <span class="n">newline</span><span class="o">=</span><span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span>
<span class="n">writer</span> <span class="o">=</span> <span class="n">csv</span><span class="o">.</span><span class="n">writer</span><span class="p">(</span><span class="n">csvfile2</span><span class="p">,</span> <span class="n">dialect</span><span class="o">=</span><span class="s1">'excel'</span><span class="p">)</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">reader</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">line</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">break</span> <span class="c1"># 跳过前四行</span>
<span class="c1"># 按JLC的格式修改表头</span>
<span class="n">line</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'Designator'</span><span class="p">,</span> <span class="s1">'Comment'</span><span class="p">,</span> <span class="s1">'Footprint'</span><span class="p">,</span> <span class="s1">'Mid X'</span><span class="p">,</span> <span class="s1">'Mid Y'</span><span class="p">,</span> <span class="s1">'Rotation'</span><span class="p">,</span> <span class="s1">'Layer'</span><span class="p">]</span>
<span class="k">print</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
<span class="n">writer</span><span class="o">.</span><span class="n">writerow</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
<span class="c1"># 查找替换表, 请按需自行修改</span>
<span class="n">my_footprints</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'CAPC2012'</span><span class="p">,</span> <span class="s1">'CAPC1608'</span><span class="p">,</span> <span class="s1">'RESC2012'</span><span class="p">,</span> <span class="s1">'RESC1608'</span><span class="p">]</span>
<span class="n">jlc_footprints</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'C0805'</span><span class="p">,</span> <span class="s1">'C0603'</span><span class="p">,</span> <span class="s1">'R0805'</span><span class="p">,</span> <span class="s1">'R0603'</span><span class="p">]</span>
<span class="k">for</span> <span class="n">line</span> <span class="ow">in</span> <span class="n">reader</span><span class="p">:</span>
<span class="k">del</span> <span class="n">line</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">line</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="c1"># 删除不需要的两列</span>
<span class="k">if</span> <span class="n">line</span><span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'NO'</span><span class="p">:</span>
<span class="n">line</span><span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'T'</span>
<span class="k">elif</span> <span class="n">line</span><span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'YES'</span><span class="p">:</span>
<span class="n">line</span><span class="p">[</span><span class="mi">6</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'B'</span>
<span class="k">if</span> <span class="n">line</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="ow">in</span> <span class="n">my_footprints</span><span class="p">:</span>
<span class="n">line</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="n">jlc_footprints</span><span class="p">[</span><span class="n">my_footprints</span><span class="o">.</span><span class="n">index</span><span class="p">(</span><span class="n">line</span><span class="p">[</span><span class="mi">2</span><span class="p">])]</span>
<span class="k">print</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
<span class="n">writer</span><span class="o">.</span><span class="n">writerow</span><span class="p">(</span><span class="n">line</span><span class="p">)</span>
<span class="n">csvfile</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
<span class="n">csvfile2</span><span class="o">.</span><span class="n">close</span><span class="p">()</span>
</pre></div>开源我的fpm skill库2016-11-28T00:00:00+08:002016-11-28T00:00:00+08:00Stavrostag:st.avros.net,2016-11-28:/articles/fpm_skill.html<p>无责任提供, 地址是<a href="https://github.com/tomzbj/fpm_skills">https://github.com/tomzbj/fpm_skills</a>, 请大家随意取用. 不定期更新.</p>
<p>部分由Tariel和Kurapica制作的封装没有放进来, 如果有需要请自行联系他们二位.</p>
<p>ps. 请先下载根目录的fpm.il并替换fpm目录的同名文件. 这个明文fpm.il由minux提供, 我添加了对槽孔的支持, 以及修正了若干bug, 比如双排简牛的缺口方向搞反, 四脚贴片有源晶振的管脚顺序错误之类.</p><p>无责任提供, 地址是<a href="https://github.com/tomzbj/fpm_skills">https://github.com/tomzbj/fpm_skills</a>, 请大家随意取用. 不定期更新.</p>
<p>部分由Tariel和Kurapica制作的封装没有放进来, 如果有需要请自行联系他们二位.</p>
<p>ps. 请先下载根目录的fpm.il并替换fpm目录的同名文件. 这个明文fpm.il由minux提供, 我添加了对槽孔的支持, 以及修正了若干bug, 比如双排简牛的缺口方向搞反, 四脚贴片有源晶振的管脚顺序错误之类.</p>一键切换屏幕分辨率2016-11-17T00:00:00+08:002016-11-17T00:00:00+08:00Stavrostag:st.avros.net,2016-11-17:/articles/change_resolution.html<p>现在大家的桌面都是1920x1080或者2560x1440之类高分辨率了。但是有时候还不得不临时调到较低的分辨率,比如遇到需要像素级精确定位的时候,遇到百度网盘或者微信PC版这样字体又小又不能调大的软件的时候,等等。桌面右键然后改分辨率还是太麻烦了,用完了还得改回来。</p>
<p>有没有办法一键切换分辨率呢?没找到现成的工具,自己写一个。程序如下:</p>
<div class="highlight"><pre><span></span>#include &lt;windows.h&gt;
int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance,
LPSTR lpszArgument, int nFunsterStil)
{
DEVMODE dm;
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &amp;dm);
if(dm.dmPelsHeight == 1080) {
dm.dmPelsHeight = 720;
dm.dmPelsWidth = 1280;
}
else {
dm.dmPelsHeight = 1080;
dm.dmPelsWidth …</pre></div><p>现在大家的桌面都是1920x1080或者2560x1440之类高分辨率了。但是有时候还不得不临时调到较低的分辨率,比如遇到需要像素级精确定位的时候,遇到百度网盘或者微信PC版这样字体又小又不能调大的软件的时候,等等。桌面右键然后改分辨率还是太麻烦了,用完了还得改回来。</p>
<p>有没有办法一键切换分辨率呢?没找到现成的工具,自己写一个。程序如下:</p>
<div class="highlight"><pre><span></span>#include &lt;windows.h&gt;
int WINAPI WinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance,
LPSTR lpszArgument, int nFunsterStil)
{
DEVMODE dm;
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &amp;dm);
if(dm.dmPelsHeight == 1080) {
dm.dmPelsHeight = 720;
dm.dmPelsWidth = 1280;
}
else {
dm.dmPelsHeight = 1080;
dm.dmPelsWidth = 1920;
}
ChangeDisplaySettings(&amp;dm, CDS_RESET);
return 0;
}
</pre></div>
<p>编译成exe,扔到随便什么地方,再拖到任务栏。好了,点一下就可以切到1280x720,再点一下就切回1920x1080了。</p>
<p>在tdm-gcc-32和tdm-gcc-64环境下测试通过。</p>卡片手电 & STLINK转接板 & 迷你电源2016-09-22T00:00:00+08:002016-09-22T00:00:00+08:00Stavrostag:st.avros.net,2016-09-22:/articles/card_light.html<ol>
<li>
<p>卡片手电 <br>
做了个和银行卡一样大的手电. 最厚处厚5.5mm, 因此可以和其他的卡一起塞在钱包里. <br>
本来用AMC7135作为驱动, 结果这东西太娇气, 一不小心就烧坏, 于是干脆直接用电阻限流了, 好象效果也差不多.<br>
效果见图:<br>
<a href="/images2/2016/card_light_1.jpg" title="卡片手电"><img src="/images2/2016/card_light_1.jpg" width="500px"/></a><br>
<a href="/images2/2016/card_light_2.jpg" title="卡片手电"><img src="/images2/2016/card_light_2.jpg" width="500px"/></a> </p>
</li>
<li>
<p>STLINK转接板<br>
JLINK和STLINK提供的都是20pin的标准JTAG口. 但是20pin实在太占地方了, 自己做板一般只用4pin或者5pin的SWD接口, 所以做了这个转接小板, 如图:<br>
<a href="/images2/2016/jtag_swd.jpg" title="STLINK转接板"><img src="/images2/2016/jtag_swd.jpg" width="500px"/></a> </p>
</li>
<li>
<p>simple power<br>
可以方便地从一节18650得到3.3V, 2.8V, 2.4V, 2.0V, 1.8V和1.5V共6种电压. 之前用SEPIC电路做过一个, 发现DC-DC还是干扰太大, 所以这次用了线性稳压, 干扰能小点.<br>
只用一个按键开关, 长按为开/关机, 短按为在不同电压之间切换, 用6个LED来指示各档输出电压.<br>
<a href="/images2/2016/simple_power.jpg" title="simple power"><img src="/images2/2016/simple_power.jpg" width="500px"/></a></p>
</li>
</ol><ol>
<li>
<p>卡片手电 <br>
做了个和银行卡一样大的手电. 最厚处厚5.5mm, 因此可以和其他的卡一起塞在钱包里. <br>
本来用AMC7135作为驱动, 结果这东西太娇气, 一不小心就烧坏, 于是干脆直接用电阻限流了, 好象效果也差不多.<br>
效果见图:<br>
<a href="/images2/2016/card_light_1.jpg" title="卡片手电"><img src="/images2/2016/card_light_1.jpg" width="500px"/></a><br>
<a href="/images2/2016/card_light_2.jpg" title="卡片手电"><img src="/images2/2016/card_light_2.jpg" width="500px"/></a> </p>
</li>
<li>
<p>STLINK转接板<br>
JLINK和STLINK提供的都是20pin的标准JTAG口. 但是20pin实在太占地方了, 自己做板一般只用4pin或者5pin的SWD接口, 所以做了这个转接小板, 如图:<br>
<a href="/images2/2016/jtag_swd.jpg" title="STLINK转接板"><img src="/images2/2016/jtag_swd.jpg" width="500px"/></a> </p>
</li>
<li>
<p>simple power<br>
可以方便地从一节18650得到3.3V, 2.8V, 2.4V, 2.0V, 1.8V和1.5V共6种电压. 之前用SEPIC电路做过一个, 发现DC-DC还是干扰太大, 所以这次用了线性稳压, 干扰能小点.<br>
只用一个按键开关, 长按为开/关机, 短按为在不同电压之间切换, 用6个LED来指示各档输出电压.<br>
<a href="/images2/2016/simple_power.jpg" title="simple power"><img src="/images2/2016/simple_power.jpg" width="500px"/></a></p>
</li>
</ol>拆解旧电子设备若干2016-05-10T00:00:00+08:002016-05-10T00:00:00+08:00Stavrostag:st.avros.net,2016-05-10:/articles/201605_disasm.html<p>最近从家里清理出一大堆旧电子设备, 都没啥用了, 于是挨个拆开研究研究.</p>
<ol>
<li>
<p>三星X859</p>
<p>2004年上市的翻盖机. 入了C网没办法, 可选的机器太少了, 那会儿只能眼馋别人的诺基亚价廉物美. 这机器搞不清楚内置存储多大, MP3也放不了, 短信只能存100条还是200条. 不要说放在现在, 以10年前的眼光来看也基本是个残废. </p>
<p>忘了拍照了, 也没啥好拍的. 除了电池和LCD, 没有别的值得拆卸的元件. LCD还不知道能否驱动起来.</p>
</li>
<li>
<p>诺亚舟NH3280</p>
<p>电子词典, 没啥特别的. 我奇怪的是, 当年文曲星只不过是6502的配置, 速度还可以; 别家的配置应该更好, 但速度反倒都比文曲星慢, 比如这个诺亚舟. 拆开一看, 里面惨不忍睹, 除了两个黑胶封装的IC以外就没啥东西了.</p>
<p><a href="/images2/2016/nh3280.jpg"><img src="/images2/2016/nh3280.jpg" width="500" /></a></p>
<p>左边空了几个器件没焊, 猜测是DC-DC升压模块, 用于1节电池的型号, 手上这个用2节电池所以没有用到.</p>
</li>
<li>
<p>快易典JP209</p>
<p>日汉英电子词典. 拆开一看, 东西还不少.</p>
<p><a href="/images2/2016/jp209.jpg"><img src="/images2/2016/jp209.jpg" width="500" /></a></p>
<p>下方中间的黑胶封装应该是ARM7之类, 旁边是LY62L1024RN, 128k的SRAM. 稍远处的空位应该可以扩展另一片LY62L1024RN, 就升级成256k内存了. 右下的K9F5608U0B是三星的32M FLASH, 在当年的电子词典里算豪华配置了. 右上的黑胶封装估计是语音合成芯片. 左上角的几个元件是DC-DC升压, 所以这货只需要一节7号电池就能工作. 总之 …</p></li></ol><p>最近从家里清理出一大堆旧电子设备, 都没啥用了, 于是挨个拆开研究研究.</p>
<ol>
<li>
<p>三星X859</p>
<p>2004年上市的翻盖机. 入了C网没办法, 可选的机器太少了, 那会儿只能眼馋别人的诺基亚价廉物美. 这机器搞不清楚内置存储多大, MP3也放不了, 短信只能存100条还是200条. 不要说放在现在, 以10年前的眼光来看也基本是个残废. </p>
<p>忘了拍照了, 也没啥好拍的. 除了电池和LCD, 没有别的值得拆卸的元件. LCD还不知道能否驱动起来.</p>
</li>
<li>
<p>诺亚舟NH3280</p>
<p>电子词典, 没啥特别的. 我奇怪的是, 当年文曲星只不过是6502的配置, 速度还可以; 别家的配置应该更好, 但速度反倒都比文曲星慢, 比如这个诺亚舟. 拆开一看, 里面惨不忍睹, 除了两个黑胶封装的IC以外就没啥东西了.</p>
<p><a href="/images2/2016/nh3280.jpg"><img src="/images2/2016/nh3280.jpg" width="500" /></a></p>
<p>左边空了几个器件没焊, 猜测是DC-DC升压模块, 用于1节电池的型号, 手上这个用2节电池所以没有用到.</p>
</li>
<li>
<p>快易典JP209</p>
<p>日汉英电子词典. 拆开一看, 东西还不少.</p>
<p><a href="/images2/2016/jp209.jpg"><img src="/images2/2016/jp209.jpg" width="500" /></a></p>
<p>下方中间的黑胶封装应该是ARM7之类, 旁边是LY62L1024RN, 128k的SRAM. 稍远处的空位应该可以扩展另一片LY62L1024RN, 就升级成256k内存了. 右下的K9F5608U0B是三星的32M FLASH, 在当年的电子词典里算豪华配置了. 右上的黑胶封装估计是语音合成芯片. 左上角的几个元件是DC-DC升压, 所以这货只需要一节7号电池就能工作. 总之, 这东西比上面那个档次高多了, 没想到没用几次就花屏了, 之后就一直扔着没动过.</p>
</li>
<li>
<p>多普达 P800</p>
<p>HTC这个逗b... 最早只在幕后做代工, 搞定制机, 贴运营商LOGO.</p>
<p><a href="/images2/2016/p800.jpg"><img src="/images2/2016/p800.jpg" width="500" /></a></p>
<p>后来搞了个多普达品牌, 折腾几年有了起色, 突然又放弃了, 扛自家HTC品牌上阵. nb了几年, 现在又是半死不活的状态. 这会儿搞起了VR, 不知道还有没有机会翻身. 这个P800还是挺有意思的, 滚轮+轨迹球的操作方式. </p>
<p><a href="/images2/2016/p800-2.jpg"><img src="/images2/2016/p800-2.jpg" width="500" /></a></p>
<p>内置钢防滚架, 够结实, 毕竟是当年的旗舰机型.</p>
</li>
<li>
<p>RD-108充电器</p>
<p>劣质5号/7号充电器.</p>
<p><a href="/images2/2016/rd108.jpg"><img src="/images2/2016/rd108.jpg" width="500" /></a></p>
<p><a href="/images2/2016/rd108-3.jpg"><img src="/images2/2016/rd108-3.jpg" width="500" /></a></p>
<p>里面简单得一塌糊涂, 一个小变压器, 一个拨动开关用于选择充/放电, 俩二极管, 三个LED, 四个电阻, 没了. 感觉极其不靠谱. </p>
</li>
<li>
<p>任e行MX200行车记录仪</p>
<p>除了便宜没啥特别的.</p>
<p><a href="/images2/2016/mx200.jpg"><img src="/images2/2016/mx200.jpg" width="500" /></a></p>
<p><a href="/images2/2016/mx200-3.jpg"><img src="/images2/2016/mx200-3.jpg" width="500" /></a></p>
<p>STK1262B的配置, 一站式配齐, 片内集成了摄像头/SD卡/SDRAM/FLASH/USB/TFT液晶屏的接口, 还有锂电池充放电管理. 一片PMS306416B, 8MB SDRAM. 一片1M容量的FLASH: EN25F80用来存固件. 拆出来TFT: TXDT200LER-31V2一个, 锂电池一块, 也许可以废物利用一下.</p>
</li>
<li>
<p>惟帆通讯KM300A型ADSL猫</p>
<p>多年前某次办宽带送的. 现在都是光纤了, 这东西也就成了废物. </p>
<p><a href="/images2/2016/km300a.jpg"><img src="/images2/2016/km300a.jpg" width="500" /></a></p>
<p><a href="/images2/2016/km300a-2.jpg"><img src="/images2/2016/km300a-2.jpg" width="500" /></a></p>
<p>RTL8671 + RTL8271的配置, 一片8M的SDRAM, M12L64164A, 一片2M的FLASH: EN29LV160A用来存固件. 供电部分用了两片34063, 感觉似乎网络设备特别喜欢用34063?</p>
</li>
</ol>试了一下BH1417用于6米波段发射2016-04-14T00:00:00+08:002016-04-14T00:00:00+08:00Stavrostag:st.avros.net,2016-04-14:/articles/50m_fm_tx_bh1417.html<p>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米业余波段以内.</p>
<p>试着搭了一块板, 果然可以工作, 用VX-7R在7个频点都能准确地收到信号. 但是前级增益低了就几乎没声, 前级增益高了又全是噪声; 如果把VX-7R强行设置成WFM模式, 则一切正常. 估计是BH1417的前端预加重/限幅模块过于强大了.</p>
<p>6米好玩, 等北京的6米解禁了要好好搞搞.</p><p>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米业余波段以内.</p>
<p>试着搭了一块板, 果然可以工作, 用VX-7R在7个频点都能准确地收到信号. 但是前级增益低了就几乎没声, 前级增益高了又全是噪声; 如果把VX-7R强行设置成WFM模式, 则一切正常. 估计是BH1417的前端预加重/限幅模块过于强大了.</p>
<p>6米好玩, 等北京的6米解禁了要好好搞搞.</p>修复宜家LED灯一则2016-03-16T00:00:00+08:002016-03-16T00:00:00+08:00Stavrostag:st.avros.net,2016-03-16:/articles/ikea_led.html<p>宜家买的LED灯不亮了。把线剪断,两边分别一测,发现LED是好的,电源适配器无输出,只得再给它做个驱动。</p>
<p>LED需要恒流驱动,直接接个恒压输出的适配器上去是不行的,要么不亮,要么烧坏。串个电阻行不行呢?行是行,不过电阻会很热。这个LED灯是3W的,工作电流1A,接到5V电源上就需要串联2欧的电阻,电阻的发热量达到2W。这么做显然太不优雅。</p>
<p>幸好手里还有若干LED驱动IC:华润的PT4115,用它可以顺便把调光功能也加上。画了个电路图如下:</p>
<p><a href="/images2/2016/ikea_led.png"><img src="/images2/2016/ikea_led.png" width="500" /></a></p>
<p>其中R1用于设定LED工作电流,公式为$I_{\rm LED} = \frac{0.1}{R_1}$. 电位器R2用于调光,从几百欧到几十kΩ的都可以用,这里用了拨轮式的音量电位器,好处是阻值按指数变化,这样LED亮度也按指数变化,会感觉实际亮度变化比较自然。</p>
<p>LDO XC6206用于给PT4115的调光脚供电,用输出2.5V或3.3V的LDO都行。PT4115允许的输入电压范围是6~30V,但注意XC6206的输入电压最高只能到7V,因此只能用6~7V的电源供电。如果需要用更高输入电压的电源,可以把XC6206换成HT7133、MIC5207之类 …</p><p>宜家买的LED灯不亮了。把线剪断,两边分别一测,发现LED是好的,电源适配器无输出,只得再给它做个驱动。</p>
<p>LED需要恒流驱动,直接接个恒压输出的适配器上去是不行的,要么不亮,要么烧坏。串个电阻行不行呢?行是行,不过电阻会很热。这个LED灯是3W的,工作电流1A,接到5V电源上就需要串联2欧的电阻,电阻的发热量达到2W。这么做显然太不优雅。</p>
<p>幸好手里还有若干LED驱动IC:华润的PT4115,用它可以顺便把调光功能也加上。画了个电路图如下:</p>
<p><a href="/images2/2016/ikea_led.png"><img src="/images2/2016/ikea_led.png" width="500" /></a></p>
<p>其中R1用于设定LED工作电流,公式为$I_{\rm LED} = \frac{0.1}{R_1}$. 电位器R2用于调光,从几百欧到几十kΩ的都可以用,这里用了拨轮式的音量电位器,好处是阻值按指数变化,这样LED亮度也按指数变化,会感觉实际亮度变化比较自然。</p>
<p>LDO XC6206用于给PT4115的调光脚供电,用输出2.5V或3.3V的LDO都行。PT4115允许的输入电压范围是6~30V,但注意XC6206的输入电压最高只能到7V,因此只能用6~7V的电源供电。如果需要用更高输入电压的电源,可以把XC6206换成HT7133、MIC5207之类。</p>
<p>电感L1用几十uH的功率电感就可以,注意饱和电流要大于1A。</p>利用Makefile实现avr-size -C的效果2016-01-03T00:00:00+08:002016-01-03T00:00:00+08:00Stavrostag:st.avros.net,2016-01-03:/articles/makefile_size.html<p>GNU工具链里的size大家应该都用过, 它可以显示elf/obj/exe/dll等可执行文件里各个段的大小, 非常方便. 加-A和-B参数分别是按sysv和berkeley格式显示, 默认带-B参数.</p>
<p>avr-gcc里的avr-size则又增加了一个-C的选项, 可以显示单片机flash和ram的占用比例, 需要同时用--mcu参数指定avr单片机的型号, 效果是这样的:</p>
<div class="highlight"><pre><span></span>avr-size -C --mcu=attiny26 main.elf
AVR Memory Usage
----------------
Device: attiny26
Program: 1316 bytes (64.3% Full)
(.text + .data + .bootloader)
Data: 23 bytes (18.0% Full)
(.data + .bss + .noinit)
</pre></div>
<p>是不是很方便? 可惜arm-gcc里的size并没有这个选项, 于是从avr转到stm32之后, 常常会感觉到不方便.</p>
<p>后来发现, 只要在Makefile里all目标后面加上几行, 也能达到同样目的. 需要你的工具链里有sed和bc, sed用来从size的结果里截取包含数据的第二行 …</p><p>GNU工具链里的size大家应该都用过, 它可以显示elf/obj/exe/dll等可执行文件里各个段的大小, 非常方便. 加-A和-B参数分别是按sysv和berkeley格式显示, 默认带-B参数.</p>
<p>avr-gcc里的avr-size则又增加了一个-C的选项, 可以显示单片机flash和ram的占用比例, 需要同时用--mcu参数指定avr单片机的型号, 效果是这样的:</p>
<div class="highlight"><pre><span></span>avr-size -C --mcu=attiny26 main.elf
AVR Memory Usage
----------------
Device: attiny26
Program: 1316 bytes (64.3% Full)
(.text + .data + .bootloader)
Data: 23 bytes (18.0% Full)
(.data + .bss + .noinit)
</pre></div>
<p>是不是很方便? 可惜arm-gcc里的size并没有这个选项, 于是从avr转到stm32之后, 常常会感觉到不方便.</p>
<p>后来发现, 只要在Makefile里all目标后面加上几行, 也能达到同样目的. 需要你的工具链里有sed和bc, sed用来从size的结果里截取包含数据的第二行, bc则用来作浮点运算.</p>
<div class="highlight"><pre><span></span> @arr=(`$(TRGT)size $(PROJECT)_rom.elf | sed -n '2p'`); \
let flash=($${arr[0]}+$${arr[1]}); \
let mem=($${arr[1]}+$${arr[2]}); \
let flash_size=$(subst K,,$(FLASH_SIZE))*1024; \
let mem_size=$(subst K,,$(MEM_SIZE))*1024; \
flash_usage=`echo "scale=1;($$flash*100/$$flash_size)" | bc`; \
mem_usage=`echo "scale=1;($$mem*100/$$mem_size)" | bc`; \
echo "Flash: $$flash / $$flash_size bytes, $$flash_usage% Full (.text + .data)"; \
echo "SRAM: $$mem / $$mem_size bytes, $$mem_usage% Full (.data + .bss)"
</pre></div>
<p>效果如下:</p>
<div class="highlight"><pre><span></span>arm-none-eabi-size main_rom.elf
text data bss dec hex filename
34928 2212 5316 42456 a5d8 main_rom.elf
Flash: 37140 / 65536 bytes, 56.6% Full (.text + .data)
SRAM: 7528 / 8192 bytes, 91.8% Full (.data + .bss)
</pre></div>74HC4046实验(2)2015-10-09T00:00:00+08:002015-10-09T00:00:00+08:00Stavrostag:st.avros.net,2015-10-09:/articles/hc4046_expr.html<p>在前几天复习HC4046计算的基础上又试了一下, 用atmega48的timer0将16M主时钟先256预分频再125分频, Toggle模式, 得到250Hz 50%占空比的方波作为参考频率; HC4046的VCO输出接到atmega48的T1口, 用timer1作为÷N分频器. </p>
<p>实测各种RC参数, 用HC4046的鉴相器2可以锁定在60kHz~165kHz, 800kHz~2.4MHz, 差不多有三倍的频率覆盖率, 给各种简单接收机做个本振应该是够了. 用鉴相器1只能锁定在120kHz~165kHz, 不过输出波形似乎稍微干净些.</p>
<p>有空再试试用DDS输出作为HC4046的参考频率. 这里DDS的频率不用很高, 在AVR的定时器中断里更新相位累加字就可以了. 这样应该就能做到1Hz级别的精密步进了.</p><p>在前几天复习HC4046计算的基础上又试了一下, 用atmega48的timer0将16M主时钟先256预分频再125分频, Toggle模式, 得到250Hz 50%占空比的方波作为参考频率; HC4046的VCO输出接到atmega48的T1口, 用timer1作为÷N分频器. </p>
<p>实测各种RC参数, 用HC4046的鉴相器2可以锁定在60kHz~165kHz, 800kHz~2.4MHz, 差不多有三倍的频率覆盖率, 给各种简单接收机做个本振应该是够了. 用鉴相器1只能锁定在120kHz~165kHz, 不过输出波形似乎稍微干净些.</p>
<p>有空再试试用DDS输出作为HC4046的参考频率. 这里DDS的频率不用很高, 在AVR的定时器中断里更新相位累加字就可以了. 这样应该就能做到1Hz级别的精密步进了.</p>在STM32F051上重新实现了SD卡WAVE播放器2015-10-09T00:00:00+08:002015-10-09T00:00:00+08:00Stavrostag:st.avros.net,2015-10-09:/articles/stm32_sd_waveplayer.html<p>前几年试过用AVR来播放sd卡上的wave文件. (链接: <a href="http://st.avros.net/articles/avr_sd_waveplayer_2.html">http://st.avros.net/articles/avr_sd_waveplayer_2.html</a>) 这次改用stm32f051试了一遍, 28.224M晶振, 1.5倍频到42.336M, 这样48kHz和44.1kHz都可以按准确的比特率播放了.</p>
<p>DAC用的是PT8211, 软件方式写I2S数据, 结果还是有爆音. 大概I2S对时序要求比较严格, 有空了改成硬件I2S再试试. </p>
<p>顺便在这块板上试验了几块TFT LCD屏. SPI接口的TFT还是太慢, 清屏等操作时能看清刷屏过程. 并口的好用, 就是布线麻烦了点.</p><p>前几年试过用AVR来播放sd卡上的wave文件. (链接: <a href="http://st.avros.net/articles/avr_sd_waveplayer_2.html">http://st.avros.net/articles/avr_sd_waveplayer_2.html</a>) 这次改用stm32f051试了一遍, 28.224M晶振, 1.5倍频到42.336M, 这样48kHz和44.1kHz都可以按准确的比特率播放了.</p>
<p>DAC用的是PT8211, 软件方式写I2S数据, 结果还是有爆音. 大概I2S对时序要求比较严格, 有空了改成硬件I2S再试试. </p>
<p>顺便在这块板上试验了几块TFT LCD屏. SPI接口的TFT还是太慢, 清屏等操作时能看清刷屏过程. 并口的好用, 就是布线麻烦了点.</p>复习74HC4046的相关计算(1)2015-09-22T00:00:00+08:002015-09-22T00:00:00+08:00Stavrostag:st.avros.net,2015-09-22:/articles/hc4046_calc.html<p>前两天没事复习了一下74HC4046的计算. 主要材料: </p>
<ol>
<li>某个在线计算器, 只有VCO的计算. url: <a href="http://www.changpuak.ch/electronics/calc_03.php">http://www.changpuak.ch/electronics/calc_03.php</a></li>
<li>Motorola的AN1410: Configuring and Applying the MC74HC4046A Phase-Locked Loop </li>
<li>Philips的Datasheet </li>
<li>Texas Instruments的Application Report SCHA003B: CMOS Phase-Locked-Loop Applications Using the CD54/74HC/HCT4046A and CD54/74HC/HCT7046A </li>
</ol>
<p>根据Philips的datasheet, 取$R_1$ = 10k, $R_2$ = 10k, $C$ = 500p, $V_\rm{CC}$ = 5.0V …</p><p>前两天没事复习了一下74HC4046的计算. 主要材料: </p>
<ol>
<li>某个在线计算器, 只有VCO的计算. url: <a href="http://www.changpuak.ch/electronics/calc_03.php">http://www.changpuak.ch/electronics/calc_03.php</a></li>
<li>Motorola的AN1410: Configuring and Applying the MC74HC4046A Phase-Locked Loop </li>
<li>Philips的Datasheet </li>
<li>Texas Instruments的Application Report SCHA003B: CMOS Phase-Locked-Loop Applications Using the CD54/74HC/HCT4046A and CD54/74HC/HCT7046A </li>
</ol>
<p>根据Philips的datasheet, 取$R_1$ = 10k, $R_2$ = 10k, $C$ = 500p, $V_\rm{CC}$ = 5.0V, $\rm{VCO_{in}}$分别为0.9V、2.5V、4.1V时Fo为2.0MHz、2.5MHz、3.0MHz, 用在线计算器算得的结果是1.1V时1926kHz, 2.5V时2409kHz, 3.9V时3099kHz, 基本吻合. </p>
<p>根据TI的scha003b, 取$R_1$ = 30k, $R_2$ = 36k, $C$ = 1000p, $V_\rm{CC}$ = 5V, $\rm{VCO_{in}}$分别为1.0V、2.5V、4.4V时Fo计算值为305kHz、391kHz、500kHz, 实测值为318kHz、384kHz、492kHz. 用在线计算器算出的结果是1.1V时287kHz, 2.5V时355kHz, 3.9V时435kHz, 有点误差, 还算可以接受. </p>
<p>根据AN1410, 取$R_1$ = 300k, $R_2$=$\infty$, $C$ = 0.1uF, $\rm{VCO_{in}}$ = 1.0V, $V_\rm{DD}$ = 4.5V, 计算得Fo = 235Hz. 同样的参数用在线计算器算得VCOin = 1.1V时Fo = 64Hz, 差得有点远. </p>
<p>AN1410里的另一个例子, 设计一个从200k到2M的锁相环, 最后给出的结果是$R_1$ = 42k, $R_2$ = $\infty$, $C$ = 175p. $\rm{VCO_{in}}$的范围是从0.25V到2.75V, $K_\rm{VCO}$ = 774.4kHz/V. 用在线计算器算出的结果是1.1V时235kHz, 2.5V时558kHz, $K_\rm{VCO}$ = 249.5kHz/V, 无论如何对不上. </p>
<p>AN1410里再找一个例子, $R_1$ = 9.1k, $R_2$ = $\infty$, $V_\rm{DD}$ = 5.0V, $\rm{VCO_{in}}$在0.25V和2.5V时Fo分别为113.4kHz和1.3MHz, $K_\rm{VCO}$ = 529kHz/V. 用在线计算器算出的结果是2.5V时Fo为423kHz, 3.9V时也只有709kHz, $K_\rm{VCO}$为190kHz/V. 同样有三倍左右的误差. </p>
<p>难道AN1410整个写错了? 不解.</p>最近的三个制作:酒酿机、6F22充电器、太阳能充电器2015-08-15T00:00:00+08:002015-08-15T00:00:00+08:00Stavrostag:st.avros.net,2015-08-15:/articles/fermetnter_6f22_solar.html<ol>
<li>
<p>酒酿机</p>
<p>做酒酿(醪醩)需要保持40度左右的温度发酵。正好家里有个最便宜的小熊酸奶机,不带控温功能的,能否用它来改装成酒酿机呢?</p>
<p>把小熊酸奶机拆开一看,里面简单得一塌糊涂:铝板上装了个PTC电阻,直接接220V电源,作为发热器,旁边甩了两条线出来接前面板的指示灯。可以说毫无技术含量。于是把这些东西都拆掉,换成前几天做的PID控温电路。控温板上加了两个两位LED数码管,分别显示设定温度和实测温度,两个按键开关用来控温。加热器还是IRF530+LM35的配置。控温范围从35度到65度。</p>
<p>发酵碗里装满水,放个温度计,开机一晚上实测……发现碗里的水温最终会比发热板的实测温度低15~20度。大概是因为发热板外面隔了一层塑料板,发酵碗又是一层塑料,两层塑料的热阻太大了。幸好温度已经能满足做酒酿的要求了。</p>
<p>下次打算把LM35的引线接长一些,粘在发热板以外的塑料侧壁上,避免从发热板直接传导热量到LM35,这样效果也许会好些?</p>
</li>
<li>
<p>6F22充电器</p>
<p>手里有两个可充电的6F22,但是一直没有好用的充电器。以前买过一个,拆开一看,里面实在是惨不忍睹,只好扔了。</p>
<p>自己做了一个,电路图如下:</p>
<p><a href="/images2/2015/6f22_charger.png"><img src="/images2/2015/6f22_charger.png" width="480" /></a> </p>
<p>从USB输入的5V电压,用TP7660二倍压得到10V,再通过100欧电阻限流后给6F22充电。TL061接成比较器,一个输入端接电池正极,另一个输入端接100欧电阻和1k电阻分压得到的约9 …</p></li></ol><ol>
<li>
<p>酒酿机</p>
<p>做酒酿(醪醩)需要保持40度左右的温度发酵。正好家里有个最便宜的小熊酸奶机,不带控温功能的,能否用它来改装成酒酿机呢?</p>
<p>把小熊酸奶机拆开一看,里面简单得一塌糊涂:铝板上装了个PTC电阻,直接接220V电源,作为发热器,旁边甩了两条线出来接前面板的指示灯。可以说毫无技术含量。于是把这些东西都拆掉,换成前几天做的PID控温电路。控温板上加了两个两位LED数码管,分别显示设定温度和实测温度,两个按键开关用来控温。加热器还是IRF530+LM35的配置。控温范围从35度到65度。</p>
<p>发酵碗里装满水,放个温度计,开机一晚上实测……发现碗里的水温最终会比发热板的实测温度低15~20度。大概是因为发热板外面隔了一层塑料板,发酵碗又是一层塑料,两层塑料的热阻太大了。幸好温度已经能满足做酒酿的要求了。</p>
<p>下次打算把LM35的引线接长一些,粘在发热板以外的塑料侧壁上,避免从发热板直接传导热量到LM35,这样效果也许会好些?</p>
</li>
<li>
<p>6F22充电器</p>
<p>手里有两个可充电的6F22,但是一直没有好用的充电器。以前买过一个,拆开一看,里面实在是惨不忍睹,只好扔了。</p>
<p>自己做了一个,电路图如下:</p>
<p><a href="/images2/2015/6f22_charger.png"><img src="/images2/2015/6f22_charger.png" width="480" /></a> </p>
<p>从USB输入的5V电压,用TP7660二倍压得到10V,再通过100欧电阻限流后给6F22充电。TL061接成比较器,一个输入端接电池正极,另一个输入端接100欧电阻和1k电阻分压得到的约9.1V电压。输出端接两个LED,分别表示正在充电和已经充满。之所以用TL061,一是因为@Tariel之前送了我不少,二是因为它的输入共模电压最高可以达到电源电压,这是一般运放不具备的。</p>
</li>
<li>
<p>太阳能充电器</p>
<p>以前做的一个小台钟,用锂电池供电,充满一次电能工作半个月左右。但是半个月充一次电还是太麻烦,如果能利用太阳能给它充电,就省事多了。电路图如下:</p>
<p><a href="/images2/2015/solar_charger.png"><img src="/images2/2015/solar_charger.png" width="480" /></a> </p>
<p>就是PT1301的基本升压电路,输出电压为5.24V左右,再经过SS34降压后差不多是5V。等太阳能直射到书房了,看看效果如何。</p>
</li>
</ol>电有没有重量?2015-08-11T00:00:00+08:002015-08-11T00:00:00+08:00Stavrostag:st.avros.net,2015-08-11:/articles/electric_mass.html<p>如果手机没有了电,重量会不会减轻?</p>
<p>答:先说结论,手机没有电了确实会减轻。</p>
<p>但这不是 “电” 的重量,应该说是 “电能” 的重量。能量和重量是统一的。</p>
<p>减轻了多少呢?可以算一下:</p>
<p>假设手机电池标称电压是$3.7\mathrm V$,容量是$1800\mathrm{mAh}$,则它能储存的能量是$3.7\mathrm V\times1800\mathrm{mA}\times3600\mathrm s = 23976\mathrm J$.</p>
<p>根据$E=mc^2$,可得</p>
<p>$$\Delta m=\frac{\Delta E}{c^2} = \frac …</p><p>如果手机没有了电,重量会不会减轻?</p>
<p>答:先说结论,手机没有电了确实会减轻。</p>
<p>但这不是 “电” 的重量,应该说是 “电能” 的重量。能量和重量是统一的。</p>
<p>减轻了多少呢?可以算一下:</p>
<p>假设手机电池标称电压是$3.7\mathrm V$,容量是$1800\mathrm{mAh}$,则它能储存的能量是$3.7\mathrm V\times1800\mathrm{mA}\times3600\mathrm s = 23976\mathrm J$.</p>
<p>根据$E=mc^2$,可得</p>
<p>$$\Delta m=\frac{\Delta E}{c^2} = \frac{23976\rm{J}}{(3\times 10^8m/s)^2}=2.664\times 10^{-13}kg$$</p>
<p>在这里需要说明一下,E=mc^2不仅仅对核反应适用,对一切涉及能量的场合都是同样适用的。只不过非核能的场合,这里的质量变化很微小,不容易测出来。但并不是完全测不出来,事实上早有人做了相关的实验了。</p>
<p><strong>比如:$^{12}\rm C$原子在不同的状态时质量是不同的,而且已经有了精确的测量值。</strong></p>
<p>单位:u (原子质量单位)</p>
<p>孤立原子的静止质量:$12.000000000000$</p>
<p>孤立原子(298K):$12.000000000045$</p>
<p>石墨(298K):$11.999999992116$</p>
<p>金刚石(298K):$11.999999992137$</p>
<p>石墨和金刚石中碳原子质量相差$2.1\times10^{-11} \mathrm{g\cdot mol^{-1}}$。</p>
<p>折算成能量是多少呢?$2.1\times10^{-11} \mathrm{g\cdot mol^{-1}}\times(3\times10^8\mathrm{m\cdot s^{-1}})^2 = 1890\mathrm J$,也就是说每摩尔石墨和金刚石中碳原子质量之差折算成能量是$1890\rm J$。</p>
<p>查兰氏化学手册,石墨的标准生成焓是$0\mathrm{kJ/mol}$,金刚石是 $1.897\mathrm{kJ/mol}$,也就是说每摩尔石墨与金刚石相互转化时,吸收/释放的能量是$1897\rm J$,与上述计算相符。</p>
<p>孤立原子在$0\mathrm K$和$298\mathrm K$时的质量相差$4.5\times10^{-11} \mathrm{g\cdot mol^{-1}}$,折算成能量是$4050\rm J$,也就是说每摩尔碳原子从$0\rm K$升温到$298\mathrm K$,质量增加了$4.5\times10^{-11} \mathrm{g}$,内能增加了$4050\mathrm J$。</p>
<p>用另一种方式计算,孤立原子按理想气体计算,热容是$\frac{3}{2} R = 1.5\times1.38^{-23}\mathrm{J\cdot K^{-1}}\times6.02\times10^{23}\mathrm{mol^{-1}} = 12.46\mathrm{J\cdot mol^{-1}\cdot K^{-1}}$。</p>
<p>$1\mathrm{mol}$ 碳原子从$0\mathrm K$ 升温到$298\mathrm K$,内能变化量是$12.46\mathrm{J\cdot mol^{-1}\cdot K^{-1}}\times298\mathrm K \times 1 \mathrm{mol} = 3713\mathrm J$,与上面的$4050\mathrm J$基本相符。</p>
<p>以上够不够说明问题?</p>学习了一下散热片的简单估算2015-08-09T00:00:00+08:002015-08-09T00:00:00+08:00Stavrostag:st.avros.net,2015-08-09:/articles/heatsink-calc.html<p>常用的板翅式散热器,其有效散热面积为:$$散热面积=(翅片高度\times2\times翅片数量+基板宽度)\times截断长度$$</p>
<p>有效散热面积和热阻的关系:</p>
<table>
<thead>
<tr>
<th>A(cm<sub>2</sub>)</th>
<th>R<sub>sa</sub>(K/W)</th>
</tr>
</thead>
<tbody>
<tr>
<td>500</td>
<td>2.0</td>
</tr>
<tr>
<td>250</td>
<td>2.9</td>
</tr>
<tr>
<td>100</td>
<td>4.0</td>
</tr>
<tr>
<td>50</td>
<td>5.2</td>
</tr>
<tr>
<td>25</td>
<td>6.5</td>
</tr>
</tbody>
</table>
<p>简单拟合得:$$R_\mathrm{sa}=23.3A^{-0.39}$$</p>
<p>总热阻$$R_\mathrm{tot}=R_\mathrm{sa}+R_\mathrm{cs}+R_ …</p><p>常用的板翅式散热器,其有效散热面积为:$$散热面积=(翅片高度\times2\times翅片数量+基板宽度)\times截断长度$$</p>
<p>有效散热面积和热阻的关系:</p>
<table>
<thead>
<tr>
<th>A(cm<sub>2</sub>)</th>
<th>R<sub>sa</sub>(K/W)</th>
</tr>
</thead>
<tbody>
<tr>
<td>500</td>
<td>2.0</td>
</tr>
<tr>
<td>250</td>
<td>2.9</td>
</tr>
<tr>
<td>100</td>
<td>4.0</td>
</tr>
<tr>
<td>50</td>
<td>5.2</td>
</tr>
<tr>
<td>25</td>
<td>6.5</td>
</tr>
</tbody>
</table>
<p>简单拟合得:$$R_\mathrm{sa}=23.3A^{-0.39}$$</p>
<p>总热阻$$R_\mathrm{tot}=R_\mathrm{sa}+R_\mathrm{cs}+R_\mathrm{jc}$$</p>
<p>注:R<sub>sa</sub>为散热片向空气散热的热阻。
R<sub>cs</sub>为器件和散热器的接触热阻,通过导热硅脂接触的取0.1~0.2K/W,加绝缘垫的取1K/W。
R<sub>jc</sub>为器件内部热阻,见器件datasheet。</p>
<p>散热能力$$P=\frac{T_\mathrm j-T_\mathrm a}{R_\mathrm{tot}}$$。T<sub>j</sub>为器件的允许工作结温,T<sub>a</sub>为环境温度。</p>
<p>举例:一个宽50mm,翅片高10mm,8片翅片,截断长度为35mm的散热片,
其有效散热面积为$$(10\mathrm{mm}\times2\times8+50\mathrm{mm})\times35\mathrm{mm}=73.5\mathrm{cm}^2$$</p>
<p>按上面的公式,
$$R_\mathrm{sa}=23.3\times73.5^{-0.39}=4.36\mathrm{K/W}$$</p>
<p>给TOP3封装的BTA41散热,用硅脂接触,取
$$R_\mathrm{cs}=0.2\mathrm{K/W}$$</p>
<p>根据BTA41的datasheet,内部热阻
$$R_\mathrm{jc}=0.9\mathrm{K/W}$$</p>
<p>因此总热阻为5.46K/W。</p>
<p>BTA41的最大允许结温T<sub>j</sub>125°C,环境温度取40°C,则有$$P=\frac{125^\circ \mathrm{C}-40^\circ \mathrm{C}}{5.46\mathrm{K/W}}=15.6\mathrm{W}$$</p>
<p>查BTA41 datasheet里的P-I<sub>RMS</sub>曲线可得此时允许通过的交流电流有效值为16A左右。</p>如何计算钨丝的直径?2015-08-07T00:00:00+08:002015-08-07T00:00:00+08:00Stavrostag:st.avros.net,2015-08-07:/articles/tungsten.html<p>知乎上一哥们提了个问题:3.7V 电压,1.2A 电流,用钨丝绕成螺旋式弹簧丝,工作温度在 1200 摄氏度左右,怎么计算出来需要用多大直径的钨丝?链接:<a href="http://www.zhihu.com/question/33791069/answer/57434994">http://www.zhihu.com/question/33791069/answer/57434994</a></p>
<p>以下是我的回答:</p>
<p>斯特凡-玻尔兹曼定律:$j^<em>=\epsilon\sigma T^4$,其中$j^</em>$为辐射通量,$\sigma$为斯特凡-玻尔兹曼常数,值为$5.67\times 10^{-8}\rm{J \cdot s}^{-1}\cdot\rm m^{-2 …</p><p>知乎上一哥们提了个问题:3.7V 电压,1.2A 电流,用钨丝绕成螺旋式弹簧丝,工作温度在 1200 摄氏度左右,怎么计算出来需要用多大直径的钨丝?链接:<a href="http://www.zhihu.com/question/33791069/answer/57434994">http://www.zhihu.com/question/33791069/answer/57434994</a></p>
<p>以下是我的回答:</p>
<p>斯特凡-玻尔兹曼定律:$j^<em>=\epsilon\sigma T^4$,其中$j^</em>$为辐射通量,$\sigma$为斯特凡-玻尔兹曼常数,值为$5.67\times 10^{-8}\rm{J \cdot s}^{-1}\cdot\rm m^{-2}\cdot\rm K^{-4}$。$\epsilon$为辐射系数,把钨丝当成黑体,则$\epsilon=1$。</p>
<p>忽略传导和对流,只考虑辐射;把钨丝作为黑体,则</p>
<p>钨丝辐射的总功率为$P = A\cdot 5.67^{-8}\cdot1473^4$。</p>
<p>已知总功率$P=3.7\rm{V}\times1.2\rm{A}=4.44\rm W$,</p>
<p>则可得钨丝表面积$A=1.66\times10^{-5} \rm m^2$。</p>
<p><a href="/images2/2015/tungsten_resistance.png"><img src="/images2/2015/tungsten_resistance.png" width="480" /></a></p>
<p>根据这个图,钨在 1200 摄氏度时的电阻率大约是$0.41\Omega\cdot \rm{mm}^2\cdot \rm{m}^{-1}$,电阻我们已经知道是$3.7\rm{V} / 1.2\rm{A} = 3.08\Omega$。</p>
<p>把钨丝当作一个截面半径为$r$,长度为$h$的圆柱体,则它的电阻应该是$\frac{0.41\times10^{-6}h}{\pi r^2}$,</p>
<p>表面积是$2\pi rh$(两个端面可以忽略不计)。</p>
<p>整理得$\frac{h}{r^2}=2.36\times10^7,rh = 2.64\times10^{-6}$。</p>
<p>解得$h=0.055\rm m$, $r=4.82\times10^{-5}\rm m$,也就是说长度 55mm,直径 0.096mm。</p>
<p>验算一下,一根长 55mm、直径 0.096mm 的钨丝,1200 度时的电阻是 3.12 欧,</p>
<p>表面积是 $16.6\rm{mm}^2$,和前面计算相符。</p>
<p>如果是做题,做到这里就可以结束了。但如果是真做一个灯泡出来,则必须考虑灯泡内部充入惰性气体的对流和传导热量、钨丝直接向灯泡引出脚的传热、钨丝具体成分导致的电阻率变化 (可能相当大!) 等等。</p>
<p>最后还得实际做一个来验证,在实测参数的基础上再调整。</p>迷你智能电源2015-07-14T00:00:00+08:002015-07-14T00:00:00+08:00Stavrostag:st.avros.net,2015-07-14:/articles/cute_power_v2.html<p>做了个简单的小电源,用一节18650供电,可以输出1.26V、1.8V、2.5V、2.85V、3.3V、5.0V和6.0V,共7种电压,可以通过USB给18650充电,如图:</p>
<p><a href="/images2/2015/cute_power_v2.jpg" title="实物图"><img src="/images2/2015/cute_power_v2.jpg" width="480px" /></a></p>
<p>原理图:</p>
<p><a href="/images2/2015/cute_power_v2.png" title="原理图"><img src="/images2/2015/cute_power_v2.png" width="480px" /></a></p>
<p>充电使用TP4056,充电电流为1200/1.5k = 800mA。LM3478接成SEPIC电路,既能升压也能降压。单片机ATtiny13输出一路PWM信号,经滤波后控制LM3478的反馈端,从而控制输出电压。三只LED用于指示输出电压。</p>
<p>源程序:</p>
<div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf"><avr/io.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><avr/interrupt.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><util/delay.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><avr/sleep.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">"misc.h …</span></pre></div><p>做了个简单的小电源,用一节18650供电,可以输出1.26V、1.8V、2.5V、2.85V、3.3V、5.0V和6.0V,共7种电压,可以通过USB给18650充电,如图:</p>
<p><a href="/images2/2015/cute_power_v2.jpg" title="实物图"><img src="/images2/2015/cute_power_v2.jpg" width="480px" /></a></p>
<p>原理图:</p>
<p><a href="/images2/2015/cute_power_v2.png" title="原理图"><img src="/images2/2015/cute_power_v2.png" width="480px" /></a></p>
<p>充电使用TP4056,充电电流为1200/1.5k = 800mA。LM3478接成SEPIC电路,既能升压也能降压。单片机ATtiny13输出一路PWM信号,经滤波后控制LM3478的反馈端,从而控制输出电压。三只LED用于指示输出电压。</p>
<p>源程序:</p>
<div class="highlight"><pre><span></span><span class="cp">#include</span> <span class="cpf"><avr/io.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><avr/interrupt.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><util/delay.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf"><avr/sleep.h></span><span class="cp"></span>
<span class="cp">#include</span> <span class="cpf">"misc.h"</span><span class="cp"></span>
<span class="n">vu8</span> <span class="n">g_status</span><span class="p">;</span>
<span class="n">vu32</span> <span class="n">g_key</span><span class="p">;</span>
<span class="c1">// 0, 1.2x, 1.8, 2.5, 2.85, 3.3, 5.0, 6.0</span>
<span class="n">vu8</span> <span class="n">g_pwm</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">200</span><span class="p">,</span> <span class="mi">105</span><span class="p">,</span> <span class="mi">90</span><span class="p">,</span> <span class="mi">77</span><span class="p">,</span> <span class="mi">70</span><span class="p">,</span> <span class="mi">62</span><span class="p">,</span> <span class="mi">29</span><span class="p">,</span> <span class="mi">0</span><span class="p">};</span> <span class="c1">// 8种状态下的PWM值</span>
<span class="kt">void</span> <span class="nf">port_init</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">PORTB</span> <span class="o">=</span> <span class="mh">0x0e</span><span class="p">;</span>
<span class="n">DDRB</span> <span class="o">=</span> <span class="mh">0x1f</span><span class="p">;</span> <span class="c1">// PB0~4作为输出</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">timer0_init</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">TCCR0B</span> <span class="o">=</span> <span class="mh">0x00</span><span class="p">;</span>
<span class="n">TCCR0A</span> <span class="o">=</span> <span class="mh">0x83</span><span class="p">;</span> <span class="c1">// 快速PWM,1分频</span>
<span class="n">TCCR0B</span> <span class="o">=</span> <span class="mh">0x01</span><span class="p">;</span> <span class="c1">// 启动定时器</span>
<span class="n">TIMSK0</span> <span class="o">|=</span> <span class="n">_BV</span><span class="p">(</span><span class="n">TOIE0</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">ISR</span><span class="p">(</span><span class="n">TIM0_OVF_vect</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">// 读键</span>
<span class="n">u8</span> <span class="n">tmp</span><span class="p">;</span>
<span class="n">g_key</span> <span class="o"><<=</span> <span class="mi">1</span><span class="p">;</span>
<span class="n">tmp</span> <span class="o">=</span> <span class="n">PORTB</span> <span class="o">&</span> <span class="n">_BV</span><span class="p">(</span><span class="n">PB3</span><span class="p">);</span>
<span class="n">PORTB</span> <span class="o">|=</span> <span class="n">_BV</span><span class="p">(</span><span class="n">PB3</span><span class="p">);</span>
<span class="n">DDRB</span> <span class="o">&=</span> <span class="o">~</span><span class="n">_BV</span><span class="p">(</span><span class="n">PB3</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span> <span class="o">!</span><span class="p">(</span><span class="n">PINB</span> <span class="o">&</span> <span class="n">_BV</span><span class="p">(</span><span class="n">PB3</span><span class="p">)</span> <span class="p">)</span> <span class="p">)</span>
<span class="n">g_key</span> <span class="o">|=</span> <span class="mi">1</span><span class="p">;</span>
<span class="k">else</span>
<span class="n">g_key</span> <span class="o">&=</span> <span class="o">~</span><span class="mi">1</span><span class="p">;</span>
<span class="n">DDRB</span> <span class="o">|=</span> <span class="n">_BV</span><span class="p">(</span><span class="n">PB3</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span><span class="n">tmp</span><span class="p">)</span> <span class="c1">// 恢复PB3的旧状态</span>
<span class="n">PORTB</span> <span class="o">|=</span> <span class="n">_BV</span><span class="p">(</span><span class="n">PB3</span><span class="p">);</span>
<span class="k">else</span>
<span class="n">PORTB</span> <span class="o">&=</span> <span class="o">~</span><span class="n">_BV</span><span class="p">(</span><span class="n">PB3</span><span class="p">);</span>
<span class="k">if</span><span class="p">(</span> <span class="p">(</span><span class="n">g_key</span> <span class="o">&</span> <span class="mh">0xffffffff</span><span class="p">)</span> <span class="o">==</span> <span class="mh">0xffffff00</span> <span class="p">)</span> <span class="p">{</span> <span class="c1">// 判断按键</span>
<span class="n">g_status</span><span class="o">++</span><span class="p">;</span>
<span class="n">g_status</span> <span class="o">%=</span> <span class="mi">8</span><span class="p">;</span>
<span class="n">OCR0A</span> <span class="o">=</span> <span class="n">g_pwm</span><span class="p">[</span><span class="n">g_status</span><span class="p">];</span>
<span class="k">if</span><span class="p">(</span> <span class="n">g_status</span> <span class="o">==</span> <span class="mi">0</span> <span class="p">)</span> <span class="p">{</span> <span class="c1">// 状态0时调慢主频,省电</span>
<span class="n">CLKPR</span> <span class="o">=</span> <span class="mh">0x80</span><span class="p">;</span>
<span class="n">CLKPR</span> <span class="o">=</span> <span class="mh">0x08</span><span class="p">;</span>
<span class="n">PORTB</span> <span class="o">&=</span> <span class="o">~</span><span class="n">_BV</span><span class="p">(</span><span class="n">PB4</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">else</span> <span class="p">{</span>
<span class="n">CLKPR</span> <span class="o">=</span> <span class="mh">0x80</span><span class="p">;</span>
<span class="n">CLKPR</span> <span class="o">=</span> <span class="mh">0x03</span><span class="p">;</span> <span class="c1">// 正常状态为8分频,9.6M / 8 = 1.2M</span>
<span class="n">PORTB</span> <span class="o">|=</span> <span class="n">_BV</span><span class="p">(</span><span class="n">PB4</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="n">init_devices</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">port_init</span><span class="p">();</span>
<span class="n">timer0_init</span><span class="p">();</span>
<span class="n">set_sleep_mode</span><span class="p">(</span><span class="n">SLEEP_MODE_IDLE</span><span class="p">);</span>
<span class="n">sleep_enable</span><span class="p">();</span>
<span class="n">CLKPR</span> <span class="o">=</span> <span class="mh">0x80</span><span class="p">;</span>
<span class="n">CLKPR</span> <span class="o">=</span> <span class="mh">0x08</span><span class="p">;</span>
<span class="n">ACSR</span> <span class="o">|=</span> <span class="n">_BV</span><span class="p">(</span><span class="n">ACD</span><span class="p">);</span> <span class="c1">// 关闭模拟比较器,也是为了省电 </span>
<span class="n">sei</span><span class="p">();</span>
<span class="n">PORTB</span> <span class="o">&=</span> <span class="o">~</span><span class="n">_BV</span><span class="p">(</span><span class="n">PB4</span><span class="p">);</span> <span class="c1">// 禁用LM3478</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="n">main</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">init_devices</span><span class="p">();</span>
<span class="k">while</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
<span class="n">PORTB</span> <span class="o">=</span> <span class="p">(</span><span class="n">PORTB</span> <span class="o">&</span> <span class="mh">0xf1</span><span class="p">)</span> <span class="o">|</span> <span class="p">((</span><span class="o">~</span><span class="p">(</span><span class="n">g_status</span><span class="o"><<</span><span class="mi">1</span><span class="p">))</span> <span class="o">&</span> <span class="mh">0x0e</span><span class="p">);</span> <span class="c1">// LED输出</span>
<span class="n">sleep_cpu</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</pre></div>PID控温实验2015-07-13T00:00:00+08:002015-07-13T00:00:00+08:00Stavrostag:st.avros.net,2015-07-13:/articles/pid_expr.html<p>做了个PID温控器,原理图如下:</p>
<p><a href="/images2/2015/pid_expr.png"><img src="/images2/2015/pid_expr.png" width="480" /></a> </p>
<p>电源电压首先流经0.33欧的取样电阻R1,然后给加热器供电。加热器用随便一个TO220封装的N沟道MOS管就行,LM35用来测温。高端电流检测虽然麻烦些,但这样加热器的连线可以更简单,四条线就够了。</p>
<p>LM35输出的电压值经Mega48 AD转换后得到温度值。Mega48输出一路PWM经低通滤波后与取样电阻R1上的电压比较后控制MOS管的电流。之后用简单的PID算法即可实现控温了。</p>
<p>把MOS管和LM35用导热胶粘在一块95mm x 66mm的散热片上,实测用12V 2A的电源供电时,开环加热可以达到44度左右。启用PID控温后,可以在室温~44度之间把温度控制到设定值正负0.1度。</p>
<p>之后在这个基础上可以做很多东西了,比如酸奶机、酒酿机、煮温泉蛋机等等。</p><p>做了个PID温控器,原理图如下:</p>
<p><a href="/images2/2015/pid_expr.png"><img src="/images2/2015/pid_expr.png" width="480" /></a> </p>
<p>电源电压首先流经0.33欧的取样电阻R1,然后给加热器供电。加热器用随便一个TO220封装的N沟道MOS管就行,LM35用来测温。高端电流检测虽然麻烦些,但这样加热器的连线可以更简单,四条线就够了。</p>
<p>LM35输出的电压值经Mega48 AD转换后得到温度值。Mega48输出一路PWM经低通滤波后与取样电阻R1上的电压比较后控制MOS管的电流。之后用简单的PID算法即可实现控温了。</p>
<p>把MOS管和LM35用导热胶粘在一块95mm x 66mm的散热片上,实测用12V 2A的电源供电时,开环加热可以达到44度左右。启用PID控温后,可以在室温~44度之间把温度控制到设定值正负0.1度。</p>
<p>之后在这个基础上可以做很多东西了,比如酸奶机、酒酿机、煮温泉蛋机等等。</p>最近的三个制作2015-05-21T00:00:00+08:002015-05-21T00:00:00+08:00Stavrostag:st.avros.net,2015-05-21:/articles/6f22_fm_rf.html<ol>
<li>
<p>彻底榨干6F22的剩余电量</p>
<p>从万用表里拆下来的6F22常常还有许多电量没有用掉, 直接扔掉比较可惜. 把它DC-DC降压后给单片机之类供电, 还能再撑一段时间. </p>
<p>电路如图, 就是AOZ1016的标准电路. 在它的EN脚对地接一个22uF的电解电容, 再对电源和对地各接一个轻触开关, 便实现了软开关. EN脚的输入电流极小, 靠22u电解就能维持工作几十分钟. EN脚拉低时, AOZ1016消耗电流仅1μA左右, 完全可以忽略不计了. DC-DC降压到3.68V左右, 再由XC6206稳压到3.3V.</p>
<p><a href="/images2/2015/6f22.png"><img src="/images2/2015/6f22.png" width="480" /></a> </p>
</li>
<li>
<p>继续试验简易FM无线话筒</p>
<p>话筒信号放大后直接推动与晶振串联的变容二极管, MMBT2222或S9018接成电容三点式振荡器, 谐振在晶振的三倍频上. 可惜这种方式能得到的频偏还是太小, 用收音机只能收到很微弱的信号. 下次试试锁相环调频吧.</p>
<p><a href="/images2/2015/fm_caller_simple.png"><img src="/images2/2015/fm_caller_simple.png" width="480" /></a> </p>
</li>
<li>
<p>RF功率计</p>
<p>几年前Tariel/BH1PHL送了我一个50欧 100W的RF电阻, 一直没用上.</p>
<p>这次用它做了个假负载+功率计, 从RF电阻上取电压, 检波、滤波后分压, 用mega48的adc采样, 显示在0801液晶屏上. </p>
<p><a href="/images2/2015/rf_power_meter.png"><img src="/images2/2015/rf_power_meter.png" width="480" /></a> </p>
<p>一开始检波二极管用的是2SC1622的BC结, 结果实测在50M时功率严重偏小, 144M和430M就一点功率也测不到了. 换成1N60之后一切正常. 估计是因为2SC1622的结电容太大?</p>
<p>但是1N60耐压太低, 只有50V, 这样只能测到峰值25V的RF电压, 换算成功率只有6.25W了. 下次还是得用先衰减再测的方案.</p>
</li>
</ol><ol>
<li>
<p>彻底榨干6F22的剩余电量</p>
<p>从万用表里拆下来的6F22常常还有许多电量没有用掉, 直接扔掉比较可惜. 把它DC-DC降压后给单片机之类供电, 还能再撑一段时间. </p>
<p>电路如图, 就是AOZ1016的标准电路. 在它的EN脚对地接一个22uF的电解电容, 再对电源和对地各接一个轻触开关, 便实现了软开关. EN脚的输入电流极小, 靠22u电解就能维持工作几十分钟. EN脚拉低时, AOZ1016消耗电流仅1μA左右, 完全可以忽略不计了. DC-DC降压到3.68V左右, 再由XC6206稳压到3.3V.</p>
<p><a href="/images2/2015/6f22.png"><img src="/images2/2015/6f22.png" width="480" /></a> </p>
</li>
<li>
<p>继续试验简易FM无线话筒</p>
<p>话筒信号放大后直接推动与晶振串联的变容二极管, MMBT2222或S9018接成电容三点式振荡器, 谐振在晶振的三倍频上. 可惜这种方式能得到的频偏还是太小, 用收音机只能收到很微弱的信号. 下次试试锁相环调频吧.</p>
<p><a href="/images2/2015/fm_caller_simple.png"><img src="/images2/2015/fm_caller_simple.png" width="480" /></a> </p>
</li>
<li>
<p>RF功率计</p>
<p>几年前Tariel/BH1PHL送了我一个50欧 100W的RF电阻, 一直没用上.</p>
<p>这次用它做了个假负载+功率计, 从RF电阻上取电压, 检波、滤波后分压, 用mega48的adc采样, 显示在0801液晶屏上. </p>
<p><a href="/images2/2015/rf_power_meter.png"><img src="/images2/2015/rf_power_meter.png" width="480" /></a> </p>
<p>一开始检波二极管用的是2SC1622的BC结, 结果实测在50M时功率严重偏小, 144M和430M就一点功率也测不到了. 换成1N60之后一切正常. 估计是因为2SC1622的结电容太大?</p>
<p>但是1N60耐压太低, 只有50V, 这样只能测到峰值25V的RF电压, 换算成功率只有6.25W了. 下次还是得用先衰减再测的方案.</p>
</li>
</ol>辉光数码管实验2015-05-13T00:00:00+08:002015-05-13T00:00:00+08:00Stavrostag:st.avros.net,2015-05-13:/articles/nixie.html<p>多年前sunzx送了我几个SZ-8数码管, 一直没顾上试验. 前几天终于给它搭了驱动电路, 如图:</p>
<p><a href="/images/nixie_1.png" title="驱动模块原理图"><img src="/images/nixie_1.png" width="480px"/></a></p>
<p>由74HC164将串行输入信号转为8位并行, 其中4位作为BCD码, 由74LS42转为数码管的驱动信号. 由于74LS42的输出是负逻辑, 因此驱动2N5551时需要用发射极驱动. HC164的另外三位用于驱动藏在SZ-8肚子下面的RGB三色LED. 几个模块之间可以级联, 这样用起来就简单多了.</p>
<p>供电部分如图:</p>
<p><a href="/images/nixie_2.png" title="供电部分原理图"><img src="/images/nixie_2.png" width="480px"/></a></p>
<p>采用boost升压电路. NE555接成多谐振荡器, 占空比约为90%, 直接驱动IRF640S的栅极. 2SC1815在这里起比较器的作用, 对输出电压取样后反馈到NE555的调制端5脚. IRF640S一般需要10V栅极驱动电平, 但实际测试输入电压5~12V均能正常工作, 升压效率约50%.</p>
<p>点亮四个数码管的效果:</p>
<p><a href="/images/nixie.jpg" title="效果图"><img src="/images/nixie.jpg" width="480px"/></a></p>
<p>视频, 其中两只有点接触不良, 以后有空再改吧.</p>
<video src="/videos/nixie.mp4" width="480" controls="controls" />(/videos/nixie.mp4)<p>多年前sunzx送了我几个SZ-8数码管, 一直没顾上试验. 前几天终于给它搭了驱动电路, 如图:</p>
<p><a href="/images/nixie_1.png" title="驱动模块原理图"><img src="/images/nixie_1.png" width="480px"/></a></p>
<p>由74HC164将串行输入信号转为8位并行, 其中4位作为BCD码, 由74LS42转为数码管的驱动信号. 由于74LS42的输出是负逻辑, 因此驱动2N5551时需要用发射极驱动. HC164的另外三位用于驱动藏在SZ-8肚子下面的RGB三色LED. 几个模块之间可以级联, 这样用起来就简单多了.</p>
<p>供电部分如图:</p>
<p><a href="/images/nixie_2.png" title="供电部分原理图"><img src="/images/nixie_2.png" width="480px"/></a></p>
<p>采用boost升压电路. NE555接成多谐振荡器, 占空比约为90%, 直接驱动IRF640S的栅极. 2SC1815在这里起比较器的作用, 对输出电压取样后反馈到NE555的调制端5脚. IRF640S一般需要10V栅极驱动电平, 但实际测试输入电压5~12V均能正常工作, 升压效率约50%.</p>
<p>点亮四个数码管的效果:</p>
<p><a href="/images/nixie.jpg" title="效果图"><img src="/images/nixie.jpg" width="480px"/></a></p>
<p>视频, 其中两只有点接触不良, 以后有空再改吧.</p>
<video src="/videos/nixie.mp4" width="480" controls="controls" />(/videos/nixie.mp4)小台钟2015-05-02T00:00:00+08:002015-05-02T00:00:00+08:00Stavrostag:st.avros.net,2015-05-02:/articles/tiny24_clock.html<p>用手里闲置的Attiny24+LCD0801屏做了个小钟, 如图:</p>
<p><a href="/images/tiny24_clock.jpg" title="照片"><img src="/images/tiny24_clock.jpg" width="500px" /></a></p>
<p>用一节600还是800mAh的手机电池供电, 充满电可以工作半个月.</p>
<p>原理图:</p>
<p><a href="/images/tiny24_clock_2.png" title="原理图"><img src="/images/tiny24_clock_2.png" width="500px" /></a></p>
<p>其中LCD用的是0801, 和1602接口完全一样, 加了一块之前做的<a href="articles/firefly&serlcd1602.html">串口转换小板</a>. 由于是3.3V供电, LCD的V0脚需要接入负压, 这里负压用MCU的一路PWM经负倍压整流产生. 晶振用什么频率其实都无关紧要, 只要是个整数, 并且按一定的分频规则能凑出2Hz的频率就行了.</p>
<p>源程序:</p>
<p><a href="/files/tiny24_clock_src.7z">tiny24_clock_src.7z</a> </p>
<p>改天再给它加个太阳能电池, 这样也许就再也不用充电了.</p><p>用手里闲置的Attiny24+LCD0801屏做了个小钟, 如图:</p>
<p><a href="/images/tiny24_clock.jpg" title="照片"><img src="/images/tiny24_clock.jpg" width="500px" /></a></p>
<p>用一节600还是800mAh的手机电池供电, 充满电可以工作半个月.</p>
<p>原理图:</p>
<p><a href="/images/tiny24_clock_2.png" title="原理图"><img src="/images/tiny24_clock_2.png" width="500px" /></a></p>
<p>其中LCD用的是0801, 和1602接口完全一样, 加了一块之前做的<a href="articles/firefly&serlcd1602.html">串口转换小板</a>. 由于是3.3V供电, LCD的V0脚需要接入负压, 这里负压用MCU的一路PWM经负倍压整流产生. 晶振用什么频率其实都无关紧要, 只要是个整数, 并且按一定的分频规则能凑出2Hz的频率就行了.</p>
<p>源程序:</p>
<p><a href="/files/tiny24_clock_src.7z">tiny24_clock_src.7z</a> </p>
<p>改天再给它加个太阳能电池, 这样也许就再也不用充电了.</p>在stm32上使用二进制字库的简单方法2015-03-13T00:00:00+08:002015-03-13T00:00:00+08:00Stavrostag:st.avros.net,2015-03-13:/articles/stm32_fonts.html<p>标题其实可以写成"在可执行程序里嵌入二进制资源的方法", 不过这个题目大了点, 还是原样吧.</p>
<p>以前如果我们用到不带字库的点阵LCD, 一般都是把字库按16进制写成一个大数组, 再和其他源程序一起编译. 有没有方便一点的办法呢?这里给出两个方案.</p>
<ol>
<li>
<p>使用objcopy把字库转成目标文件(.o/.obj)</p>
<p>假设我们需要嵌入的是5x7的ascii点阵字库, 文件名是asc5x7.bin.</p>
<p>在arm-gcc环境下, 命令如下:</p>
<div class="highlight"><pre><span></span>arm-none-eabi-objcopy -B arm -I binary -O elf32-littlearm --rename-section .data=.rodata asc5x7.bin asc5x7.o
</pre></div>
<p>需要注意的是, objcopy生成的.o文件默认是把数据放在.data段的. 因此这里需要加个--rename-section的选项, 把.data改成.text或者.rodata, 不然单片机可怜的一点点RAM根本不够用. 如果是在PC上运行, 这里改不改就无所谓了, 不过内存还是能省点就省点的好.</p>
<p>在.o里会生成三个符号: <code>_binary_asc5x7_bin_start, _binary_asc5x7_bin_end, binary_asc5x7_bin_size.</code></p>
<p>在程序里这么调用 …</p></li></ol><p>标题其实可以写成"在可执行程序里嵌入二进制资源的方法", 不过这个题目大了点, 还是原样吧.</p>
<p>以前如果我们用到不带字库的点阵LCD, 一般都是把字库按16进制写成一个大数组, 再和其他源程序一起编译. 有没有方便一点的办法呢?这里给出两个方案.</p>
<ol>
<li>
<p>使用objcopy把字库转成目标文件(.o/.obj)</p>
<p>假设我们需要嵌入的是5x7的ascii点阵字库, 文件名是asc5x7.bin.</p>
<p>在arm-gcc环境下, 命令如下:</p>
<div class="highlight"><pre><span></span>arm-none-eabi-objcopy -B arm -I binary -O elf32-littlearm --rename-section .data=.rodata asc5x7.bin asc5x7.o
</pre></div>
<p>需要注意的是, objcopy生成的.o文件默认是把数据放在.data段的. 因此这里需要加个--rename-section的选项, 把.data改成.text或者.rodata, 不然单片机可怜的一点点RAM根本不够用. 如果是在PC上运行, 这里改不改就无所谓了, 不过内存还是能省点就省点的好.</p>
<p>在.o里会生成三个符号: <code>_binary_asc5x7_bin_start, _binary_asc5x7_bin_end, binary_asc5x7_bin_size.</code></p>
<p>在程序里这么调用:</p>
<div class="highlight"><pre><span></span>extern const int _binary_asc5x7_bin_start;
uint8_t *start = (uint8_t *) (&amp;_binary_asc5x7_bin_start);
</pre></div>
<p>这样我们就得到了字库的起始地址. 在AVR上可能会稍复杂一些, 因为数据存储在FLASH里, 所以需要象PROGMEM数组一样, 用pgm_read_byte之类函数来读取.</p>
<p>链接时会有一堆错误提示: "Conflicting CPU architectures ....", 这是因为.o里还缺少一个叫.ARM.attributes的段. 不过实际上也没啥影响, 程序是可以正确运行的.</p>
</li>
<li>
<p>直接利用GNU汇编的.incbin功能</p>
<p>这是minux@bdwm提供的方法, 解决得明显更漂亮一些.</p>
<p>首先建立一个asc5x7.s的源文件,内容如下:</p>
<div class="highlight"><pre><span></span><span class="na">.section</span> <span class="no">.rodata</span><span class="p">,</span><span class="s">""</span><span class="p">,</span><span class="err">%</span><span class="no">progbits</span>
<span class="na">.global</span> <span class="no">_binary_asc5x7_bin_start</span><span class="p">,</span> <span class="no">_binary_asc5x7_bin_end</span><span class="p">,</span> <span class="no">_binary_asc5x7_bin_size</span>
<span class="nl">_binary_asc5x7_bin_start:</span>
<span class="na">.incbin</span> <span class="s">"asc5x7.bin"</span>
<span class="nl">_binary_asc5x7_bin_end:</span>
<span class="nf">_binary_asc5x7_bin_size</span> <span class="err">=</span> <span class="no">_binary_asc5x7_bin_end</span> <span class="p">-</span> <span class="no">_binary_asc5x7_bin_start</span>
</pre></div>
<p>其实_binary_asc5x7_bin_size和_binary_asc5x7_bin_end这两个符号不要也可以, 因为字库的存储格式我们事先已经知道了.</p>
<p>然后建立一个空的.c文件: <code>touch empty.c, arm-none-eabi-gcc -S empty.c</code>, 这样我们得到了一个empty.s, 内容如下:</p>
<div class="highlight"><pre><span></span> .cpu arm7tdmi-s
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 1
.eabi_attribute 30, 6
.eabi_attribute 18, 4
.file "empty.c"
.ident "GCC: (Sourcery G++ Lite 2011.03-42) 4.5.2"
</pre></div>
<p>把这些东西复制到之前那个asc5x7.s里, 部分内容可能要按需调整一下, 比如.cpu这里应该改成cortex-m0或者cortex-m3之类. 这样在链接时就不会出现前面那个"Conflicting CPU architectures ...."的报错信息了.</p>
<p>如果要使用几个字库呢? 可以把它们全都放在一个段里, 但是如果只用到了某一个或几个字库, 也会把它们全都链接进去, 导致最终的可执行文件体积过大. 因此最好是拆成几个段. 假设我们用到了asc5x7.bin, asc12.bin, asc16.bin和asc24.bin, 写出来应该是这样:</p>
<div class="highlight"><pre><span></span><span class="na">.section</span> <span class="no">.rodata.asc5x7</span><span class="p">,</span><span class="s">""</span><span class="p">,</span><span class="err">%</span><span class="no">progbits</span>
<span class="na">.global</span> <span class="no">_binary_asc5x7_bin_start</span>
<span class="nl">_binary_asc5x7_bin_start:</span>
<span class="na">.incbin</span> <span class="s">"asc5x7.bin"</span>
<span class="na">.section</span> <span class="no">.rodata.asc12</span><span class="p">,</span><span class="s">""</span><span class="p">,</span><span class="err">%</span><span class="no">progbits</span>
<span class="na">.global</span> <span class="no">_binary_asc12_bin_start</span>
<span class="nl">_binary_asc12_bin_start:</span>
<span class="na">.incbin</span> <span class="s">"asc12.bin"</span>
<span class="na">.section</span> <span class="no">.rodata.asc16</span><span class="p">,</span><span class="s">""</span><span class="p">,</span><span class="err">%</span><span class="no">progbits</span>
<span class="na">.global</span> <span class="no">_binary_asc16_bin_start</span>
<span class="nl">_binary_asc16_bin_start:</span>
<span class="na">.incbin</span> <span class="s">"asc16.bin"</span>
<span class="na">.section</span> <span class="no">.rodata.asc24</span><span class="p">,</span><span class="s">""</span><span class="p">,</span><span class="err">%</span><span class="no">progbits</span>
<span class="na">.global</span> <span class="no">_binary_asc24_bin_start</span>
<span class="nl">_binary_asc24_bin_start:</span>
<span class="na">.incbin</span> <span class="s">"asc24.bin"</span>
</pre></div>
<p>然后Makefile里需要增加几个参数, 假如之前没有的话.</p>
<div class="highlight"><pre><span></span>CFLAGS += -ffunction-sections --data-sections,
LDFLAGS += -Wl,--gc-sections
</pre></div>
<p>这样就只会把实际用到的段链接到最终可执行文件了.</p>
<p>如果要在可执行文件里嵌入图片, 音频之类, 也可以用同样的方法.</p>
<p>以上程序均在Windows 7 & Sourcery G++ & STM32F103/F030环境下测试通过. 在Keil/IAR等环境下请自行类推.</p>
<p>补充:注意asc5x7.bin的字节数是奇数, 这样会使得后面几个字库的起始地址都是奇数, stm32进行某些操作时会进入HardFault. 解决办法是在每个.section之前的位置加个.align(3).</p>
</li>
</ol>带负载指示的USB一拖三充电器2015-01-17T00:00:00+08:002015-01-17T00:00:00+08:00Stavrostag:st.avros.net,2015-01-17:/articles/usb_3x_charger.html<p>现在平板/手机之类一般都用USB充电了. 晚上睡觉前, 经常得两三个设备一起充电, 插座都不够用了. 如果能在一个充电器上做出几个USB口同时给它们充电, 岂不是很方便?</p>
<p>不过这么一来, 供电就比较成问题了. 现在的设备一般都需要1A以上的充电电流, 有的需要2A. 3个2A一起充就得6A, 4个就得8A. 前面如果用12V降压到5V, 80%效率的话, 5V 6A需要提供12V 3.2A, 5V 8A需要提供12V 4.2A. 能提供这么大电流的12V适配器倒是有, 但是不太便携了. 所以还是折衷一下, 输出4A电流, 这样前面用12V 2A的适配器, 勉强够用. 这样就不能同时充3个2A的设备了, 免得一不小心就冒烟. 安全起见, 最好是再加个负载指示, 随时知道输出多大电流.</p>
<p>电路如图, 从12V降压到5V, 用了AOSMD的AOZ1014. 这颗SOIC8的小芯片能提供最大5A的输出电流, 不过感觉不怎么踏实, 4A保险些. 输出电压用8.2k和1.5k电阻设定为0.8V * (8.2+1.5 …</p><p>现在平板/手机之类一般都用USB充电了. 晚上睡觉前, 经常得两三个设备一起充电, 插座都不够用了. 如果能在一个充电器上做出几个USB口同时给它们充电, 岂不是很方便?</p>
<p>不过这么一来, 供电就比较成问题了. 现在的设备一般都需要1A以上的充电电流, 有的需要2A. 3个2A一起充就得6A, 4个就得8A. 前面如果用12V降压到5V, 80%效率的话, 5V 6A需要提供12V 3.2A, 5V 8A需要提供12V 4.2A. 能提供这么大电流的12V适配器倒是有, 但是不太便携了. 所以还是折衷一下, 输出4A电流, 这样前面用12V 2A的适配器, 勉强够用. 这样就不能同时充3个2A的设备了, 免得一不小心就冒烟. 安全起见, 最好是再加个负载指示, 随时知道输出多大电流.</p>
<p>电路如图, 从12V降压到5V, 用了AOSMD的AOZ1014. 这颗SOIC8的小芯片能提供最大5A的输出电流, 不过感觉不怎么踏实, 4A保险些. 输出电压用8.2k和1.5k电阻设定为0.8V * (8.2+1.5)/1.5 = 5.17V, 比标准的5V高出3.5%, 还算安全. 在输出端和USB充电口之间再串联0.025欧的电阻用作电流取样. 当输出1A时, 这个电阻上的压降为25mV, 4A时为100mV.</p>
<p>用LM358的其中一个运放接成差分放大器, 把取样电阻上的电压放大20倍左右. 另一只运放提供约0.73V的参考电压, 因为LM358按单电源方式工作时, 最低输出电压不能到0V, 至少要0.6V左右, 所以这里把它的输出电压"抬"高一些.</p>
<p><a href="/images/usb_3x_charger.png" title="电路图"><img src="/images/usb_3x_charger.png" width="500px" /></a></p>
<p>单片机供电用了XC6206, 结果一通电, 马上冒烟了... 原来XC6206的供电电压最高只能是5V. 没办法, 先凑和一下, 把单片机的VCC改接到输出的5V上. 下次这里还是得换成AMS1117之类.</p>
<p>单片机用的是ATMEGA48. 用ADC6来读取LM358的输出电压. 负载指示用的是10位LED光条, 用MEGA48的PD0~PD7再加上PB0, PB1, 够了. 每格表示约0.4A电流, 10格一共4A. 程序很简单, 主要部分:</p>
<div class="highlight"><pre><span></span>while(1) {
u16 data, p;
float volt, curr;
u8 i;
data = get_adc();
volt = data/256.0*5.0;
curr = volt*2.01-1.63;
i = curr / 0.4;
if(i&gt;10)
i=10;
p = 0x3ff &gt;&gt; (10-i);
PORTD = p &amp; 0xff;
PORTB = p &gt;&gt; 8;
_delay_ms(500);
}
</pre></div>
<p>来两张效果图:</p>
<p>输出电流约1.6A时, 亮4格:</p>
<p><a href="/images/dc_tube_power_4.jpg" title="4格, 负载电流约1.6A"><img src="/images/dc_tube_power_4.jpg" width="500px" /></a></p>
<p>输出电流约2.8A时, 亮7格:</p>
<p><a href="/images/dc_tube_power_7.jpg" title="7格, 负载电流约2.8A"><img src="/images/dc_tube_power_7.jpg" width="500px" /></a></p>直流电子管电源2015-01-16T00:00:00+08:002015-01-16T00:00:00+08:00Stavrostag:st.avros.net,2015-01-16:/articles/dc_tube_power.html<p>玩直流管, 供电是个大麻烦. 甲电还好办, 一节电池搞定; 乙电一般需要60~90V, 要么从市电变压整流再滤波, 要么就DC-DC升压; boost升压还不行, 得和甲电隔离才行, 不然玩2P2之类需要栅偏压的管子就麻烦了, 因此只能用flyback或者推挽的方式.</p>
<p>电路如图, CD4047接成多谐振荡器, 由两只74AHC1G00推动AO4800, AO4800的两只NMOS以推挽方式工作.</p>
<p><a href="/images/dc_tube_power.png" title="电路图"><img src="/images/dc_tube_power.png" width="500px" /></a></p>
<p>变压器的参数是... 忘了, 只好用LC表测量各绕组电感量, 初级分别是659uH和666uH, 次级则是188mH+188mH. 由此可算出匝数比是1:17. 按这个匝数比, 两个次级绕组串联, 锂电池电压从4.2V降落到3.5V时, 理论输出电压应该是118V~142V. 这个变压器不大, 线径很细, 内阻不小, 因此输出电压不会这么高, 给直流电子管供电还算合适.</p>
<p>AMS1117-ADJ提供甲电. 1117要求5~10mA的最小负载电流, 否则空载输出电压会偏高. 这里应该给它加个几百欧的电阻作为负载. 不是大问题, 算了吧.</p>
<p>用ATTiny13的ADC实现了简单的电池电量检测, 由红绿双色LED显示. 电池电压在4.0V以上时, LED显示绿色; 3.7V …</p><p>玩直流管, 供电是个大麻烦. 甲电还好办, 一节电池搞定; 乙电一般需要60~90V, 要么从市电变压整流再滤波, 要么就DC-DC升压; boost升压还不行, 得和甲电隔离才行, 不然玩2P2之类需要栅偏压的管子就麻烦了, 因此只能用flyback或者推挽的方式.</p>
<p>电路如图, CD4047接成多谐振荡器, 由两只74AHC1G00推动AO4800, AO4800的两只NMOS以推挽方式工作.</p>
<p><a href="/images/dc_tube_power.png" title="电路图"><img src="/images/dc_tube_power.png" width="500px" /></a></p>
<p>变压器的参数是... 忘了, 只好用LC表测量各绕组电感量, 初级分别是659uH和666uH, 次级则是188mH+188mH. 由此可算出匝数比是1:17. 按这个匝数比, 两个次级绕组串联, 锂电池电压从4.2V降落到3.5V时, 理论输出电压应该是118V~142V. 这个变压器不大, 线径很细, 内阻不小, 因此输出电压不会这么高, 给直流电子管供电还算合适.</p>
<p>AMS1117-ADJ提供甲电. 1117要求5~10mA的最小负载电流, 否则空载输出电压会偏高. 这里应该给它加个几百欧的电阻作为负载. 不是大问题, 算了吧.</p>
<p>用ATTiny13的ADC实现了简单的电池电量检测, 由红绿双色LED显示. 电池电压在4.0V以上时, LED显示绿色; 3.7V~4.0V, 橙色; 3.5~3.7V, 红色; 3.5V以下, 红色闪烁. 程序很简单就不贴了. </p>
<p>分别用220V 3W节能灯泡和5W白炽灯泡测试的结果, 前者作为负载时, 输入5V 0.5A, 输出达到71V 27mA, 效率有77%; 后者当输入电压从4.2V降到3.3V时, 输出电压/电流从45.8V/52mA变化到34.0V/47mA, 效率约为56%. 考虑到一般直流电子管的屏流都在5mA以下, 几个电子管的组合估计也不会超过20mA, 这个结果还算满意.</p>3.579MHz CW发射机2015-01-15T00:00:00+08:002015-01-15T00:00:00+08:00Stavrostag:st.avros.net,2015-01-15:/articles/cw3579.html<p>电路如图, 用74HC240的一个门振荡, 另外7个门并联推动IRF510.
用RS-232串口的RTS信号控制IRF510的供电, 作为电键.
DTR信号控制整机供电和天线切换, 作为PTT.</p>
<p><a href="/images/cw3579.png" title="电路图"><img src="/images/cw3579.png" width="500px" /></a></p>
<p>实测发现一个大问题: CP2102转出来的RS-232的DTR和RTS极性是反的! 再一查, PL2303和FT232也是这样. 现在的PC基本已经不提供RS-232了, 没办法, 装个串口挡板, 用真实的串口再试试吧.</p><p>电路如图, 用74HC240的一个门振荡, 另外7个门并联推动IRF510.
用RS-232串口的RTS信号控制IRF510的供电, 作为电键.
DTR信号控制整机供电和天线切换, 作为PTT.</p>
<p><a href="/images/cw3579.png" title="电路图"><img src="/images/cw3579.png" width="500px" /></a></p>
<p>实测发现一个大问题: CP2102转出来的RS-232的DTR和RTS极性是反的! 再一查, PL2303和FT232也是这样. 现在的PC基本已经不提供RS-232了, 没办法, 装个串口挡板, 用真实的串口再试试吧.</p>Sansei DMM2650背光改装记录2014-12-12T00:00:00+08:002014-12-12T00:00:00+08:00Stavrostag:st.avros.net,2014-12-12:/articles/dmm2650.html<p>Sansei DMM2650是80年代的小型台式四位半自动量程万用表, 在Diyers中一直很受欢迎. sunzx送了我一台, 相当好用. 使用过程中发现它有一个很大的不足之处就是液晶屏没有背光, 光线较暗时读数不容易看清, 所以我决定给它加装背光. </p>
<p><a href="/images/dmm2650_1.jpg"><img src="/images/dmm2650_1.jpg" width="500" /></a></p>
<p>DMM2650的液晶屏是双列针脚直插式的, 小心地把它从插座上取下来, 如图:</p>
<p><a href="/images/dmm2650_2.jpg"><img src="/images/dmm2650_2.jpg" width="500" /></a></p>
<p>背面贴了一层反光膜. 这层膜很致密, 用LED手电从背后照, 在前面基本看不到. 因此要加装背光, 必须把这层膜撕下来. </p>
<p><a href="/images/dmm2650_3.jpg"><img src="/images/dmm2650_3.jpg" width="500" /></a></p>
<p>撕的时候要很小心, 引脚碰弯了就不容易按回去了. </p>
<p><a href="/images/dmm2650_4.jpg"><img src="/images/dmm2650_4.jpg" width="500" /></a> </p>
<p>接下来制作背光板. 这块2cm x 8cm的洞洞板长度长了点, 两端要锯掉一些. </p>
<p><a href="/images/dmm2650_5.jpg"><img src="/images/dmm2650_5.jpg" width="500" /></a> </p>
<p>锯完之后, 尺寸正合适. </p>
<p><a href="/images/dmm2650_6.jpg"><img src="/images/dmm2650_6.jpg" width="500" /></a> </p>
<p>在上面焊10个0805的白光LED, 以及相应的限流电阻. 背光不需要很亮, 大约0.5mA就足够, 这里限流电阻用了5.1K. </p>
<p><a href="/images/dmm2650_7.jpg"><img src="/images/dmm2650_7.jpg" width="500" /></a> </p>
<p>点亮背光的效果. </p>
<p><a href="/images/dmm2650_8.jpg"><img src="/images/dmm2650_8.jpg" width="500" /></a> </p>
<p>液晶屏插座正中是驱动芯片, 做好的背光板可以用双面胶贴在驱动芯片上. </p>
<p><a href="/images/dmm2650_9.jpg"><img src="/images/dmm2650_9.jpg" width="500" /></a> </p>
<p>接下来要找到供电正负端, 很好找, 红色的电源开关最后面那两个引脚就是. 把背光板的引线缠在上面, 焊好. </p>
<p><a href="/images/dmm2650_10.jpg"><img src="/images/dmm2650_10.jpg" width="500" /></a> </p>
<p>装回前面板, 开机! 怎么效果有点逗比……看来没有柔光片是不行的. </p>
<p><a href="/images/dmm2650_11.jpg"><img src="/images/dmm2650_11.jpg" width="500" /></a> </p>
<p>柔光片这东西不好找, 试了不干胶贴纸的背纸、白色绝缘胶带、普通A4纸, 效果都不理想 …</p><p>Sansei DMM2650是80年代的小型台式四位半自动量程万用表, 在Diyers中一直很受欢迎. sunzx送了我一台, 相当好用. 使用过程中发现它有一个很大的不足之处就是液晶屏没有背光, 光线较暗时读数不容易看清, 所以我决定给它加装背光. </p>
<p><a href="/images/dmm2650_1.jpg"><img src="/images/dmm2650_1.jpg" width="500" /></a></p>
<p>DMM2650的液晶屏是双列针脚直插式的, 小心地把它从插座上取下来, 如图:</p>
<p><a href="/images/dmm2650_2.jpg"><img src="/images/dmm2650_2.jpg" width="500" /></a></p>
<p>背面贴了一层反光膜. 这层膜很致密, 用LED手电从背后照, 在前面基本看不到. 因此要加装背光, 必须把这层膜撕下来. </p>
<p><a href="/images/dmm2650_3.jpg"><img src="/images/dmm2650_3.jpg" width="500" /></a></p>
<p>撕的时候要很小心, 引脚碰弯了就不容易按回去了. </p>
<p><a href="/images/dmm2650_4.jpg"><img src="/images/dmm2650_4.jpg" width="500" /></a> </p>
<p>接下来制作背光板. 这块2cm x 8cm的洞洞板长度长了点, 两端要锯掉一些. </p>
<p><a href="/images/dmm2650_5.jpg"><img src="/images/dmm2650_5.jpg" width="500" /></a> </p>
<p>锯完之后, 尺寸正合适. </p>
<p><a href="/images/dmm2650_6.jpg"><img src="/images/dmm2650_6.jpg" width="500" /></a> </p>
<p>在上面焊10个0805的白光LED, 以及相应的限流电阻. 背光不需要很亮, 大约0.5mA就足够, 这里限流电阻用了5.1K. </p>
<p><a href="/images/dmm2650_7.jpg"><img src="/images/dmm2650_7.jpg" width="500" /></a> </p>
<p>点亮背光的效果. </p>
<p><a href="/images/dmm2650_8.jpg"><img src="/images/dmm2650_8.jpg" width="500" /></a> </p>
<p>液晶屏插座正中是驱动芯片, 做好的背光板可以用双面胶贴在驱动芯片上. </p>
<p><a href="/images/dmm2650_9.jpg"><img src="/images/dmm2650_9.jpg" width="500" /></a> </p>
<p>接下来要找到供电正负端, 很好找, 红色的电源开关最后面那两个引脚就是. 把背光板的引线缠在上面, 焊好. </p>
<p><a href="/images/dmm2650_10.jpg"><img src="/images/dmm2650_10.jpg" width="500" /></a> </p>
<p>装回前面板, 开机! 怎么效果有点逗比……看来没有柔光片是不行的. </p>
<p><a href="/images/dmm2650_11.jpg"><img src="/images/dmm2650_11.jpg" width="500" /></a> </p>
<p>柔光片这东西不好找, 试了不干胶贴纸的背纸、白色绝缘胶带、普通A4纸, 效果都不理想. 最后用快递盒子里的泡沫棉, 垫了两层, 好象稍微好点了. </p>
<p><a href="/images/dmm2650_12.jpg"><img src="/images/dmm2650_12.jpg" width="500" /></a> </p>
<p>装回外壳, 放在书架上, 先凑和着用吧, 等以后找到了合适的柔光片再给它换上. </p>
<p><a href="/images/dmm2650_13.jpg"><img src="/images/dmm2650_13.jpg" width="500" /></a> </p>
<p>完~</p>南瓜灯2014-05-07T00:00:00+08:002014-05-07T00:00:00+08:00Stavrostag:st.avros.net,2014-05-07:/articles/pumpkin_light.html<p>某次在超市看到有这种球形蜡烛头卖,如图:</p>
<p><a href="/images/pumpkin_1.jpg"><img src="/images/pumpkin_1.jpg" width="500" /></a></p>
<p>用记号笔把适当的地方涂黑,就成了这样:</p>
<p><a href="/images/pumpkin_2.jpg"><img src="/images/pumpkin_2.jpg" width="500" /></a></p>
<p>最后呢,在它下面熔个洞,放进一个橙色大功率LED,点亮以后的效果:</p>
<p><a href="/images/pumpkin_3.jpg"><img src="/images/pumpkin_3.jpg" width="500" /></a></p>
<p>好象万圣节的时间搞错了……不过无所谓啦。</p>
<p>最后,用AVR让它的亮度忽明忽暗,尽可能象真正的蜡烛一样——其实挺困难的。</p><p>某次在超市看到有这种球形蜡烛头卖,如图:</p>
<p><a href="/images/pumpkin_1.jpg"><img src="/images/pumpkin_1.jpg" width="500" /></a></p>
<p>用记号笔把适当的地方涂黑,就成了这样:</p>
<p><a href="/images/pumpkin_2.jpg"><img src="/images/pumpkin_2.jpg" width="500" /></a></p>
<p>最后呢,在它下面熔个洞,放进一个橙色大功率LED,点亮以后的效果:</p>
<p><a href="/images/pumpkin_3.jpg"><img src="/images/pumpkin_3.jpg" width="500" /></a></p>
<p>好象万圣节的时间搞错了……不过无所谓啦。</p>
<p>最后,用AVR让它的亮度忽明忽暗,尽可能象真正的蜡烛一样——其实挺困难的。</p>8x8 LED点阵动画2014-05-06T00:00:00+08:002014-05-06T00:00:00+08:00Stavrostag:st.avros.net,2014-05-06:/articles/8x8_led_animation.html<p>翻出来一个8x8的LED屏,决定做点动画玩。电路很简单,ATmega8的PB口做行选,PD口做列选。</p>
<p>做出来的效果是这样的:</p>
<video src="/videos/8x8_led_animation.mp4" width="500" controls="controls" />(/videos/8x8_led_animation.mp4)<p>翻出来一个8x8的LED屏,决定做点动画玩。电路很简单,ATmega8的PB口做行选,PD口做列选。</p>
<p>做出来的效果是这样的:</p>
<video src="/videos/8x8_led_animation.mp4" width="500" controls="controls" />(/videos/8x8_led_animation.mp4)棉花糖机2013-09-10T00:00:00+08:002013-09-10T00:00:00+08:00Stavrostag:st.avros.net,2013-09-10:/articles/candy_floss.html<p>完全是参考网上那篇硬盘改棉花糖机的教程. 手里这块硬盘似乎坏得有点严重, 通电也转不起来了... 查了一下, 原来硬盘电机就是一个三相无刷电机, 于是用AVR给它搭了个驱动电路如图.</p>
<p><a href="/images/candy_floss.png"><img src="/images/candy_floss.png" width="500" /></a></p>
<p>其中三只NPN管用常用的C945, C1815之类都完全可以; 三对MOS管可以用分立的, 也可以用现成的互补对管, AOP605或AOP607之类, 在DIP8封装里集成了NMOS和PMOS各一只, 用起来方便一些.</p>
<p>程序很简单, 按照U+V-, U+W-, V+W-, V+U-, W+U-, W+V- 这个顺序依次驱动6只MOS管, 判断剩余一相的过零时刻来换相, 就能转得很好. 闭环工作时, 如果把盘片全拆下来, 只剩光轴, 转速能达到4万转, 装上盘片就只有几千转了. 想让它转得稳定一些的话, 控制逻辑还得再复杂一些才行.</p>
<p>后面的大同小异了, 不过效果不太理想, 固体酒精的火力不太好掌握, 费了很大劲只做出一点点. 以后有机会把它改成感应式加热的, 也许效果会好些?</p><p>完全是参考网上那篇硬盘改棉花糖机的教程. 手里这块硬盘似乎坏得有点严重, 通电也转不起来了... 查了一下, 原来硬盘电机就是一个三相无刷电机, 于是用AVR给它搭了个驱动电路如图.</p>
<p><a href="/images/candy_floss.png"><img src="/images/candy_floss.png" width="500" /></a></p>
<p>其中三只NPN管用常用的C945, C1815之类都完全可以; 三对MOS管可以用分立的, 也可以用现成的互补对管, AOP605或AOP607之类, 在DIP8封装里集成了NMOS和PMOS各一只, 用起来方便一些.</p>
<p>程序很简单, 按照U+V-, U+W-, V+W-, V+U-, W+U-, W+V- 这个顺序依次驱动6只MOS管, 判断剩余一相的过零时刻来换相, 就能转得很好. 闭环工作时, 如果把盘片全拆下来, 只剩光轴, 转速能达到4万转, 装上盘片就只有几千转了. 想让它转得稳定一些的话, 控制逻辑还得再复杂一些才行.</p>
<p>后面的大同小异了, 不过效果不太理想, 固体酒精的火力不太好掌握, 费了很大劲只做出一点点. 以后有机会把它改成感应式加热的, 也许效果会好些?</p>迷你电源2013-09-10T00:00:00+08:002013-09-10T00:00:00+08:00Stavrostag:st.avros.net,2013-09-10:/articles/mini_power.html<p>用一节锂电boost升压到5V, 后面接LDO, 用MCU的PWM输出一个电压信号给LDO的ADJ脚, 实现了可调输出. 同时用LCD显示输出电压电流和电池电压. 不过效率似乎低了点, 一节锂电用不了多久. 下次试试把LDO换成buck降压芯片.</p><p>用一节锂电boost升压到5V, 后面接LDO, 用MCU的PWM输出一个电压信号给LDO的ADJ脚, 实现了可调输出. 同时用LCD显示输出电压电流和电池电压. 不过效率似乎低了点, 一节锂电用不了多久. 下次试试把LDO换成buck降压芯片.</p>50M FM发射实验2013-07-17T00:00:00+08:002013-07-17T00:00:00+08:00Stavrostag:st.avros.net,2013-07-17:/articles/50m_fm_tx.html<p>电路如图, 74HC04的一个非门接成10.245M晶体振荡器, 晶体一端并联变容二极管. 用剩下的五个非门来推动2N7002, 2N7002的D极谐振在10.245M的五倍频, 51.225M频率上. </p>
<p><a href="/images/50m_fm.png"><img src="/images/50m_fm.png" width="500" /></a></p>
<p>用VX-7R接收, 不管走到屋里哪个角落, 信号都挺强的. 可惜北京不允许使用50M频率, 只能在屋里大概试试了. 估计到开阔地能发射相当远的吧. </p><p>电路如图, 74HC04的一个非门接成10.245M晶体振荡器, 晶体一端并联变容二极管. 用剩下的五个非门来推动2N7002, 2N7002的D极谐振在10.245M的五倍频, 51.225M频率上. </p>
<p><a href="/images/50m_fm.png"><img src="/images/50m_fm.png" width="500" /></a></p>
<p>用VX-7R接收, 不管走到屋里哪个角落, 信号都挺强的. 可惜北京不允许使用50M频率, 只能在屋里大概试试了. 估计到开阔地能发射相当远的吧. </p>R-2R SD卡WAVE播放器2013-07-14T00:00:00+08:002013-07-14T00:00:00+08:00Stavrostag:st.avros.net,2013-07-14:/articles/avr_sd_waveplayer_2.html<p>用ATMega8, 16.9344M晶振, 14位r-2r作为DAC, 实现了流畅播放16位 44.1kbps单声道wav. 双声道没试, 估计超点频应该差不多了. </p>
<p>这东西有点说来话长. 最早是amobbs的马潮老师出了个题目, 8*8的LED屏, 中间四个常亮, 最外圈亮一个转圈跑. 那会儿我正好有块点阵屏闲着, 就焊了一块板, 从开始写程序计算, 39分钟解决了. </p>
<p>讨论过程中师弟TwoPerson把这位马潮老师惹怒了. 于是他放出狂言, 原文如下: </p>
<blockquote>
<p>如果不服, 可以再次比试. 你在北大找5个学生, 组成一个小组. 用m16加一片lm324, 设计一个读取sd卡上wave文件, 并播放的wave播放器, 看谁做的好. 给你们一个月的时间, 下个学期开学我到北大找你, 比试实物效果. </p>
</blockquote>
<p>在我这个外行看来, 这个题目也就是一个人两三天到一周左右的工作量, 至于五个人搞一个月么? 不过后来事情一多也就把这回事忘了. </p>
<p>今年1月份想起来了, 于是动手开干. 用8位PWM先试了一次, 从学习SD协议、实现FAT开始, 焊接、写程序到调试全算上, 用了两个晚上、周六全天加周日半天, 基本完事. 当然8位PWM的音质有点惨不忍睹……</p>
<p>这次改用r-2r ladder来实现16位输出 …</p><p>用ATMega8, 16.9344M晶振, 14位r-2r作为DAC, 实现了流畅播放16位 44.1kbps单声道wav. 双声道没试, 估计超点频应该差不多了. </p>
<p>这东西有点说来话长. 最早是amobbs的马潮老师出了个题目, 8*8的LED屏, 中间四个常亮, 最外圈亮一个转圈跑. 那会儿我正好有块点阵屏闲着, 就焊了一块板, 从开始写程序计算, 39分钟解决了. </p>
<p>讨论过程中师弟TwoPerson把这位马潮老师惹怒了. 于是他放出狂言, 原文如下: </p>
<blockquote>
<p>如果不服, 可以再次比试. 你在北大找5个学生, 组成一个小组. 用m16加一片lm324, 设计一个读取sd卡上wave文件, 并播放的wave播放器, 看谁做的好. 给你们一个月的时间, 下个学期开学我到北大找你, 比试实物效果. </p>
</blockquote>
<p>在我这个外行看来, 这个题目也就是一个人两三天到一周左右的工作量, 至于五个人搞一个月么? 不过后来事情一多也就把这回事忘了. </p>
<p>今年1月份想起来了, 于是动手开干. 用8位PWM先试了一次, 从学习SD协议、实现FAT开始, 焊接、写程序到调试全算上, 用了两个晚上、周六全天加周日半天, 基本完事. 当然8位PWM的音质有点惨不忍睹……</p>
<p>这次改用r-2r ladder来实现16位输出, 三个晚上加两个白天, 完事了. 算上之前的两晚上和一个半白天, 还算符合我之前“一个人一周工作量”的估计吧. m8的io稍微有点不够用了, 凑了14位出来, 倒是也差不多了. 音质么我觉得还不错. </p>
<p>原理图:</p>
<p><a href="/images/avr_sd_waveplayer_2.png"><img src="/images/avr_sd_waveplayer_2.png" width="500" /></a></p>
<p>程序:
<a href="/files/avr_sd_waveplayer_2_src.7z">avr_sd_waveplayer_2_src.7z</a> </p>
<p>马老师那边啥反应? 猜也猜得出, 他在精神上永远都能胜利, 我实在不想引用那个“永远不要试图去战胜一个纯xx, 他会把你的智商拖到跟他一样的水平, 然后用他丰富的经验打败你. ”的段子, 不过还是把链接贴过来好了. </p>
<p><a href="http://www.amobbs.com/thread-5535140-1-1.html" target="_blank">http://www.amobbs.com/thread-5535140-1-1.html</a></p>
<p>马老师喷了几大篇以后不知出于一种什么心理, 封贴了, 对此咱就不作啥评论了, 呵呵.</p>滑动触摸实验2013-07-14T00:00:00+08:002013-07-14T00:00:00+08:00Stavrostag:st.avros.net,2013-07-14:/articles/slide_sense.html<p>见ST的两个应用笔记, AN2927和AN2896. 基本原理就是把触摸区域当作一个电容, 用一个IO口通过大电阻对触摸区域充放电, 另一个IO口来读取状态, 记录充放电时间. 当手指摸上去时, 这个电容变大了, 因此充放电时间会变长. </p>
<p><a href="http://v.youku.com/v_show/id_XNTMzNTkxMDQ0.html" target="_blank">视频链接</a></p><p>见ST的两个应用笔记, AN2927和AN2896. 基本原理就是把触摸区域当作一个电容, 用一个IO口通过大电阻对触摸区域充放电, 另一个IO口来读取状态, 记录充放电时间. 当手指摸上去时, 这个电容变大了, 因此充放电时间会变长. </p>
<p><a href="http://v.youku.com/v_show/id_XNTMzNTkxMDQ0.html" target="_blank">视频链接</a></p>火电和核电, 哪个造成的放射性污染更严重?2013-06-25T00:00:00+08:002013-06-25T00:00:00+08:00Stavrostag:st.avros.net,2013-06-25:/articles/nuclear_or_thermo_power.html<p>常识告诉我们...... 别急, 不要太相信常识, 一切要用数据说话. </p>
<p>100万千瓦的核电站: 每年耗铀约30吨. 铀的密度很高, 和黄金差不多, 30吨铀也就是家里的大衣柜那么大, 一辆重型卡车就能拉走. 核燃料和核废料的运输和储存都有极严格的程序, 除非发生事故, 想泄露点都是很难的. 核废料最终会熔炼成类似玻璃的状态, 用水泥之类包裹, 再深埋处理. 一年埋一个大衣柜体积的核废料, 真的不算多, 一家人一年扔掉的生活垃圾估计都远不止这点体积.</p>
<p>100万千瓦的火电站: 火电排放大量的粉尘和CO2之类, 这些都不用说了. 每年耗煤300万吨, 还用30吨重卡拉走的话, 就得10万辆, 平均每天就得300辆了. 注意这里还有个问题: 煤里也含有微量的铀. 在中国, 煤的平均含铀量大约3个ppm, 也就是说100万吨煤里就有3吨铀, 300万吨煤里就是9吨. 这些铀一部分随着烟尘排放到大气中, 一部分成了粉煤灰, 然后被加工成水泥、空心砖之类, 做了建筑材料. </p>
<p>完了没有? 没完. 煤里还有另外一种放射性元素钍, 含量还要高一些, 在中国平均为6~10ppm. 也就是说这个100万千瓦的火电站每年消耗的300万吨煤里含有18~30吨的钍. 这些钍也一样, 要么被排放到大气中, 要么做了建筑材料. </p>
<p>这还不算, 煤里还含有微量的钋 …</p><p>常识告诉我们...... 别急, 不要太相信常识, 一切要用数据说话. </p>
<p>100万千瓦的核电站: 每年耗铀约30吨. 铀的密度很高, 和黄金差不多, 30吨铀也就是家里的大衣柜那么大, 一辆重型卡车就能拉走. 核燃料和核废料的运输和储存都有极严格的程序, 除非发生事故, 想泄露点都是很难的. 核废料最终会熔炼成类似玻璃的状态, 用水泥之类包裹, 再深埋处理. 一年埋一个大衣柜体积的核废料, 真的不算多, 一家人一年扔掉的生活垃圾估计都远不止这点体积.</p>
<p>100万千瓦的火电站: 火电排放大量的粉尘和CO2之类, 这些都不用说了. 每年耗煤300万吨, 还用30吨重卡拉走的话, 就得10万辆, 平均每天就得300辆了. 注意这里还有个问题: 煤里也含有微量的铀. 在中国, 煤的平均含铀量大约3个ppm, 也就是说100万吨煤里就有3吨铀, 300万吨煤里就是9吨. 这些铀一部分随着烟尘排放到大气中, 一部分成了粉煤灰, 然后被加工成水泥、空心砖之类, 做了建筑材料. </p>
<p>完了没有? 没完. 煤里还有另外一种放射性元素钍, 含量还要高一些, 在中国平均为6~10ppm. 也就是说这个100万千瓦的火电站每年消耗的300万吨煤里含有18~30吨的钍. 这些钍也一样, 要么被排放到大气中, 要么做了建筑材料. </p>
<p>这还不算, 煤里还含有微量的钋, 镭等放射性元素, 虽然含量较少, 但它们的放射性还要强一些.</p>
<p>即使发生核事故, 也只是把数量少得多的放射性物质在短时间和小范围内释放出来而已. 而火电所做的, 是把多得多的放射性物质在时间和空间上平摊到我们每个人头上. </p>发V机2013-06-11T00:00:00+08:002013-06-11T00:00:00+08:00Stavrostag:st.avros.net,2013-06-11:/articles/v_tx.html<p>功能很简单, 就是发出字母V的莫尔斯电码"...-", 用来调试机器, 很好用. </p>
<p>原理图:</p>
<p><a href="/images/v_tx.png" title="电路图"><img src="/images/v_tx.png" width="500px" /></a></p>
<p>由CD4060组成约100kHz的RC振荡器, 6次二分频后得到大约600Hz的音频信号; 继续由74HC393分频得到4bit控制信号, 由两只CD4011组成的逻辑电路变换成字母V的开关信号, 最后由一只NPN管实现600Hz音频调制. </p>
<p>用一只8脚单片机的话, 硬件上可以更简单. 用逻辑电路的好处是不用调试, 焊好通电就能工作了. </p>
<p>开始由一只10440锂电池直接供电, 结果发现电池电压变化会严重影响音调, 于是增加了HT7750升压电路, 让它在固定5V电压下工作, 效果好多了. </p><p>功能很简单, 就是发出字母V的莫尔斯电码"...-", 用来调试机器, 很好用. </p>
<p>原理图:</p>
<p><a href="/images/v_tx.png" title="电路图"><img src="/images/v_tx.png" width="500px" /></a></p>
<p>由CD4060组成约100kHz的RC振荡器, 6次二分频后得到大约600Hz的音频信号; 继续由74HC393分频得到4bit控制信号, 由两只CD4011组成的逻辑电路变换成字母V的开关信号, 最后由一只NPN管实现600Hz音频调制. </p>
<p>用一只8脚单片机的话, 硬件上可以更简单. 用逻辑电路的好处是不用调试, 焊好通电就能工作了. </p>
<p>开始由一只10440锂电池直接供电, 结果发现电池电压变化会严重影响音调, 于是增加了HT7750升压电路, 让它在固定5V电压下工作, 效果好多了. </p>继续试验外差机2013-05-23T00:00:00+08:002013-05-23T00:00:00+08:00Stavrostag:st.avros.net,2013-05-23:/articles/heterodyne_test.html<p>分别用LA1600和分立器件实现了两个中波外差机.</p>
<p>效果差不多, 在阳台上能收到中国之声一个台, 别的台都收不到了. 总之和之前做的直放机没啥区别吧.</p>
<p>大概是输入回路的Q值太低, 弱信号全被中国之声压住了. 有空了再做FM机试试吧. </p><p>分别用LA1600和分立器件实现了两个中波外差机.</p>
<p>效果差不多, 在阳台上能收到中国之声一个台, 别的台都收不到了. 总之和之前做的直放机没啥区别吧.</p>
<p>大概是输入回路的Q值太低, 弱信号全被中国之声压住了. 有空了再做FM机试试吧. </p>USB电子管声卡2013-05-23T00:00:00+08:002013-05-23T00:00:00+08:00Stavrostag:st.avros.net,2013-05-23:/articles/usb_dac_tube.html<p>这次是PCM2702+NE5534+2P2的组合——以USB的供电能力最多只能带动2P2了. </p>
<p><a href="/images/usb_dac_tube.jpg" title="电路图"><img src="/images/usb_dac_tube.jpg" width="500px" /></a></p>
<p>相当小巧, PCB面积比公交卡还小, 不过输出变压器没包括在内. </p>
<p>电路图如下, PCM2702输出的音频信号由NE5534反相放大后推动2P2. </p>
<p><a href="/images/usb_dac_tube.png" title="电路图"><img src="/images/usb_dac_tube.png" width="500px" /></a></p>
<p>主要的麻烦是供电, 一只2P2需要60V屏压、1.2或2.4V灯丝、-3.5V栅偏压. 60V高压用LM2577升压得到; 这里用灯丝串联电阻R14上的压降来代替栅偏压, 于是可以省下一组供电. 此外NE5534的最高供电电压是±22V, 这里给它提供了一路30V电压. 这块小板子上供电占了大概1/3的面积. </p>
<p>效果么...... 只能说还凑合吧, 主要是音量太小了, 2P2的输出功率只有100mW. 下次试试两只2P2推挽的效果吧. </p><p>这次是PCM2702+NE5534+2P2的组合——以USB的供电能力最多只能带动2P2了. </p>
<p><a href="/images/usb_dac_tube.jpg" title="电路图"><img src="/images/usb_dac_tube.jpg" width="500px" /></a></p>
<p>相当小巧, PCB面积比公交卡还小, 不过输出变压器没包括在内. </p>
<p>电路图如下, PCM2702输出的音频信号由NE5534反相放大后推动2P2. </p>
<p><a href="/images/usb_dac_tube.png" title="电路图"><img src="/images/usb_dac_tube.png" width="500px" /></a></p>
<p>主要的麻烦是供电, 一只2P2需要60V屏压、1.2或2.4V灯丝、-3.5V栅偏压. 60V高压用LM2577升压得到; 这里用灯丝串联电阻R14上的压降来代替栅偏压, 于是可以省下一组供电. 此外NE5534的最高供电电压是±22V, 这里给它提供了一路30V电压. 这块小板子上供电占了大概1/3的面积. </p>
<p>效果么...... 只能说还凑合吧, 主要是音量太小了, 2P2的输出功率只有100mW. 下次试试两只2P2推挽的效果吧. </p>636收音机2013-04-22T00:00:00+08:002013-04-22T00:00:00+08:00Stavrostag:st.avros.net,2013-04-22:/articles/636_recv.html<p>说来惭愧, 玩了这么多年无线电, 以前从来没装响过一台收音机...... 后来发现, 不是收音机不行, 而是那会儿宿舍的电磁环境太差了, 用成品Philips D1875也照样一个AM台也收不到. </p>
<p>636估计是除了矿石机以外, 最简单的能收到台的收音机了, 电路图如下: </p>
<p><a href="/images/636_recv.png" title="电路图"><img src="/images/636_recv.png" width="500px" /></a></p>
<p>这个电路图实际上已经是加强版了, 原版的636是没有倍压检波的. 我这次的实验用了长磁棒和空气双联, 跟当年的成品636相比, 可以算是豪华版了. 在阳台上试了一下, 中波低端可以收到中国之声, 声音挺清楚;高端就收不到什么信号了. </p>
<p>636后来的版本又加上了再生, 应该能加强一些灵敏度和选择性;但是现在的电磁环境跟60年代不能相比了, 已经不适合装直放机了. 以后还是玩外差机吧. </p><p>说来惭愧, 玩了这么多年无线电, 以前从来没装响过一台收音机...... 后来发现, 不是收音机不行, 而是那会儿宿舍的电磁环境太差了, 用成品Philips D1875也照样一个AM台也收不到. </p>
<p>636估计是除了矿石机以外, 最简单的能收到台的收音机了, 电路图如下: </p>
<p><a href="/images/636_recv.png" title="电路图"><img src="/images/636_recv.png" width="500px" /></a></p>
<p>这个电路图实际上已经是加强版了, 原版的636是没有倍压检波的. 我这次的实验用了长磁棒和空气双联, 跟当年的成品636相比, 可以算是豪华版了. 在阳台上试了一下, 中波低端可以收到中国之声, 声音挺清楚;高端就收不到什么信号了. </p>
<p>636后来的版本又加上了再生, 应该能加强一些灵敏度和选择性;但是现在的电磁环境跟60年代不能相比了, 已经不适合装直放机了. 以后还是玩外差机吧. </p>NE555升压实验_32013-04-22T00:00:00+08:002013-04-22T00:00:00+08:00Stavrostag:st.avros.net,2013-04-22:/articles/ne555_boost_3.html<p>之前试验各种升压电路的结论是, 要想实现从单节锂电升压到5V或更高、大电流输出, PWM ic必须具有以下几个性能: </p>
<ol>
<li>
<p>工作电压足够低, 一般锂电终止放电电压定在3.0V上下, 因此PWM ic的最低工作电压最好是2.7V或者更低; </p>
</li>
<li>
<p>必须是推挽输出, 否则输出电流不够, MOS开关管要么不能完全导通, 要么不能完全关断, 两种情况都严重影响效率; </p>
</li>
</ol>
<p>之前的实验里, NE555在5V升6.3V时表现良好, 但它的最低工作电压只能到4.5V, 不符合上述条件1. 于是想到能否用自举电路或者用7660倍压给NE555供电呢?搭电路实验, 结果如下: </p>
<p>使用自举电路时, 正常启动后, 输入电压可以一直低到1.8V都能正常升压工作; 但输入电压低于4.0V时不能启动. 可见此路不通. </p>
<p>使用7660倍压时可以在2.8V正常启动, 算是勉强达到要求, 可靠性还是不足. </p>
<p>可以再试试用BL8530、HT7750之类小功率升压ic为NE555辅助供电, 如果还是不行, 那就得放弃用NE555实现单节锂电升5V的思路了. </p><p>之前试验各种升压电路的结论是, 要想实现从单节锂电升压到5V或更高、大电流输出, PWM ic必须具有以下几个性能: </p>
<ol>
<li>
<p>工作电压足够低, 一般锂电终止放电电压定在3.0V上下, 因此PWM ic的最低工作电压最好是2.7V或者更低; </p>
</li>
<li>
<p>必须是推挽输出, 否则输出电流不够, MOS开关管要么不能完全导通, 要么不能完全关断, 两种情况都严重影响效率; </p>
</li>
</ol>
<p>之前的实验里, NE555在5V升6.3V时表现良好, 但它的最低工作电压只能到4.5V, 不符合上述条件1. 于是想到能否用自举电路或者用7660倍压给NE555供电呢?搭电路实验, 结果如下: </p>
<p>使用自举电路时, 正常启动后, 输入电压可以一直低到1.8V都能正常升压工作; 但输入电压低于4.0V时不能启动. 可见此路不通. </p>
<p>使用7660倍压时可以在2.8V正常启动, 算是勉强达到要求, 可靠性还是不足. </p>
<p>可以再试试用BL8530、HT7750之类小功率升压ic为NE555辅助供电, 如果还是不行, 那就得放弃用NE555实现单节锂电升5V的思路了. </p>用LM2596搭建数控稳压电源2013-03-23T00:00:00+08:002013-03-23T00:00:00+08:00Stavrostag:st.avros.net,2013-03-23:/articles/lm2596_dac.html<p>常用的LM2596芯片可以方便地搭成各种降压式开关稳压电源, 但要用单片机来控制它的输出电压就稍微有点麻烦了——主要的思路有两种, 一种是使用传统的电位器控制方式, 用单片机控制数字电位器来代替模拟电位器; 另一种则是利用单片机的PWM或DAC输出一个控制电压, 引入到LM2596的反馈环路中. 这次试验的是后一种思路. </p>
<p><a href="/images/lm2596_dac.png" title="电路图"><img src="/images/lm2596_dac.png" width="500px" /></a></p>
<p>如图, 设输出电压为Vout, 控制电压为Vctrl, LM2596的反馈端电压为Vfb, 根据运放的基本性质可得:</p>
<p>Vctrl * R3/(R3+R8) + Vfb * R8/(R3+R8) = Vout * R9 / (R2+R9)</p>
<p>按上图的参数, 可以写为Vctrl * 10/11 + Vfb * 1/11 = Vout * 1/4</p>
<p>对于LM2596-ADJ, 其Vfb = 1.23V, 于是有Vout = 4/11 * (10 * Vctrl + 1.23 )</p>
<p>于是, 当Vctrl = 0V时, 输出电压为1 …</p><p>常用的LM2596芯片可以方便地搭成各种降压式开关稳压电源, 但要用单片机来控制它的输出电压就稍微有点麻烦了——主要的思路有两种, 一种是使用传统的电位器控制方式, 用单片机控制数字电位器来代替模拟电位器; 另一种则是利用单片机的PWM或DAC输出一个控制电压, 引入到LM2596的反馈环路中. 这次试验的是后一种思路. </p>
<p><a href="/images/lm2596_dac.png" title="电路图"><img src="/images/lm2596_dac.png" width="500px" /></a></p>
<p>如图, 设输出电压为Vout, 控制电压为Vctrl, LM2596的反馈端电压为Vfb, 根据运放的基本性质可得:</p>
<p>Vctrl * R3/(R3+R8) + Vfb * R8/(R3+R8) = Vout * R9 / (R2+R9)</p>
<p>按上图的参数, 可以写为Vctrl * 10/11 + Vfb * 1/11 = Vout * 1/4</p>
<p>对于LM2596-ADJ, 其Vfb = 1.23V, 于是有Vout = 4/11 * (10 * Vctrl + 1.23 )</p>
<p>于是, 当Vctrl = 0V时, 输出电压为1.23V; 当Vctrl = 3V时, 输出电压为11.3V左右. 实际上由于LM358运放输入共模电压的限制, 当供电电压为12V时, 本电路最高输出电压为10V左右. 在R2和R9的分压端引出一路信号到单片机的ADC来测量输出电压. </p>
<p>怎么测量输出电流呢?在输出地端串联小电阻检测电流虽然较简单, 但是造成输入、输出不共地, 许多情况下反倒更麻烦, 因此这里选择了由R4、R1、R6、U3和Q1等元件构成的高端电流检测电路. 如图, R4上的压降被U3放大15倍后, 得到一个对地的电压, 单片机测出此电压, 除以15, 再除以R4的阻值50毫欧即可得到输出电流. 用12V 15W灯泡作为负载, 实测工作状况如下:</p>
<table>
<thead>
<tr>
<th align="center">PWM duty</th>
<th align="center">Vctrl/V</th>
<th align="center">Vout/V</th>
<th align="center">Iout/A</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">14.6%</td>
<td align="center">0.74</td>
<td align="center">3.1</td>
<td align="center">0.45</td>
</tr>
<tr>
<td align="center">24.4%</td>
<td align="center">1.22</td>
<td align="center">4.9</td>
<td align="center">0.56</td>
</tr>
<tr>
<td align="center">34.2%</td>
<td align="center">1.70</td>
<td align="center">6.6</td>
<td align="center">0.65</td>
</tr>
<tr>
<td align="center">43.9%</td>
<td align="center">2.17</td>
<td align="center">8.4</td>
<td align="center">0.74</td>
</tr>
<tr>
<td align="center">53.7%</td>
<td align="center">2.61</td>
<td align="center">10.2</td>
<td align="center">0.82</td>
</tr>
</tbody>
</table>
<p>后记:用同样原理实现了APW7120+2SK3919*2的可调同步整流降压电路, 实测最大稳定输出电流达到11A. </p>萤火虫瓶子&LCD1602串口转换板2013-03-19T00:00:00+08:002013-03-19T00:00:00+08:00Stavrostag:st.avros.net,2013-03-19:/articles/firefly&serlcd1602.html<p>前者是用AVR的io口模拟PWM, 驱动8个LED闪亮. </p>
<p><a href="http://v.youku.com/v_show/id_XNTI4Nzc4MDYw.html" target="_blank">视频链接</a></p>
<p>装到大玻璃瓶里, 关了灯看, 效果不错.</p>
<p>分别试验了用PCF8574, 74HC164和用一片ATmega48实现用串口驱动1602液晶屏. </p>
<p>PCF8574的方案很简单, 4个IO按4线法连接LCD高4位, 2个IO连接EN端和RS端. LCD RW直接接地, 用一只7660产生负压. 需要占用i2c口, 显示速度慢、性价比也低, 总之不推荐. </p>
<p>用ATmega48扩展的话, 可以8线连接, 接口用i2c、spi、uart都可以, 用一个PWM口产生负压可以节省一只7660, 是最灵活的方式, 不过用uart时需要双方都有晶振. </p>
<p>用74HC164要多占用两个IO, 不过用一些小技巧可以实现只占用两个GPIO:如图, 用电阻和二极管形成一个与门, 在串行写入数据时将最高位置1, 写完8bit后再拉高DATA端, 此时与门输出高电平, EN动作. 之后要拉低DATA, 连续八个CLK以清空164输出端, 避免影响下一轮. 实测写LCD快速、稳定, 成本也是三种方式里最低的. </p>
<p><a href="/images/lcd_2wire.png" title="电路图"><img src="/images/lcd_2wire.png" width="500px" /></a></p>
<p>后记: 后来还是觉得4线接法驱动LCD1602不太稳定. 继续改进, 改为用HC164的八个输出驱动LCD1602的全部8位数据接口, 输入端同时驱动RS脚, 同时再用一个IO来驱动EN脚. 总共用了三个IO, 不过稳定性好多了.</p><p>前者是用AVR的io口模拟PWM, 驱动8个LED闪亮. </p>
<p><a href="http://v.youku.com/v_show/id_XNTI4Nzc4MDYw.html" target="_blank">视频链接</a></p>
<p>装到大玻璃瓶里, 关了灯看, 效果不错.</p>
<p>分别试验了用PCF8574, 74HC164和用一片ATmega48实现用串口驱动1602液晶屏. </p>
<p>PCF8574的方案很简单, 4个IO按4线法连接LCD高4位, 2个IO连接EN端和RS端. LCD RW直接接地, 用一只7660产生负压. 需要占用i2c口, 显示速度慢、性价比也低, 总之不推荐. </p>
<p>用ATmega48扩展的话, 可以8线连接, 接口用i2c、spi、uart都可以, 用一个PWM口产生负压可以节省一只7660, 是最灵活的方式, 不过用uart时需要双方都有晶振. </p>
<p>用74HC164要多占用两个IO, 不过用一些小技巧可以实现只占用两个GPIO:如图, 用电阻和二极管形成一个与门, 在串行写入数据时将最高位置1, 写完8bit后再拉高DATA端, 此时与门输出高电平, EN动作. 之后要拉低DATA, 连续八个CLK以清空164输出端, 避免影响下一轮. 实测写LCD快速、稳定, 成本也是三种方式里最低的. </p>
<p><a href="/images/lcd_2wire.png" title="电路图"><img src="/images/lcd_2wire.png" width="500px" /></a></p>
<p>后记: 后来还是觉得4线接法驱动LCD1602不太稳定. 继续改进, 改为用HC164的八个输出驱动LCD1602的全部8位数据接口, 输入端同时驱动RS脚, 同时再用一个IO来驱动EN脚. 总共用了三个IO, 不过稳定性好多了.</p>AVR SD WAVE播放器2013-01-17T00:00:00+08:002013-01-17T00:00:00+08:00Stavrostag:st.avros.net,2013-01-17:/articles/avr_sd_waveplayer.html<p>得从大约两年前说起, 那会儿amobbs的马潮老师出了个题目: 8x8的LED屏, 中间四个常亮, 最外圈亮一个转圈跑. </p>
<p>这东西没啥难度吧?我正好有块点阵屏闲着, 就焊了一块板, 从开始写程序计算, 39分钟解决了. </p>
<p>讨论过程中一师弟(好象是TwoPerson?)大概出口不慎, 把这位马潮老师惹怒了——于是他又出了个题, 原话如下: </p>
<blockquote>
<p>如果不服, 可以再次比试. 你在北大找5个学生, 组成一个小组. 用m16加一片lm324, 设计一个读取sd卡上wave文件, 并播放的wave播放器, 看谁做的好. 给你们一个月的时间, 下个学期开学我到北大找你, 比试实物效果. </p>
</blockquote>
<p>首先声明一下, 本人纯粹是外行, 本科化学, 研究生改物理了, 以上纯属业余爱好. 马老师这题目在我这个外行看来, 也就是一个人两三天到一周左右的工作量, 至于五个人搞一个月么?不过后来事情一多也就把这回事忘了. </p>
<p>前段时间突然记起来了, 于是动手开干. 电路图太简单就不画了. 觉得没必要上m16, 于是用了一片m8, 硬件SPI接SD卡, 8位PWM输出, 用一片TL061搭成低通滤波, 后面一只8050缓冲接喇叭. 从学习SD协议、实现FAT开始, 焊接、写程序到调试全算上, 用了两个晚上 …</p><p>得从大约两年前说起, 那会儿amobbs的马潮老师出了个题目: 8x8的LED屏, 中间四个常亮, 最外圈亮一个转圈跑. </p>
<p>这东西没啥难度吧?我正好有块点阵屏闲着, 就焊了一块板, 从开始写程序计算, 39分钟解决了. </p>
<p>讨论过程中一师弟(好象是TwoPerson?)大概出口不慎, 把这位马潮老师惹怒了——于是他又出了个题, 原话如下: </p>
<blockquote>
<p>如果不服, 可以再次比试. 你在北大找5个学生, 组成一个小组. 用m16加一片lm324, 设计一个读取sd卡上wave文件, 并播放的wave播放器, 看谁做的好. 给你们一个月的时间, 下个学期开学我到北大找你, 比试实物效果. </p>
</blockquote>
<p>首先声明一下, 本人纯粹是外行, 本科化学, 研究生改物理了, 以上纯属业余爱好. 马老师这题目在我这个外行看来, 也就是一个人两三天到一周左右的工作量, 至于五个人搞一个月么?不过后来事情一多也就把这回事忘了. </p>
<p>前段时间突然记起来了, 于是动手开干. 电路图太简单就不画了. 觉得没必要上m16, 于是用了一片m8, 硬件SPI接SD卡, 8位PWM输出, 用一片TL061搭成低通滤波, 后面一只8050缓冲接喇叭. 从学习SD协议、实现FAT开始, 焊接、写程序到调试全算上, 用了两个晚上、周六全天加周日半天, 基本完事. 当然8位PWM的音质有点惨不忍睹……</p>
<p>原理图: </p>
<p><a href="/images/avr_sd_waveplayer.png" title="电路图"><img src="/images/avr_sd_waveplayer.png" width="500px" /></a></p>
<p>程序:</p>
<p><a href="/files/avr_sd_waveplayer_src.7z">src.7z</a></p>2012制作总结2012-12-10T00:00:00+08:002012-12-10T00:00:00+08:00Stavrostag:st.avros.net,2012-12-10:/articles/2012_conclusion.html<p>各种实验性质的就不提了, 挑几个好玩的吧~</p>
<ol>
<li>
<p>桌面温湿度计</p>
<p>ATmega48+DS18B20+DHT11的经典配置, 简单试验了一下能工作. 不过DHT11精度太差了, 跟另外一个专门的湿度计读数相差1/3, 完全没法用. </p>
</li>
<li>
<p>三用手电</p>
<p>ATtiny26, 用INT0切换控制一个白光LED、一个紫外LED和一个红色激光LED, 实现手电/验钞笔/激光笔三合一, 如图.</p>
<p><a href="/images/cash_detector_1.jpg" title="验钞笔"><img src="/images/cash_detector_1.jpg"width="500px"/></a></p>
<p>图1 内部构造</p>
<p><a href="/images/cash_detector_2.jpg" title="验钞笔"><img src="/images/cash_detector_2.jpg"width="500px"/></a></p>
<p>图2 验钞效果</p>
<p><a href="/images/cash_detector_3.jpg" title="验钞笔"><img src="/images/cash_detector_3.jpg"width="500px"/></a></p>
<p>图3 激光笔效果</p>
</li>
<li>
<p>直流电子管电源</p>
<p>用一节锂电池当电源, LM2577接成flyback, 输出再通过IRFR420接成线性稳压, 输出60V. 另一路通过1117输出1.4V. 两路相互隔离. </p>
</li>
<li>
<p>盖革计数器</p>
<p>用一只锂电供电, 两只74HC00中的一只接成多谐振荡器, 缓冲后推动两只Si2302, 通过变压器升压到400V给盖革计数管供电; 另一只74HC00接成单稳态电路, 盖革计数管输出的脉冲整形、延时后推动LED和蜂鸣器. </p>
</li>
<li>
<p>毫欧表/高斯计/温度计</p>
<p>本质都一样, 都是四线法测电阻, 电流引线上串个精密电阻, 取它两端压降作为基准电压, 也就是所谓的比例式配置. 当毫欧表和高斯计用时 …</p></li></ol><p>各种实验性质的就不提了, 挑几个好玩的吧~</p>
<ol>
<li>
<p>桌面温湿度计</p>
<p>ATmega48+DS18B20+DHT11的经典配置, 简单试验了一下能工作. 不过DHT11精度太差了, 跟另外一个专门的湿度计读数相差1/3, 完全没法用. </p>
</li>
<li>
<p>三用手电</p>
<p>ATtiny26, 用INT0切换控制一个白光LED、一个紫外LED和一个红色激光LED, 实现手电/验钞笔/激光笔三合一, 如图.</p>
<p><a href="/images/cash_detector_1.jpg" title="验钞笔"><img src="/images/cash_detector_1.jpg"width="500px"/></a></p>
<p>图1 内部构造</p>
<p><a href="/images/cash_detector_2.jpg" title="验钞笔"><img src="/images/cash_detector_2.jpg"width="500px"/></a></p>
<p>图2 验钞效果</p>
<p><a href="/images/cash_detector_3.jpg" title="验钞笔"><img src="/images/cash_detector_3.jpg"width="500px"/></a></p>
<p>图3 激光笔效果</p>
</li>
<li>
<p>直流电子管电源</p>
<p>用一节锂电池当电源, LM2577接成flyback, 输出再通过IRFR420接成线性稳压, 输出60V. 另一路通过1117输出1.4V. 两路相互隔离. </p>
</li>
<li>
<p>盖革计数器</p>
<p>用一只锂电供电, 两只74HC00中的一只接成多谐振荡器, 缓冲后推动两只Si2302, 通过变压器升压到400V给盖革计数管供电; 另一只74HC00接成单稳态电路, 盖革计数管输出的脉冲整形、延时后推动LED和蜂鸣器. </p>
</li>
<li>
<p>毫欧表/高斯计/温度计</p>
<p>本质都一样, 都是四线法测电阻, 电流引线上串个精密电阻, 取它两端压降作为基准电压, 也就是所谓的比例式配置. 当毫欧表和高斯计用时, 测试电流用100mA, 基准电阻取24欧; 当温度计用的话, 测试电流取1mA, 基准电阻用2700欧. 数模转换用AD7705, 国产的TM7705也挺好用, 测出来结果和AD7705基本一致. </p>
<p><a href="/images/milliohmmeter.jpg" title="毫欧计"><img src="/images/milliohmmeter.jpg" width="500px"/></a></p>
<p>图4 测量一段铜线的电阻</p>
</li>
<li>
<p>车载USB充电器</p>
<p>以前买过一个十几块钱的点烟口充电器, 用了一年左右吧, 坏了. 拆开一看发现做工相当差, 就是34063推PMOS的结构, 号称输出2.1A... 于是决定自己做一个. 用两套2596降压到5V, 各接一个双层USB座, 合起来能提供6A的电流, 这回怎么也够了. 再用热熔胶全部封上. </p>
</li>
<li>
<p>厨房定时器</p>
<p>很简单, 倒计时15秒, 时间到了就嘀嘀嘀. 按一下按钮延长一分钟, 最多十分钟. 样子有点象定时炸弹... </p>
<p><a href="/images/kitchen_timer.jpg" title="厨房定时器"><img src="/images/kitchen_timer.jpg" width="500px"/></a></p>
<p>图5 厨房定时器</p>
</li>
<li>
<p>I2CLCD</p>
<p>1602LCD按四线配置, 用一只PCF8574驱动, 这样做简单实验时只要四线就能驱动液晶屏了. 再用一只7660提供负压, 这样3.3V和5V都能工作了. 在AVR和STM8上给它写了驱动. 不过I2C还是嫌有点慢, 以后再做UART和SPI方式的吧. UART可以少一条线, 但是两边都得有晶振. </p>
</li>
<li>
<p>LED测试器</p>
<p>做了个简单的恒流源, 专门检测LED用. 用开关切换5mA和40mA两档, 普通小LED和大功率LED都能测了. </p>
</li>
<li>
<p>磷酸铁锂充电器</p>
<p>用运放和两只BJT简单实现了恒流充电+恒压补充, 用ATmega48对电压采样后驱动10段LED发光条作为电量指示. 试了几次, 还算好用. </p>
</li>
<li>
<p>移动电源</p>
<p>电池用两节2000mAh的锂聚合物并联, 充电用TP4056, 升压用LM2577. 用LED+BJT+PMOS实现了欠压保护, 不过不太准, 大概放到3V多一点关断输出. 输出电压按3.5V计算时, LM2577理论上输出电流是3.5V * 2.1A / 5V = 1.5A; 实际使用时发现同时带两个手机充电时发热挺严重, 充一个还行. 以后用LM3478或MAX1771做个功率大点的, 至少2A吧.</p>
<p><a href="/images/mobile_power.jpg" title="移动电源"><img src="/images/mobile_power.jpg" width="500px"/></a></p>
<p>图6 移动电源</p>
<p>后记: 某次出差时在首都机场被没收了, 因为没有生产厂家, 没有容量标识什么的. 只好买了个品牌的移动电源用.</p>
</li>
<li>
<p>PCL86功放</p>
<p>做了个PCL86的外围小板, 简单验证了一下能响, 以后再慢慢优化吧. </p>
</li>
<li>
<p>AVRDDS</p>
<p>参考这两个老外的设计: </p>
<p><a href="http://www.myplace.nu/avr/minidds/index.htm">http://www.myplace.nu/avr/minidds/index.htm</a></p>
<p><a href="http://codeandlife.com/2012/03/13/fast-dds-with-atmega88">http://codeandlife.com/2012/03/13/fast-dds-with-atmega88</a></p>
<p>做了一点改进, 用四位DIP开关选择16个频点, 结果莫名其妙地总是不正常, 后来发现是asmloop的参数里有浮点计算, 老外的程序里参数都是常量, 于是浮点的问题由编译器解决了; 我在参数里用了变量的结果是把浮点库编译进来了, 于是ATmega48可怜的512字节RAM不够用了. 改了改程序, 解决了. </p>
<p>然后试了一下AM调制: DDS的输出经过LC滤波、2SC945缓冲放大后接天线, 电脑的音频输出经过运放缓冲给2SC945供电. 初步试验的结果只能说能工作了, 收音机离几厘米远能收到, 再远就不行了. 以后还得改进. </p>
<p><a href="/images/dds_455khz.png" title="dds输出455kHz波形"><img src="/images/dds_455khz.png" width="500px"/></a></p>
<p>图7 dds输出455kHz波形</p>
<p><a href="/images/dds_550khz.png" title="dds输出550kHz波形"><img src="/images/dds_550khz.png" width="500px"/></a></p>
<p>图8 dds输出550kHz波形</p>
</li>
</ol>CM102音箱2011-02-13T00:00:00+08:002011-02-13T00:00:00+08:00Stavrostag:st.avros.net,2011-02-13:/articles/cm102_speaker.html<p>CM102是台湾C-Media公司的USB声卡芯片. 跟著名的PCM270x相比, 好处就是: 便宜、有DIP封装, 当然效果没法比了. 电路图如下: </p>
<p><a href="/images/cm102_speaker.png" title="电路图"><img src="/images/cm102_speaker.png" width="500px" /></a></p>
<p>结果是有很大的不规则的噪声...开始以为是VBUS直供TDA2822的原因, 于是让VBUS过了1117-3.3再供TDA2822, 结果仍然噪声很大;全换成用电池供电, 仍然噪声很大;干脆断开TDA2822, 把耳机接到CM102的输出上, 噪声没了. 看样子是买到山寨2822了, 下次用TEA2025重做吧, 或者直接改用LM4890. </p>
<p>ps. C-Media的网站怎么可以这么2呢... 手里CM102的datasheet旧了, 而且几个图都巨模糊, 想找个新的看看, 上CM官网一找, 倒是有, 但是不支持google浏览器;换ie, 发现让注册用户;注册了用户, 下载了datasheet一看, 几个图还是模糊的. 这家的东西似乎卖得还不错, 比如当年的CMI8738. </p><p>CM102是台湾C-Media公司的USB声卡芯片. 跟著名的PCM270x相比, 好处就是: 便宜、有DIP封装, 当然效果没法比了. 电路图如下: </p>
<p><a href="/images/cm102_speaker.png" title="电路图"><img src="/images/cm102_speaker.png" width="500px" /></a></p>
<p>结果是有很大的不规则的噪声...开始以为是VBUS直供TDA2822的原因, 于是让VBUS过了1117-3.3再供TDA2822, 结果仍然噪声很大;全换成用电池供电, 仍然噪声很大;干脆断开TDA2822, 把耳机接到CM102的输出上, 噪声没了. 看样子是买到山寨2822了, 下次用TEA2025重做吧, 或者直接改用LM4890. </p>
<p>ps. C-Media的网站怎么可以这么2呢... 手里CM102的datasheet旧了, 而且几个图都巨模糊, 想找个新的看看, 上CM官网一找, 倒是有, 但是不支持google浏览器;换ie, 发现让注册用户;注册了用户, 下载了datasheet一看, 几个图还是模糊的. 这家的东西似乎卖得还不错, 比如当年的CMI8738. </p>继续进行 NE555 boost 和 flyback 实验2011-02-13T00:00:00+08:002011-02-13T00:00:00+08:00Stavrostag:st.avros.net,2011-02-13:/articles/ne555_boost_2.html<p>之前试过用NE555推MTD3055, 5V升6.3V的实验, 效果很好, 输出1A以上电流, 效率在80%到90%之间. 这次的电路图基本相同, 打算升压到125V左右, 再经过后面的线性稳压, 得到90V左右的稳定电压. 结果不太理想, 5V输入时闭环只能升到85V左右, 12V输入时可以达到130V, 效率50%~60%. 加大负载则效率迅速跌到30%. 从5V逐渐降低输入电压, 降到3.3V时仍能工作, 但带负载时(3W节能灯)不能从3.3V启动工作. 把振荡频率从25kHz提高到50kHz, 效率提高到接近70%, 但没有根本的改善. 再就是变压器的吱吱声实在是太烦人了. </p>
<p>下次的实验目标:</p>
<p>1)改用低Rds(on)的MOSFET代替IRFR420, 仍用boost方式, 看能不能稳定实现5V升到110V左右. boost没有噪音的优势还是很明显的. </p>
<p>2)继续绕变压器, 实现升压到400V, 同时也试试用74HC04、晶体管自激之类实现升压的可能性. </p>
<p>电路图:</p>
<p><a href="/images/ne555_flyback_2.png" title="电路图"><img src="/images/ne555_flyback_2.png" width="500px" /></a></p><p>之前试过用NE555推MTD3055, 5V升6.3V的实验, 效果很好, 输出1A以上电流, 效率在80%到90%之间. 这次的电路图基本相同, 打算升压到125V左右, 再经过后面的线性稳压, 得到90V左右的稳定电压. 结果不太理想, 5V输入时闭环只能升到85V左右, 12V输入时可以达到130V, 效率50%~60%. 加大负载则效率迅速跌到30%. 从5V逐渐降低输入电压, 降到3.3V时仍能工作, 但带负载时(3W节能灯)不能从3.3V启动工作. 把振荡频率从25kHz提高到50kHz, 效率提高到接近70%, 但没有根本的改善. 再就是变压器的吱吱声实在是太烦人了. </p>
<p>下次的实验目标:</p>
<p>1)改用低Rds(on)的MOSFET代替IRFR420, 仍用boost方式, 看能不能稳定实现5V升到110V左右. boost没有噪音的优势还是很明显的. </p>
<p>2)继续绕变压器, 实现升压到400V, 同时也试试用74HC04、晶体管自激之类实现升压的可能性. </p>
<p>电路图:</p>
<p><a href="/images/ne555_flyback_2.png" title="电路图"><img src="/images/ne555_flyback_2.png" width="500px" /></a></p>流水灯2011-02-13T00:00:00+08:002011-02-13T00:00:00+08:00Stavrostag:st.avros.net,2011-02-13:/articles/water_lights.html<p>ourdev的马潮老师出了个题目: 8x8的LED屏, 中间四个常亮, 最外圈亮一个灯转圈跑. 说实话没啥难度, 一伙人讨论得煞有介事. 似乎马潮那边的学生衰了点, 作为专业搞电子的学生, 俩小时搞不出来的都有. 我正好闲着就焊了块板, 从开始写程序开始, 39分钟搞定. </p>
<p>中间一北大的师弟把马潮老师惹毛了, 于是这老师又出了个题, 当joke看吧:</p>
<blockquote>
<p>如果不服, 可以再次比试. 你在北大找5个学生, 组成一个小组. 用m16加一片lm324, 设计一个读取sd卡上wave文件, 并播放的wave播放器, 看谁做的好. 给你们一个月的时间, 下个学期开学我到北大找你, 比试实物效果. </p>
</blockquote><p>ourdev的马潮老师出了个题目: 8x8的LED屏, 中间四个常亮, 最外圈亮一个灯转圈跑. 说实话没啥难度, 一伙人讨论得煞有介事. 似乎马潮那边的学生衰了点, 作为专业搞电子的学生, 俩小时搞不出来的都有. 我正好闲着就焊了块板, 从开始写程序开始, 39分钟搞定. </p>
<p>中间一北大的师弟把马潮老师惹毛了, 于是这老师又出了个题, 当joke看吧:</p>
<blockquote>
<p>如果不服, 可以再次比试. 你在北大找5个学生, 组成一个小组. 用m16加一片lm324, 设计一个读取sd卡上wave文件, 并播放的wave播放器, 看谁做的好. 给你们一个月的时间, 下个学期开学我到北大找你, 比试实物效果. </p>
</blockquote>又试了一下用NE555做boost2010-04-13T00:00:00+08:002010-04-13T00:00:00+08:00Stavrostag:st.avros.net,2010-04-13:/articles/ne555_boost.html<p>555搭成多谐振荡器推动MOSFET,用C1815当作比较器,输入5V,输出6.3V左右,试着点了几个电子管的灯丝。
结果如下:</p>
<table>
<thead>
<tr>
<th align="center"></th>
<th align="center">输出电压(V)</th>
<th align="center">标称电流(A)</th>
<th align="center">输出电流(A)</th>
<th align="center">输入电流(A)</th>
<th align="center">效率</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">空载</td>
<td align="center">6.76</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
</tr>
<tr>
<td align="center">6U1</td>
<td align="center">6.20</td>
<td align="center">0.30</td>
<td align="center">0.32</td>
<td align="center">0.46</td>
<td align="center">86%</td>
</tr>
<tr>
<td align="center">6N2</td>
<td align="center">6.19</td>
<td align="center">0.34</td>
<td align="center">0.33</td>
<td align="center">0.48</td>
<td align="center">85%</td>
</tr>
<tr>
<td align="center">6F2</td>
<td align="center">6.17</td>
<td align="center">0.45</td>
<td align="center">0.43</td>
<td align="center">0.61</td>
<td align="center">87%</td>
</tr>
<tr>
<td align="center">6P1 …</td></tr></tbody></table><p>555搭成多谐振荡器推动MOSFET,用C1815当作比较器,输入5V,输出6.3V左右,试着点了几个电子管的灯丝。
结果如下:</p>
<table>
<thead>
<tr>
<th align="center"></th>
<th align="center">输出电压(V)</th>
<th align="center">标称电流(A)</th>
<th align="center">输出电流(A)</th>
<th align="center">输入电流(A)</th>
<th align="center">效率</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">空载</td>
<td align="center">6.76</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
<td align="center">-</td>
</tr>
<tr>
<td align="center">6U1</td>
<td align="center">6.20</td>
<td align="center">0.30</td>
<td align="center">0.32</td>
<td align="center">0.46</td>
<td align="center">86%</td>
</tr>
<tr>
<td align="center">6N2</td>
<td align="center">6.19</td>
<td align="center">0.34</td>
<td align="center">0.33</td>
<td align="center">0.48</td>
<td align="center">85%</td>
</tr>
<tr>
<td align="center">6F2</td>
<td align="center">6.17</td>
<td align="center">0.45</td>
<td align="center">0.43</td>
<td align="center">0.61</td>
<td align="center">87%</td>
</tr>
<tr>
<td align="center">6P1</td>
<td align="center">6.15</td>
<td align="center">0.50</td>
<td align="center">0.50</td>
<td align="center">0.73</td>
<td align="center">84%</td>
</tr>
<tr>
<td align="center">6N1</td>
<td align="center">6.12</td>
<td align="center">0.60</td>
<td align="center">0.61</td>
<td align="center">0.89</td>
<td align="center">84%</td>
</tr>
<tr>
<td align="center">6P15</td>
<td align="center">6.05</td>
<td align="center">0.76</td>
<td align="center">0.75</td>
<td align="center">1.11</td>
<td align="center">82%</td>
</tr>
<tr>
<td align="center">6F3</td>
<td align="center">6.02</td>
<td align="center">0.90</td>
<td align="center">0.92</td>
<td align="center">1.40</td>
<td align="center">79%</td>
</tr>
</tbody>
</table>
<p>素质相当高了,比34063强不少。以前用34063点6N3的灯丝,也是从5V升6.3V,效率只有60%多的样子。</p>USB温度计2010-04-07T00:00:00+08:002010-04-07T00:00:00+08:00Stavrostag:st.avros.net,2010-04-07:/articles/usb18b20.html<p>用ATMEGA8+DS18B20做了个USB接口的温度计, 插上电脑就能显示室内温度, 体积和一般的U盘差不多大.</p><p>用ATMEGA8+DS18B20做了个USB接口的温度计, 插上电脑就能显示室内温度, 体积和一般的U盘差不多大.</p>验钞笔2010-03-27T00:00:00+08:002010-03-27T00:00:00+08:00Stavrostag:st.avros.net,2010-03-27:/articles/cash_detector.html<p>拆了一支圆珠笔,粗细正好能装下一节7号锂电,利用原来的弹簧当触点。</p>
<p>笔尖的位置装了一个5mm紫外LED,串27欧电阻限流。</p>
<p>就这么简单!</p><p>拆了一支圆珠笔,粗细正好能装下一节7号锂电,利用原来的弹簧当触点。</p>
<p>笔尖的位置装了一个5mm紫外LED,串27欧电阻限流。</p>
<p>就这么简单!</p>车载充电器2010-01-18T00:00:00+08:002010-01-18T00:00:00+08:00Stavrostag:st.avros.net,2010-01-18:/articles/auto_charger.html<p>用LM2596T的标准电路搭了个12V输入/5V输出的降压变换器. 因为听说有人的点烟器座里面居然把正负极接反了, 充电器一插上就冒烟, 于是保险起见在2596的前面加了个整流桥.</p>
<p>整流二极管用B540C, 电感是在20mm磁环上绕了5T, 用LC表测了一下有40多uH, 够用了.</p>
<p>负载电阻用5.1欧 1/2瓦电阻. 这个电阻功率明显不够, 于是用长线把它接出来放进水盆里, 应该安全了.</p>
<p>一个负载电阻时, 输出电压5.00V, 电流0.98A, 输入电压12.0V, 电流0.55A. 两个电阻时输出5.00V 1.96A, 输入电流达到了1.12A.</p>
<p>测了一下2596输入端的电压居然只有10V多一点了, 看来桥还是挺影响效率的, 以后得换个肖特基桥.</p>
<p>按说2596的最大输出电流能达到3A, 但是不知道为什么, 三个电阻时电路就保护了, 试了几次都一样. 幸好2A也够用了.</p><p>用LM2596T的标准电路搭了个12V输入/5V输出的降压变换器. 因为听说有人的点烟器座里面居然把正负极接反了, 充电器一插上就冒烟, 于是保险起见在2596的前面加了个整流桥.</p>
<p>整流二极管用B540C, 电感是在20mm磁环上绕了5T, 用LC表测了一下有40多uH, 够用了.</p>
<p>负载电阻用5.1欧 1/2瓦电阻. 这个电阻功率明显不够, 于是用长线把它接出来放进水盆里, 应该安全了.</p>
<p>一个负载电阻时, 输出电压5.00V, 电流0.98A, 输入电压12.0V, 电流0.55A. 两个电阻时输出5.00V 1.96A, 输入电流达到了1.12A.</p>
<p>测了一下2596输入端的电压居然只有10V多一点了, 看来桥还是挺影响效率的, 以后得换个肖特基桥.</p>
<p>按说2596的最大输出电流能达到3A, 但是不知道为什么, 三个电阻时电路就保护了, 试了几次都一样. 幸好2A也够用了.</p>改造AM中周2010-01-18T00:00:00+08:002010-01-18T00:00:00+08:00Stavrostag:st.avros.net,2010-01-18:/articles/ift_mod.html<p>FCZ 的许多无线电制作资料上都用了他们自制的线圈, 这些线圈估计是很难买到的. 幸好查到了它们的绕制数据:</p>
<table>
<thead>
<tr>
<th align="center">型号</th>
<th align="center">频率(MHz)</th>
<th align="center">谐振电容(pF)</th>
<th align="center">电感(μH)</th>
<th align="center">空载Q值</th>
<th align="center">4~6脚匝数</th>
<th align="center">3~1脚匝数</th>
<th align="center">3~2脚匝数</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">FCZ3.5</td>
<td align="center">3.5</td>
<td align="center">220</td>
<td align="center">9.4</td>
<td align="center">70</td>
<td align="center">7</td>
<td align="center">20</td>
<td align="center">10</td>
</tr>
<tr>
<td align="center">FCZ7</td>
<td align="center">7</td>
<td align="center">120</td>
<td align="center">4.6</td>
<td align="center">80</td>
<td align="center">5</td>
<td align="center">14</td>
<td align="center">7</td>
</tr>
<tr>
<td align="center">FCZ14</td>
<td align="center">14</td>
<td align="center">70</td>
<td align="center">1.85</td>
<td align="center">75</td>
<td align="center">4</td>
<td align="center">12</td>
<td align="center">6</td>
</tr>
<tr>
<td align="center">FCZ21</td>
<td align="center">21</td>
<td align="center">40 …</td></tr></tbody></table><p>FCZ 的许多无线电制作资料上都用了他们自制的线圈, 这些线圈估计是很难买到的. 幸好查到了它们的绕制数据:</p>
<table>
<thead>
<tr>
<th align="center">型号</th>
<th align="center">频率(MHz)</th>
<th align="center">谐振电容(pF)</th>
<th align="center">电感(μH)</th>
<th align="center">空载Q值</th>
<th align="center">4~6脚匝数</th>
<th align="center">3~1脚匝数</th>
<th align="center">3~2脚匝数</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center">FCZ3.5</td>
<td align="center">3.5</td>
<td align="center">220</td>
<td align="center">9.4</td>
<td align="center">70</td>
<td align="center">7</td>
<td align="center">20</td>
<td align="center">10</td>
</tr>
<tr>
<td align="center">FCZ7</td>
<td align="center">7</td>
<td align="center">120</td>
<td align="center">4.6</td>
<td align="center">80</td>
<td align="center">5</td>
<td align="center">14</td>
<td align="center">7</td>
</tr>
<tr>
<td align="center">FCZ14</td>
<td align="center">14</td>
<td align="center">70</td>
<td align="center">1.85</td>
<td align="center">75</td>
<td align="center">4</td>
<td align="center">12</td>
<td align="center">6</td>
</tr>
<tr>
<td align="center">FCZ21</td>
<td align="center">21</td>
<td align="center">40</td>
<td align="center">1.45</td>
<td align="center">95</td>
<td align="center">3</td>
<td align="center">10</td>
<td align="center">5</td>
</tr>
<tr>
<td align="center">FCZ28</td>
<td align="center">28</td>
<td align="center">30</td>
<td align="center">1.1</td>
<td align="center">90</td>
<td align="center">3</td>
<td align="center">8</td>
<td align="center">4</td>
</tr>
<tr>
<td align="center">FCZ50</td>
<td align="center">50</td>
<td align="center">15</td>
<td align="center">0.68</td>
<td align="center">100</td>
<td align="center">2</td>
<td align="center">6</td>
<td align="center">3</td>
</tr>
</tbody>
</table>
<p>其中谐振电容接在 1 和 3 脚之间, 2 是抽头. 4 和 6 是次级. 从图上看, 结构和中周是一样的, 正好手里还有几个 AM 中周, 于是决定先改一个 7MHz 的试试.</p>
<p>手里只有 82p 和 330p 的电容, 这样如果用 82p 的电容谐振在 7MHz 左右的话, 电感量应该是 6uH, 相应的匝数是 16T 左右. 改好用 LC 表测了一下, 差不多是 6uH.</p>
<p>前段时间买了 MC1648, 接上改好的线圈, 配 82p 电容, 接上频率计. 磁芯全部旋进时是 6.7MHz 左右, 全部旋出是 7.6MHz 左右, 差不多.</p>
<p>其他规格的估计也可以照样改绕, 不过 AM 中周的磁芯可能不合适了, 可以找 FM 中周和电视中周试试.</p>MC1648+1SV149VCO实验2010-01-18T00:00:00+08:002010-01-18T00:00:00+08:00Stavrostag:st.avros.net,2010-01-18:/articles/mc1648_1sv149_vco.html<p>以前搭过Colpitts和Hartley式的VCO, 但是频率覆盖总是只有2倍, 可能的原因是1SV149只能部分接入LC槽路, 接入多了反馈就少. MC1648是负阻振荡器, 在这一点上不受限制.</p>
<p>把82p电容换成1SV149, 再试, 还是只能从2.7MHz调到5.1MHz.</p>
<p>检查了一下各点的电压情况, 原来是MC1648的槽路有+1.5V左右的偏压, 这样在5V供电时1SV149只有3.5V的电压区间可以利用了, 反向电压1V以下不算的话, 只有2.5V了, 频率覆盖不够也算正常.</p>
<p>于是接上辅助电源, 可以从2.7MHz调到11.9MHz了, 但是1SV149的反向电压才6.5V. 反向电压1V时的频率是3.3MHz左右, 频率覆盖有3倍多, 还是不能算满意.</p>
<p>检查了一下电路没有问题, 看来是频率计到上限了. 于是把线圈的磁芯全部旋进, 这样可以从2.0MHz调到9.6MHz, 反向电压1V时的频率是2.7MHz, 差不多也还是3.5倍的频率覆盖, 估计勉强能做到从455kHz到1600kHz了.</p><p>以前搭过Colpitts和Hartley式的VCO, 但是频率覆盖总是只有2倍, 可能的原因是1SV149只能部分接入LC槽路, 接入多了反馈就少. MC1648是负阻振荡器, 在这一点上不受限制.</p>
<p>把82p电容换成1SV149, 再试, 还是只能从2.7MHz调到5.1MHz.</p>
<p>检查了一下各点的电压情况, 原来是MC1648的槽路有+1.5V左右的偏压, 这样在5V供电时1SV149只有3.5V的电压区间可以利用了, 反向电压1V以下不算的话, 只有2.5V了, 频率覆盖不够也算正常.</p>
<p>于是接上辅助电源, 可以从2.7MHz调到11.9MHz了, 但是1SV149的反向电压才6.5V. 反向电压1V时的频率是3.3MHz左右, 频率覆盖有3倍多, 还是不能算满意.</p>
<p>检查了一下电路没有问题, 看来是频率计到上限了. 于是把线圈的磁芯全部旋进, 这样可以从2.0MHz调到9.6MHz, 反向电压1V时的频率是2.7MHz, 差不多也还是3.5倍的频率覆盖, 估计勉强能做到从455kHz到1600kHz了.</p>34063扩流实验的一些结果2009-12-30T00:00:00+08:002009-12-30T00:00:00+08:00Stavrostag:st.avros.net,2009-12-30:/articles/34063_ext_1.html<p>34063做buck的效率是相当低的, 手册上给出的83.7%的效率是在输入25V, 输出5V的条件下测到的. 以前我自己实验的结果是, 输入12V, 输出6V左右时效率只有60%多, 比线性稳压高不了多少. 因为是用达林顿管接成OC或OE开关, 没法直接驱动外接MOSFET.</p>
<p>fdisk手里的一个路由器板, 3.3V供电是从5V buck降压得到的, 而且居然是用的34063. 5V降到3.3V如果用的是LDO, 那么效率就是66%, 可见这里效率一定远比66%高;于是和fdisk, sunzx一起把这部分电路抄了下来.</p>
<p>基本原理: 34063内部开关管导通时, Q1关断, PFET栅极通过二极管D1被拉低导通;34063内部开关管关断时, Q1导通, PFET栅极拉高关断. 从而实现了利用外置MOSFET扩流. sunzx紧接着找到一个类似原理的boost升压电路, 换成了PNP管和NFET.</p>
<p>照这两个电路接了一下, buck电路使用2SC945和MTD2955, 结果是输入5V 0.24A, 输出3.2V 0.29A, 效率大约77%;boost电路使用2SA733和MTD3055, 12V升29V效率只有52%了, 输入电压5V时则不能工作;换用导通电压很低的IRLML2502, 还是不能工作 …</p><p>34063做buck的效率是相当低的, 手册上给出的83.7%的效率是在输入25V, 输出5V的条件下测到的. 以前我自己实验的结果是, 输入12V, 输出6V左右时效率只有60%多, 比线性稳压高不了多少. 因为是用达林顿管接成OC或OE开关, 没法直接驱动外接MOSFET.</p>
<p>fdisk手里的一个路由器板, 3.3V供电是从5V buck降压得到的, 而且居然是用的34063. 5V降到3.3V如果用的是LDO, 那么效率就是66%, 可见这里效率一定远比66%高;于是和fdisk, sunzx一起把这部分电路抄了下来.</p>
<p>基本原理: 34063内部开关管导通时, Q1关断, PFET栅极通过二极管D1被拉低导通;34063内部开关管关断时, Q1导通, PFET栅极拉高关断. 从而实现了利用外置MOSFET扩流. sunzx紧接着找到一个类似原理的boost升压电路, 换成了PNP管和NFET.</p>
<p>照这两个电路接了一下, buck电路使用2SC945和MTD2955, 结果是输入5V 0.24A, 输出3.2V 0.29A, 效率大约77%;boost电路使用2SA733和MTD3055, 12V升29V效率只有52%了, 输入电压5V时则不能工作;换用导通电压很低的IRLML2502, 还是不能工作, 从示波器上看栅极波形, 根本不能关断. 两个电路的结果都不理想.</p>
<p>大概分析了一下: 主要的问题应该在MTD2955和3055这两个管子上. 在VGS=10V时, 两者的RDS(on)分别是0.23Ω和0.18Ω, 相比之下, fdisk路由器板上使用的MMSF7P03, RDS(on)只有35mΩ. 这个buck电路改用低导通电阻的管子应该会好些. 至于boost电路, 在输入电压较低时, 34063内部开关管和二极管D4上的压降使得MTD3055还不能完全导通;换用IRLML2502之后, 它的导通电压低了, 但是不能饱和导通的Q4使得IRLML2502没法关断. 因此这个boost电路在输入电压较低(3.3V到5V)时不能用, 而输入电压再高些的时候则有性能高得多的UC3843可用, 看来它的实用价值不大了.</p>
<p>下一步考虑换个低导通电阻的MOSFET比如AO4419, 再试一下buck电路的性能, 应该还是有潜力的.</p>土绕线机2009-11-01T00:00:00+08:002009-11-01T00:00:00+08:00Stavrostag:st.avros.net,2009-11-01:/articles/winding_machine.html<p>本来是个PWM调电机转速的板子, 做多了几块, 于是改造了一下. 用M48的INT0口数圈数, 在电机接轴器上粘了一块磁铁, 用A3144检测.
电机是300转的减速电机.</p>
<p>两个按键, 其中一个按了转100圈, 另一个键是10圈.</p>
<p>用来绕变压器很方便.</p><p>本来是个PWM调电机转速的板子, 做多了几块, 于是改造了一下. 用M48的INT0口数圈数, 在电机接轴器上粘了一块磁铁, 用A3144检测.
电机是300转的减速电机.</p>
<p>两个按键, 其中一个按了转100圈, 另一个键是10圈.</p>
<p>用来绕变压器很方便.</p>频率计2009-10-15T00:00:00+08:002009-10-15T00:00:00+08:00Stavrostag:st.avros.net,2009-10-15:/articles/freqmeter.html<p>输入信号经 K246 共源缓冲, 直耦到 C1959 放大, 74HC04 整形后通过另一只作为闸门的 C1959, 由 74HC393 和 Mega8 的 T1 计数器一起计数. 理论能测到 224=16.777216MHz.</p>
<p>电路如图:</p>
<p><a href="/images/freqmeter.png" title="电路图"><img src="/images/freqmeter.png" width="500px" /></a></p><p>输入信号经 K246 共源缓冲, 直耦到 C1959 放大, 74HC04 整形后通过另一只作为闸门的 C1959, 由 74HC393 和 Mega8 的 T1 计数器一起计数. 理论能测到 224=16.777216MHz.</p>
<p>电路如图:</p>
<p><a href="/images/freqmeter.png" title="电路图"><img src="/images/freqmeter.png" width="500px" /></a></p>继续试验升压开关电源2009-08-19T00:00:00+08:002009-08-19T00:00:00+08:00Stavrostag:st.avros.net,2009-08-19:/articles/step_up_expr_2.html<p>用UC3843搭flyback实现了输入18V, 输出220V左右点亮25W灯泡. 变压器使用EE25.4磁心.</p>
<p>用MAX1771轻易实现单节18650升压输出5V 1A, 估计有输出5V 2A的潜力. Maxim的东西到底靠谱.</p>
<p>LM2577搭flyback实现单节14500锂电升压输出60V, 输出6-13mA时效率大约在50%上下, 一般般吧. 同时线性降压输出1.2V.</p>
<p>BL8530、PT1301等从1AA升到5V有点力不从心, 感觉还是从1AA升到2.5V/3.3V, 从2AA或单锂电升到5V比较合适.</p><p>用UC3843搭flyback实现了输入18V, 输出220V左右点亮25W灯泡. 变压器使用EE25.4磁心.</p>
<p>用MAX1771轻易实现单节18650升压输出5V 1A, 估计有输出5V 2A的潜力. Maxim的东西到底靠谱.</p>
<p>LM2577搭flyback实现单节14500锂电升压输出60V, 输出6-13mA时效率大约在50%上下, 一般般吧. 同时线性降压输出1.2V.</p>
<p>BL8530、PT1301等从1AA升到5V有点力不从心, 感觉还是从1AA升到2.5V/3.3V, 从2AA或单锂电升到5V比较合适.</p>最近试验各种升压电路的一些结果2009-05-10T00:00:00+08:002009-05-10T00:00:00+08:00Stavrostag:st.avros.net,2009-05-10:/articles/step_up_expr.html<ol>
<li>
<p>MC34063:
限制最高升到40V, 实际试验可以升到60V左右. 外接2N5551大约能升至85V (输入电压12V), 只能输出10mA左右的电流. 由于占空比的限制, 很难升到更高了.</p>
</li>
<li>
<p>NE555+IRFR420:
输入12V, 输出空载时可升到220V以上, 但接上负载后输出电压就急剧跌落. 用220V 5W灯泡作负载时, 大约能输出110V左右; 将输入电压提高到24V时能得到输出160V 30mA的结果, 效率50%左右.</p>
</li>
<li>
<p>UC3843+IRF740:
与NE555+IRFR420的结果基本相同, 输出稍硬一些.</p>
</li>
<li>
<p>级联UC3843 boost:
前级将18V升压至55V, 后级从55V升压至约210V. 用5W灯泡能稳定输出210V, 加大负载后电压跌落, 最好成绩是将输入电压提高到24V后, 输出150V/90mA, 不过效率只有大概56%.</p>
</li>
</ol>
<p>总结: 似乎使用简单的boost很难做到输出200V/100mA以上, 还是得用反激、半桥或者全桥变换器才行。下一步先用MC34063接成反激式,用一个小磁环试试看,如果好用再换LM2577+E字磁芯。</p>
<p>ps, 用LM2596接成inverter时,启动瞬间需要4.5A的电流,所以延迟启动一定不能省,并且需要较大的输入电容 …</p><ol>
<li>
<p>MC34063:
限制最高升到40V, 实际试验可以升到60V左右. 外接2N5551大约能升至85V (输入电压12V), 只能输出10mA左右的电流. 由于占空比的限制, 很难升到更高了.</p>
</li>
<li>
<p>NE555+IRFR420:
输入12V, 输出空载时可升到220V以上, 但接上负载后输出电压就急剧跌落. 用220V 5W灯泡作负载时, 大约能输出110V左右; 将输入电压提高到24V时能得到输出160V 30mA的结果, 效率50%左右.</p>
</li>
<li>
<p>UC3843+IRF740:
与NE555+IRFR420的结果基本相同, 输出稍硬一些.</p>
</li>
<li>
<p>级联UC3843 boost:
前级将18V升压至55V, 后级从55V升压至约210V. 用5W灯泡能稳定输出210V, 加大负载后电压跌落, 最好成绩是将输入电压提高到24V后, 输出150V/90mA, 不过效率只有大概56%.</p>
</li>
</ol>
<p>总结: 似乎使用简单的boost很难做到输出200V/100mA以上, 还是得用反激、半桥或者全桥变换器才行。下一步先用MC34063接成反激式,用一个小磁环试试看,如果好用再换LM2577+E字磁芯。</p>
<p>ps, 用LM2596接成inverter时,启动瞬间需要4.5A的电流,所以延迟启动一定不能省,并且需要较大的输入电容。</p>
<p>用MC34063做inverter的效率则相当低,输入12V,输出-9V时大概只有50%的效率。看来要得到正负电压还是用反激式容易些。</p>分压电阻计算器2009-02-08T00:00:00+08:002009-02-08T00:00:00+08:00Stavrostag:st.avros.net,2009-02-08:/articles/res_divider.html<p>写了个计算DC-DC电路输出分压电阻的小工具, 如图.</p>
<p><a href="/images/res_divider.png" title="截图"><img src="/images/res_divider.png" height="300px" /></a></p>
<p>输入所需要的电压和FB端参考电压, 它就自动计算出所需要的电阻值和误差, 电阻全部用5%精度的E24序列.</p>
<p>下载链接:</p>
<p><a href="/files/calc.zip">calc.zip</a></p><p>写了个计算DC-DC电路输出分压电阻的小工具, 如图.</p>
<p><a href="/images/res_divider.png" title="截图"><img src="/images/res_divider.png" height="300px" /></a></p>
<p>输入所需要的电压和FB端参考电压, 它就自动计算出所需要的电阻值和误差, 电阻全部用5%精度的E24序列.</p>
<p>下载链接:</p>
<p><a href="/files/calc.zip">calc.zip</a></p>