迷你LED数显气温计
这是我大概一年前就设想的一个作品,在刚刚实验试制感光PCB成功后,终于得以完成。元件选用是需要消耗以前囤积的直插器件(以后新设计和采购将以贴片为主了),所以是直插和贴片的混用。数码管是几年前从郑州东明邮购的,绿色双位共阳,两个独立的7段管子。我觉得它的显示效果比在市场上买的好一点儿。单片机为ATTiny13,用74HC164静态驱动LED方案。电源用2节镍氢电池,直接电阻限流点LED,损耗还不会很大(没有3.3V更没有5V)。但是DS18B20需要3V以上的电压,所以我设想的是"倍压电路“方案。电路画出来就是这样:
ATTiny13的PB0, PB1用来串行输出给74HC164驱动数码管,PB2输出方波,与C1 C2 D2 D3 一起产生倍压。PB3是DS18B20的单线通讯接口。用D4和R4的想法是:R2端的电压高与单片机的VCC,于是会从I/O口灌入电流。加入二极管可减小这个灌入电流(此处是权宜之计)。R1是给所有LED用的限流电阻,而我没有给每个LED设独立的限流电阻(减少元件数量)。布线后的PCB图(PCB单面设计,有三处跳线):
这次做了两块PCB,都不算完美,其中一块有一处断线,另一块多处需要补刀。
这是补刀后的那块,比较难看了:
开始焊装:先装跳线
然后可以焊数码管了
接着是贴片IC……这里报废了一块板子:L ,原因很悲剧,仔细看图能发现异样的。
幸好是做了两块板,还有一块继续用。焊好两只HC164
焊其它元件
正面:单片机还在程序编写中
程序调通了之后,终于能显示温度了
整体的大致效果。电池还可以改用7号的。这已经比我当初想的要mini了。
=================================================================================
C语言源程序代码,用avr-gcc编译
#include <avr/io.h>
#include <avr/sleep.h>
#define F_CPU 2.0E6 /* 2 MHz RC */
#include <util/delay.h>
#include <stdlib.h>
inline void nop(void)
{
__asm__ volatile("nop");
}
inline void w_down(){ DDRB|=_BV(3); }
inline void w_up(){ DDRB&=~_BV(3); }
inline char w_low(){ return !(PINB&_BV(3)); }
void write_byte(unsigned char data)
{
char i;
for(i=0;i<8;i++) // LSB first
{
nop();
w_down();
nop();
if( (data &(1<<i)))
w_up();
_delay_us(60);
w_up();
nop();
}
}
char read_bit(void)
{
char r;
w_down();
nop();
w_up();
nop();
nop();
r=w_low();
_delay_us(60);
if(r)
return 0;
else
return 1;
}
char read_byte(void)
{
char i,data;
data=0;
for(i=0;i<8;i++)
{
data|=(read_bit()<<i);
}
return data;
}
void debug_byte(uint8_t b)
{
char i;
/* MSB first */
for(i=7;i>=0;i--)
{
if(b&(1<<i))
PORTB&=~_BV(0);
else
PORTB|=_BV(0);
PORTB|=_BV(2);
nop(); /* Pulse PB.0 */
PORTB&=~_BV(2);
}
}
void debug_hex(uint8_t data)
{
uint8_t hb,lb;
const char tab={
0xed, 0x28, 0xce, 0x6e, 0x2b, 0x67, 0xe7, 0x2c,
0xef, 0x6f, 0xaf, 0xe3, 0xc5, 0xea, 0xc7, 0x87
};
hb=(data>>4);
lb=data&0x0f;
debug_byte(tab);
debug_byte(tab);
}
int main (void)
{
uint8_t i=0;
DDRB=_BV(2)|_BV(1)|_BV(0);
CLKPR=_BV(CLKPCE);
CLKPR=_BV(CLKPS1);// div by 4=2M
OCR0A=160;
OCR0B=80;
TCCR0A=_BV(COM0B1)|_BV(WGM01)|_BV(WGM00);
/* Fast PWM mode, OCRA as TOP */
/* clear OC0B on match, set OC0B at TOP */
TCCR0B=_BV(CS00)|_BV(WGM02); /* no prescaler */
// TIMSK0=_BV(TOIE0); /* interrupt on overflow, 30kHz approx. */
char digit;
uint16_t fun;
for(fun=0;;fun++)
{
w_down();
_delay_us(800);
w_up();
char i;
for(i=0;i<=4;i++)
{
_delay_us(60);
if(w_low())
{
break;
}
}
_delay_us(500);
if(i>4)
{
debug_hex(0x1e);
_delay_ms(500);
continue;
}
write_byte(0xcc);/* Skip ROM command */
_delay_us(500);
if(fun%2==0)
{
write_byte(0x44);/* convert */
while(read_bit()==0);
}
else
{
unsigned char cl,ch;
uint16_t temp;
write_byte(0xbe);/* Read Scratchpad command */
cl=read_byte();
ch=read_byte();
temp=(ch<<4)|(cl>>4);
debug_hex(((temp/10)<<4)+(temp%10));
_delay_ms(8000);
}
}
for(i=0;;i++)
{
debug_hex(i);
_delay_ms(800);
}
}
=======================================
程序还需要优化,把省电模式加进去……
[ 本帖最后由 d3b7 于 2011-5-3 19:56 编辑 ] 很不错的东西,,上程序呀,,我也仿一个.. 挺不错的!ATTiny13 AVR编程设计可以用Keil C么?
回复 3# 绿洲 的帖子
鄙人没有用过Keil, 写AVR只用过AVR Studio带的汇编,和AVR-GCC(汇编和C)。下面是编译过后的HEX
:1000000009C021C020C01FC01EC01DC01CC01BC015
:100010001AC019C011241FBECFE9CDBF10E0A0E661
:10002000B0E0E0E8F2E002C005900D92A037B10721
:10003000D9F710E0A0E7B0E001C01D92A037B107EA
:10004000E1F7A0D01CC1DCCF00000895BB9A089551
:10005000BB98089586B3992723E0969587952A95AE
:10006000E1F78095909581709070089520E030E0E0
:10007000482F55270000BB9A0000CA01022E02C07B
:10008000959587950A94E2F780FDBB9884E18A955F
:10009000F1F7BB9800002F5F3F4F2830310551F733
:1000A0000895BB9A0000BB980000000096B384E15D
:1000B0008A95F1F720E093FF21E081E02827822F45
:1000C000992708951F93CF93DF9310E0C0E0D0E00D
:1000D000E8DF992787FD90950C2E02C0880F991FA5
:1000E0000A94E2F7182B2196C830D10589F7812FA1
:1000F000992787FD9095DF91CF911F91089527E073
:1001000030E0482F5527CA01022E02C095958795E9
:100110000A94E2F780FF02C0C09801C0C09AC29A58
:100120000000C298215030408FEF2F3F380759F719
:1001300008950F931F93CF93DF93CDB7DEB7219729
:100140000FB6F894DEBF0FBECDBF982F82958F708B
:1001500000E610E0F801E80FF11D80819983CFDF00
:1001600099819F70090F111DF8018081C8DF2196C8
:100170000FB6F894DEBF0FBECDBFDF91CF911F91B8
:100180000F910895CFE9D0E0DEBFCDBF87E087BBF8
:1001900080E886BD82E086BD80EA86BF80E589BDB5
:1001A00083E28FBD89E083BFC0E0D0E0BB9A88ECDA
:1001B00090E00197F1F7BB9890E084E18A95F1F720
:1001C000B39B03C09F5F9530C1F706EA802F8A95E5
:1001D000F1F7953064F08EE1ACDF28E833E189E196
:1001E00090E00197F1F72150304099F1F8CF8CEC75
:1001F0003DDF0A95F1F7C0FD06C084E437DF51DF2B
:10020000882339F5FCCF8EEB31DF5CDF082F5ADF16
:1002100002950F701127992734E0880F991F3A959E
:10022000E1F7082B192BC8016AE070E014D09B019C
:100230002295207FC8016AE070E00DD0820F79DF3F
:100240002FEF3FEF89E190E00197F1F72150304027
:10025000C9F72196ABCFAA1BBB1B51E107C0AA1F50
:10026000BB1FA617B70710F0A61BB70B881F991F57
:100270005A95A9F780959095BC01CD010895FFCFBF
:10028000ED28CE6E2B67E72CEF6FAFE3C5EAC7878B
:00000001FF 这焊接工艺,不敢恭维。 我感兴趣的是,你的印制板制作过程。 要想省电就用lcd显示屏
同时启用睡眠运行 原帖由 绿洲 于 2011-5-3 15:51 发表 http://www.crystalradio.cn/bbs/images/common/back.gif
挺不错的!ATTiny13 AVR编程设计可以用Keil C么?
Keil是给51或者ARM单片机写程序的,AVR有自己的编译器。 原帖由 伏特 于 2011-5-3 21:48 发表 http://www.crystalradio.cn/bbs/images/common/back.gif
这焊接工艺,不敢恭维。
热转印+氯化铁腐蚀的板子是没那么好处理的。
回复 9# Paktu 的帖子
的是没阻焊层? d3b7兄 一出贴 就是精品请斑竹 加精!
ps:为何不弄热转印法,呵呵 这个好给兄弟我来个现场学习。 热转印简单的很,关键你要有一台黑白激打。将PCB印图在不干胶贴纸的背纸上(黄色那种,表面很滑的),然后用适当的温度“转印”到PCB敷铜板上即可。注意的是:
①画PCB时尽量选用粗点的线经;
②激打墨粉要够黑;不干胶纸先在激打中打印一次空白内容,目的在于熨平它;
③PCB敷铜板清洁处理彻底;
④转印温度适中,大约在180℃左右;
⑤等温度降低后再揭纸;
⑥用油漆笔修补断线部份。:victory: led测温要校准的。 LZ这个 是先用编程器下载,然后再把单片机取下放到电路板上的DIP插座 看效果,
然后再调整程序 再下载,再验证。。
是这样过程把? 文章写得不错,有几个问题能否指教:请问显示出的温度需要标定么?据说每个DS18B20都内嵌独立的ID,那该系统是否可以同时并联多个DS18B20呢?显示温度的精度可否提高,可提高到何程度?分辨率最大能为多少?十分感谢。