Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
5 / 5 / 0
Регистрация: 03.09.2013
Сообщений: 79

Работа с прерыванием TIMER0. Atmega328p. Arduino nano

16.10.2024, 21:29. Показов 1996. Ответов 23

Студворк — интернет-сервис помощи студентам
Хочу по прерыванию TIM0_OFV зажигать светодиод PB5.

Assembler
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
.equ    DDRB, 0x04                                                              
.equ    PORTB, 0x05                                                             
                                                                                
.equ    TCCR0B, 0x25            ; 14.9.2 of datasheet.                          
.equ    TIMSK0, 0x6E            ; 14.9.6 of datasheet. Timer Interrupt Mask     
.equ    TCNT0, 0x26             ; 14.9.3 of datasheet. Timer Register.          
                                ; Register.                                     
.equ    SPH, 0x3E               ; 6.5.1 of datasheet.                           
.equ    SPL, 0x3D                                                               
                                                                                
.equ    RAMEND, 0x8FF           ; Не  до конца уверен, что правильно 
; определил эту константу, но если верить 7.3  datasheet 
; и заголовочникам, всё ок.                                           
                                                                                
.section .text   ; Эта куча nop'ов взята из той же методички Донова. 
; В datasheet вместо nop'ов прыжки на метки прерываний.                                                               
                                                                                
jmp RESET    ; Reset Handler                                                    
nop                                                                             
nop                                                                             
nop                                                                             
nop                                                                             
nop                                                                             
nop                                                                             
nop                                                                             
nop                                                                             
nop                                                                             
nop                                                                             
nop                                                                             
nop                                                                             
nop                                                                             
nop                                                                             
jmp TIM0_OVF ; Если сделать  avr-objdump -d main.elf, будет показано 
; что данная команда находится по адресу 0x20, по которому и должно быть
; указано по п. 11.1 datasheet                                        
nop                                                                             
nop                                                                             
nop                                                                             
nop                                                                             
nop                                                                             
nop                                                                             
nop                                                                             
nop                                                                             
nop                                                                             
                                                                                
main: rjmp main                                                               
                                                                                
RESET:                         
       ; инициализация стека                                          
        ldi r16, hi8(RAMEND)                                                    
        out SPH, r16                                                            
        ldi r16, lo8(RAMEND)                                                    
        out SPL, r16                                                            
                                                                                
        ldi r16, 0b00100000                                                     
        out DDRB, r16                                                                                                                    
         
        ; Настраиваем прерывания, это сделано по методичке Донова Г.И.
        ; с предварительно проверкой адресов в datasheet                                                               
        ldi r16, 0x00                                                           
        out TCNT0, r16          ; Set Timer0 zero time.                         
        ldi r16, 0x01                                                           
        sts TIMSK0, r16         ; Set interrupt for Timer0 overflow TCNT0.          
        ldi r16, 0b00000101                                                     
        out TCCR0B, r16         ; Set 1/1024 tick.                              
        sei                     ; Global Interrupt Enable                       
                                                                                
        rjmp main                                                               
                                                                                
                                                                                
TIM0_OVF:                                                                       
        sbi PORTB, 5                                                            
        reti

Собирается и прошивается так:
Code
1
2
3
avr-gcc -Wall -mmcu=atmega328p -nostdlib main.S -o main.elf
avrdude -b 57600 -c usbasp -p atmega328p -P usb \
    -U flash:w:main.elf
В результате, светодиодик не загорается. Что я делаю не так?
0
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
16.10.2024, 21:29
Ответы с готовыми решениями:

