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

Вопрос По Программе Джона Мортона "частотомер"


Рекомендуемые сообщения

ldi temp, 0

out DDRB, temp

У вас же PB0-PB3 на катоды должны идти вроде, как так DDRB=0.

Для счета внешних импульсов лучше бы использовать Т0, он 8-битный, чтобы оставить 16-битный Т1 на точный отсчет времени. Ну и по форматированию

.macro outi	 ;макрос для записи числа в регистр ввода-вывода. В коде он выглядит вдвое короче, чем обычная запись. Само собой, на объем прошивки и скорость работы он не влияет. Ну и надо помнить, что он "портит" регистр temp.
 ldi temp,@1
 out @0,temp
.endm
...
outi TCCR0B, (0b111 << CS00)

такая запись, с макросом и сдвигом, выглядит несколько более понятно, чем "магическое число" 0b00000111.

Ну и конструкция получилась.

Так из головы же писал, причем только для демонстрации принципа. Сегодня набросал полную версию, она занимает 282 строки (с учетом форматирования и комментариев) и 408 байт в скомпилированном виде. Предусмотрено 2 предела, 1-9999 кГц с частотой 1 кГц либо 0.01 - 99.99 кГц с частотой 0.01 кГц. Пределы вполне логичные, 10 МГц - теоретический максимум на 20 МГц кварце, а 10 Гц - минимальное число, кратное 10, которое можно получить на 16-битном таймере без лишних извращений. В железе не проверял, только в протеусе. Так что теперь могу советовать более конструктивно.

Еще один совет по форматированию, на этот раз применительно к семисегментникам

.equ SEG_A=    (1<<0)
.equ SEG_B=    (1<<1)
.equ SEG_C=    (1<<2)
.equ SEG_D=    (1<<3)
.equ SEG_E=    (1<<4)
.equ SEG_F=    (1<<5)
.equ SEG_G=    (1<<6)
.equ SEG_H=    (1<<7)
...
INT2LED:
.db (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F),        (SEG_B | SEG_C)
.db (SEG_A | SEG_B | SEG_D | SEG_E | SEG_G),            (SEG_A | SEG_B | SEG_C | SEG_D | SEG_G)
.db (SEG_B | SEG_C | SEG_F | SEG_G),                (SEG_A | SEG_C | SEG_D | SEG_F | SEG_G)
.db (SEG_A | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G),        (SEG_A | SEG_B | SEG_C)
.db (SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G),    (SEG_A | SEG_B | SEG_C | SEG_D | SEG_F | SEG_G)

То есть отдельно назначены выводы на каждый сегмент, а отдельно из них построены комбинации. При таком подходе их удобно "перетасовывать" для упрощения разводки платы. А то что у контроллера, что у индикатора выводы расположены едва ли не в случайном порядке. То же относится к выбору разряда, свою версию которого я приводил, но для наглядности повторю

;port_mask - 4-байтный массив в ОЗУ
 ldi ZH,0
 ldi ZL,port_mask
 ldi temp, 0b00001110    ;запишем в ОЗУ комбинации битов для выбора каждого разряда
 st Z+,temp
 ldi temp, 0b00001101
 st Z+,temp
 ldi temp, 0b00001011
 st Z+,temp
 ldi temp, 0b00000111
 st Z+,temp

То есть можно переместить 4-й сегмент на PD6, изменив по всему массиву 6-е биты. Можно было также использовать сдвиги, но для 4 состояний я счел это излишним.

А подпрограмму работы дисплея мне в конце всей программы можно разместить или какое то есть особое расположение?

А что, есть разница, в каком месте кода расположить отдельную процедуру?

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

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

Реклама: ООО ТД Промэлектроника, ИНН: 6659197470, Тел: 8 (800) 1000-321

  • Ответов 107
  • Создана
  • Последний ответ

Топ авторов темы

Топ авторов темы

Изображения в теме

Т.е. я в инициализацию могу написать дословно инициализацию таймеров так?

.macro outi     
 ldi temp,@1
 out @0,temp
.endm
outi TCCR0B, (0b111 << CS00)

Изменено пользователем Dastan89
Ссылка на комментарий
Поделиться на другие сайты

20% скидка на весь каталог электронных компонентов в ТМ Электроникс!

Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!

Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!

Перейти на страницу акции

Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849

Пока этот код даже не компилируется, все же покажу, раз Вы мой учитель)

.include "tn2313def.inc"
.list
.def temp=r16
.def pos=r17
.def flag=r19
.org 0
rjmp RESET
.org 0x0004
rjmp TIMER1_COMPA
.org 0x0006
rjmp TIMER0_OVF
.org 0x0012
reti
.DSEG
digit: .byte 4 ;
num_mask: .byte 4
.CSEG

DcMatrix:
.db 0b00111111,0b00000110 ;0,1
.db 0b01011011,0b01001111 ;2,3
.db 0b01100110,0b01101101 ;4,5
.db 0b01111101,0b00000111 ;6,7
.db 0b01111111,0b01101111 ;8,9



RESET:

ldi XH,high(digit)
ldi XL,low(digit)
ldi temp,0
st X+,temp ;
st X+,temp
st X+,temp
st X+,temp

ldi temp,0b00001110 ;
st X+,temp
ldi temp,0b00001101
st X+,temp
ldi temp,0b00001011
st X+,temp
ldi temp,0b00000111
st X+,temp
ret

ldi temp, RAMEND
out SPL, temp

ldi temp, 0
out DDRB, temp
ldi temp, 0xFF
out DDRD, temp

.macro outi
ldi temp,@1
out @0,temp
.endm
outi TCCR0B, (0b111 << CS00)

;---------------------------------------
ldi temp,(1<<TOIE0 | 1<<OCIE1A) ;
out TIMSK,temp
sei

CYCLE:
rcall DISPLAY ;
sbrs flag,0;
rjmp CYCLE ;
;
;
rcall ITOA ;
clr countH ;
clr countL
out TCNT0,countL
out TCNT1H, countL
out TCNT1L, countL
ldi temp, (0b001 << CS00) ;
out TCCR0B,temp
ldi temp, (1<<WGM12 | 0b011 << CS10) ;
out TCCR1B,temp
sei
rjmp CYCLE

TIMER1_COMPA: ;
ldi temp,0
out TCCR0B,temp ;
out TCCR1B,temp
ldi flag,1 ;
reti

TIMER0_OVF:
adiw countL,1 ;
reti

DISPLAY:
ldi ZH,0 ;
ldi ZL,low(digit) ;
add ZL,pos ;
ldi temp, 0b00011111 ;
out PORTD,temp
ld temp, Z ;
out PORTB,temp
add ZL,4 ;
ld temp,Z
out PORTD,temp ;
inc pos ;
andi pos,3 ;
ret
;
SET_DIGIT:
ldi ZH,high(DcMatrix*2)
ldi XL,low(DcMatrix*2)
add ZL,temp ;
ldi temp,0 ;
adc ZH,new_pos
lpm temp ;
ldi ZH,0
ldi ZL,low(digit)
add ZL,new_pos ;
st Z,temp
ret

Изменено пользователем Dastan89
Ссылка на комментарий
Поделиться на другие сайты

Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов

 Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>>

Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161

оО оказывается у меня новая профессия.

Пока этот код даже не компилируется, все же покажу, раз Вы мой учитель)

Может быть, стоило разобраться, почему он не компилируется? Лично у меня avra выдает вот это

test.asm(73) : Error   : Found no label/variable/constant named ITOA
test.asm(74) : Error   : No register associated with countH
test.asm(75) : Error   : No register associated with countL
test.asm(76) : Error   : No register associated with countL
test.asm(77) : Error   : No register associated with countL
test.asm(78) : Error   : No register associated with countL
test.asm(94) : Error   : No register associated with countL
test.asm(94) : Error   : adiw can only use registers R24, R26, R28 or R30
test.asm(105) : Error   : No register associated with 4
test.asm(117) : Error   : No register associated with new_pos

То есть не определена процедура (дословно - "метка", но по смыслу кода - процедура) ITOA. Я так обозвал перевод из 16-битного числа в массив "видеопамяти", по аналогии с функцией itoa() из Си. У вас она вроде была, хотя и с другим названием

Не объявлены регистры countL, countH, new_pos - стоило бы их объявить.

add работает только с двумя регистрами, о чем вчера я не вспомнил.

Но вообще-то это был кусок кода, взятый из головы, без проверок. Описание принципа, а не истина в последней инстанции. Лучше возьмите за основу свой код динамической индикации и допиливайте его. Личто мне последовательность модификаций видится следующей:

- динамическая индикация, не использующая таймеров (вообще говоря, на таймерах удобнее, но тут их всего 2 и они нужны для более важного дела)

- преобразование 16-битного числа в строку (максимум, что можно отобразить на 4-разрядном индикаторе - 9999 - не влезает в 1 байт, но влезает в 2)

- подсчет импульсов на одном из таймеров за заранее заданное время, например, 1 сек. Оцените допустимый диапазон входных частот?

- вывод полученного числа на индикатор и повторный запуск счета

- "подбор" времени измерения для нужного диапазона. Я посчитал, что 2 достаточно, но это потому что мне лень было делать другие, смотрите под свои ожидания, теоретически можно измерять частоты до 10 МГц. Нижняя планка зависит от допустимого времени измерения.

- вывод числа на индикатор в соответствии с режимом. Ну там, отображение знаков "МГц", "кГц", "Гц", "мГц" или хотя бы разделительной точки (в своей прошивке я так и сделал, частота всегда отображается в килогерцах, но явное отображение, конечно, лучше)

Собственно с основой все, дальше можно прикручивать украшательства.

Разумеется, программу стоит делать блочной, чтобы один блок как можно меньше влиял на остальные. Тогда и менять их местами будет легче, и избавляться от устаревших. Только без фанатизма! Скажем, сохранять временную переменную перед использованием в каждой процедуре излишне. Она и так временная, процедура не будет полагаться на "предопределенное" значение. В avr-gcc, скажем, регистр r0 зарезервирован чтобы быть нулем (из соображений оптимизации), и ассемблерные вставки должны это учитывать.

Надеюсь, не обижаетесь, что я пытаюсь добиться решения от вас, а не дать сразу свое.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

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

Не на что обижаться.Кстати вы случайно не Linux пользуетесь? Но перейдем к вопросу о написании программы. Вот эта программа Display без таймера так? Так. Но для меня есть одно но. Здесь она показывает заведомо мной введенные числа в пункте "загрузка начальных значений". А как ее заставить показывать что насчитала программа частотомера?

.include "tn2313def.inc"
.list
.def temp1=R16
.def temp2=R17
.def temp3=R18
.def temp4=R19
.def temp =R20
.dseg
Digit: .byte 4
;-----------------
.cseg
.org 0
rjmp RESET ; Reset Handler
rjmp EXT_INT0 ; IRQ0 Handler
rjmp EXT_INT1 ; IRQ1 Handler
rjmp TIM_CAPT1 ; Timer1 Capture Handler
rjmp TIM_COMP1 ; Timer1 Compare Handler
rjmp TIM_OVF1 ; Timer1 Overflow Handler
rjmp TIM_OVF0 ; Timer0 Overflow Handler
rjmp UART_RXC ; UART RX Complete Handler
rjmp UART_DRE ; UDR Empty Handler
rjmp UART_TXC ; UART TX Complete Handler
rjmp ANA_COMP ; Analog Comparator Handler
;-----------------------------------------
EXT_INT0 : ret
EXT_INT1 : ret
TIM_CAPT1 : ret
TIM_OVF0 : ret
TIM_OVF1 : ret
UART_RXC : ret
UART_DRE : ret
UART_TXC : ret
ANA_COMP : ret
TIM_COMP1 : ret
;--------------------------------------------

reset: ldi temp1,RamEnd ;инициализация стека
out SPL,temp1

cli

ldi temp,0b11111111 ;настройка портов
out ddrb,temp

ldi temp,0b00001111
out ddrd,temp

ldi temp,4
sts Digit ,temp ;загрузка начальных значений
ldi temp,3
sts Digit+1,temp
ldi temp,2
sts Digit+2,temp
ldi temp,1
sts Digit+3,temp


;*********************************************************
;MAIN
;*********************************************************

IndicCycle:
rcall Display ;цикл индикации
rjmp IndicCycle

;*********************************************************
Display:
;последовательный вывод на индикацию содержимого
;переменной Digit

lds temp1,Digit ;загружаем 0-ю ячейку
ldi temp,0b00001110 ;активируем 0-й разряд
;индикации
out PortD,temp
rcall Decoder ;вызываем 7-сегм.декодер
out PortB,temp1 ;выводим значение в порт
rcall Delay1 ;ждем

lds temp1,Digit+1
ldi temp,0b00001101
out PortD,temp
rcall Decoder
out PortB,temp1
rcall Delay1

lds temp1,Digit+2
ldi temp,0b00001011
out PortD,temp
rcall Decoder
out PortB,temp1
rcall Delay1

lds temp1,Digit+3
ldi temp,0b00000111
out PortD,temp
rcall Decoder
out PortB,temp1
rcall Delay1

ret


;*********************************************************
Decoder:


ldi ZL,Low(DcMatrix*2) ;
ldi ZH,High(DcMatrix*2)

ldi temp2,0 ;
add ZL,temp1 ;
adc ZH,temp2

lpm
mov temp1,r0
ret

DcMatrix:

.db 0b00111111,0b00000110 ;0,1
.db 0b01011011,0b01001111 ;2,3
.db 0b01100110,0b01101101 ;4,5
.db 0b01111101,0b00000111 ;6,7
.db 0b01111111,0b01101111 ;8,9

;*********************************************************
Delay1:


push temp1
push temp2


ldi temp1,0
ldi temp2,1

d11: dec temp1
brne d11
dec temp2
brne d11

pop temp2
pop temp1

ret

Изменено пользователем Dastan89
Ссылка на комментарий
Поделиться на другие сайты

Кстати вы случайно не Linux пользуетесь?
Начинал с AVRStudio4 (там отладчик очень понравился, на порядки удобнее протеусовского), сейчас больше под линуксом. Впрочем, сами компиляторы одни и те же. Там avrasm32, тут его клон avra. Там winavr (порт avr-gcc), тут сам avr-gcc. Разницы почти нет, только тут с отладкой похуже.

rjmp RESET ; Reset Handler

rjmp EXT_INT0 ; IRQ0 Handler

rjmp EXT_INT1 ; IRQ1 Handler

rjmp TIM_CAPT1 ; Timer1 Capture Handler

rjmp TIM_COMP1 ; Timer1 Compare Handler

rjmp TIM_OVF1 ; Timer1 Overflow Handler

rjmp TIM_OVF0 ; Timer0 Overflow Handler

rjmp UART_RXC ; UART RX Complete Handler

rjmp UART_DRE ; UDR Empty Handler

rjmp UART_TXC ; UART TX Complete Handler

rjmp ANA_COMP ; Analog Comparator Handler

;-----------------------------------------

EXT_INT0 : ret

EXT_INT1 : ret

TIM_CAPT1 : ret

TIM_OVF0 : ret

TIM_OVF1 : ret

UART_RXC : ret

UART_DRE : ret

UART_TXC : ret

ANA_COMP : ret

TIM_COMP1 : ret

Во-первых, не ret, а reti - возврат не абы откуда, а из прерывания. Во-вторых, зачем лишний прыжок? Я обычно пишу так:

rjmp RESET
reti;    INT0
reti;    INT1
reti;    TIMER1_CAPT
rjmp TIMER1_COMPA
reti;    TIMER1_OVF
rjmp TIMER0_OVF
reti;    USART_RX
reti;    USART_UDRE
reti;    USART_TX
reti;    ANA_COMP
reti;    PCINT
reti;    TIMER1_COMPB
reti;    TIMER0_COMPA
reti;    TIMER0_COMPB
reti;    USI_START
reti;    USI_OVF
reti;    EE_RDY
reti;    WDT

Но это не универсальное решение. Правильнее явно указывать адреса, то есть

.org 0
rjmp RESET
;.org 1 ;или .org 2, не помню, надо в даташит глянуть
;reti;    INT0
;оказывается, в tn2313def.inc определены специальные константы, так что совсем правильно будет написать
.org INT0addr
reti;    INT0

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

По процедуре Display: еще раз советую сделать ее максимально компактной и делимой, чтобы туда мог безболезненно вклиниться любой другой код. Именно эта процедура будет занимать большую часть времени программы. Пусть лучше вызывается чаще, чем будет дольше работать. Пусть выводит только один знак, номер каторого хранится в соответствующем регистре. Но ладно, это и правда скорее вопросы оптимизации (которые все мы так любим... советовать другим). Может и правда полезнее сначала сделать черновик, а облизывать его уже потом.

Здесь она показывает заведомо мной введенные числа в пункте "загрузка начальных значений". А как ее заставить показывать что насчитала программа частотомера?
Если я не ошибаюсь, она циклически выводит содержимое массива Digit на индикатор. Менять содержимое этого массива можно в любой момент. Например, там же, где посчитан результат.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

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

А у меня Debian8 Jessie, в дуалбуте с Win7. Мда. мне этот проект не осилить. Я конечно понимаю что многие новички умнее и способнее меня. Но я не всегда понимаю что и где менять потому что один автор говорит пиши так это правильно, и предлагает сотни вариантов. А другой говорит не пиши так у меня правильнее. В итоге у меня каша в голове из разных мнений и я не могу нормально писать код потому что что я ни делаю это все в корне неверно. Поэтому видимо пора закрывать тему. Спасибо что помогали мне как могли но я не напишу то что хотел и наверно уже никогда не сделаю свой проект.

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

Проект на самом деле не сложный, к тому же большая часть уже сделана. Зря я, наверное, уговаривал на счет оптимизации - сначала стоит запустить, потом и тестировать легче будет.

Предлагаю следующий шаг - запустить Timer1 чтобы срабатывал с частотой 10 Гц (для простоты можно взять предделитель 1:256 и модуль счета 65536, то есть просто по переполнению, это даст частоту 1.2 Гц, на данном этапе конкретная частота не важна, важнее увидеть, правильно ли меняется число) и в прерывании увеличивать выводимое значение на 1.

Настроить таймер и написать обработчик надеюсь труда не составит? Если что, достаточно настроить источник тактирования (биты CS), разрешить прерывание таймера (регистр TIMSK) и не забыть разрешить прерывания глобально (sei)

Для увеличения выводимого значения можно пойти двумя путями. Сложный вариант - использовать двухбайтную переменную, увеличивать ее (скажем, храним значение в регистре X, тогда увеличивать можно adiw XL,1), после чего процедура разбиения числа на разряды и собственно индикация. Простой способ - считываем младший разряд, увеличиваем на 1, записываем обратно; считываем следующий разряд, увеличиваем на 0 (с учетом переноса), записываем; и т.д.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

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

Спасибо. Но я не знаю как это писать. У меня теория с практикой расходятся, а со слов еще не научился писать. А готовую программу могу примерно разобрать, а когда кусками не могу. Хоть и занимаюсь приводами, но программировать мне не суждено. Прошить или скомпилировать норм, все остальное нет. максимум программа переключения семисегментного индикатора у Мортона, а далее хардкор. И книги не помогают ибо в них отрывки чего то, что я не могу просто скопировать и поставить для своей программы. Это надо иметь понимание, а у меня его нет. Вот если бы начали так звучит по детски конечно, но написать 3 строчки инициализации, потом меня проверят, ок, если неправильно скажут куда смотреть и поправить. И так до готовой программы, а самообучение без внешней поддержки у меня не задалось. Я не знаю что с этим делать. Вот Вы говорите для Вас очевидные вещи, а для меня это не очевидно совсем. А если бы вставь: вставь в свой код вот это после конкретной строчки и объяснить почему так а не иначе, тогда да, я пойму, а так процесс познания для меня зашел в тупик. Надеюсь на Ваше понимание.

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

Ладно, начнем с таймеров. Открываем даташит на ATtiny2313 либо Евстифеева на разделе "Таймеры". Имеет смысл пролистать до режимов работы и почитать их описания, просто как художественную литературу. В каких режимах может работать таймер и чем эти режимы отличаются. Потом посмотреть режимы тактирования. Что может служить тактовым сигналом для данного таймера.

Раз уж назначили меня своим учителем, вот вам домашнее задание:

1. Прочитать про таймеры и перечислить режимы работы с их особенностями (в даташите их 15 штук, но фактически, всего 4).

2. Прочитать про источники тактового сигнала (в даташите их 8, но фактически всего 3 (асинхронный генератор не обсуждаем, это отдельная тема)), какой выберем для отсчета времени?

3. Подобрать режим таймера Timer1, чтобы его частоту можно было легко менять.

4. CS = 0b010 ; OCR1H:OCR1L = 0x0080 ; WGM = 0b0001. С какой частотой будет возникать прерывание по сравнению?

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

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

Начну что то отвечать с 4-го вопроса. Тут как я понял по Евстифееву используется таймер/счетчик Т1. OCR1H:OCR1L(OCR1A:OCR1B) это два 16-битных регистра сравнения. CS 10= 0b010(делим системный тактовый сигнал на 8).WGM = 0b0001 возможно это WGM13(режим Fast PWM), за то есть такая настройка WGM12=00001(сброс по совпадению-модуль счета OCR1A). Но не нашел формулы расчета по вашим значениям. Там только есть пункт частота генерируемого сигнала и все.

---------------------------------------

Для отсчета времени будем использовать Т1(хотя и T0 подошел бы, но советует же Евстифеев).Перечислить все режимы таймеров с особенностями? Мне что книгу переписать? Там все вроде нужное слов не выкинешь. А так все очень-очень сложно.

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

Прошу прощения, сначала упомянул, что речь и задачи по Timer1, но потом стер. Разница между Timer1 и Timer0 в том, что первый 16-разрядный, а второй 8-разрядный. Из этого следует разное количество режимов работы (вон у Timer1 сколько режимов ШИМ (PWM), отличающихся максимальным значением 0x00FF, 0x01FF, 0x03FF, OCR1A, ICR, может еще что забыл). А Timer0 обычно самый примитивный (от контроллера зависит, у той же ATtiny2313 он почти не уступает Timer1, а у ATmega8 он умеет только самый простой режим работы).

Тут как я понял по Евстифееву используется таймер/счетчик Т1. OCR1H:OCR1L(OCR1A:OCR1B) это два 16-битных регистра сравнения
То, что я говорил про Timer1 можно было понять только по 3-му вопросу и обозначению OCR1H:OCR1L. Обозначение регистров через двоеточие показывает, что они в данном случае используются не как отдельные 8-битные, а как единая 16-битная регистровая пара. Поэтому ваша запись OCR1A:OCR1B неверна, тут надо было перечислять через запятую. По-хорошему, стоило бы написать OCR1AH:OCR1AL, OCR1BH:OCR1BL, но часто в литературе и в языках высокого уровня окончания H/L (High byte / Low byte надеюсь, очевидно) опускают и пишут OCR1A, OCR1B. Но при этом надо не забывать что это не отдельные регистры, а регистровые пары. Само собой, это не упрек, а разъяснение терминологии и традиций.
WGM = 0b0001 возможно это WGM13(режим Fast PWM), за то есть такая настройка WGM12=00001(сброс по совпадению-модуль счета OCR1A)
Тут тоже, возможно, я неточно выразился. WGM=0b0001 значит, что WGM13=0; WGM12=0; WGM11=0; WGM10=1. Режим 13 судя по таблице из даташита, вообще "reserved". Может, у вас другая книга Евстифеева? На роль справочника по ATtiny подходит "Микроконтроллеры AVR семейства Tiny". Для AT90S - "...семейства classic", а для ATmega - "...семейства Mega". Ну и даташит (с официального сайта Atmel, на английском) в любом случае более достоверный источник, чем любой перевод или компиляция. Хотя у Евстифеева я особых ляпов не замечал, кроме распиновки ISP-разъема.
Для отсчета времени будем использовать Т1(хотя и T0 подошел бы, но советует же Евстифеев).
Евстифеев советует?! Я там такого не видел. Вопрос про отсчет времени я вроде не задавал, но ответ, что подошел бы любой таймер, верен. T1 просто немного удобнее, поскольку 16-разрядный. Больше возможностей тонкой подстройки.
Перечислить все режимы таймеров с особенностями? Мне что книгу переписать?
Вот книгу переписывать точно не надо, понимания от этого вряд ли прибавится.

Вот, например, режим ШИМ. Их там аж 12 разновидностей, 7 phase-correct и 5 fast. В чем разница между этими двумя группами и в чем между режимами внутри групп?

А так все очень-очень сложно
Скорее, просто непривычно. Вам что ближе, цифровые микросхемы (логические элементы, счетчики, триггеры) или программирование для компьютера? С какой стороны идете к контроллерам, аналогии из какой области будут понятнее?

.

Внесу определенность, которую забыл в предыдущем посте. Контроллер ATtiny2313, кварц 20 МГц, рассматриваем Timer1.

3. Какой режим таймера будем использовать, чтобы получить на выходе (кстати, с какого вывода будем снимать?) сигнал частотой 1 кГц? Это уточнение 3-го вопроса.

5. Раз уж зашел разговор о "тактовом сигнале". Помимо уточненных условий, подаем на вывод Т1 (он же вход внешнего тактового сигнала для Timer1, он же PD5, он же 9-й вывод для DIP-корпуса) сигнал частотой 1 кГц. Какова будет частота тактирования таймера?

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

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

1.Насчет OCR1AH, OCR1AL эти определения для меня еще не столь привычны, но я постараюсь запомнить и да в книге так и записывалось, что правильно так именовать.

2.Вопрос по WGM. Я не знал что нужно так писать, думал читать в столбик, поэтому мой

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

1.OCR1AH, OCR1AL, да еще не освоился с описанием, да и автор так говорил именовать.

2.Вопрос по WGM(задаем режим работы таймера/счетчика Т1 как я понял, установкой битов регистра TCCR1B(WGM 13,12 )и TCCR1A(WGM11,10)). Не понял по той причине что не знал как правильно смотреть данные режима работы. Я думал надо в столбик один из них смотреть. А оказывается по вашей записи их надо смотреть слева направо, все. Этого не говорилось как читать, поэтому и неправильно записал. Это я запомнил. И вот откуда читал, привожу фрагмент из книги Евстифеева про Attiny.s807c4qer.jpg

3. Я как раз и рассматривал для данного микроконтроллера и частоты 20 МГц, это я еще помню).

А вот с расчетом я затрудняюсь где и что смотреть. Допустим если тактировать Т1 от внешнего сигнала я по другим урокам выставлял 111. Далее WGM по данной картинке и вашему описанию(WGM=0b0001) почему то равен = Phase Correct PWM, 8-битный при ТОP(что это и какое оно имеет значения я так и не понял), если следовать тому что я понял то, формула может иметь вид s80oa2jpy.jpg

т.е. 20МГц/2* 8*TOP,(где это загадочное число для этого ТОP взять я так и не понял). Вот такая у меня логика, скорее не правильная но разбираться же надо как то. Если что поправте. По этой ли формуле считать, если нет то по какой и почему. Спасибо.

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

Сами-то таблицы зачем было вставлять, поберегите объем форума :-) Книжка у меня точно такая же, можно было просто привести номер таблицы.

Так в таблице, 7 столбец, "модуль счета, TOP". С английского слово "top" переводится как "верх", по смыслу - верхняя граница счета. Итак, в свете этого, вопрос: чем отличаются разные Phase Correct PWM друг от друга?

Далее WGM по данной картинке и вашему описанию(WGM=0b0001) почему то равен = Phase Correct PWM, 8-битный
Верно. Этот режим я привел не для использования в частотометре, а только для примера. Формула для этого режима правильная. Надо объяснять откуда берутся коэффициенты?

Кстати, сравните номер режима и значение битов WGM. Например, WGM=0b0101 = 0x05 = 510 волшебным образом 5-му режиму работы.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

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

Ок, значит надо считать так 20 МГц/2* 8*255(для примера взял WGM 0b0001 TOP=$00FF=255), то имеем 4901Гц?

Итак, в свете этого, вопрос: чем отличаются разные Phase Correct PWM друг от друга?

Они отличаются: как я понял, разрешающей способностью от 8...10 бит(фиксированное значение) и содержимым определенных регистров(ICR1A или OCR1A).

Это я привел расчет как понял по той формуле(картинке которую прислал)

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

Да, ответ похож на правду.

"Содержимым регистров"? Всего лишь модуль счета (он же разрешающая способность) определяется не константой, а регистром OCR1A либо ICR1. Кстати, регистр ICR1 в таймере всего один, так что он не может быть ICR1A. Изначально он вообще не был предназначен для ШИМа, только сохранять значение TCNT1 при возникновении внешнего события "захвата".

Очевидно, постижение таймеров продолжается. Почти на все мои "домашние задания" вы ответили. Остался только вопрос #3

3. Какой режим таймера будем использовать, чтобы получить на выходе (кстати, с какого вывода будем снимать?) сигнал частотой 1 кГц? Это уточнение 3-го вопроса.

Вот этот вопрос пригодится в частотометре. Можно даже расширить и изменить его до задачи:

3а. Задача: вывести этот сигнал, частоты 1 кГц скажем на PB7 (именно потому, что этот вывод не соединен с таймером - придется делать программно в прерывании).

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

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

(под выводом имеется выход или вход).Мне нужно уточнить, по 3-му вопросу я должен настроить таймер на счет импульсов по нарастанию так?

Для примера подаю на вход 2313 допустим PD4(T0)=подаем сигнал. Это я должен настроить, как я понимаю не счетчик времени как мы решили Т1, а счетчик импульсов на входе, используем Т0, я по вашему вопросу только так и понимаю.

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

Нет, нужно получить заданную частоту, не зависящую от внешнего сигнала. То есть поделить тактовую частоту контроллера, чтобы прерывание срабатывало с частотой 1 кГц, на том же Timer1. Давайте для начала определимся, какой из 4 режимов использовать, Normal, CTC, fastPWM или Phase correct PWM? Какой из них наиболее гибко позволяет менять частоту? Например, рассмотренный нами 0001-й режим не подходит: он позволяет только делить системную тактовую частоту на 1, 8, 64 и т.д. Даже модуль счета (TOP) и тот константа. Кстати, а на сколько нам нужно поделить системную частоту?

Ну и, если уж хотите перейти к счету внешних импульсов, давайте параллельно решим что будем делать при переполнении. Timer0 всего 8-битный. Что будет, если за время измерения, на него придет больше 255 импульсов?

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

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

Почему phase correct pwm? Чем он лучше остальных режимов? Почему прерывание именно при переполнении, а не при сравнении? Собственно, для нашей задачи надо даже получить не частоту, а однократный интервал времени 1 мс, но пусть лучше будет частота.

И все-таки, на сколько надо поделить тактовый сигнал, чтобы из 20 МГц получить 1 кГц? Это же простая арифметика.

Какой режим позволяет делить тактовый сигнал на произвольное число? Не на 0x00FF, 0x01FF или там 0xFFFF, а на значение какого-нибудь регистра.

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

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

Наверное тут 2 опечатки. 20`000 кГц (тактовая) делится на 20`000 (а не на 200`000) чтобы получить 1 кГц (оно же 1000 Гц, но не 1000 кГц). Будем надеяться, вы поняли, что имеется в виду. Посмотрим на делитель 20`000: хотя он не помещается в 1 байт (макс. 255), о вполне помещается в 2 байта (65535). А регистры сравнения у Timer1 как раз двухбайтные. На частоте 10 Гц будет чуть сложнее. Можете также попробовать подобрать делитель (тактовая по прежнему 20 МГц, результирующая - 10 Гц), он уже не будет двухбайтным. Но это не помешает воспользоваться тем же таймером и в этом случае.

Итак, мы выяснили, что для получения колебаний с частотой 1 кГц (период 1 мс) надо поделить тактовый сигнал на 20000.

1. Я смотню, недопонимание материала еще осталось. Попробуйте сформулировать ответ на свой же вопрос "что такое TOP?"

2. Какой из режимов позволяет поделить тактовый сигнал на 20000 (0x4E20)?

3. Что делать, если делить надо на число, не влезающее в 2 байта? Например, хотим получить сигнал частотой 1/8 кГц (именно 1/8 выбрано не случайно).

Ругался на отсутствие форматирования исходного кода (включая отсутствие осмысленных комментариев и наличие неубранного после конфигуратора мусора) не менее 15 раз.

Часть моих наработок.

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

Откуда вы взяли эти 20кГц?

Пардон. Правда опечатка. Второпях поделил.

Так, берем 20 000 000/2 000 000= 10 Гц это влазит только в 3 байта ибо 2553=16581375

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

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

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

Гость
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Ответить в этой теме...

×   Вставлено с форматированием.   Восстановить форматирование

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

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

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

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

Загрузка...
  • Последние посетители   0 пользователей онлайн

    • Ни одного зарегистрированного пользователя не просматривает данную страницу

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