|
Помогите понять, в чем ошибка в куске кода |
|
|
|
Jun 23 2006, 05:15
|

Профессионал
    
Группа: Свой
Сообщений: 1 751
Регистрация: 4-08-05
Из: Великие Луки
Пользователь №: 7 360

|
Есть такой код: Код /***************************************************** Chip type : ATmega8535 Program type : Application Clock frequency : 7,372800 MHz Memory model : Small External SRAM size : 0 Data Stack size : 128 *****************************************************/ #include <mega8535.h> // 1 Wire Bus functions #asm .equ __w1_port=0x18;PORTB .equ __w1_bit=0 #endasm #include <1wire.h> #include <delay.h> // стандартная функция задержек #include <stdio.h> // Standard Input/Output functions #include <string.h> #define LED PORTB.1 // выход на индикатор чтения #define BEEP PORTB.2 // выход BEEP #define ALARM PORTB.3 // выход ALARM #define MAX_DEVICES 1 //определяем максимальное количество устройств на шине unsigned char rom_code[MAX_DEVICES][9]; //выделяет память (9 бит умноженное на кол-во устройств) unsigned char my_code_1[9]={0x01,0x1E,0x06,0xCA,0x0C,0x00,0x00,0x70,0x01}; unsigned char my_code_2[9]={0x01,0xFD,0xE2,0xCC,0x0C,0x00,0x00,0xCC,0x01}; //функция инициализации микроконтроллера void initialization(void) { // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=Out Func1=Out Func0=Out // State7=T State6=T State5=T State4=T State3=0 State2=0 State1=0 State0=0 PORTB=0x00; DDRB=0x0F; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x04; // USART initialization // USART Baud rate: 115200 // Communication Parameters: 8 Data, 1 Stop, No Parity // USART Receiver: Off // USART Transmitter: On // USART Mode: Asynchronous UBRRL=0x03; UCSRA=0x00; UCSRB=0x08; UCSRC=0x86; UBRRH=0x00; UBRRL=0x03; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; SFIOR=0x00; // 1 Wire Bus initialization w1_init(); #asm("wdr") // Watchdog Timer initialization // Watchdog Timer Prescaler: OSC/2048k #pragma optsize- WDTCR=0x1F; WDTCR=0x0F; #asm("wdr") #ifdef _OPTIMIZE_SIZE_ #pragma optsize+ #endif } void test_key(void) //проверка кода ключа { if(memcmp(rom_code,my_code_1,9)==0) printf("CodeOK\n\r"); else printf("CodeError\n\r"); } //функция звукового сигнала BEEP void beep(void) { unsigned char a=0; unsigned char b=0; for (b=0;b<2;b++) { for(a=0;a<150;a++) { BEEP=1; delay_us(377); BEEP=0; delay_us(377); }; delay_ms(100); }; } //oбработка прерывания по переполнению таймера TIMER1 interrupt [TIM1_OVF] void timer1_ovf_isr(void) { unsigned char i,j,devices; TCCR1B=0x00; //останавливаем таймер TIMER1 LED=1; //моргаем светодиодом delay_ms(10); LED=0; //ищем устройство командой 0xf0, в rom_codes ложится 9 байт (family-1,serial-6,CRC8-1,некоторые устройства возвращают 9 байт) devices=w1_search(0xf0,rom_code); printf("%-u DEVICE DETECTED\r",devices); //вывод через UART количества найденных устройств for (j=0;j<9;j++) //задаем, какую часть кода выводить { printf("0x%02X ",rom_code[i][j]); } printf("\r"); test_key(); TCCR1B=0x03; //запускаем таймер TIMER1 } void main(void) { initialization(); beep(); #asm("sei") // Разрешение прерываний TCCR1B=0x03; // запуск счетчика TIMER1 { begin: #asm("wdr") goto begin; } } Он подразумевает, что считывается DS1990 каждые ~0,5с, и выводит на СОМ следующее: 1 DEVICE DETECTED 0x01,0x1E,0x06,0xCA,0x0C,0x00,0x00,0x70,0x01 //номер ключа CodeOK Вот теперь вопрос, иногда вместо реального номера ключа пишет: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 хотя устройство на шине определяется и выводится Code OK. иногда вместо нулей выводится неправильный код, сразу после включения (мусор в ОЗУ?)) Иногда работает как часы... Вчера пару часов пытался выяснить закономерность, неполучилось. Подразумеваю, что проблема в железе, сегодня буду бится дальше. P.S. Mega шилась раз 50 - 100, может здесь засада?
--------------------
Андрей Смирнов
|
|
|
|
|
Jun 23 2006, 05:36
|

Гуру
     
Группа: Свой
Сообщений: 2 720
Регистрация: 24-03-05
Пользователь №: 3 659

|
RE: P.S. Mega шилась раз 50 - 100, может здесь засада? У меня на макетке МК в день перешиваются раз по 10! и на всех (пока ))) ) ферификация проходит успешно, хотя МК уже более года, так что трабл явно не здесь. Если датчики ВСЕГДА определяются успешно, значит, вероятно, причина в передаче данных от МК к РС. Попробуйте printf заменить чем то своим, проверенным и надежным, или, для начала, сбавьте скорость) а то у Вас аж 115200
--------------------
|
|
|
|
|
Jun 23 2006, 09:31
|

Профессионал
    
Группа: Свой
Сообщений: 1 751
Регистрация: 4-08-05
Из: Великие Луки
Пользователь №: 7 360

|
Кажется проблема была в питании, подзарядил аккумулятор и со старым кодом пошло (старый был взят и examples). Хотя не понимаю, в чем виноват аккумулятор, на нем было 12,5 вольт на холостом ходу, а потребления никакого от макетки. Но я изменил код в соответствии с советами многоуважаемых форумчан, за что всем ОГРОМНОЕ СПАСИБО! Код /***************************************************** Chip type : ATmega8535 Program type : Application Clock frequency : 7,372800 MHz Memory model : Small External SRAM size : 0 Data Stack size : 128 *****************************************************/ #include <mega8535.h> // 1 Wire Bus functions #asm .equ __w1_port=0x18;PORTB .equ __w1_bit=0 #endasm unsigned char rom_code[9]; //выделяет память (9 бит умноженное на кол-во устройств) unsigned char my_code_1[9]={0x01,0x1E,0x06,0xCA,0x0C,0x00,0x00,0x70,0x01}; void test_key(void) { if(memcmp(rom_code,my_code_1,9)==0) // сравниваем код, полученный от ключа с заданным printf("CodeOK "); // вывод сообщения else printf("CodeError "); } //функция звукового сигнала BEEP void beep(void) { unsigned char a=0; unsigned char b=0; for (b=0;b<2;b++) { for(a=0;a<150;a++) { BEEP=1; delay_us(377); BEEP=0; delay_us(377); }; delay_ms(100); }; } //oбработка прерывания по переполнению таймера TIMER1 interrupt [TIM1_OVF] void timer1_ovf_isr(void) { unsigned char j,devices; TCCR1B=0x00; //останавливаем таймер TIMER1 LED=1; //моргаем светодиодом delay_ms(10); LED=0; //ищем устройство командой 0xf0, в rom_codes ложится 9 байт (family-1,serial-6,CRC8-1,некоторые устройства возвращают 9 байт) devices=w1_search(0xf0,rom_code); if (devices==1) // если устройство присуствует, выводим подтверждение и номер { printf("Device Detected "); for (j=0;j<9;j++) //задаем, какую часть кода выводить { printf("0x%02X ",rom_code[j]); } printf(" "); }; test_key(); TCCR1B=0x03; //запускаем таймер TIMER1 } void main(void) { initialization(); beep(); #asm("sei") // Разрешение прерываний TCCR1B=0x03; // запуск счетчика TIMER1 { begin: #asm("wdr") goto begin; } } Цитата (девятый байт не надо т.к. его в ключах DS1990 нет) Понятно, по даташиту нет, я согласен, но 9 у меня всегда равен 01h, не знаю почему... Пробовал для эксперимента смотреть дальше в ОЗУ = 00h. Этот момент для меня не понятен.
--------------------
Андрей Смирнов
|
|
|
|
|
Jun 25 2006, 15:30
|
Местный
  
Группа: Новичок
Сообщений: 232
Регистрация: 24-06-06
Пользователь №: 18 332

|
Цитата(defunct @ Jun 24 2006, 01:44)  Цитата(prottoss @ Jun 23 2006, 08:36)  для начала, сбавьте скорость) а то у Вас аж 115200
Зачем это? Кварц правильный, не надо ничего сбавлять. Кроме кварца важно еще как сделан физический интерфейс. 115200 не каждому подсилу. Цитата(Gorby @ Jun 25 2006, 18:11)  С каких пор хорошим тоном является делание громоздких операций в прерывании? Нельзя было установкой флага обойтись? А остальное делать в main.
А вызов printf() из прерывания - вообще песня. А delay_ms(10) в прерывании? Наверно 123 читал. И похоже не внимательно.
|
|
|
|
|
Jun 26 2006, 05:37
|

Профессионал
    
Группа: Свой
Сообщений: 1 751
Регистрация: 4-08-05
Из: Великие Луки
Пользователь №: 7 360

|
Цитата С каких пор хорошим тоном является делание громоздких операций в прерывании? Нельзя было установкой флага обойтись? А остальное делать в main.
А вызов printf() из прерывания - вообще песня. А delay_ms(10) в прерывании?
Считаю, что в данной задаче никакой обоснованной необходимости в прерывании не было. Нужен тик таймера - запустите таймер и анализируйте поллом в main. Тем более что ничего другого не делается. Насчет красивости учту  Чем плохо printf() в прерывании, если времени гарантированно хватает (ну просто вагон)? Цитата Кроме кварца важно еще как сделан физический интерфейс. 115200 не каждому подсилу. преобразователь на FT232 с гальванической развязкой, с железом проблем нет, стабильно работает
--------------------
Андрей Смирнов
|
|
|
|
|
Jun 26 2006, 06:03
|
Местный
  
Группа: Новичок
Сообщений: 232
Регистрация: 24-06-06
Пользователь №: 18 332

|
Цитата(Pyku_He_oTTyda @ Jun 26 2006, 09:37)  Чем плохо printf() в прерывании, если времени гарантированно хватает (ну просто вагон)? Надеюсь defunct вам сейчас объяснит!
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|