|
这是我大概一年前就设想的一个作品,在刚刚实验试制感光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……这里报废了一块板子 ,原因很悲剧,仔细看图能发现异样的。
幸好是做了两块板,还有一块继续用。焊好两只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[16]={
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[hb]);
debug_byte(tab[lb]);
}
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[10];
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 编辑 ] |
评分
-
2
查看全部评分
-
|