Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.137.192.3] |
|
Сообщ.
#1
,
|
|
|
Всем привет!
Нужен мне термостат для роутера - читать температуру и выдавать ШИМ на вентилятор. На ардуине все сделал за пару минут, но хочется сделать именно на Tiny13 =) Примеры и либы что нашел в инете либо почему-то не работают, либо не помещаются в 13-шку Велосипедить не хочется. Скиньте пожалуйста рабочий пример/библиотеку для работы с 1-wire на С++. Если конкретно - то чтение с DS18B20 на Tiny13. |
Сообщ.
#2
,
|
|
|
Вобщем, в итоге навелосипедил) Только в тиньку 13-ю код не помещается =((( нужно жестко оптимайзить.
|
Сообщ.
#3
,
|
|
|
Поботал даташиты и победил таки 1-Wire на тиньке =)
Может кому пригодится. Тест для ATTiny13 на 1 датчик DS18B20. Пример читает температуру с датчика и если она выше 40 градусов - запускает PWM (например вентилятор). Размер кода - 592 байта. Впринципе помещается даже с функцией поиска всех устройств на шине и с выбором нужного устройства. Но в этом примере для простоты сделана работа только с одним датчиком. #include <inttypes.h> #include <string.h> #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> // --- Configuration for OneWire #define ONEWIRE_PORTReg PORTB #define ONEWIRE_DDRReg DDRB #define ONEWIRE_PINReg PINB #define ONEWIRE_PIN PB0 // --- Configure for PWM #define PWM_PORTReg PORTB #define PWM_DDRReg DDRB #define PWM_PIN PB1 // - Set OneWire pin in Output mode #define OneWire_setPinAsOutput ONEWIRE_DDRReg |= (1<<ONEWIRE_PIN) // - Set OneWire pin in Input mode #define OneWire_setPinAsInput ONEWIRE_DDRReg &= ~(1<<ONEWIRE_PIN) // - Set LOW level on OneWire pin #define OneWire_writePinLOW ONEWIRE_PORTReg &= ~(1<<ONEWIRE_PIN) // - Set HIGH level on OneWire pin #define OneWire_writePinHIGH ONEWIRE_PORTReg |= (1<<ONEWIRE_PIN) // - Read level from OneWire pin #define OneWire_readPin ( ( ONEWIRE_PINReg & (1<<ONEWIRE_PIN) ) ? 1 : 0 ) // - PWM Value ( 0 - off, 255 - max ) uint8_t PWMValue = 0; // - Oveflow counter for PWM uint8_t PWMCounter = 0; uint8_t PWM = 0; //! Calculate CRC-8 uint8_t crc8(const uint8_t * addr, uint8_t len){ uint8_t crc = 0; while (len--) { uint8_t inbyte = *addr++; for (uint8_t i = 8; i; i--) { uint8_t mix = (crc ^ inbyte) & 0x01; crc >>= 1; if (mix) crc ^= 0x8C; inbyte >>= 1; } } return crc; } //! Reset function uint8_t OneWire_reset(){ // - Wait for line uint8_t Retries = 125; OneWire_setPinAsInput; do{ if( --Retries == 0 ) return 0; _delay_us( 2 ); }while( !OneWire_readPin ); // - Drop line OneWire_writePinLOW; OneWire_setPinAsOutput; _delay_us( 480 ); // - Listen for reply pulse OneWire_setPinAsInput; _delay_us( 70 ); // - Read line state uint8_t State = !OneWire_readPin; _delay_us( 410 ); return State; } //! Write single bit void OneWire_writeBit( uint8_t Bit ){ if( Bit & 1 ){ // - Drop line OneWire_writePinLOW; OneWire_setPinAsOutput; // - Write Bit-1 _delay_us( 10 ); OneWire_writePinHIGH; _delay_us( 55 ); }else{ // - Drop line OneWire_writePinLOW; OneWire_setPinAsOutput; // - Write Bit-0 _delay_us( 65 ); OneWire_writePinHIGH; _delay_us( 5 ); } } //! Read single bit uint8_t OneWire_readBit(){ // - Drop line OneWire_setPinAsOutput; OneWire_writePinLOW; _delay_us( 3 ); // - Wait for data OneWire_setPinAsInput; _delay_us( 10 ); // - Read bit into byte uint8_t Bit = OneWire_readPin; _delay_us( 53 ); return Bit; } //! Write byte void OneWire_writeByte( const uint8_t Byte, uint8_t Power = 0 ){ // - Write each bit for( uint8_t BitMask = 0x01; BitMask; BitMask <<= 1 ) OneWire_writeBit( (BitMask & Byte) ? 1 : 0 ); // - Disable power if( !Power ){ OneWire_setPinAsInput; OneWire_writePinLOW; } } //! Read byte inline uint8_t OneWire_readByte(){ uint8_t Byte = 0; // - Read all bits for( uint8_t BitMask = 0x01; BitMask; BitMask <<= 1 ){ // - Read & store bit into byte if( OneWire_readBit() ) Byte |= BitMask; } return Byte; } //! Read buffer inline void OneWire_read( uint8_t * Buffer, uint8_t Size ){ for( uint8_t i = 0; i < Size; i++ ) Buffer[ i ] = OneWire_readByte(); } //! Write buffer 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 ){ // - Disable power OneWire_setPinAsInput; OneWire_writePinLOW; } } //! Main function int main() { // - Configure PWM pin DDRB |= ( 1 << PB1 ); // - Configure timer for PWM TIMSK0 = 0b00000010; TCCR0B = 0b00000001; // - Allow interrupts sei(); // - Buffer for ROM uint8_t ROM[ 9 ]; while( 1 ){ // - Prepare for new cycle _delay_ms( 1000 ); memset( ROM, 0, sizeof( ROM ) ); // - Start conversion OneWire_reset(); OneWire_writeByte( 0xCC, 1 ); OneWire_writeByte( 0x44, 1 ); // - Wait until conversion finished _delay_ms( 1000 ); // - Read ROM OneWire_reset(); OneWire_writeByte( 0xCC, 1 ); OneWire_writeByte( 0xBE, 1 ); OneWire_read( ROM, sizeof( ROM ) ); // - Check ROM CRC if( crc8( ROM, 8 ) != ROM[ 8 ] ){ PWMValue = 0; continue; } // --- Get 8-bit temperature // - Construct 16-bit register value from 0 and 1 bytes of ROM. // - Remove float part (4 right bits) to get interger value uint8_t Temperature = ((( ROM[ 1 ] << 8 ) | ROM[ 0 ]) >> 4); if( Temperature < 40 ){ PWMValue = 0; continue; } PWMValue = Temperature * 2 - 40; } } //! PWM ISR( TIM0_OVF_vect ){ // - Set PWM pin HIGH on each PWM counter overflow if( ++PWMCounter == 0 ){ PWM = PWMValue; PORTB |= (1<<PB1); } // - Set PWM pin LOW when PWM counter == PWMValue if( PWMCounter == PWM ) PORTB &= ~(1<<PB1); } Добавлено Тайминги взяты из 1-Wire библиотеки для Arduino как вероятно, настроенные на практике. Тайминге по даташитам как-то не очень работают =) |
Сообщ.
#4
,
|
|
|
Ну могу дать на ассемблере
Прикреплённый файл1_wire.rar (6,9 Кбайт, скачиваний: 747) |
Сообщ.
#5
,
|
|
|
Цитата HardRock @ Поботал даташиты и победил таки 1-Wire на тиньке =) Может кому пригодится. Тест для ATTiny13 на 1 датчик DS18B20. Пример читает температуру с датчика и если она выше 40 градусов - запускает PWM (например вентилятор). Размер кода - 592 байта. Впринципе помещается даже с функцией поиска всех устройств на шине и с выбором нужного устройства. Но в этом примере для простоты сделана работа только с одним датчиком. #include <inttypes.h> #include <string.h> #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> // --- Configuration for OneWire #define ONEWIRE_PORTReg PORTB #define ONEWIRE_DDRReg DDRB #define ONEWIRE_PINReg PINB #define ONEWIRE_PIN PB0 // --- Configure for PWM #define PWM_PORTReg PORTB #define PWM_DDRReg DDRB #define PWM_PIN PB1 // - Set OneWire pin in Output mode #define OneWire_setPinAsOutput ONEWIRE_DDRReg |= (1<<ONEWIRE_PIN) // - Set OneWire pin in Input mode #define OneWire_setPinAsInput ONEWIRE_DDRReg &= ~(1<<ONEWIRE_PIN) // - Set LOW level on OneWire pin #define OneWire_writePinLOW ONEWIRE_PORTReg &= ~(1<<ONEWIRE_PIN) // - Set HIGH level on OneWire pin #define OneWire_writePinHIGH ONEWIRE_PORTReg |= (1<<ONEWIRE_PIN) // - Read level from OneWire pin #define OneWire_readPin ( ( ONEWIRE_PINReg & (1<<ONEWIRE_PIN) ) ? 1 : 0 ) // - PWM Value ( 0 - off, 255 - max ) uint8_t PWMValue = 0; // - Oveflow counter for PWM uint8_t PWMCounter = 0; uint8_t PWM = 0; //! Calculate CRC-8 uint8_t crc8(const uint8_t * addr, uint8_t len){ uint8_t crc = 0; while (len--) { uint8_t inbyte = *addr++; for (uint8_t i = 8; i; i--) { uint8_t mix = (crc ^ inbyte) & 0x01; crc >>= 1; if (mix) crc ^= 0x8C; inbyte >>= 1; } } return crc; } //! Reset function uint8_t OneWire_reset(){ // - Wait for line uint8_t Retries = 125; OneWire_setPinAsInput; do{ if( --Retries == 0 ) return 0; _delay_us( 2 ); }while( !OneWire_readPin ); // - Drop line OneWire_writePinLOW; OneWire_setPinAsOutput; _delay_us( 480 ); // - Listen for reply pulse OneWire_setPinAsInput; _delay_us( 70 ); // - Read line state uint8_t State = !OneWire_readPin; _delay_us( 410 ); return State; } //! Write single bit void OneWire_writeBit( uint8_t Bit ){ if( Bit & 1 ){ // - Drop line OneWire_writePinLOW; OneWire_setPinAsOutput; // - Write Bit-1 _delay_us( 10 ); OneWire_writePinHIGH; _delay_us( 55 ); }else{ // - Drop line OneWire_writePinLOW; OneWire_setPinAsOutput; // - Write Bit-0 _delay_us( 65 ); OneWire_writePinHIGH; _delay_us( 5 ); } } //! Read single bit uint8_t OneWire_readBit(){ // - Drop line OneWire_setPinAsOutput; OneWire_writePinLOW; _delay_us( 3 ); // - Wait for data OneWire_setPinAsInput; _delay_us( 10 ); // - Read bit into byte uint8_t Bit = OneWire_readPin; _delay_us( 53 ); return Bit; } //! Write byte void OneWire_writeByte( const uint8_t Byte, uint8_t Power = 0 ){ // - Write each bit for( uint8_t BitMask = 0x01; BitMask; BitMask <<= 1 ) OneWire_writeBit( (BitMask & Byte) ? 1 : 0 ); // - Disable power if( !Power ){ OneWire_setPinAsInput; OneWire_writePinLOW; } } //! Read byte inline uint8_t OneWire_readByte(){ uint8_t Byte = 0; // - Read all bits for( uint8_t BitMask = 0x01; BitMask; BitMask <<= 1 ){ // - Read & store bit into byte if( OneWire_readBit() ) Byte |= BitMask; } return Byte; } //! Read buffer inline void OneWire_read( uint8_t * Buffer, uint8_t Size ){ for( uint8_t i = 0; i < Size; i++ ) Buffer[ i ] = OneWire_readByte(); } //! Write buffer 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 ){ // - Disable power OneWire_setPinAsInput; OneWire_writePinLOW; } } //! Main function int main() { // - Configure PWM pin DDRB |= ( 1 << PB1 ); // - Configure timer for PWM TIMSK0 = 0b00000010; TCCR0B = 0b00000001; // - Allow interrupts sei(); // - Buffer for ROM uint8_t ROM[ 9 ]; while( 1 ){ // - Prepare for new cycle _delay_ms( 1000 ); memset( ROM, 0, sizeof( ROM ) ); // - Start conversion OneWire_reset(); OneWire_writeByte( 0xCC, 1 ); OneWire_writeByte( 0x44, 1 ); // - Wait until conversion finished _delay_ms( 1000 ); // - Read ROM OneWire_reset(); OneWire_writeByte( 0xCC, 1 ); OneWire_writeByte( 0xBE, 1 ); OneWire_read( ROM, sizeof( ROM ) ); // - Check ROM CRC if( crc8( ROM, 8 ) != ROM[ 8 ] ){ PWMValue = 0; continue; } // --- Get 8-bit temperature // - Construct 16-bit register value from 0 and 1 bytes of ROM. // - Remove float part (4 right bits) to get interger value uint8_t Temperature = ((( ROM[ 1 ] << 8 ) | ROM[ 0 ]) >> 4); if( Temperature < 40 ){ PWMValue = 0; continue; } PWMValue = Temperature * 2 - 40; } } //! PWM ISR( TIM0_OVF_vect ){ // - Set PWM pin HIGH on each PWM counter overflow if( ++PWMCounter == 0 ){ PWM = PWMValue; PORTB |= (1<<PB1); } // - Set PWM pin LOW when PWM counter == PWMValue if( PWMCounter == PWM ) PORTB &= ~(1<<PB1); } Добавлено Тайминги взяты из 1-Wire библиотеки для Arduino как вероятно, настроенные на практике. Тайминге по даташитам как-то не очень работают =) Увидел ваш вариант работы с 1-Wire, он действительно работает, попробовал для Atmega8 у вас только одна ошибка вот здесь, пропущен выделенный фрагмент Скрытый текст //! Write buffer 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 ], Power ); if( !Power ){ // - Disable power OneWire_setPinAsInput; OneWire_writePinLOW; } } |
Сообщ.
#6
,
|
|
|
Да, есть такое.
На работу это не влияет т.к. определено значение по умолчанию для этой пременной |
Сообщ.
#7
,
|
|
|
Цитата HardRock @ Да, есть такое. На работу это не влияет т.к. определено значение по умолчанию для этой пременной Просто в эту функцию OneWire_writeByte должно же передаваться 2 параметра, а передаётся только один на что компилятор и ругался. Ещё хочу спросить как оптимально полученный результат в uint8_t Temperature перевести в char для вывода на дисплей от нокии 1202, Использую библиотеку отсюда http://digitalchip.ru/podklyuchenie-disple...-2660-2760-6085 в ней есть 3 функции вывода на дисплей void nlcd_Print(char * message); void nlcd_PrintF(unsigned char * message); void nlcd_Putc(unsigned char c); пробовал в 2 первых выводить nlcd_GotoXY(0,3); // третья строка nlcd_PrintF((unsigned int)Temperature); получается абракадабра сделал так ... PWMValue = Temperature; // * 2; // - 40; buffer2[0]=PWMValue % 10; PWMValue/=10; buffer2[1]=PWMValue % 10; PWMValue/=10; buffer2[2]=PWMValue % 10; PWMValue/=10; buffer2[3]=PWMValue % 10; nlcd_GotoXY(4,4); nlcd_Putc(0x30+buffer2[3]); nlcd_GotoXY(5,4); nlcd_Putc(0x30+buffer2[2]); nlcd_GotoXY(6,4); nlcd_Putc(0x30+buffer2[1]); nlcd_GotoXY(7,4); nlcd_Putc(0x30+buffer2[0]); но как-то коряво выглядит, так как этот не соответствует теме, чтобы модератор не ругал, ответ можно в личные сообщения отправлять. |
Сообщ.
#8
,
|
|
|
Значение с датчика - это число, сколько фактически градусов цельсия. Экран принимает символы по таблице ASCII.
Для перевода в числа в строку нужно использовать функцию itoa http://www.cplusplus.com/reference/cstdlib/itoa/ Её скорее всего у тебя не будет, и то что напсал ты - это по сути та самая itoa(). которая может выглядеть как-то так: char* itoa(int val, int base){ static char buf[32] = {0}; int i = 30; for(; val && i ; --i, val /= base) buf[i] = "0123456789abcdef"[val % base]; return &buf[i+1]; } В интернете куча вариантов этой функции как "стандартных" из системных библиотек, так и альтернативных, как вариант выше. Добавлено Цитата BigallS @ Просто в эту функцию OneWire_writeByte должно же передаваться 2 параметра, а передаётся только один на что компилятор и ругался. Просто ты видимо пользуешься С компилятором, а я писал под C++, там есть значения по умолчанию. (AVR-GCC) Кстати, прошивка, которая сейчас работает на железе: #include <inttypes.h> #include <string.h> #include <avr/io.h> #include <util/delay.h> #include <avr/interrupt.h> // --- Configuration for OneWire #define ONEWIRE_PORTReg PORTB #define ONEWIRE_DDRReg DDRB #define ONEWIRE_PINReg PINB #define ONEWIRE_PIN PB0 // --- Configure for PWM (fan) #define PWM_PORTReg PORTB #define PWM_DDRReg DDRB #define PWM_PIN PB1 // - Minimal temperature to activate fan #define FAN_MIN_TEMPERATURE 40 // - Temperature for maximum fan power #define FAN_MAX_TEMPERATURE 70 // - Power, used to start fan. Must be enough to start! #define FAN_START_PWM_VALUE 200 #define FAN_START_TIME 2000 // - Minimal fan power #define FAN_MIN_POWER 60 // - Maximal fan power #define FAN_MAX_POWER 255 // - Configure for alarm #define ALARM_PORTReg PORTB #define ALARM_DDRReg DDRB #define ALARM_PIN PB2 #define ALARM_ON_MAX_ERRORS 16 #define ALARM_ON_MAX_TEMPERATURE 80 // - Set OneWire pin in Output mode #define OneWire_setPinAsOutput ONEWIRE_DDRReg |= (1<<ONEWIRE_PIN) // - Set OneWire pin in Input mode #define OneWire_setPinAsInput ONEWIRE_DDRReg &= ~(1<<ONEWIRE_PIN) // - Set LOW level on OneWire pin #define OneWire_writePinLOW ONEWIRE_PORTReg &= ~(1<<ONEWIRE_PIN) // - Set HIGH level on OneWire pin #define OneWire_writePinHIGH ONEWIRE_PORTReg |= (1<<ONEWIRE_PIN) // - Read level from OneWire pin #define OneWire_readPin ( ( ONEWIRE_PINReg & (1<<ONEWIRE_PIN) ) ? 1 : 0 ) // - Turn on alarm #define Alarm_On ALARM_PORTReg |= (1<<ALARM_PIN); // - Turn off alarm #define Alarm_Off ALARM_PORTReg &= ~(1<<ALARM_PIN); // - PWM Value ( 0 - off, 255 - max ) uint8_t PWMValue = 0; // - Oveflow counter for PWM uint8_t PWMCounter = 0; uint8_t PWM = 0; //! Calculate CRC-8 uint8_t crc8(const uint8_t * addr, uint8_t len){ uint8_t crc = 0; while (len--) { uint8_t inbyte = *addr++; for (uint8_t i = 8; i; i--) { uint8_t mix = (crc ^ inbyte) & 0x01; crc >>= 1; if (mix) crc ^= 0x8C; inbyte >>= 1; } } return crc; } //! Reset function uint8_t OneWire_reset(){ // - Wait for line uint8_t Retries = 125; OneWire_setPinAsInput; do{ if( --Retries == 0 ) return 0; _delay_us( 2 ); }while( !OneWire_readPin ); // - Drop line OneWire_writePinLOW; OneWire_setPinAsOutput; _delay_us( 480 ); // - Listen for reply pulse OneWire_setPinAsInput; _delay_us( 70 ); // - Read line state uint8_t State = !OneWire_readPin; _delay_us( 410 ); return State; } //! Write single bit void OneWire_writeBit( uint8_t Bit ){ if( Bit & 1 ){ // - Drop line OneWire_writePinLOW; OneWire_setPinAsOutput; // - Write Bit-1 _delay_us( 10 ); OneWire_writePinHIGH; _delay_us( 55 ); }else{ // - Drop line OneWire_writePinLOW; OneWire_setPinAsOutput; // - Write Bit-0 _delay_us( 65 ); OneWire_writePinHIGH; _delay_us( 5 ); } } //! Read single bit uint8_t OneWire_readBit(){ // - Drop line OneWire_setPinAsOutput; OneWire_writePinLOW; _delay_us( 3 ); // - Wait for data OneWire_setPinAsInput; _delay_us( 10 ); // - Read bit into byte uint8_t Bit = OneWire_readPin; _delay_us( 53 ); return Bit; } //! Write byte inline void OneWire_writeByte( const uint8_t Byte, uint8_t Power = 0 ){ // - Write each bit for( uint8_t BitMask = 0x01; BitMask; BitMask <<= 1 ) OneWire_writeBit( (BitMask & Byte) ? 1 : 0 ); // - Disable power if( !Power ){ OneWire_setPinAsInput; OneWire_writePinLOW; } } //! Read byte inline uint8_t OneWire_readByte(){ uint8_t Byte = 0; // - Read all bits for( uint8_t BitMask = 0x01; BitMask; BitMask <<= 1 ){ // - Read & store bit into byte if( OneWire_readBit() ) Byte |= BitMask; } return Byte; } //! Read buffer inline void OneWire_read( uint8_t * Buffer, uint8_t Size ){ for( uint8_t i = 0; i < Size; i++ ) Buffer[ i ] = OneWire_readByte(); } //! Write buffer 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 ){ // - Disable power OneWire_setPinAsInput; OneWire_writePinLOW; } } //! Map one range to another uint16_t map( uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max){ return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } //! Main function int main() { // - Configure alarm pin ALARM_DDRReg |= ( 1 << PB2 ); // - Configure PWM pin PWM_DDRReg |= ( 1 << PB1 ); // - Configure timer for PWM TIMSK0 = 0b00000010; TCCR0B = 0b00000001; // - Allow interrupts sei(); // - Buffer for ROM uint8_t ROM[ 9 ]; // - Fan state uint8_t FanState = 0; // - Error count uint8_t ErrorCount = 0; // - Main loop while( 1 ){ // - Check error count if( ErrorCount >= ALARM_ON_MAX_ERRORS ){ // - Force start fan at 100% power PWMValue = 255; FanState = 1; ErrorCount = 0; // - Turn on alarm pin Alarm_On; } // - Prepare for new cycle _delay_ms( 500 ); memset( ROM, 0, sizeof( ROM ) ); // - Start conversion if( !OneWire_reset() ){ // - Report error ErrorCount++; continue; } OneWire_writeByte( 0xCC, 1 ); OneWire_writeByte( 0x44, 1 ); // - Wait until conversion finished _delay_ms( 1000 ); // - Read ROM if( !OneWire_reset() ){ // - Report error ErrorCount++; continue; } OneWire_writeByte( 0xCC, 1 ); OneWire_writeByte( 0xBE, 1 ); OneWire_read( ROM, sizeof( ROM ) ); // - Check ROM CRC if( crc8( ROM, 8 ) != ROM[ 8 ] ){ // - Report error ErrorCount++; continue; } // ------------------------------------------------------------------ // - Reset error count & turn alarm off ErrorCount = 0; Alarm_Off; // ------------------------------------------------------------------ // --- Get 8-bit temperature // - Construct 16-bit register value from 0 and 1 bytes of ROM. // - Remove float part (4 right bits) to get interger value uint8_t Temperature = ((( ROM[ 1 ] << 8 ) | ROM[ 0 ]) >> 4 ); // - Disable fan when temperature lower than 40* celsius if( Temperature < FAN_MIN_TEMPERATURE ){ // - Stop fan PWMValue = 0; FanState = 0; continue; } // - Start fan if stopped if( !FanState ){ PWMValue = FAN_START_PWM_VALUE; _delay_ms( FAN_START_TIME ); FanState = 1; } // - Alarm if overheated if( Temperature > ALARM_ON_MAX_TEMPERATURE ){ // - Turn alarm on Alarm_On; _delay_ms( 100 ); // - Turn alarm off Alarm_Off; } // - Set fan power uint16_t Power = map( Temperature, FAN_MIN_TEMPERATURE, FAN_MAX_TEMPERATURE, FAN_MIN_POWER, FAN_MAX_POWER ); // - Limit power to max PWM if( Power > 255 ) Power = 255; // - Set fan power PWMValue = Power; } } //! PWM ISR( TIM0_OVF_vect ){ // - Set PWM pin HIGH on each PWM counter overflow if( ++PWMCounter == 0 ){ PWM = PWMValue; PWM_PORTReg |= (1<<PWM_PIN); } // - Set PWM pin LOW when PWM counter == PWMValue if( PWMCounter == PWM ) PWM_PORTReg &= ~(1<<PWM_PIN); } Добавлено Тут если нет показаний с датчика некоторе время, то вентилятор включается на полную, плюс светодиод извещает о перегреве своим миганием. Скорость вентилятора регулируется пропорционально температуре. Плюс есть "раскрутка" вентилятора при включении (иначе из остановленного состояния невозможно включить на минимальные обороты, не хватит мощности) |
Сообщ.
#9
,
|
|
|
Спасибо, по выводу строки теперь понятно.
Я пишу на Atmel Studio 6, по умолчанию проект на С. |
Сообщ.
#10
,
|
|
|
Простите, а "плюсЫ"-то где? Кроме значения параметра по умолчанию ничего другого от С++ я в этом исходнике не вижу... И есть еще пути для оптимизации - если внимательно посмотреть на картинки чтения и записи бита то можно увидеть, что две функции (чтения и записи бита) можно фактически заменить на одну "обмен битом". Аналогично и функции чтения/записи байта заменяются на одну - "обмен байтом". Для чтения передаем 0xFF и используем результат, для записи - передаем что надо и результат игнорируем.
Примерно так: uint8_t one_wire::exchange(uint8_t data) { PORTC &= ~BIT_MASK; uint8_t Counter = 8; do { bool Result = exchange_bit(data & (1<<0)); data = Result ? (data >> 1) | (1 << 7) : data >> 1; } while (--Counter); PORTC |= BIT_MASK; return data; } inline bool one_wire::exchange_bit(bool data) { DDRC |= BIT_MASK; _delay_us(7); if(data) DDRC &= ~BIT_MASK; _delay_us(8); data = PINC & BIT_MASK; _delay_us(45); DDRC &= ~BIT_MASK; _delay_us(1); return data; } |
Сообщ.
#11
,
|
|
|
...совсем маленький термостат на тиньке-26 http://arv.radioliga.com/content/view/152/44/
|