Буратино 0 13 мая, 2011 Опубликовано 13 мая, 2011 · Жалоба Показывайте схему. Показывайте разводку. Вероятнее всего проблема в неправильной разводке земли, либо в висящем в воздухе без подтяжки входе Reset, либо не на все ноги завели земли/питания. Схема: http://electronix.ru/forum/index.php?act=a...st&id=54636 (В схеме С8 с R12 нужно поменять местами) Плата: Все неиспол. выводы сделал выходами и записал туда нули: void Init_Ports (void) { DDRB = (1<<DDB5)|(1<<DDB3)|(1<<DDB2)|(1<<DDB1)|(1<<DDB0); PORTB = (1<<PB4)|(1<<PB2); DDRC = (1<<DDC5)|(1<<DDC4)|(1<<DDC3)|(1<<DDC2)|(1<<DDC0); PORTC = (1<<PC1); DDRD = (1<<DDD7)|(1<<DDD6)|(1<<DDD5)|(1<<DDD4)|(1<<DDD3)|(1<<DDD1)|(1<<DDD0); PORTD = (1<<PD2)|(1<<PD1); } --- На четвертой картинке "подсветил" именно землю на плате: --- При этом я обратил внимание, что траблы именно с лампой где стоят дневного типа лампочки.. Сейчас попробую посмотреть на питающее напряжение в моменты вкл/откл такой нагрузки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 121 13 мая, 2011 Опубликовано 13 мая, 2011 · Жалоба Схема:У вас AVcc в воздухе. По разводке - c1 далековато от ног процессра. Подключите AVcc, не забудьте на него тоже емкость повесить. И очень мне не понравилась земля на конденсаторы кварца петлей через всю плату. Ее бы тут же вокруг кварца (вниз по картинке) обвести и максимально близко к земляным ногам процессора на земляную дорожку. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Буратино 0 13 мая, 2011 Опубликовано 13 мая, 2011 · Жалоба У вас AVcc в воздухе. По разводке - c1 далековато от ног процессра. Подключите AVcc, не забудьте на него тоже емкость повесить. И очень мне не понравилась земля на конденсаторы кварца петлей через всю плату. Ее бы тут же вокруг кварца (вниз по картинке) обвести и максимально близко к земляным ногам процессора на земляную дорожку. Спасибо, сейчас все поправлю! AVCC куда подключать? К +питания процессора? У меня в схеме не используется АЦП, AVCC обязательно подключать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 121 13 мая, 2011 Опубликовано 13 мая, 2011 · Жалоба У меня в схеме не используется АЦП, AVCC обязательно подключать?Читаем даташит:AVCC is the supply voltage pin for the A/D Converter, Port C (3..0), and ADC (7..6). It should be externally connected to VCC, even if the ADC is not used. If the ADC is used, it should be connected to VCC through a low-pass filter. Note that Port C (5..4) use digital supply voltage, VCC. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Буратино 0 13 мая, 2011 Опубликовано 13 мая, 2011 · Жалоба ААААА:) теперь все работает даже с тремя лампами! :) Спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
tklim 0 16 мая, 2011 Опубликовано 16 мая, 2011 · Жалоба Можно чтобы считал до ICR1. Самое простое решение для данной задачи: FastPWM со счетом до ICR1. При 8мгц - легко получить 125кгц. И без всяких прерываний. // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: 8000,000 kHz // Mode: Fast PWM top=ICR1 // OC1A output: Inverted // OC1B output: Non-Inv. // Noise Canceler: Off // Input Capture on Falling Edge // Timer1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=0xE2; TCCR1B=0x19; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x3F; OCR1AH=0x00; OCR1AL=0x1F; OCR1BH=0x00; OCR1BL=0x1F; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Буратино 0 21 мая, 2011 Опубликовано 21 мая, 2011 · Жалоба Самое простое решение для данной задачи: FastPWM со счетом до ICR1. При 8мгц - легко получить 125кгц. И без всяких прерываний. Самое простое решение (без прерываний) подсказал Сергей Борщ. используется режим "сброс по совпадению" вот с такой фишечкой: TCCR1A |= (1 << FOC1A); Сегодня пробую EEPROM на ATMega8. Вот код функций чтения и записи в энергонезависимую память: void EEPROMWrite(INT16U uiAddress, INT08U ucData) { while(EECR & (1<<EEWE)) // Wait for completion of previous write / ; EEAR = uiAddress; // Set up address and data registers / EEDR = ucData; EECR |= (1<<EEMWE); // Write logical one to EEMWE / EECR |= (1<<EEWE); // Start eeprom write by setting EEWE / } INT08U EEPROMRead(INT16U uiAddress) { while(EECR & (1<<EEWE)) // Wait for completion of previous write / ; EEAR = uiAddress; // Set up address register / EECR |= (1<<EERE); // Start eeprom read by writing EERE / return EEDR; // Return data from data register / } Не получается вычитывать записанные данные. В программе делаю вот так: ... for(i=0; i<8; i++) { EEPROMWrite(i, (INT08U)tmp2); tmp2 >>= 8; } for (i=0; i < 8; i++) UARTTransmitByte ( EEPROMRead(i) ); ... Все четко работает. Но если заремить строку EEPROMWrite(i, (INT08U)tmp2);, то получаю вместо записанной и сохраненной информации 0xFFы... Где я ошибся? Спасибо! --- Я все понял! :))))))))0 Кто догадается в чем дело было? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 121 21 мая, 2011 Опубликовано 21 мая, 2011 · Жалоба Самое простое решение (без прерываний) подсказал Сергей Борщ.На самом деле dimka76 прав - в режиме Fast PWM можно ограничить период значением ICR1. А выходы настроить дергаться в противофазе. Тогда не нужен будет FOC1A, вся настройка сведется к трем строчкам. Я все понял! :))))))))0 Кто догадается в чем дело было?EEPROM стиралась вместе ко старым кодом перед записью новой прошивки? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Diusha 0 23 мая, 2011 Опубликовано 23 мая, 2011 · Жалоба Все четко работает. Но если заремить строку EEPROMWrite(i, (INT08U)tmp2);, то получаю вместо записанной и сохраненной информации 0xFFы... Я все понял! :))))))))0 Кто догадается в чем дело было? Ну наверно в этом: tmp2 >>= 8; А если заремить, то читались, видимо, ранее правильно записанные данные. Правда, я сей (или сёв?) не знаю и могу только предположить, что при сдвиге на 8 в регистре оказываются единицы. Это по поводу загадки. А по делу на всякий пожарный напомню, что между запись EEWE д. б. после EEMWE в теч. не более 4-х тактов. Если у Вас в программе разрешены прерывания, условие может нарушиться Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Буратино 0 24 мая, 2011 Опубликовано 24 мая, 2011 · Жалоба EEPROM стиралась вместе ко старым кодом перед записью новой прошивки? Да, именно так:) А по делу на всякий пожарный напомню, что между запись EEWE д. б. после EEMWE в теч. не более 4-х тактов. Если у Вас в программе разрешены прерывания, условие может нарушиться То есть лучше кусочек который пишет значения в ЕЕПРОМ, заключить в: __disable_interrupt(); ... __enable_interrupt(); ? Подскажите, как программно выполнить ресет? Вот у меня в программе есть место где по сути дела алгоритм должен просто начать выполняться с самого начала, как выполнить ресет программно? Спасибо! АТMega8, IAR Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Sergey_Aleksandrovi4 1 24 мая, 2011 Опубликовано 24 мая, 2011 · Жалоба То есть лучше кусочек который пишет значения в ЕЕПРОМ, заключить в: __disable_interrupt(); ... __enable_interrupt(); ? Это небезопасно, т.к. этим кодом можно несанкционированно разрешить прерывания там, где они запрещены. Лучше так: char temp = SREG; __disable_interrupt(); ... SREG = temp; Про ресет тут целая тема на нескольких страницах была. В кратце: если аппаратно надо сбросить, то только с помощью WatchDog это можно сделать, если просто програмно перепрыгнуть куда-либо, то как-то так: unsigned short Addr = (unsigned short)main; ((void(*)(void))Addr)(); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 9 24 мая, 2011 Опубликовано 24 мая, 2011 · Жалоба Подскажите, как программно выполнить ресет?Вот тут это было Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Буратино 0 24 мая, 2011 Опубликовано 24 мая, 2011 · Жалоба Спасибо! :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 121 24 мая, 2011 Опубликовано 24 мая, 2011 · Жалоба То есть лучше кусочек который пишет значения в ЕЕПРОМ, заключить в:Лучше всего воспользоваться средствами компилятора: #include <stdint.h> // И не нужно придумывать свои типы вроде UINT8U __eeprom uint8_t My_data[8]; void test() { for(uint_fast8_t i = 0; i < sizeof(My_data) / sizeof(My_data[0]); ++i) My_data[i] = i; for(uint_fast8_t i = 0; i < sizeof(My_data) / sizeof(My_data[0]); ++i) UARTTransmitByte(My_data[i]); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Bass 0 26 мая, 2011 Опубликовано 26 мая, 2011 · Жалоба Это небезопасно, т.к. этим кодом можно несанкционированно разрешить прерывания там, где они запрещены. Лучше так: char temp = SREG; __disable_interrupt(); ... SREG = temp; Если используете gcc (он же WinAVR), то в util/atomic.h есть средства для работы с атомарными блоками. Можно использовать такую конструкцию ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { // тут код блока с атомарным доступом } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться