Перейти к содержанию
    

Здравствуйте

Проблема возникла такая, есть у меня atmega32a китайский. постигаю таймеры. использую таймер0 (8 бит).

Логика моих мыслей такова:

 

если там частота 16МГц а таймер считает до 256 то каждое переполнение таймера будет происходить (1 / 16 000 000) * 256 = 16 микросекунд (0,000016).

Соответственно, что бы получить 1 секунду надо таких отрезков 62 500 (0,000016 * 62 500 = 1 сек.)

Что бы особо не мучиться с 16 битными числами я разбил на две 8 битные, т.е. 250 и 250.

Значит в прерывании по переполнению мы считаем первый счетчик, када он доходит до 250 мы увеличиваем второй и обнуляем первый.

Сразу что скажу что cksel биты не менял, они все отключены, значит частота должна быть нормальной. В коде не устанавливаю предделитель для таймера.

Внешнего кварца, как и осциллографа, не имею. замерить частоту не выходит. пробовал всю партию контроллеров (10 штук) результат один и тот же, либо у них у всех не 16 МГц, либо логика моих действий не верна.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

результат один и тот же

Не плохо было бы узнать полученный результат, способ наблюдения оного.

И перепроверить cksel сравнив с DS.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ishpanec, Вы раздел 8-bit Timer/Counter0 with PWM документации читали? В частности про делители ( prescaler ) частоты.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

если там частота 16МГц

а там точно 16МГЦ? не 8?

 

пс: таблицу 9 смотрите

Изменено пользователем stells

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня такой способ получить 1 мс при 8 и 16 мгц:

/========================================================================
#define ST_TCNT		 TCNT0
#define ST_TIMSK		TIMSK
#define ST_OCIE		 OCIE0
#define ST_OCR		  OCR0
#define ST_TCCR		 TCCR0
#define CS0			 CS00
#define CS1			 CS01
#define CS2			 CS02
//========================================================================

//========================================================================
#define SYS_TICK_FLG	0
//------------------------------------------------------------------------

//========================================================================
#pragma vector = TIMER0_COMP_vect
__interrupt void Timer0Comp(void)
{
ST_OCR += 250;
sys_tick |= 1<<SYS_TICK_FLG;
}
//========================================================================

//========================================================================
void init_sys_timer (void)
{
sys_tick = 0;
ST_TCNT = 0;
ST_TIMSK |= 1<<ST_OCIE;
ST_OCR = 250;
ST_TCCR |= (1<<CS0) | (1<<CS1);
}
//------------------------------------------------------------------------

 

При 8 мгц 125, при 16 мгц 250.

 

Делаем счетчики и получаем любую времянку с дискретностью в 1 мс. 1000 мс = 1 с.

Изменено пользователем demiurg1978

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

С точностью до такта можно временной интервал формировать так. Писано для tiny13, но и для mega32 будет примерно также.

	.INCLUDE "tn13def.inc"


.equ	Fo=7890123
;.equ	Fo=8000000


.org $0000
.CSEG
RJMP	START
.org $0003
TIMER0_OVER:
SBIW	YL,1
RET
.org $0006
TIMER0_COMPA:
RET
;*******************************
START:
SBI	DDRB,0

LDI	YH,BYTE3(Fo-1)
LDI	YL,BYTE2(Fo-1)
LDI	R22,BYTE1(Fo-1)
OUT	OCR0A,R22

LDI	R22,1<<SE
OUT	MCUCR,R22	; SLEEP IDLE

CLR	R19
OUT	TCCR0A,R19

LDI	R21,1<<OCIE0A

LDI	R20,1<<TOIE0
OUT	TIMSK0,R20	;  разрешить прерывание переполнения
OUT	TIFR0,R20

LDI	R20,1
OUT	TCCR0B,R20	;  старт Т0

SEI
WAIT:
SLEEP
BRNE	PC-2

LDI	R19,1<<WGM01
OUT	TCCR0A,R19	; режим сравнения с самоочисткой CTC

OUT	TIMSK0,R21	;  разрешить прерывание сравнения
OUT	TIFR0,R21
SEI
WAIT_COMP:
SLEEP
SBI	PINB,0		; инвертировать выход
RJMP	START

.EXIT

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

отвечу всем по порядку)

 

Не плохо было бы узнать полученный результат

 

 

значит при счете до 62 500 мигает он раз в 15 секунд %) наблюдал просто, ни каких особых измерений, это если бы там миллисекунды погрешности было, другое дело) вот биты из программки fX99QfC2nw8.jpg

 

Вы раздел 8-bit Timer/Counter0 with PWM документации читали?

 

я исключительно по книжкам. не думал что там особая разница есть.

 

не 8?

 

пробовал клепать расчеты под 8, все равно заметные глазу отличия есть) мигание ~ раз в 7 секунд

что за таблица 9?

 

У меня такой способ получить 1 мс при 8 и 16 мгц:

 

