|
|
  |
ATMega |
|
|
|
May 13 2011, 08:32
|

Профессионал
    
Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215

|
Цитата(Сергей Борщ @ May 13 2011, 11:02)  Показывайте схему. Показывайте разводку. Вероятнее всего проблема в неправильной разводке земли, либо в висящем в воздухе без подтяжки входе 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); } --- На четвертой картинке "подсветил" именно землю на плате: --- При этом я обратил внимание, что траблы именно с лампой где стоят дневного типа лампочки.. Сейчас попробую посмотреть на питающее напряжение в моменты вкл/откл такой нагрузки.
Эскизы прикрепленных изображений
--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
|
|
|
|
|
May 13 2011, 10:29
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (Буратино @ May 13 2011, 11:32)  Схема: У вас AVcc в воздухе. По разводке - c1 далековато от ног процессра. Подключите AVcc, не забудьте на него тоже емкость повесить. И очень мне не понравилась земля на конденсаторы кварца петлей через всю плату. Ее бы тут же вокруг кварца (вниз по картинке) обвести и максимально близко к земляным ногам процессора на земляную дорожку.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 13 2011, 11:18
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (Буратино @ May 13 2011, 14:13)  У меня в схеме не используется АЦП, AVCC обязательно подключать? Читаем даташит: QUOTE 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.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 16 2011, 06:24
|
Местный
  
Группа: Свой
Сообщений: 230
Регистрация: 7-04-08
Из: Украина, Запорожье
Пользователь №: 36 541

|
Цитата(dimka76 @ May 13 2011, 11:20)  Можно чтобы считал до 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;
|
|
|
|
|
May 21 2011, 12:02
|

Профессионал
    
Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215

|
Цитата(Клим @ May 16 2011, 09:24)  Самое простое решение для данной задачи: 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 Кто догадается в чем дело было?
--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
|
|
|
|
|
May 21 2011, 21:35
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (Буратино @ May 21 2011, 15:02)  Самое простое решение (без прерываний) подсказал Сергей Борщ. На самом деле dimka76 прав - в режиме Fast PWM можно ограничить период значением ICR1. А выходы настроить дергаться в противофазе. Тогда не нужен будет FOC1A, вся настройка сведется к трем строчкам. QUOTE (Буратино @ May 21 2011, 15:02)  Я все понял!  )))))))0 Кто догадается в чем дело было? EEPROM стиралась вместе ко старым кодом перед записью новой прошивки?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 23 2011, 04:16
|
Вечный студент
   
Группа: Участник
Сообщений: 500
Регистрация: 11-09-06
Из: Питер
Пользователь №: 20 262

|
Цитата(Буратино @ May 21 2011, 15:02)  Все четко работает. Но если заремить строку EEPROMWrite(i, (INT08U)tmp2);, то получаю вместо записанной и сохраненной информации 0xFFы... Я все понял!  )))))))0 Кто догадается в чем дело было? Ну наверно в этом: tmp2 >>= 8; А если заремить, то читались, видимо, ранее правильно записанные данные. Правда, я сей (или сёв?) не знаю и могу только предположить, что при сдвиге на 8 в регистре оказываются единицы. Это по поводу загадки. А по делу на всякий пожарный напомню, что между запись EEWE д. б. после EEMWE в теч. не более 4-х тактов. Если у Вас в программе разрешены прерывания, условие может нарушиться
|
|
|
|
|
May 24 2011, 07:56
|

Профессионал
    
Группа: Свой
Сообщений: 1 433
Регистрация: 27-10-08
Из: Украина, Киев
Пользователь №: 41 215

|
Цитата(Сергей Борщ @ May 22 2011, 00:35)  EEPROM стиралась вместе ко старым кодом перед записью новой прошивки? Да, именно так  Цитата(Diusha @ May 23 2011, 07:16)  А по делу на всякий пожарный напомню, что между запись EEWE д. б. после EEMWE в теч. не более 4-х тактов. Если у Вас в программе разрешены прерывания, условие может нарушиться То есть лучше кусочек который пишет значения в ЕЕПРОМ, заключить в: Код __disable_interrupt(); ... __enable_interrupt(); ? Подскажите, как программно выполнить ресет? Вот у меня в программе есть место где по сути дела алгоритм должен просто начать выполняться с самого начала, как выполнить ресет программно? Спасибо! АТMega8, IAR
--------------------
Брак - это такой вид отношений, в которых один всегда прав, - а другой - муж.
|
|
|
|
|
May 24 2011, 08:47
|
Частый гость
 
Группа: Свой
Сообщений: 168
Регистрация: 8-10-08
Из: РФ Смоленск
Пользователь №: 40 764

|
Цитата(Буратино @ May 24 2011, 11:56)  То есть лучше кусочек который пишет значения в ЕЕПРОМ, заключить в: Код __disable_interrupt(); ... __enable_interrupt(); ? Это небезопасно, т.к. этим кодом можно несанкционированно разрешить прерывания там, где они запрещены. Лучше так: Код char temp = SREG; __disable_interrupt(); ... SREG = temp; Про ресет тут целая тема на нескольких страницах была. В кратце: если аппаратно надо сбросить, то только с помощью WatchDog это можно сделать, если просто програмно перепрыгнуть куда-либо, то как-то так: Код unsigned short Addr = (unsigned short)main; ((void(*)(void))Addr)();
|
|
|
|
|
May 24 2011, 10:22
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (Буратино @ May 24 2011, 10:56)  То есть лучше кусочек который пишет значения в ЕЕПРОМ, заключить в: Лучше всего воспользоваться средствами компилятора: CODE #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]); }
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
May 26 2011, 03:42
|

Участник

Группа: Свой
Сообщений: 66
Регистрация: 5-08-10
Из: Томск
Пользователь №: 58 761

|
Цитата(Sergey_Aleksandrovi4 @ May 24 2011, 15:47)  Это небезопасно, т.к. этим кодом можно несанкционированно разрешить прерывания там, где они запрещены. Лучше так: Код char temp = SREG; __disable_interrupt(); ... SREG = temp; Если используете gcc (он же WinAVR), то в util/atomic.h есть средства для работы с атомарными блоками. Можно использовать такую конструкцию Код ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { // тут код блока с атомарным доступом }
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|