Ось програма, не судіть строго...в програмуванні не сяю) частини програм брав з різних готових проектів, складав все в кучу і підганяв під себе і Attiny):
Code: Select all
#include <util/delay.h>
#include <avr/interrupt.h>
#include <avr/io.h>
#include <util/atomic.h>
#include <avr/wdt.h>
uint8_t a;
uint8_t ROM[ 2 ];
int temp,dig0,dig1,dig2,dig3,temp1;
#define PShift PB2 // сдвиг
#define PData PB0 // данные
#define PLatch PB1 // вывод
#define bit_set(p,m) ((p) |= (m))
#define bit_clear(p,m) ((p) &= ~(m))
#define bit_write(c,p,m) (c ? bit_set(p,m) : bit_clear(p,m))
#define BIT(x) (0x01 << (x))
#define STROBE(p) bit_set(PORTB,BIT(p)); bit_clear(PORTB,BIT(p));
#define write_port_bit(data) bit_write(data & 1, PORTB, BIT(PData)); STROBE(PShift);
#define OneWire_setPinAsOutput DDRB |= (1<<PB4)
#define OneWire_setPinAsInput DDRB &= ~(1<<PB4)
#define OneWire_writePinLOW PORTB &= ~(1<<PB4)
#define OneWire_writePinHIGH PORTB |= (1<<PB4)
#define OneWire_readPin ( ( PINB & (1<<PB4) ) ? 1 : 0 )
uint8_t sseg[] = {0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,0x01,0x09,0xFD,0xFF};
uint8_t sseg0[] = {0x02,0x9E,0x24,0x0C,0x98,0x48,0x40,0x1E,0x00,0x08};
uint8_t addr1[]= {0x28,0x6D,0xC2,0xE6,0x03,0x00,0x00,0x92};
uint8_t addr2[]= {0x28,0x38,0x07,0xB3,0x05,0x00,0x00,0x2F};
uint8_t OneWire_reset(){
uint8_t Retries = 125;
OneWire_setPinAsInput;
do{
if( --Retries == 0 ) return 0;
_delay_us( 2 );
}while( !OneWire_readPin );
OneWire_writePinLOW;
OneWire_setPinAsOutput;
_delay_us( 480 );
OneWire_setPinAsInput;
_delay_us( 70 );
uint8_t State = !OneWire_readPin;
_delay_us( 410 );
return State;
}
void OneWire_writeBit( uint8_t Bit ){
if( Bit & 1 ){
OneWire_writePinLOW;
OneWire_setPinAsOutput;
_delay_us( 10 );
OneWire_writePinHIGH;
_delay_us( 55 );
}else{
OneWire_writePinLOW;
OneWire_setPinAsOutput;
_delay_us( 65 );
OneWire_writePinHIGH;
_delay_us( 5 );
}
}
uint8_t OneWire_readBit(){
OneWire_setPinAsOutput;
OneWire_writePinLOW;
_delay_us( 3 );
OneWire_setPinAsInput;
_delay_us( 10 );
uint8_t Bit = OneWire_readPin;
_delay_us( 53 );
return Bit;
}
void OneWire_writeByte( const uint8_t Byte, uint8_t Power = 0 ){
for( uint8_t BitMask = 0x01; BitMask; BitMask <<= 1 ) OneWire_writeBit( (BitMask & Byte) ? 1 : 0 );
if( !Power ){
OneWire_setPinAsInput;
OneWire_writePinLOW;
}
}
inline uint8_t OneWire_readByte(){
uint8_t Byte = 0; // - Read all bits
for( uint8_t BitMask = 0x01; BitMask; BitMask <<= 1 ){
if( OneWire_readBit() ) Byte |= BitMask;
}
return Byte;
}
inline void OneWire_read( uint8_t * Buffer, uint8_t Size ){
for( uint8_t i = 0; i < Size; i++ ) Buffer[ i ] = OneWire_readByte();
}
inline void OneWire_write(const uint8_t * Buffer, uint8_t Size, uint8_t Power = 0 ){
for( uint8_t i = 0; i < Size; i++ ) OneWire_writeByte( Buffer[ i ] );
if( !Power ){
OneWire_setPinAsInput;
OneWire_writePinLOW;
}
}
void write_port_byte(uint8_t data) {
for (uint8_t i=0;i<8;i++) {
write_port_bit(data); data = data >> 1;
}
}
ISR(SIG_OVERFLOW0)
{
temp=temp+1;
}
SIGNAL(SIG_PIN_CHANGE0)
{
if (bit_is_set(PINB,PB3))
a=1; else a=0;
}
void lcd() {
//STROBE(PLatch);
if (dig0==0) {
write_port_byte(0xEF);
write_port_byte(0xFD);
STROBE(PLatch);
} else {
write_port_byte(0xEF);
write_port_byte(0xFF);
STROBE(PLatch);
}
if (dig1==0) {
write_port_byte(0xDF);
write_port_byte(0xFF);
STROBE(PLatch);
write_port_byte(0xBF);
write_port_byte(sseg0[dig2]);
STROBE(PLatch);
write_port_byte(0x7F);
write_port_byte(sseg[dig3]);
STROBE(PLatch);
} else {
write_port_byte(0xDF);
write_port_byte(sseg[dig1]);
STROBE(PLatch);
write_port_byte(0xBF);
write_port_byte(sseg0[dig2]);
STROBE(PLatch);
write_port_byte(0x7F);
write_port_byte(sseg[dig3]);
STROBE(PLatch);
}
}
void tempe() {
OneWire_reset();
OneWire_writeByte( 0x55, 1 );
if (a==1)
OneWire_write( addr2, sizeof( addr2 ) );
else
OneWire_write( addr1, sizeof( addr1 ) );
OneWire_writeByte( 0xBE, 1 );
OneWire_read( ROM, sizeof( ROM ) );
OneWire_reset();
OneWire_writeByte( 0xCC, 1 );
OneWire_writeByte( 0x44, 1 );
ConvTempDi();
}
void ConvTempDi()
{
unsigned int tempint;//,tempint1,tempint2,tempint3; // переменные для целого значения температуры
unsigned int temppoint,temppoint1; // переменные для дробного значения температуры
unsigned char Temp_H,Temp_L,temp_flag;
Temp_L = ROM[0]; // читаем первые 2 байта
Temp_H = ROM[1];
temp_flag = 1; // флаг знака температуры равен 1(плюс)
if(Temp_H &(1 << 3)) // проверяем бит знака температуры на равенство единице
{
signed int tmp;
temp_flag = 0; // флаг знака равен 0(минус)
tmp = (Temp_H << 8) | Temp_L;
tmp = -tmp;
Temp_L = tmp;
Temp_H = tmp >> 8; }
tempint = ((Temp_H << 4) & 0x70)|(Temp_L >> 4); // вычисляем целое значение температуры
temppoint = Temp_L & 0x0F; // вычисляем дробное значение температуры
temppoint = temppoint * 625;
temppoint1 = temppoint / 1000;
dig0 = temp_flag;
dig1 = tempint /10;
dig2 = tempint % 10;
dig3 = temppoint1;
}
int main(void) {
a=0;
DDRB = 1<<PShift|1<<PData|1<<PLatch;
PORTB &= ~(1<<PShift|1<<PLatch);
TCCR0A = 0;
TCCR0B = 0b00000101; //делитель
TIMSK0 = 0b00000010; // Разрешение прерываний по переполнению
GIMSK = 0b00100000; // Разрешение прерываний PCINTn
PCMSK = 0b00001000; // прерывание по входу PCINT1 (PB1)
sei();
while(1) {
if (temp>10){
tempe();
temp=0;}
lcd();
}
}
Але при зчитуванні температури з датчика присутнє одноразове моргання індикатора.
Можливо хтось побачить помилку в програмі і підскаже) бо я щось не можу її знайти) на мою думку це якесь переприсвоєння при спілкуванні з датчиком, або проблема в самому контролері (можливо він не справляється). Але більше всього це я не справляюсь з ним)) Допоможіть, кому не складно) Дякую!)