с Си не дружу) после того как gcc танцы с бубном устраивать заставлял)))))

 

С точностью до такта можно временной интервал формировать так. Писано для tiny13, но и для mega32 будет примерно также.

 

вашу магию тоже не совсем понял...

 

вот моя магия

 


device atmega32a
.include "D:\asm\include\m32def.inc"
.def temp = r16 ; темповая переменная
.def countTimer = r17 ; счетчик задержки
.def countTimer2 = r27
.def posR = r25

.equ timerSleep = 250
.equ timerSleep2 = 125

; начало программы
.org 0
rjmp RESET

.org $16 ; перывание таймера 0
rjmp TIMER0

TIMER0: ;начало таймер0

inc countTimer
cpi countTimer, timerSleep
ldi temp, 0
out TCNT0, temp
breq showsInt
reti

showsInt:

clr countTimer
inc countTimer2
cpi countTimer2, timerSleep2
breq IncsSeconds
reti

IncsSeconds:
clr countTimer2
inc posR
cpi posR,1
breq showReg1
cpi posR,2
breq showReg2

showReg1:
ldi temp, 0b11111111
rjmp continueTimers

showReg2:
ldi temp, 0b00000000
ldi posR,0


continueTimers:
out PORTA, temp
reti ;конец таймер 0


RESET:

ldi temp,low(RAMEND) ;загружаем указатель на стек
out SPL,temp

ldi temp,high(RAMEND) ; указатель стека, старший байт
out SPH,temp

ldi temp,0b11111111 ; контакт 0-7 порта A на выход
out DDRA,temp ;

ldi temp, 0b00000001 ; контакт 0-1 порта В на выход
out DDRB, temp
out PORTB,temp

clr countTimer
clr countTimer2

ldi temp,0b00000001
out TIMSK,temp

ldi temp,0b00000001
out TCCR0,temp

clr posR

sei ;разрешить прерывания

END:
rjmp END ;бесконечный цикл

там у меня просто циферблат стоит, пока им моргаю...)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

получается Internal Calibrated RC Oscillator 1 MHz.

Если галочка соответствует биту равному нулю.

Table 9-8. Internal Calibrated RC Oscillator Operating Modes

DS

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

что за таблица 9?

таблица 9 из даташита... или 9-8 из приведенного выше... в принципе все уже понятно

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

да, уже разобрался, всем спасибо за помощь!)

по умолчанию в мк и правда был 1МГц, поменял биты, рпсчитал на 8 и все заработало как надо)

Table 9. Internal Calibrated RC Oscillator Operating Modes
CKSEL3..0    Nominal Frequency (MHz)
0001        1.0
0010        2.0
0011        4.0
0100        8.0

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ваш код дает интервал 1 секунды, за счёт сравнений в обработчике, на 39мс больше. Если такая погрешность устраивает, нет проблем. Без ручного пересчёта чисел сравнения Вы не можете менять частоту. По мне, лучше поручить эту работу ассемблеру.

ldi temp, 0b00000001 ; контакт 0-1 порта В на выход
out DDRB, temp
out PORTB,temp

;*******************************
;.equ Fo=8000000
.equ	 Fo=7890123

MOV	R0,TEMP
SET_SEC:

       IN	TEMP,PINB
EOR	TEMP,R0

	LDI	R20,BYTE3(Fo-8); загрузка 1 секунды в тиках Fo за вычетом установок 
LDI	R21,BYTE2(Fo-8);
LDI	R22,BYTE1(Fo-8);

SEC_WAIT:
SUBI R22,BYTE1(5); 
SBCI	 R21,BYTE2(5)
SBCI	 R20,BYTE3(5)

BRCC	SEC_WAIT
OUT		PORTB,TEMP
RJMP	SET_SEC
;*******************************
.EXIT

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Зачем для этой цели использовать 8-ми разрядный счетчик? Не проще использовать 16-ти разрядный в режиме CTC ? Один раз настроил - и будет Вам прерывание 1 раз в сек без всяких дополнительных счетчиков на Си/Асме

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не проще использовать 16-ти разрядный в режиме CTC ? Один раз настроил - и будет Вам прерывание 1 раз в сек без всяких дополнительных счетчиков на Си/Асме
Проще, конечно. Попробуйте настроить один раз без дополнительных счётчиков формирователь 1.000'000 секунды для частоты 7'890'123 Гц на 16-ти разрядном таймере в режиме CTC.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Проще, конечно. Попробуйте настроить один раз без дополнительных счётчиков формирователь 1.000'000 секунды для частоты 7'890'123 Гц на 16-ти разрядном таймере в режиме CTC.

Ну, в обычных мегах эти Ваши 7'890'123 Гц можно было поделить на 256 предделителем и для CTC поставить значение 30820. Будет частота 0,999993283, разве плохо? :) А для Ваших 1.000'000 секунды поди надо кварц специально отобранный да ещё и в термостат всю конструкцию засунуть...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...