C наступающим Новым Годом! Возникла вот какая проблема. Программа считывает код с DS1990, но как оказалось неверно, например на выходе у меня получается в 16-ричном виде F2242424FC279F27. По даташиту DS1990 выяснилось что 64-битный код состоит из 3 частей: первые 8 бит - родительский код (должен быть 01), 48 бит сам серийный номер, остальные 8 бит - CRC. Играл с задержками при чтении, результата не дало, не могу добиться 01. Краткое описание программы: Контроллер опрашивает считыватель, как только появился сигнал присутствия, передает команду 0x33. Затем начинает считывать и заносить 0 и 1 в двухмерный массив. По окончанию вывожу массив в порт. На компьютере анализирую полученный код и передаю одну из команд на МК. Он принимает и на основании команды зажигает один из светодиодов. Вот сама программа:
| Код | #include <avr/io.h> #include <avr/iom128.h> #include <stdio.h> #include <stdlib.h> #include <util/delay.h> #include <avr/interrupt.h> #define F_CPU 8000000UL // 8 MHz
//Инициализация UART void Init_UART0(void) { UCSR0A = 0x0; // 0000 0000 UBRR0H=0x0; UBRR0L=0x33; // скорость 9600 при 8MHz UCSR0B |= (1<<RXEN0) | (1<<TXEN0); UCSR0C |= (1<<UCSZ01) | (3<<UCSZ00); }
//Чтение из UART char _get(void) { while ( !(UCSR0A & (1<<RXC0)) ); // Ждем пока данные не приняты return UDR0; // Возвращаем содержимое UDR0
}
//Вывод символа в UART void _put(char data) { while ( !( UCSR0A & (1<<UDRE0)) ); // Ждем,если предыдущий символ не передался. UDR0 = data; // Кладем данные в регистр UDR0
}
void send_ds1990_command(unsigned char command); void read_ds1990(void); unsigned char tcnt, i; char buffer[8][8];
//Вывод массива void port_output(void) { for (int n = 0; n < 8; n++) { for(int n2 = 0;n2 < 8; n2++) { _put(buffer[n][n2]); } } }
//Функция сброса DS1990 void reset_ds1990(void) { DDRB|=_BV(0); // Вывод порта настраиваем как выход PORTB&=~_BV(0);
cli(); _delay_ms(0.680); //Устанавливаем 0 в теч. около 480 мкс
DDRB&=~_BV(0); //Вывод порта настраиваем как вход _delay_ms(0.07); //Ожидание сигнала присутствия 70 мкс if(PINB & (1<<PINB0)) //Если 1 - нет сигнала присутствия { _delay_ms(0.41); //410 мкс sei(); } else { _delay_ms(0.41); //410 мкс sei(); send_ds1990_command(0x33); read_ds1990(); } }
//Чтение
void read_ds1990(void) { cli(); for(i = 0; i < 8; i++) // байтовый цикл {
for(tcnt = 0; tcnt < 8; tcnt++) // битовый цикл { DDRB|=_BV(0); PORTB&=~_BV(0); _delay_ms(0.006);// ждем 6 мкс DDRB&=~_BV(0); PORTB&=~_BV(0); _delay_ms(0.009); // ждем 9 мкс if(PINB & (1 << PINB0)) { buffer[i][tcnt] = '1'; } else { buffer[i][tcnt] = '0'; } } _delay_ms(0.044); } port_output();
unsigned char rec = _get(); // приходит команда от ПК switch( rec ) { case 'a': PORTC = 0x20; _delay_ms(4000); PORTC = 0x00; break; //зеленый case 'b': PORTC = 0x08; _delay_ms(2000); PORTC = 0x00; break; //красный default: break; } sei(); }
//Функция пересылки команд
void send_ds1990_command(unsigned char command) { cli(); unsigned char data=command; for(i=0;i<8;i++) { data=data<<7; //Сдвиг на i разрядов влево command=command>>1; //Сдвиг передаваемого байта if(data==0x00) //Передача лог.0 { DDRB|=_BV(0); PORTB&=~_BV(0); _delay_ms(0.06); //60 мкс DDRB&=~_BV(0); PORTB&=~_BV(0); _delay_ms(0.01); //10 мкс } else //Передача лог.1 { DDRB|=_BV(0); PORTB|=_BV(0); _delay_ms(0.006); //Задержка примерно на 6 мкс DDRB&=~_BV(0); PORTB&=~_BV(0); _delay_ms(0.064); //Задержка примерно на 64 мкс } data=command; //Новое значение для сдвига }; sei(); }
int main (void) { Init_UART0(); DDRC = 0xff;
while (1) { reset_ds1990(); } }
|
|