murmur 0 22 мая, 2011 Опубликовано 22 мая, 2011 (изменено) · Жалоба Коллеги, посоветуйте. Есть индикатор семисегментный о 4-х разрядах, сегменты соединены для динамической индикации. PORTD управляет сегментами, а PORTB.2-5 - разрядами. Есть датчик DS1820. Естественно, динамическая индикация должна коммутироваться постоянно. А датчик требует продолжительное время для считывания информации. ПРиведенный код заставляет его моргать, пока чтается информация с датчика. Как организовать одновременное управление индикаторои и опрос датчика? #include <mega48.h> #include <delay.h> #include <ds1820.h> #asm .equ __w1_port=8 .equ __w1_bit=1 #endasm unsigned char Temp; unsigned int interval; unsigned char DIGIT(unsigned char dig) { // 7 6 5 4 3 2 1 0 , // e d h g c a f b if (dig==0) return 0b11001111; if (dig==1) return 0b00001001; if (dig==2) return 0b11010101; if (dig==3) return 0b01011101; if (dig==4) return 0b00011011; if (dig==5) return 0b01011110; if (dig==6) return 0b11011110; if (dig==7) return 0b00001101; if (dig==8) return 0b11011111; if (dig==9) return 0b01011111; if (dig==11) return 0b00010111; else return 0x00; } /* maximum number of DS1820/DS18S20 connected to the 1 Wire bus */ #define MAX_DEVICES 8 /* DS1820/DS18S20 devices ROM code storage area */ unsigned char rom_code[MAX_DEVICES][9]; void main() { unsigned char i,j,devices; int temp; DDRD=0xFF; DDRB=0xFF; PORTD=0xFF; devices=w1_search(0xf0,rom_code); while(1) { interval++; if (interval >10000) {Temp=ds1820_temperature_10(&rom_code[0][0]);interval=0;} PORTB=0xFF; delay_us(1); PORTB.3=0; PORTD=DIGIT(0); delay_us(5); PORTD=0x00; PORTB=0xFF; delay_us(1); PORTB.4=0; PORTD=DIGIT(9)|0b00100000; delay_us(5); PORTD=0x00; PORTB=0xFF; delay_us(1); PORTB.5=0; PORTD=DIGIT(6); delay_us(5); PORTD=0x00; PORTB=0xFF; delay_us(1); PORTB.2=0; PORTD=DIGIT(11); delay_us(5); PORTD=0x00; } Изменено 22 мая, 2011 пользователем murmur Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
st232bd 0 22 мая, 2011 Опубликовано 22 мая, 2011 · Жалоба Повесте динамическую индикацию на прерывание таймера. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
murmur 0 22 мая, 2011 Опубликовано 22 мая, 2011 · Жалоба Что-то не получается... время обработки прерывания вышло 42 мкс. Не много ли? Не замусорит ли такое прерывание данные из DS1820? На какую частоту настраивать прерывание? #include <mega48.h> #include <delay.h> #include <ds1820.h> #asm .equ __w1_port=8 .equ __w1_bit=1 #endasm unsigned char Temp,temp, cur_digit; unsigned int interval; flash char DIGITS[] = { 0b11001111, 0b00001001, 0b11010101, 0b01011101, 0b00011011, 0b01011110, 0b11011110, 0b00001101, 0b11011111, 0b01011111, 0b00010111 }; /* maximum number of DS1820/DS18S20 connected to the 1 Wire bus */ #define MAX_DEVICES 8 /* DS1820/DS18S20 devices ROM code storage area */ unsigned char rom_code[MAX_DEVICES][9]; interrupt [TIM0_OVF] void timer0_ovf_isr(void) { PORTC.0=1; PORTB=0b11110111; PORTD=DIGITS[temp/10]; delay_us(1); PORTD=0x00; PORTB=0b11101111; PORTD=DIGITS[temp%10]; delay_us(1); PORTD=0x00; PORTB=0b11011111; PORTD=DIGITS[6]; delay_us(1); PORTD=0x00; PORTB=0b11111011; PORTD=DIGITS[11]; delay_us(1); PORTD=0x00; PORTC.0=0; } void main() { unsigned char i,j,devices; int temp; DDRC.0=1; DDRD=0xFF; DDRB=0xFF; PORTD=0xFF; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 8000,000 kHz // Mode: Normal top=FFh // OC0A output: Disconnected // OC0B output: Disconnected TCCR0A=0x00; TCCR0B=0x02; TCNT0=0x00; OCR0A=0x00; OCR0B=0x00; // Timer/Counter 0 Interrupt(s) initialization TIMSK0=0x01; //devices=w1_search(0xf0,rom_code); w1_init(); #asm("sei") while(1) { // #asm("cli") Temp=ds1820_temperature_10(0); // #asm("sei") temp=(Temp>>1); } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
marti 0 23 мая, 2011 Опубликовано 23 мая, 2011 · Жалоба Что-то не получается... время обработки прерывания вышло 42 мкс. Не много ли? Не замусорит ли такое прерывание данные из DS1820? На какую частоту настраивать прерывание? 24 раза в секунду, как в кино. Прм трех индкаторах 3Х24 = 72 раза в секунду. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Слесарь 9 23 мая, 2011 Опубликовано 23 мая, 2011 (изменено) · Жалоба У меня тупо опрашивает один датчик, потом другой датчик, а потом проблескивает 8 разрядов индикация. И так по кругу.. здесь Ой. Ошибочка. Девять разрядов динамической индикации. Девятый разряд для светодиодной индикации режимов. Мерцание на глаз незаметно. Связь с датчиками по SPI. Таймеры не используются. Все работает циклично по кругу. В том числе и настройка и ввод значений. Изменено 23 мая, 2011 пользователем Слесарь Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Буратино 0 23 мая, 2011 Опубликовано 23 мая, 2011 · Жалоба Для решения этой и многих других задач, удобно и правильно использовать автоматное программирование -> Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
e-serg 0 23 мая, 2011 Опубликовано 23 мая, 2011 · Жалоба У меня тупо опрашивает один датчик, потом другой датчик, а потом проблескивает 8 разрядов индикация. И так по кругу.. Такое решение слишком примитивно в лоб. для сиюминутного подойдет, а дальше? для "murmur" динамическая индикация шине 1-wire мешать не должна, если она через UART никогда не помешают или на чтение бита ставь запрет прерываниям. в приведенном коде ерунда, какие задержки? в прерывании только надо обновить позицию, сменить знакоместо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ae_ 2 23 мая, 2011 Опубликовано 23 мая, 2011 · Жалоба 24 раза в секунду, как в кино. Прм трех индкаторах 3Х24 = 72 раза в секунду. каждое прерывание индикация выводится на 1 из 3 индикаторов, время экспозиции одного знакоместа =42мс, итого 24/3=8 раз/сек., так? обновление дисплея 24 раза в секунду при 1 индикаторе = 24 FPS обновление дисплея 24 раза в секунду при 2 индикаторах = 12 FPS обновление дисплея 24 раза в секунду при 3 индикаторах = 8 FPS Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Слесарь 9 23 мая, 2011 Опубликовано 23 мая, 2011 · Жалоба Такое решение слишком примитивно в лоб. для сиюминутного подойдет, а дальше? Работает второй год. Несколько образцов Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ukpyr 0 23 мая, 2011 Опубликовано 23 мая, 2011 (изменено) · Жалоба Явно кривая реализация timer0_ovf_isr - у вас последовательно выводятся все индикаторы в одном вызове прерывания. Нужно добавить счетчик текущего знакоместа и выводить по одному разряду при каждом вызове прерывания. Частоту таймера достаточно сделать 400Гц или больше. Температуру выводить в отдельный буфер индикации в основном цикле. При опросе 18В20 в критических местах (в битовых задержках) запрещать прерывания. время обработки прерывания вышло 42 мкс. Не много ли?Это очень мало. Вот когда параллельно работают несколько таймеров, задействовано ШИМ-управление, UART, USB и нужно опрашивать несколько 1-wire устройств - это да, жопа Изменено 23 мая, 2011 пользователем ukpyr Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Слесарь 9 23 мая, 2011 Опубликовано 23 мая, 2011 · Жалоба Есть датчик DS1820. Естественно, динамическая индикация должна коммутироваться постоянно. Да. Не дочитал. У меня на стиральной машине на получение данных с этого датчика уходит примерно 0,1 секунды времени. На этот промежуток динамическая индикация прерывается. Благо я опрашиваю датчик по таймеру не так часто. Хотя, я могу продумать обработчик динамической индикации и в коде обработчика 1-Wire датчика. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
murmur 0 28 мая, 2011 Опубликовано 28 мая, 2011 · Жалоба Получилось, но хоть ты тресни, показывает 85 градусов. Блокирировала прерывания на время измерения - индикаторглючит - выводит по очереди цифры, но все равно видно что 85 градусов. Подключала как по классической схеме, так и по паразитному питанию. ЧТо не так? #asm .equ __w1_port=0x08 .equ __w1_bit=1 #endasm #include <mega48.h> #include <stdio.h> #include <delay.h> #include <ds1820.h> #include <1wire.h> unsigned char cur_digit; unsigned int Temp; unsigned char dig[4]; flash char DIGITS[] = { 0b11001111, 0b00001001, 0b11010101, 0b01011101, 0b00011011, 0b01011110, 0b11011110, 0b00001101, 0b11011111, 0b01011111, 0b00010111 }; /* maximum number of DS1820/DS18S20 connected to the 1 Wire bus */ #define MAX_DEVICES 8 /* DS1820/DS18S20 devices ROM code storage area */ unsigned char rom_code[MAX_DEVICES][9]; interrupt [TIM0_OVF] void timer0_ovf_isr(void) { PORTD=0x00; if (cur_digit==3) cur_digit=0;else cur_digit++; PORTB = 0xFF &(~(1<<cur_digit+2)); PORTD=DIGITS[dig[cur_digit]]; } void main() { unsigned char i,j,devices; int temp; DDRC.0=1; DDRD=0xFF; DDRB=0xFF; PORTD=0xFF; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 8000,000 kHz // Mode: Normal top=FFh // OC0A output: Disconnected // OC0B output: Disconnected TCCR0A=0x00; TCCR0B=0x03; TCNT0=0x00; OCR0A=0x00; OCR0B=0x00; // Timer/Counter 0 Interrupt(s) initialization TIMSK0=0x01; //devices=w1_search(0xf0,rom_code); w1_init(); devices=w1_search(0xf0,rom_code); #asm("sei") dig[3]=0; dig[0]=11; PORTB=0x00; PORTD=0x00; while(1) { // #asm("cli") Temp=ds1820_temperature_10(&rom_code[0][0])/10; // #asm("sei") //dig[1]=devices; dig[1]=Temp/ 10; dig[2]=Temp % 10; } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Слесарь 9 28 мая, 2011 Опубликовано 28 мая, 2011 · Жалоба Получилось, но хоть ты тресни, показывает 85 градусов. У меня тоже кажись показывало 85 градусов когда неправильно инициализиповал датчик перед запросом значения температуры. Сейчас поищу код, если нацду, представлю Вот, когдат делал char ds18b20_init(void) { unsigned char c = 0; PORTBbits.RB4 = 1; // импульс сброса DelayUs( 200 ); DelayUs( 200 ); DelayUs( 200 ); DelayUs( 200 ); PORTBbits.RB4 = 0; DelayUs( 1 ); while( PORTAbits.RA2 == 0 ) // Дождаться ответа чипа о готовности { DelayUs( 1 ); c++; if( c > 20 ) return 0; } if( c < 4 ) return 0; DelayUs( 1 ); c = 0; while( PORTAbits.RA2 == 1 ) // Дождаться нормализации { DelayUs( 10 ); c++; if( c > 20 ) return 0; } if( c < 3 ) return 0; DelayUs( 1 ); return 1; } void ds18b20_write_bit( char b) { PORTBbits.RB4 = 1; if( b == 1 ) { DelayUs(1); //min 1us PORTBbits.RB4 = 0; } DelayUs( 60 ); // 20 ... PORTBbits.RB4 = 0; DelayUs(1); } void ds18b20_write_byte( char B ) { char i, aux; for( i=0; i<8; i++ ) { aux = B >> i; aux &= 0x01; ds18b20_write_bit(aux); } } char ds18b20_read_bit(void) { char ret; char tick = 0; PORTBbits.RB4 = 1; // импульс сброса DelayUs(1); //min 1us PORTBbits.RB4 = 0; DelayUs(1); //min 1us while( PORTAbits.RA2 ) { DelayUs(1); tick++; } if( tick > 4 ) return 0; DelayUs( 50 ); return 1; } char ds18b20_read_byte(void) { char i, result=0x00; for( i=0; i < 8; i++ ) { if( ds18b20_read_bit() ) result |= (0x01 << i); } return result; } signed float GetTemp() { char i; unsigned char scratchpad_data[9]; signed float temperature; if( !ds18b20_init() ) Error( 2 ); // если что-то пошло не так ds18b20_write_byte(0xCC); ds18b20_write_byte(0x44); while( PORTAbits.RA2 ); if( !ds18b20_init() ) Error( 2 ); ds18b20_write_byte(0xCC); ds18b20_write_byte(0xBE); for( i=0; i < 9; i++ ) { scratchpad_data[i] = ds18b20_read_byte(); } if( scratchpad_data[5] != 0xFF ) Error( 2 ); if( scratchpad_data[7] != 0x10 ) Error( 2 ); temperature = ( scratchpad_data[0] * 0.0625 ) + ( scratchpad_data[1] * 16 ); return temperature; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
murmur 0 29 мая, 2011 Опубликовано 29 мая, 2011 · Жалоба У вас какой-то странный код. Что за ответ "готовности от чипа"? ДЛя чего контроль ножки на PORTA? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
murmur 0 29 мая, 2011 Опубликовано 29 мая, 2011 (изменено) · Жалоба Проблема решилась - оказалось датчик не хочет рабоать в паразитном режиме. Причем он работает, когда нога VDD вообще висит в воздухе!!!!!! Это может быть связано с самим датчиком? Я не проектирую устройство с нуля, я заново переписываю прошивку для уже готового устройства, в котором сгорел контроллер, а прошивки нет... Изменено 29 мая, 2011 пользователем murmur Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться