ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
26 апреля
480467
OlegALL (16.01.2014 15:12, просмотров: 1160)
Некорректно считывается TCNT1, ATmega168 Привет. Проблема: неправильно считывается значение счётного регистра (TCNT1, ATmega168) Каждые 12мс происходит прерывание по сравнению Ожидаю увидеть значение около 12000(dec) (0x2EE0). Приходит в 4 раза больше. Сделал всё по дататашиту. И прерывания запрещал-разрешал на момент считывания. Привожу код: void init(){ // порты C и D DDRC |= 1<<DDC0 | 1<<DDC1 | 1<<DDC2 | 1<<DDC3 | 1<<DDC4; PORTC |= 1<<PC3; // сигнал Strob в "0", D1 в "1" PORTC &= ~(1<<STROB); // Сигналы Strob и D1 PORTC |= 1<<D1; //PORTC |= 1<<PC4; // отладочный светодиод DDRD &= ~(1<<DDD0 | 1<<DDD3); DDRD |= 1<<DDD1 | 1<<DDD2; //PORTD |= 1<<PD2; в режиме приёма PD2 = 0 //EICRA |= 1<<ISC10 | 1<<ISC11; // внешнее //EIMSK |= 1<<INT1; TIMSK1 |= 1<<OCIE1A | 1<<OCIE1B; // прерывание таймера1 по сравнению // таймер //OCR1AL = _200us; OCR1A = _200us; OCR1B = _12ms; //TCCR1B |= 1<<CS10 | 1<<CS12; //TCCR1B |= 1<<CS10 | 1<<CS11; TCCR1B |= 1<<CS11; // UART UBRR0 = 7; // скорость 57600 UCSR0B |= 1<<RXEN0 | 1<<RXCIE0 | 1<<TXEN0; // разрешили прерывания по приёму и передаче // переменные и флаги //request[1] = RUN_IMPULSES_DIR1_DIR2; // по умолчанию работают 2 последовательности request[0] = 0; //request[1] = RUN_IMPULSES_DIR1_DIR2; request[1] = RUN_IMPULSES_DIR1; request[2] = 0; request[3] = 0; answer[0] = REQUEST_START; answer[1] = 0; answer[2] = 0; answer[3] = 0; answer[4] = 0; answer[5] = 0; answer[6] = 0; answer[7] = 0; answer[8] = 0; answer[9] = 0; answer[10] = 0; answer[11] = 0; answer[12] = 0; //unsigned char answer[13] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; flags.form_impulse = 1; flags.impulse_was_on_line = DIR_2; flags.half_period_passed = 0; flags.send_answer = 0; flags.run_measure_dir_1 = 0; //flag = 0; //flag_send_answer = 0; rx_stage = 0; // прерывания: SREG |= 0b10000000; // все } ISR(TIMER1_COMPB_vect){ // срабатывает по сравнению, через 12 мс после сброса счётного регистра /* cli(); TCNT1L = 0x0F; TCNT1H = 0xF0; sei(); */ //cli(); answer[4] = TCNT1L; answer[3] = TCNT1H; //sei(); //PORTC |= 1<<PC1; // отладочный светодиод !!!! 40 мс!! flags.run_measure_dir_1 = 0; flags.run_measure_dir_2 = 0; //invert_Strob_D1(); PORTC &= ~(1<<STROB); // Сигналы Strob и D1 PORTC |= 1<<D1; if (request[1] == RUN_IMPULSES_DIR1_DIR2){ if (flags.impulse_was_on_line == DIR_2){ form_impulse(DIR_1); //flags.run_measure_dir_1 = 1; //TIMSK1 |= 1<<OCIE1A; flags.impulse_was_on_line = DIR_1; } else if (flags.impulse_was_on_line == DIR_1){ form_impulse(DIR_2); //flags.run_measure_dir_1 = 1; //TIMSK1 |= 1<<OCIE1A; flags.impulse_was_on_line = DIR_2; //SREG = 0; } } else if (request[1] == RUN_IMPULSES_DIR1){ if (flags.half_period_passed == 0){ form_impulse(DIR_1); // формируем спустя первые 12 мс //flags.run_measure_dir_1 = 1; //TIMSK1 |= 1<<OCIE1A; flags.half_period_passed = 1; } else { flags.half_period_passed = 0; // через 12 мс - ещё 12 мс } } else if (request[1] == RUN_IMPULSES_DIR2){ if (flags.half_period_passed == 0){ form_impulse(DIR_2); flags.run_measure_dir_2 = 1; //TIMSK1 |= 1<<OCIE1A; flags.half_period_passed = 1; } else { flags.half_period_passed = 0; } } TCNT1H = 0; TCNT1L = 0; } #include <avr\io.h> #include <avr\interrupt.h> #include <util\delay.h> #include <util\crc16.h> //#define _200us 2 //#define _12ms 87 //#define _200us 23 //#define _12ms 1382 #define _200us 182 #define _12ms 10909 //#define _12ms 5000 #define DIR_1 0 #define DIR_2 1 #define STROB PC2 #define D1 PC3 #define BEGIN 0 // запрос #define WAITING_START 0 #define WAITING_COMMAND 1 #define WAITING_LRC_HIGH 2 #define WAITING_LRC_LOW 3 #define LAST 4 #define REQUEST_START 0x3A #define RUN_IMPULSES_DIR1 0x01 #define RUN_IMPULSES_DIR2 0x02 #define RUN_IMPULSES_DIR1_DIR2 0x03 // ответ #define ANSWER_START 0x3A #define FLAG_NORM_DIR_1 0x81 #define FLAG_FAILURE_DIR_1 0x01 #define FLAG_NORM_DIR_2 0x82 #define FLAG_FAILURE_DIR_2 0x02 /* Прототипы функций */ void init(); // инициализация всего void send_answer(); // отправка посылки из UART0 void debug(); void send_byte(unsigned char data); //void run_time(unsigned char* time); //void invert_Strob_D1(); void form_impulse(unsigned char line); //unsigned short get_lrc(unsigned char *p); unsigned short get_lrc(); void send_answer(); void measure(unsigned char line); /* Переменные, массивы, структуры */ unsigned char rx_stage; // счётчик стадии приёма посылки unsigned short lrc; unsigned char request[5]; // unsigned char answer[13]; // //unsigned char answer[13] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char line_flag; unsigned char debug_var; // запрос union{ unsigned short two_bytes; struct{ unsigned char low; unsigned char high; } byte; } request_lrc, answer_lrc; // ответ union{ float four_bytes; struct{ unsigned char first_high; unsigned char second; unsigned char third; unsigned char fourth_low; } byte; } t1, t2; struct{ unsigned int failure_or_norm: 1; // 0 - авария, 1 - норма unsigned int form_200us: 1; unsigned int form_impulse: 1; unsigned int form_12ms: 1; unsigned int impulse_was_on_line: 1; unsigned int half_period_passed: 1; unsigned int send_answer: 1; unsigned int _12ms_passed: 1; //unsigned int send: 1; unsigned int run_measure_dir_1: 1; unsigned int run_measure_dir_2: 1; } flags; /* Кварц 7.3728 МГц Время такта: 1/(7.3728 * 10^6) = 0.135*10^-6 с Время такта без предделителя: 1/(7.3728 * 10^6) = 0.135 мкс Столько тактов нужно для формирования времени 12 мс: 12 мс / 0.138 мкс = 86956 - переполняет регистр Время такта c учётом предделителя 1024: 1/(7.3728 * 10^6 / 1024) = 0.138 мс Столько тактов нужно для формирования времени 12 мс: 12 мс / 0.138 мс = 87 Столько тактов нужно для формирования времени 200 мкс: 200 мкс / 0.138 мс = 1.44 = 2 Время такта c учётом предделителя 64: 1/(7.3728 * 10^6 / 64) = 8.68 мкс Столько тактов нужно для формирования времени 12 мс: 12 мс / 8.68 мкс = 1382 Столько тактов нужно для формирования времени 200 мкс: 200 мкс / 8.68 мкс = 23 Время такта c учётом предделителя 8: 1/(7.3728 * 10^6 / 8) = 1.1 мкс Столько тактов нужно для формирования времени 12 мс: 12 мс / 1.1 мкс = 10909 Столько тактов нужно для формирования времени 200 мкс: 200 мкс / 1.1 мкс = 182 */