Не работает серво на ARDUINO NANO ATMEGA328P
Здравствуйте! Есть проблема не работает серво на ардуино nano, не ну то-есть как не работает....... она работала но в один прекрасный(ваще...

Проблемы с прошивкой Arduino Nano, ATmega328P
#define LED_R 11 // Pin D11 --> красный #define LED_G 10 // Pin D10 --> зеленый #define LED_B 9 // Pin D9 --> синий int red(); ...

Самопроизвольная перезагрузка Arduino Atmega328P
Добрый день. Заметил достаточно странное поведение, контроллер периодически самопроизвольно перезагружается. В данное время...

23
 Аватар для COKPOWEHEU
4078 / 2676 / 432
Регистрация: 09.09.2017
Сообщений: 11,885
16.10.2024, 23:25
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
Хочу по прерыванию TIM0_OFV зажигать светодиод PB5.
Это все же не относится к исполнению кода из неправильного места. Давайте попросим модератора откусить ваш вопрос в новую тему. Только название придумайте, например "TIM0 на ассемблере AVR"
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
.equ DDRB, 0x04
#include <avr/io.h> и не надо прописывать адреса вручную. Неужели не лень?!
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
jmp TIM0_OVF ; Если сделать avr-objdump -d main.elf, будет показано
; что данная команда находится по адресу 0x20, по которому и должно быть
; указано по п. 11.1 datasheet
Хорошо если так. Но лучше прописать явно:
Assembler
1
2
.org 0x0020
  jmp TIM0_OVF
Кстати, именно в таблице векторов будьте осторожны: размер jmp и rjmp отличается, и без .org это критично
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
.section .text
Просто .text. Директива .section предназначена для именованных "подсекций".
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
ldi r16, 0b00100000
Не привыкайте использовать магические числа. Если вам нужен 5-й бит, который ничем не выделяется из остальных, так и напишите ldi r16, (1<<5)
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
ldi r16, 0b00000101
out TCCR0B, r16 ; Set 1/1024 tick.
А вот здесь биты 0 и 2 это не просто биты, а трехбитное число, отвечающее за делитель таймера.
Assembler
1
2
ldi r16, (0b101<<CS00)
out _SFR_IO_ADDR(TCCR0B), r16
Кстати, будьте осторожны и всегда проверяйте, идут ли нужные биты подряд. Потому что WGM13:10, например, по-идиотски разделены на два регистра. И еще с каким-то регистром я также обжегся.
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
nop
main: rjmp main
RESET:
Видать, при допиливании предыдущего примера проглядели это. Внимательнее надо быть. Полагаю, проблема именно здесь.
1
5 / 5 / 0
Регистрация: 03.09.2013
Сообщений: 79
17.10.2024, 08:33  [ТС]
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
попросим модератора
Тему создал, модератора попросил.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
прописывать адреса вручную. Неужели не лень?!
В этом есть какая-то романтика.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
учше прописать явно
Прописал. Также указал 0x000 для jmp RESET и после конца секции прерываний 0x034. (В документации адрес 0x033, но если такой указать, ассемблер ругается на нечётное число).

"The most typical and general program setup for the reset and interrupt vector addresses in Atmel® ATmega328P is:"
Assembler
1
2
3
4
5
6
7
8
9
...
 
0x0030 jmp TWI ; 2-wire Serial Interface Handler
0x0032 jmp SPM_RDY ; Store Program Memory Ready Handler
;
0x0033 RESET: ldi r16, high(RAMEND); Main program start
0x0034 out SPH,r16
 
...
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Не привыкайте использовать магические числа.
Да тут магии для меня нет. В лекциях и в книгах все регистры показывают побитово, поэтому и хочется написать в битах. Буду писать со сдвигом, так, судя по всему, общепринято.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
примера проглядели это
Не понимаю что не так. main: rjmp main -- просто жужжалка. А так я жду пока переполнится TCNT0, произойдёт прерывание и диодик загорит.
0
 Аватар для FFPowerMan
2153 / 1232 / 508
Регистрация: 11.10.2018
Сообщений: 6,231
17.10.2024, 08:41
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
Assembler
1
2
3
4
5
6
7
8
.equ    DDRB, 0x04                                                              
.equ    PORTB, 0x05                                                             
.equ    TCCR0B, 0x25            ; 14.9.2 of datasheet.                          
.equ    TIMSK0, 0x6E            ; 14.9.6 of datasheet. Timer Interrupt Mask     
.equ    TCNT0, 0x26             ; 14.9.3 of datasheet. Timer Register.          
                                ; Register.                                     
.equ    SPH, 0x3E               ; 6.5.1 of datasheet.                           
.equ    SPL, 0x3D
- Как я уже говорил, адреса всех регистров прописаны в специальном файле, который есть в среде. И двойную работу делать не надо. А надо читать литературу, статьи в Интернете и т.д.

Добавлено через 1 минуту
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
Assembler
1
.section .text
- директивы не имеют смысла, это я также говорил, но Вы совершенно ничему не учитесь. Повторяйте теорию.

Добавлено через 2 минуты
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
Assembler
1
main: rjmp main
- Это пишется после инициализации. Заканчивайте со своими фокусами.

Добавлено через 4 минуты
0
5 / 5 / 0
Регистрация: 03.09.2013
Сообщений: 79
17.10.2024, 08:52  [ТС]
Цитата Сообщение от FFPowerMan Посмотреть сообщение
А надо читать литературу, статьи в Интернете и т.д.
Вы хоть конкретику укажите, я же после литературы же и дошёл до жизни такой.

Цитата Сообщение от FFPowerMan Посмотреть сообщение
директивы не имеют смысла
Каюсь. .section уже убрал. В nasm'е пишется "section .text (.bss, .data)", а тут видимо ассемблер ругнулся на section, а в интернете увидел как пишут ".section .text".

Цитата Сообщение от FFPowerMan Посмотреть сообщение
Это пишется после инициализации.
Если счётчик команд начинается с 0x00 и мы сразу прыгаем в метку RESET, какая разница где расположена жужжалка main: rjmp main в памяти программы (исключая, конечно же, адреса зарезервированные под прерывания) ?
0
 Аватар для FFPowerMan
2153 / 1232 / 508
Регистрация: 11.10.2018
Сообщений: 6,231
17.10.2024, 09:26
Зачем сразу прошивать готовое устройство? Пройдитесь дебаггером сначала - пошаговая отладка. Посмотрите, что в регистрах творится. Не забудьте симуляцию включить.
0
 Аватар для COKPOWEHEU
4078 / 2676 / 432
Регистрация: 09.09.2017
Сообщений: 11,885
17.10.2024, 09:35
Лучший ответ Сообщение было отмечено Medusa Kaiser как решение

Решение

Assembler
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
#include <avr/io.h>
 
#define b0(x)   (((x)>>0 )&0xFF)
#define b1(x)   (((x)>>8 )&0xFF)
#define b2(x)   (((x)>>16)&0xFF)
#define b3(x)   (((x)>>24)&0xFF)
 
.text
 
jmp RESET
.org (TIMER0_OVF_vect_num * 4)
jmp TIM0_OVF
.org _VECTORS_SIZE
 
RESET:
  ldi r16, hi8(RAMEND)
  out _SFR_IO_ADDR(SPH), r16
  ldi r16, lo8(RAMEND)
  out _SFR_IO_ADDR(SPL), r16
 
  ldi r16, (1<<5)
  out _SFR_IO_ADDR(DDRB), r16
 
  ldi r16, (1<<TOIE0)
  sts _SFR_MEM_ADDR(TIMSK0), r16
  ldi r16, (0b101 << CS00)
  out _SFR_IO_ADDR(TCCR0B), r16
 
  sei
main:
    rjmp main
 
TIM0_OVF:
  sbi _SFR_IO_ADDR(PINB), 5
  reti
Проблема была в том, что в даташите указывается не адрес байта, а адрес машинного слова. То есть нужно не 0x0020, a 0x0040 выставлять. И что еще хуже, размер jmp и nop разный, то есть их нельзя просто так менять.

Добавлено через 4 минуты
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
Да тут магии для меня нет.
Это пока. Когда освоите больше периферии и больше контроллеров, быстро забудете, что эти биты обозначают. А вот мнемоники вроде того же CS00 вспомнить легче. Опять же, вы ведь не пишете sbi 0x0x04, 0b00100000
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
Буду писать со сдвигом, так, судя по всему, общепринято.
Оно общепринято, потому что люди, более опытные чем вы или я, уже прошлись по этим граблям и придумали как их получше обойти.
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
Не понимаю что не так. main: rjmp main -- просто жужжалка.
Да, это моя невнимательность. Там у вас ошибки нет.
0
 Аватар для COKPOWEHEU
4078 / 2676 / 432
Регистрация: 09.09.2017
Сообщений: 11,885
17.10.2024, 10:33
Цитата Сообщение от FFPowerMan Посмотреть сообщение
- Как я уже говорил, адреса всех регистров прописаны в специальном файле, который есть в среде.
Неправда. Вы всего лишь голословно утверждали, что этот файл есть, но найти его не сумели.
Цитата Сообщение от FFPowerMan Посмотреть сообщение
- Это пишется после инициализации. Заканчивайте со своими фокусами.
Это не ошибка. jmp из таблицы векторов так и так начнет выполнение с RESET-а. Единственное что этот main - jmp main выглядит несколько непривычно, что и сбило меня с толку.
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
Вы хоть конкретику укажите, я же после литературы же и дошёл до жизни такой.
Евстифеев (перевод / компиляция даташитов), курс DiHalt-а "AVR. Учебный курс". Лично я начинал с Ревича "Занимательная электроника" (но там немного и тоже с косяками).
Цитата Сообщение от FFPowerMan Посмотреть сообщение
Зачем сразу прошивать готовое устройство? Пройдитесь дебаггером сначала - пошаговая отладка. Посмотрите, что в регистрах творится. Не забудьте симуляцию включить.
Давайте уж полную инструкцию какой симулятор ставить, как настроить, как к нему подключиться. Учитывая, что ТС использует avr-as, очевидно, AVRStudio / Atmel studio у него не установлено и, вполне возможно, нормально не заработают. Proteus тоже. Кажется, он не понимает современный стандарт эльфов, из-за чего с пошаговой отладкой все плохо. Теоретически есть simulavr, но как им пользоваться я не знаю.

Добавлено через 5 минут
Цитата Сообщение от Dushevny Посмотреть сообщение
Запись же (0b101<<CS00) однозначна, самодокументируема (не требует комментариев
Не совсем. Как минимум, стоит прокомментировать какому делителю эта комбинация соответствует. Ну и я уже упоминал пару битовых последовательностей, которые по факту нифига не последовательности, а разбиты по нескольким регистрам или по разным участкам одного регистра. Такое компилятор не отловит.
Но это так, несущественные уточнения. Medusa Kaiser учится по тому учебнику, который нашел и в котором, похоже, не все вещи рассматриваются должным образом.
1
 Аватар для FFPowerMan
2153 / 1232 / 508
Регистрация: 11.10.2018
Сообщений: 6,231
17.10.2024, 10:35
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Неправда. Вы всего лишь голословно утверждали, что этот файл есть, но найти его не сумели.
- Кто что не сумел найти?
Миниатюры
Работа с прерыванием TIMER0. Atmega328p. Arduino nano  
0
 Аватар для FFPowerMan
2153 / 1232 / 508
Регистрация: 11.10.2018
Сообщений: 6,231
17.10.2024, 10:35
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Это не ошибка.
- Я понял, что это не ошибка. Заканчивайте меня корить.
0
5 / 5 / 0
Регистрация: 03.09.2013
Сообщений: 79
17.10.2024, 10:45  [ТС]
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Проблема была в том, что в даташите указывается не адрес байта, а адрес машинного слова. То есть нужно не 0x0020, a 0x0040 выставлять. И что еще хуже, размер jmp и nop разный, то есть их нельзя просто так менять.
Да вы правы, так заработало. А как я должен был понять, какой адрес имеется ввиду?

Заработало, даже получается через таймер помигать диодом (дополнительные локальные метки добавил для читаемости):
Assembler
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
.equ    DDRB, 0x04                                                              
.equ    PORTB, 0x05                                                             
                                                                                
.equ    TCCR0B, 0x25            ; 14.9.2 of datasheet.                          
.equ    TIMSK0, 0x6E            ; 14.9.6 of datasheet. Timer Interrupt Mask     
.equ    TCNT0, 0x26             ; 14.9.3 of datasheet. Timer Register.          
                                                                                
.equ    SPH, 0x3E               ; 6.5.1 of datasheet.                           
.equ    SPL, 0x3D                                                               
                                                                                
.equ    RAMEND, 0x8FF           ;                                               
                                                                                
#define tim0_ovf_counter    r17                                                 
#define tim0_ovf_limiter    0x4                                                 
#define tim0_is_on          r18                                                 
                                                                                
.text                                                                           
                                                                                
.org 0x000                                                                      
jmp RESET    ; Reset Handler                                                    
                                                                                
.org 0x040                                                                      
jmp TIM0_OVF ; Timer0 Overflow Handler                                          
                                                                                
.org 0x080                                                                      
                                                                                
RESET:                                                                          
.stack_init:                                                                    
        ldi r16, hi8(RAMEND)                                                    
        out SPH, r16                                                            
        ldi r16, lo8(RAMEND)                                                    
        out SPL, r16                                                            
.set_timer0_variables:                                                          
        ldi tim0_ovf_counter, 0x00                                              
        ldi tim0_is_on, 0x00                                                    
.set_hi_output:                                                                 
        ldi r16, (1<<5)                                                         
        out DDRB, r16
.set_timer0_ovf_interrupt:                                                      
        ldi r16, 0x00                                                           
        out TCNT0, r16          ; Set Timer0 zero time.                         
        ldi r16, (1<<1)                                                         
        sts TIMSK0, r16         ; Set interrupt for Timer0 overflow TCNT0.      
        ldi r16, 0b00000100                                                     
        out TCCR0B, r16         ; Set 1/1024 tick.                              
        sei                     ; Global Interrupt Enable                       
.start_program:                                                                  
        rjmp main                                                               
                                                                                
main:                                                                           
        rjmp main                                                               
                                                                                
TIM0_OVF:                                                                       
        inc tim0_ovf_counter                                                    
        cp tim0_ovf_counter, tim0_ovf_limiter                                   
        brne .exit                                                              
.change_state:                                                                  
        ldi tim0_ovf_counter, 0x00                                              
        cp tim0_is_on, 0x00                                                     
        brne .turn_off                                                          
.turn_on:                                                                       
        ldi tim0_is_on, 0x01                                                    
        sbi PORTB, 5                                                            
        rjmp .exit                                                              
.turn_off:                                                                      
        ldi tim0_is_on, 0x00                                                    
        cbi PORTB, 5                                                            
.exit:                                                                          
        reti
Где-то явно закралась ошибка, т.к. я рассчитывал, что от значения tim0_ovf_limiter будет зависеть частота мигания, но это уже, как говорится, моя проблема. (Или потом создам отдельную тему. )

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Евстифеев (перевод / компиляция даташитов), курс DiHalt-а "AVR. Учебный курс". Лично я начинал с Ревича "Занимательная электроника" (но там немного и тоже с косяками).
Спасибо, гляну!

Как я понял, есть разные "диалекты" ассемблера для AVR, в этой литературе рассматривается который использует avr-as, avr-gcc? Сейчас, например, столкнулся, что .def не работает с avr-gcc, пришлось через #define. (А также я написал в нижнем регистре определения "типо переменные", когда это директивы макро-процессору, которые принято в верхнем регистре писать.)

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
он не понимает современный стандарт эльфов
Подтверждаю.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Давайте уж полную инструкцию какой симулятор ставить, как настроить, как к нему подключиться.
Я недавно нашёл статью с инструкцией, так что лучше не нагружать коллегу.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
main - jmp main выглядит несколько непривычно
А как общепринято жужжалку ставить?
0
 Аватар для COKPOWEHEU
4078 / 2676 / 432
Регистрация: 09.09.2017
Сообщений: 11,885
17.10.2024, 11:32
Цитата Сообщение от FFPowerMan Посмотреть сообщение
- Кто что не сумел найти?
Тот, кто говорил про ассемблерные файлы с объявлениями регистров.
Как подключить Си-шный файл настроек я ТСу показывал давным-давно, и даже командную строку привел чтобы оно работало.
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
А как я должен был понять, какой адрес имеется ввиду?
Не знаю. Собственно, если бы это было написано где-то на видном месте, я бы вас в это место и послал. А так самому экспериментировать пришлось, потому что это и правда не очевидно.
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
Заработало, даже получается через таймер помигать диодом
А мой код вы не запускали? Там ведь именно это и делается.
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
rjmp main
main:
rjmp здесь лишний. Еще раз: я же привел рабочий код, даже с оформлением, пусть и примитивным.
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
дополнительные локальные метки добавил для читаемости
Метки читаемости не добавляют, скорее наоборот. Метка воспринимается как что-то, куда могут прыгнуть. Поэтому если вы не хотите дезинформировать людей будто в середину инициализации выполнение попадает повторно, лучше лишних меток не ставить. Комментарии лучше.
Кстати, если хотите показать, что метка очень-очень локальная (цикл или условие в пределах пары десятков строчек), куда с другого конца кода не попадают, можно вообще обойтись цифрами:
Assembler
1
2
3
4
5
6
1:
  dec r16
    brne 1b //прыжок на метку "1" выше по коду
  rjmp 1f // прыжок на метку "1" ниже по коду
  ldi r16, 0xFF
1:
Логика такая же: цикл или условие не настолько уникальные события, чтобы давать каждому свои имена. Но вот если тот же цикл большой, строчек на 20, лучше поставить метку. И искать проще, и внутрь можно будет добавлять другие метки.
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
А также я написал в нижнем регистре определения "типо переменные", когда это директивы макро-процессору, которые принято в верхнем регистре писать.
Как и со всеми остальными соглашениями: вы вольны их игнорировать, если знаете зачем и если это дает какое-то преимущество. Скажем, макрофункции часто именуются как обычные функции. Потому что использование их одинаковое: #define sqr(x) ((x)*(x))
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
Как я понял, есть разные "диалекты" ассемблера для AVR, в этой литературе рассматривается который использует avr-as, avr-gcc?
Да, диалектов у avr-ассмеблера несколько. Но на практике полезнее гнутый, поскольку в ассемблерных вставках используется именно он.
Кстати об ассемблерных вставках: вы правильно сделали, что начали изучать контроллеры с ассемблера, поскольку это дает отличное представление о функционировании как самого контроллера, так и, шире, ЭВМ вообще. Но слишком на ассемблере засиживаться не стоит. У вас 32кБ флеша, программу, которая была бы достаточно сложной чтобы его занять, вы на ассемблере не напишете, это слишком долго. Поэтому предлагаю сначала просто поиграться с контроллером, пощупать внутренности и периферию (что вы сейчас и делаете). Потом, например, реализовать какой-нибудь несложный проект. А потом уходить в сторону Си.
1
 Аватар для FFPowerMan
2153 / 1232 / 508
Регистрация: 11.10.2018
Сообщений: 6,231
17.10.2024, 11:42
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Тот, кто говорил про ассемблерные файлы с объявлениями регистров.
- Ну я говорил и нашел. Не надо претензии лепить там, где их нет.
0
5 / 5 / 0
Регистрация: 03.09.2013
Сообщений: 79
17.10.2024, 11:49  [ТС]
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
А мой код вы не запускали? Там ведь именно это и делается.
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
rjmp здесь лишний. Еще раз: я же привел рабочий код, даже с оформлением, пусть и примитивным.
Да. Мне было интересно сделать это по возможности самостоятельно через прерывание таймера.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Как и со всеми остальными соглашениями
Я в основном ориентируюсь на книгу "Оформление программного кода" Столярова А.В., хотя про конкретно ассемблер там мало.

Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Потом, например, реализовать какой-нибудь несложный проект.
Идея для проекта есть, но решил начать "с мелких задачек", чтобы просто убедиться что я с базовыми вещами справляюсь (как видите, убедился в обратном).


Большое спасибо, сам бы я тут вряд ли справился!
0
1182 / 458 / 68
Регистрация: 22.09.2023
Сообщений: 1,384
17.10.2024, 13:38
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
Да вы правы, так заработало. А как я должен был понять, какой адрес имеется ввиду?
Из документации:

Иногда ее бывает полезно прочитать от корки до корки.

И не забыть сказать "спасибо" горячим финским студентам-изобретателям ядра AVR за этот бардак.
0
1182 / 458 / 68
Регистрация: 22.09.2023
Сообщений: 1,384
17.10.2024, 13:53
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Проблема была в том, что в даташите указывается не адрес байта, а адрес машинного слова. То есть нужно не 0x0020, a 0x0040 выставлять.
Еще одна проблема в том, что меги 48, 88, 168 и 328 засунули в одно описание. И нажимая на "прерывания" в оглавлении попадаешь на таблицу прерываний меги 48, у которой (как и у 88) размер вектора равен одному слову.

Я вот про адрес сразу подумал, полез в документацию, ткнул в оглавление, увидел таблицу, нашел в ней TIMER0_OVF, увидел 0x010, умножил на 2, получил 0x20, подумал "вот молодец Medusa Kaiser, знает, что программное слово равно двум байтам, проблема не тут". А вот про то, что начиная с 168 меги rjmp уже не может покрыть все адресное пространство и размер вектора сделан под размер jmp, то есть 2 слова (4 байта), за много лет уже забыл и на то, что эта таблица от меги 48 внимания не обратил...
0
5 / 5 / 0
Регистрация: 03.09.2013
Сообщений: 79
17.10.2024, 14:08  [ТС]
Цитата Сообщение от Dushevny Посмотреть сообщение
И не забыть сказать "спасибо" горячим финским студентам-изобретателям ядра AVR за этот бардак.
Лучше скажу вам спасибо, что тыкнули где именно это. Но, честно, я если бы и прочитал выделенный текст, то не понял бы о чём речь.

Цитата Сообщение от Dushevny Посмотреть сообщение
Еще одна проблема в том, что меги 48, 88, 168 и 328 засунули в одно описание
Я смотрю в datasheet конкретно на 328p.

Цитата Сообщение от Dushevny Посмотреть сообщение
"вот молодецMedusa Kaiser, знает, что программное слово равно двум байтам
Хаха, попался! Смог заставить думать о себе слишком хорошо!
0
 Аватар для COKPOWEHEU
4078 / 2676 / 432
Регистрация: 09.09.2017
Сообщений: 11,885
17.10.2024, 15:14
Цитата Сообщение от FFPowerMan Посмотреть сообщение
- Ну я говорил и нашел.
Его можно подключить напрямую в ассемблерный файл и использовать как написано в книге (то есть без _SFR_IO_ADDR)? Нет.
Согласитесь, сама проблема, с которой ТС пришел на форум, совсем не очевидная, и ваше "читай документацию" было не к месту. Ну либо опишите процесс логических построений, как он должен был ее решить.
Потому что я-то оба раза попытался это сделать и не преуспел - почему и привел готовые решения. Ну и потому Medusa Kaiser действительно пытается разобраться в теме, а не попрошайничает готовое решение к очередной лабораторке.
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
Лучше скажу вам спасибо, что тыкнули где именно это. Но, честно, я если бы и прочитал выделенный текст, то не понял бы о чём речь.
Там, к сожалению, не про это написано. Строго говоря, нас обычно вообще не волнует какой там размер машинного слова - на адресацию это не влияет. В тех же x86_64 машинное слово вообще 64-битное, но адреса все равно побайтные. И какой логикой руководствовались Микрочипы тогда еще Атмелы, когда нумеровали адреса именно в машинных словах, мне неизвестно. Постоянно приходится угадывать нужно там умножение на 2 или нет.
Цитата Сообщение от Dushevny Посмотреть сообщение
начиная с 168 меги rjmp уже не может покрыть все адресное пространство и размер вектора сделан под размер jmp, то есть 2 слова (4 байта),
Еще одна причина использовать абсолютные адреса (.org). Ну или писать на Си, где с адресами разбирается компилятор. Но к этому ТС еще придет.
0
5 / 5 / 0
Регистрация: 03.09.2013
Сообщений: 79
17.10.2024, 23:16  [ТС]
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
Где-то явно закралась ошибка, т.к. я рассчитывал, что от значения tim0_ovf_limiter будет зависеть частота мигания, но это уже, как говорится, моя проблема.
Ошибки нашёл. В прерывании TIM0_OVF везде вместо cp должно быть cpi.
0
649 / 402 / 76
Регистрация: 21.09.2008
Сообщений: 1,385
18.10.2024, 18:15
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Давайте уж полную инструкцию какой симулятор ставить, как настроить, как к нему подключиться.
QEMU вполне неплох. Можно сделать по этому руководству .
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
18.10.2024, 18:15
Помогаю со студенческими работами здесь

Arduino uno на atmega328P-PU ошибка
Всем доброго времени суток, уважаемые! Купил сыну на день рождения на али робота, собрал, а обновить прошивку не дает. Выдает ошибку...

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

Тестировщик на Arduino Nano
Доброго времени, нужен элементарный скетч на тестировщик, однако по алгоритму и уточнить ряд неясностей: 1) Замеряем тестируемое...

Arduino Nano, I2C
Привет бойцы невидимого фронта. Проблема такова, у меня есть часы реального времени DS1307, и OLED I2C дисплей 0.91 (128x32) а так же...

Программирование Arduino nano
Через каждые 20 мс производить опрос кнопки с помощью таймера, и если кнопка нажата, то импульсы выключить, а если кнопка не нажатой...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
Фото: Daniel Greenwood
kumehtar 13.11.2025
Расскажи мне о Мире, бродяга
kumehtar 12.11.2025
— Расскажи мне о Мире, бродяга, Ты же видел моря и метели. Как сменялись короны и стяги, Как эпохи стрелою летели. - Этот мир — это крылья и горы, Снег и пламя, любовь и тревоги, И бескрайние. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru