Форум программистов, компьютерный форум, киберфорум
Наши страницы
Микроконтроллеры Atmega AVR
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.65/31: Рейтинг темы: голосов - 31, средняя оценка - 4.65
alhis88
0 / 0 / 0
Регистрация: 30.09.2012
Сообщений: 9
1

Настройка таймера в ATmega8

25.01.2014, 08:18. Просмотров 5896. Ответов 16
Метки нет (Все метки)

Здравствуйте! Необходимо сделать таймер с обратным отсчетом. Исходник уже есть. В нем не понятно несколько строк! Я их представил ниже, а Вы, если будет не сложно, объясните пожалуйста их значение.

TCNT1H=0xBDC >> 8; не понятно для меня значение xBDC >> 8 и 0xBDC & 0xff. Можно поподробнее?
TCNT1L=0xBDC & 0xff;
ACSR=0x80; почему регистр Analog Comparator принимает значение будучи выключенным?

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
Chip type               : ATmega8
Program type            : Application
AVR Core Clock frequency: 4,000000 MHz
Memory model            : Small
External RAM size       : 0
Data Stack size         : 256
*****************************************************/
 
#include <mega8.h>
#asm
.equ __lcd_port=0x12 ;PORTD
#endasm
#include <lcd.h>
#include <delay.h>
unsigned char a=0, b=0, c=0, d=0, e=0, f=0, help=0;     // ab : cd : ef
char hours, minuts, seconds;
#define SIGNAL PORTC.0
#define ON 1
#define OFF 0
#define PUSK PINB.0
#define MPLUS PINB.1
#define SPLUS PINB.2
#define STOP PINB.3
#define MMINUS PINB.4
#define SMINUS PINB.5
 
// ФУНКЦИЯ ОТОБРАЖЕНИЯ ВРЕМЕНИ
 
void time(void) // Подготовка регистров для заполнения данными 
{
a = 0;
b = 0;
c = 0;
d = 0;
e = 0;
f = 0;
 
//=============================================================================
help = hours;                // Разложение значения ЧАСов по разрядам ab : __ : __
while (help > 9)
    {
    help -= 10;
    a++;
    };
b = help;
//=============================================================================
help = minuts;               // Разложение значения МИНут по разрядам __ : cd : __ 
while (help > 9)
    {
    help -= 10;
    c++;
    };
d = help;
//=============================================================================
help = seconds;              // Разложение значения СЕКунд по разрядам __ : __ : ef
while (help > 9)
    {
    help -= 10;
    e++;
    };
f = help;
//=============================================================================
// ОТОБРАЖЕНИЕ НА ДИСПЛЕЕ ВРЕМЕНИ В СООТВЕТСТВИИ с местоположением
// ab : cd : ef
// Alrm gh : ij
lcd_gotoxy(0,0);
lcd_putchar(a+0x30);
lcd_putchar(b+0x30);
lcd_putsf(":");
lcd_putchar(c+0x30);
lcd_putchar(d+0x30);
lcd_putsf(":");
lcd_putchar(e+0x30);
lcd_putchar(f+0x30);
lcd_gotoxy(0,1);
lcd_putsf("<<<<>>>>");
};
 
// Timer1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Reinitialize Timer 1 value
TCNT1H=0xBDC >> 8; 
TCNT1L=0xBDC & 0xff;
// Place your code here
seconds--;                      // Инкремент таймера +1СЕК
if (seconds > 59)               // условия при которых таймер ведет себя как часы
    {
    seconds = 59;
    minuts--;
    if (minuts > 59)
        {
        minuts = 59;
        hours--;
        if (hours > 23)
            {
            hours = 23;
            };
        };
    };
// В данные часы включена функция включения нагрузки с 8 до 23, поэтому проверяем условие и делаем вывод    
time();       // обновление дисплея
}
 
void main(void)
{
 
// Port B initialization
 
PORTB=0xFF;
DDRB=0x00;
 
// Port C initialization
 
PORTC=0x00;
DDRC=0x01;
 
// Port D initialization
 
PORTD=0x00;
DDRD=0x00;
 
 
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 62,500 kHz
// Mode: Normal top=0xFFFF
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x03;
TCNT1H=0x0B;
TCNT1L=0xDC;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
 
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x04;
 
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80; 
SFIOR=0x00;
 
// LCD module initialization
lcd_init(16);
// НАЧАЛЬНАЯ ИНИЦИАЛИЗАЦИЯ
timing:
while (PUSK == 1)
    {
    if (MPLUS == 0)
        {
        minuts++;
        if (minuts > 59)
            {
            minuts = 0;
            hours++;
            if (hours > 23)
                {
                hours = 0;
                };
            };
        }
    if (MMINUS == 0)
        {
        minuts--;
        if (minuts > 59)
            {
            minuts = 59;
            hours--;
            if (hours > 23)
                {
                hours = 23;
                };
            };
        };
    if (SPLUS == 0)
        {
        seconds++;
        if (seconds > 59) seconds = 0;
        };
    if (SMINUS == 0)
        {
        seconds--;
        if (seconds > 59) seconds = 59;
        };
    delay_ms(100);
    time();
    };
// Global enable interrupts
#asm("sei")
 
while (1)
    {
      // проводим сравнение для включения нагрузки
    if (STOP == 0)
        {
        #asm("cli")
        SIGNAL = OFF;
        goto timing;
        };
    if (hours == 0)
        {
        if (minuts == 0)
            {
            if (seconds == 0) 
                {
                #asm("cli")
                SIGNAL = ON;
                }
            }
        }
    };
}
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.01.2014, 08:18
Ответы с готовыми решениями:

2 разных таймера в atmega8
Добрый вечер всем. У меня возникла проблема с таймерами ..... Написал код...

Странное поведение таймера Т2 AtMega8
Всем доброго дня. Я, смешно сказать, пытаюсь помигать светодиодом. С точной...

ATmega2560 настройка таймера
Добрый день, уважаемые участники форума, В процессе изучения курса AVR и...

настройка таймера/счетчика
Как настроить таймер ATmega8 на отсчет интервалов времени равных 1 сек. Я...

Настройка таймера с разными предделителями
Пытаюсь настроить восьми битный таймер мк atmega8 на частоту 31250 Гц, что бы...

16
raxp
10188 / 6571 / 492
Регистрация: 28.12.2010
Сообщений: 21,166
Записей в блоге: 1
25.01.2014, 10:46 2
0xBDC >> 8
00001011 11011100 смещение вправо на 8 бит.

0xBDC & 0xff;
00001011 11011100 умножение на маску 00000000 11111111.
0
alhis88
0 / 0 / 0
Регистрация: 30.09.2012
Сообщений: 9
25.01.2014, 12:03  [ТС] 3
И последние 2 вопроса: зачем смещать вправо на 8 бит и зачем умножение на маску в этих регистрах TCNT1H и TCNT1L?
0
pyzhman
791 / 485 / 66
Регистрация: 15.05.2012
Сообщений: 2,749
25.01.2014, 16:29 4
Чтобы в старший байт счетчика попал старший байт числа, а в младший байт счетчика попал младший байт числа.
ACSR=0x80; это и есть отключение компаратора, чтоб не кушал электроэнергию.
0
Voland_
1689 / 1034 / 97
Регистрация: 04.01.2010
Сообщений: 3,484
27.01.2014, 01:32 5
alhis88, в CV AVR (в AVR Studio не в курсе) 16-битные регистры лучше не использовать как пару 8-битных, а писать прямо - TCNT1 = 0xBDC;
а смещение и маска написаны просто для понимания процесса разделения числа 0xBDC на старший и младший разряды.

Правильность написания связана с синхронностью записи этого значения в регистр (а именно регистровую пару), чтобы счетчик правильно работал и не выставилось никаких лишних событий. Об этом сказано в ДШ, если что, с примером. Так что ваша запись в общем случае неправильная.
1
Eugene375
0 / 0 / 0
Регистрация: 29.01.2014
Сообщений: 2
29.01.2014, 01:33 6
Цитата Сообщение от alhis88 Посмотреть сообщение
Здравствуйте! Необходимо сделать таймер с обратным отсчетом. Исходник уже есть. В нем не понятно несколько строк! Я их представил ниже, а Вы, если будет не сложно, объясните пожалуйста их значение.
[/C]
Хочу собрать такой таймер. Поделитесь опытом пожалуйста. Вы использовали внешний кварц?
0
alhis88
0 / 0 / 0
Регистрация: 30.09.2012
Сообщений: 9
31.01.2014, 23:08  [ТС] 7
Eugene375, да, я использовал внешний кварц, отказался от работы с timer1 в atmega8, использовал timer2 перевел его в ассинхронный режим, чтобы тактирование происходило от внешнего кварцевого резонатора. Можете оставить почту, я вам скину готовый проект (исходник, схема в протеусе).
0
Eugene375
0 / 0 / 0
Регистрация: 29.01.2014
Сообщений: 2
01.02.2014, 00:34 8
alhis88, я тоже воспользовался внешним кварцем и таймером 2, но проект пока еще не доделал Завтра закуплю все необходимое для платы и попробую сделать Еще печатку надо развести. В ответ могу поделиться своими наработками. Вот мой email: eugene375@yandex.ru
0
Alex201
0 / 0 / 0
Регистрация: 12.02.2014
Сообщений: 52
02.12.2014, 17:43 9
подскажите а обязательно значение в регистр OCR1A записывать в 16ричном формате? и обязательно ли записывать значение сначала в старший а потом младший, т.е. вот так:

OCR1AH=0x03;//записываем в регистр OCR1A 1000
OCR1AL=0xE8;
или можно просто

OCR1A=0x03E8;
0
Витальич
1274 / 1184 / 174
Регистрация: 02.12.2013
Сообщений: 4,886
02.12.2014, 17:47 10
От компилятора зависит, все с какими работал OCR1A=0x03E8; понимали
2
Alex201
0 / 0 / 0
Регистрация: 12.02.2014
Сообщений: 52
02.12.2014, 19:08 11
я в AVR Studio на GCC пишу. А десятичный и какой-либо другой формат значит не канает да? Еще вопрос, если я регулярно меняю значение OCR1A (400 раз в секунду), данные для этого регистра приходят от другого МК. Дак вот, когда я меняю значение регистра OCR1A , прерывания по таймеру запрещаю, но на сколько я понял флаг все равно может выставиться (при совпадении значения этого регистра со значением таймера). Возможно ли просто стереть этот флаг чтоб не сработало прерывание?
вот как то так:
C
1
2
3
4
5
6
7
8
9
10
11
12
ISR(INT0_vect)
{   
    TCNT1H=0x00;        
    TCNT1L=0x00;
    
    OCR1AH=data_r[0];   
    OCR1AL=data_r[1];
    
    /TIFR&=~(1<<OCF1A);                     
 
    TIMSK1=(1<<OCIE1A); 
}
0
Витальич
1274 / 1184 / 174
Регистрация: 02.12.2013
Сообщений: 4,886
03.12.2014, 08:01 12
Цитата Сообщение от Alex201 Посмотреть сообщение
я в AVR Studio на GCC пишу.
OCR1A работает.
Цитата Сообщение от Alex201 Посмотреть сообщение
А десятичный и какой-либо другой формат значит не канает да?
канает, для GCC-AVR даже бинарный канает.
0; - десятичный
0x00; - шестнадцатиричный
0b00000000; - двоичный

На третью часть вопроса, ответить не могу, мануал нужно смотреть.
0
pyzhman
791 / 485 / 66
Регистрация: 15.05.2012
Сообщений: 2,749
03.12.2014, 10:02 13
Флаг выставлятся когда уже аллес, сработало прерывание. Стирай/не стирай - прерывание есть.
0
Voland_
1689 / 1034 / 97
Регистрация: 04.01.2010
Сообщений: 3,484
03.12.2014, 10:09 14
Цитата Сообщение от pyzhman Посмотреть сообщение
Флаг выставлятся когда уже аллес, сработало прерывание. Стирай/не стирай - прерывание есть.
ничего подобного. В момент, когда ...IE-флаг сброшен вы вольны сбрасывать флаг события как вам угодно. Обычно это и делается в момент включения ...IE-флага, чтобы прерывание работало за актуальные период времени.
Например, когда вы запускаете UART:
// инициализация UART'а.
// Разная бла-бла-бла (время какое-то, за которое неизвестно что имелось на ноге UART'а).
// Сброс флага RXC, OVR.
// Включение прерывания RXC.

Таким образом вы гарантированно получите прерывание именно при приходе данных после включения прерывания, независимо о того, что было ранее.

ЗЫ: то же самое и с таймером.
0
pyzhman
791 / 485 / 66
Регистрация: 15.05.2012
Сообщений: 2,749
03.12.2014, 10:23 15
Согласен. Разрешение прерывания я имел ввиду взведенным.
0
Alex201
0 / 0 / 0
Регистрация: 12.02.2014
Сообщений: 52
03.12.2014, 14:09 16
Пасиба всем)), я правильно понял из даташита, что флаг стирается записью 1 в нужный бит?
0
pyzhman
791 / 485 / 66
Регистрация: 15.05.2012
Сообщений: 2,749
03.12.2014, 14:24 17
Да, именно так.
0
03.12.2014, 14:24
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.12.2014, 14:24

Разница между ATMEGA8-16AI и ATMEGA8-16AU
Кто подскажет, в чем разница между ATMEGA8-16AI и ATMEGA8-16AU. Смотрю в...

PIC16F887 настройка таймера
Здравствуйте! Начал изучать pic контролеры. Таймер запустился таким...

ATMEGA8
Подскажите пожалуйста чем отличаються микроконтролер atmega8 от например етого ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru