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

Некорректно работает прошивка. Должна мигать светодиодом при переполнении TIMER0

23.09.2025, 17:24. Показов 1835. Ответов 47

Студворк — интернет-сервис помощи студентам
Здравствуйте!

Когда-то давно, для общего развития, учился писать на ассемблере для avr и достиг неких результатов. Всё благодаря участникам данного форума, которые проявили ко мне невероятную терпимость!

Теперь было решено, одну из программ переписать с ассемблера на си в рамках факультатива. Но что-то пошло не так и я не смог разобраться что именно, но зацепка есть.

Программа на ассембере
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#include "def.h"
 
#define LED_PIN 5           
#define T0MAX   40          ; Max value for t0c counter.
 
 
.data
t0c:    .byte 1             ; Counter for timer.
led_on: .byte 1             ; Boolean for led.
 
 
.text                   ;+Interrupts section
.org 0x000
    jmp reset           ; Reset Handler.
.org 0x040
    jmp tim0ovf         ; Timer0 Overflow Handler.
.org 0x06a              ;-Interrupts section
main:
    rjmp main           ; Buzzer.
;main:
 
 
reset:
    ldi r16, hi8(RAMEND)        ; Stack init.
    out SPH, r16
    ldi r16, lo8(RAMEND)
    out SPL, r16
 
    ldi r16, (1<<LED_PIN)       ; High output for led5.
    out DDRB, r16
 
    ldi r16, 1          ; Start with led on.
    ldi XL, lo8(led_on)
    ldi XH, hi8(led_on)
    st X, r16
 
    ldi r16, 0          ; Set counter value.
    ldi XL, lo8(t0c)
    ldi XH, hi8(t0c)
    st X, r16
 
    rcall tim0init
 
    sei             ; Global Interrupt Enable.
 
    rjmp main           ; Start program.
;reset:
 
 
tim0init:
    push r16
 
    ldi r16, 0x00
    out TCNT0, r16          ; Set Timer0 zero time.
    ldi r16, (1<<1)
    sts TIMSK0, r16         ; Set interrupt Timer0 overflow TCNT0.
    ldi r16, 0b00000101
    out TCCR0B, r16         ; Set tick. 14.9.2 of datasheet.
    
    pop r16
    ret
;tim0init:
 
tim0ovf:                ; Timer0 Overflow Handler.
    ldi XL, lo8(t0c)        ; t0c to r16;
    ldi XH, hi8(t0c)
    ld r16, X
 
    inc r16             ; Increment t0c.
    cpi r16, T0MAX          ; Compare with T0MAX.
    brlo 1f             ; Skip if lower.
 
    ldi r16, 0          ; Reset t0c.
 
    ldi YL, lo8(led_on)     ; led_on to r17.
    ldi YH, hi8(led_on)
    ld r17, Y       
 
    cpi r17, 1          ; Is led_on?
    breq 2f             ; If equal jmp.
 
    inc r17             ; led_on = true
    ldi r18, (1<<LED_PIN)
    out PORTB, r18
    rjmp 3f
2:  
    dec r17             ; led_on = false
    ldi r18, (0<<LED_PIN)
    out PORTB, r18
3:
    st Y, r17
1:
    st X, r16           ; Load new value to t0c.
    reti
;tim0ovf:
Содержимое файла `def.h`:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef DEF_H_SENTY
#define DEF_H_SENTY
 
#define DDRB 0x04                                                                 
#define PORTB 0x05                                                                
 
#define XL r26
#define XH r27
#define YL r28
#define YH r29
                    /* Stack pointer. */
#define SPL 0x3D            /* 6.5.1 of datasheet. */
#define SPH 0x3E            /* 6.5.1 of datasheet. */
                    /* RAM pointers. */
#define SRAMSTART 0x100         /* 7.3 of datasheet. */
#define RAMEND  0x8FF           /* 7.3 of datasheet. */
                    /* timer0 section. */
#define TCCR0B 0x25         /* 14.9.2 of datasheet. */                          
#define TIMSK0 0x6E         /* 14.9.6 of datasheet. Interrupt Mask. */
#define TCNT0 0x26          /* 14.9.3 of datasheet. Timer Register. */
 
#endif
Моя попытка переписать это на С:
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
#include <avr/io.h>
#include <avr/interrupt.h>
 
enum { pin_led = 5, tim0_max = 40 };
 
volatile int g_tim0_counter = 0;
volatile char g_is_led_on = 1; /* Starts on. */
 
#if 1
ISR(TIMER0_OVF_vect)
{
    g_tim0_counter++;
 
    if (g_tim0_counter > tim0_max) {
        g_tim0_counter = 0;
        
        g_is_led_on = !g_is_led_on;
 
        PORTB = (g_is_led_on<<pin_led);
    }
}
#endif
 
static void init_led()
{
    DDRB = 1<<pin_led;      /* High output for led. */
    PORTB = g_is_led_on<<pin_led;   /* Switch led state. */
}
 
static void init_timer0()
{
    TCNT0 = 0;          /* T0 zero time. */
    TIMSK0 = 1<<1;          /* Set interrupt T0 overflowf TCNT0 */
    TCCR0B = 0b0000101;     /* Set 1/1024 tick. */
}
 
static void init()
{
    /* Is stack init needed?.. */
    init_led();
    init_timer0();
    sei();              /* Enable interrupts. */
}
 
int main()
{
    init();
    for (;;) {
    /* Just chill. */
    }
}
И `Makefile` им собирается, что ассемблерная, что сишная версия:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
FILENAME = blink_led_tim0
 
MCU = atmega328p
OBJCOPY = avr-objcopy
BAUDRATE = 57600
 
#compiler
GCC = avr-gcc
GCC_FLAGS = -Wall -g -nostdlib -ansi -short-enums
 
#flash
AVRDUDE_FLAGS = -F -V -D
    # -D -- Disable auto-erase for flash. Helps save the bootloader.
    # -F -- Helps if device signature was erased.
    # -V
 
build: $(FILENAME).c
    $(GCC) $(GCC_FLAGS) -mmcu=$(MCU) $< -o $(FILENAME).elf
 
flash: $(FILENAME).elf
    avrdude -b $(BAUDRATE) -c usbasp -p $(MCU) -P usb -U flash:w:$<
Ожидалось, что светодиод будет равномерно мигать, но нет. Мигает неравномерно, а значение в DDRB для светодиода не 1, а 0. Судя по всему, выполняется только подпрограмма `ISR(TIMER0_OVF_vect)`, а `main()` нет. `main()` переносил в начало исходного кода, оно отрабатывало, а всё что в `ISR(TIMER0_OVF_vect)` -- нет.

Проверил с помощью `avr-objdump`, судя по всему, некорректно формируются первые ячейки program memory, через которые и происходит прыжки при прерывании.

`avr-objdump` программы на ассемблере:
Assembler
1
2
3
4
5
6
7
8
9
Disassembly of section .text:
 
00000000 <__ctors_end>:
   0:   0c 94 36 00     jmp     0x6c    ; 0x6c <reset>
        ...
 
00000040 <.Loc.1>:
  40:   0c 94 51 00     jmp     0xa2    ; 0xa2 <tim0ovf>
        ...
`avr-objdump` программы на си:
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
Disassembly of section .text:
 
00000000 <__vector_16>:
   0:   1f 92           push    r1
   2:   0f 92           push    r0
   4:   0f b6           in      r0, 0x3f        ; 63
   6:   0f 92           push    r0
   8:   11 24           eor     r1, r1
   a:   2f 93           push    r18
   c:   8f 93           push    r24
   e:   9f 93           push    r25
  10:   ef 93           push    r30
  12:   ff 93           push    r31
  14:   cf 93           push    r28
  16:   df 93           push    r29
  18:   cd b7           in      r28, 0x3d       ; 61
  1a:   de b7           in      r29, 0x3e       ; 62
 
0000001c <.Loc.1>:
  1c:   80 91 02 01     lds     r24, 0x0102     ; 0x800102 <g_tim0_counter>
  20:   90 91 03 01     lds     r25, 0x0103     ; 0x800103 <g_tim0_counter+0x1>
  24:   01 96           adiw    r24, 0x01       ; 1
  26:   90 93 03 01     sts     0x0103, r25     ; 0x800103 <g_tim0_counter+0x1>
  2a:   80 93 02 01     sts     0x0102, r24     ; 0x800102 <g_tim0_counter>
 
0000002e <.Loc.2>:
  2e:   80 91 02 01     lds     r24, 0x0102     ; 0x800102 <g_tim0_counter>
  32:   90 91 03 01     lds     r25, 0x0103     ; 0x800103 <g_tim0_counter+0x1>
 
00000036 <.Loc.3>:
  36:   87 39           cpi     r24, 0x97       ; 151
  38:   91 05           cpc     r25, r1
  3a:   b4 f0           brlt    .+44            ; 0x68 <.L4>
 
0000003c <.Loc.4>:
  3c:   10 92 03 01     sts     0x0103, r1      ; 0x800103 <g_tim0_counter+0x1>
  40:   10 92 02 01     sts     0x0102, r1      ; 0x800102 <g_tim0_counter>
Как это дело поправить? Изучал исходники других проектов. Вроде всё должно быть нормально, но всё же что-то упускаю.

Добавлено через 1 час 13 минут
Смог найти в чём проблема. Нужно убрать флаг `-nostdlib`.

Добавлено через 56 минут
Гыгы, ещё в ассемблерной части, была ошибка, было так:
Assembler
1
2
ldi r16, (1<<1)
sts TIMSK0, r16         ; Set interrupt Timer0 overflow TCNT0.
А должно было быть так:
Assembler
1
2
ldi r16, (1<<0)
sts TIMSK0, r16         ; Set interrupt Timer0 overflow TCNT0.
Но на ассемблере оно в обоих случая работает. А вот на сишке нет...

А совсем правильно так:
C
1
TIMSK0 = 1<<TOIE0; /* TOIE0 -- бит под номером 0 отвечающий за перерыванию по переполнению таймера0.  */
1
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
23.09.2025, 17:24
Ответы с готовыми решениями:

SysTick можно ли с его помощью мигать светодиодом
Снова здравствуйте!) Перешел к изучению SysTck Рассмотрел примеры, в которых на основе этого...

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

Не работает TIMER0 OVF
Всем привет, подскажите почему программа не входит в обработчик прерывания хотя флаг выставляется,...

47
44 / 42 / 2
Регистрация: 23.01.2019
Сообщений: 326
25.09.2025, 11:35
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
можете перевести собранную прошивку в формат `base64`
Почему не 128
IntelHex 32-х битный, а avrasm2 создаёт 16-ти битные, если я ничего не путаю..
Возможно, если вы переведёте в другую битность, то и адреса поменяются. Я так глубоко не вникаю. Просто мне интереснее заниматься более творческими занятиями, чем биться с разными форматами и создавать и преодолевать прочие ненужные сложности.

Что в результате получаю я? Работающие устройства.
Что в результате получаете вы? То что у вас срабатывают прерывания, которые вы не разрешали.

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

Мне не жалко. В архиве тестовый исходник и файл скомпилированный в avrasm2.

test.rar

Но повторюсь, вы сами себе придумываете сложности.
0
1184 / 460 / 68
Регистрация: 22.09.2023
Сообщений: 1,397
25.09.2025, 11:39
В документации указаны адреса векторов в словах. гцц использует байтовую адресацию. Одно слово из документации (и avrasm) равно двум байтам гцц. Знатная подлянка, подложенная авторами ядра AVR.
1
44 / 42 / 2
Регистрация: 23.01.2019
Сообщений: 326
25.09.2025, 11:43
Цитата Сообщение от Dushevny Посмотреть сообщение
Одно слово из документации (и avrasm) равно двум байтам гцц.
Спасибо. С этим разобрались. Я этого не знал, да и не нужно было.

Но почему у ТС прерывания срабатывают, которые он не назначал
0
5 / 5 / 0
Регистрация: 03.09.2013
Сообщений: 79
25.09.2025, 11:45  [ТС]
Цитата Сообщение от shonty Посмотреть сообщение
Почему не 128
IntelHex 32-х битный, а avrasm2 создаёт 16-ти битные, если я ничего не путаю..
Вы меня совсем неправильно поняли. :^)

Поскольку прошивка получается в бинарном формате, чтобы её отправить plain text'ом, её можно перевести в формат base64.

А ещё, я не обратил внимание, что тут есть возможность прикрепить файл, я обычно общаюсь на форумах, где такой возможности нет. Затупил. )))

Цитата Сообщение от shonty Посмотреть сообщение
Мне не жалко. В архиве тестовый исходник и файл скомпилированный в avrasm2.
Да, спасибо!

Вот:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
0000003c <.sec15>:
  3c:   18 95           reti
 
Disassembly of section .sec16:
 
00000040 <.sec16>:
  40:   1c c0           rjmp    .+56        ;  0x7a
 
Disassembly of section .sec17:
 
00000044 <.sec17>:
  44:   18 95           reti
И метка на само прерывание:
Assembler
1
  7a:   18 95           reti
1
1184 / 460 / 68
Регистрация: 22.09.2023
Сообщений: 1,397
25.09.2025, 11:50
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
Мигает неравномерно,
Уточните термин "неравномерно".
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
а значение в DDRB для светодиода не 1, а 0.
Значение этой фразы тоже непонятно. Как проверяли?

Добавлено через 5 минут
Цитата Сообщение от shonty Посмотреть сообщение
Но почему у ТС прерывания срабатывают, которые он не назначал
Потому что он повесил обработчик на переполнение таймера, а разрешил прерывание по сравнению, и комментарий не соответствует коду:
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
C
1
TIMSK0 = 1<<1;          /* Set interrupt T0 overflowf TCNT0 */
0
5 / 5 / 0
Регистрация: 03.09.2013
Сообщений: 79
25.09.2025, 12:17  [ТС]
Конкретно данная проблема решена тем, что убрал флаг `-nostdlib`, т.к. с ним не формируется секция памяти программы для прерываний (векторов). Сейчас вопрос уже в другом. :^)

Но всё равно уточню.

Цитата Сообщение от Dushevny Посмотреть сообщение
Уточните термин "неравномерно".
Ожидаемая работа программы: что некоторое время t1 светодиод включен, а потом время t2 (t1 == t2) не включен. По факту было, что t1 != t2 при визуальном анализе. При этом t1 и t2 в ходе работы были не постоянного значения в ходе работы.

Цитата Сообщение от Dushevny Посмотреть сообщение
Значение этой фразы тоже непонятно. Как проверяли?
Визуально, по яркости светодиода. Если значение 1 в соответствующем бите регистра DDRB светодиод при включении горит ярко, если 0 -- тускло.


Повторюсь, что с этими проблемами разобрался.

Добавлено через 18 минут
Цитата Сообщение от Dushevny Посмотреть сообщение
Потому что он повесил обработчик на переполнение таймера, а разрешил прерывание по сравнению, и комментарий не соответствует коду:
Да, это правда. Это тоже исправил. Но!

При этом с кодом на ассемблере таймер работает как надо независимо от того, какие прерывания для timer0 я разрешил, главное, что разрешил.

Могу привести более актуальный код, если интересно поучаствовать. (Но правильнее, наверное, будет создать новый топик.)
0
44 / 42 / 2
Регистрация: 23.01.2019
Сообщений: 326
25.09.2025, 12:51
Цитата Сообщение от shonty Посмотреть сообщение
Почему не 128
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
Вы меня совсем неправильно поняли. :^)
Так и есть Скажу больше, число 64 меня несколько возмутило

Объясню почему.
Не так давно я пытался преобразовывать *.bmp изображения для вывода на дисплей. Сначала решил "выдирать" данные из бмп при помощи хекс-редактора. Но то что я увидел под виндой, было далеко от 8-ми или 16-ти бит
В результате пришлось поизучать паскаль Работа с *.bmp изображением
В содержание темы можно не вникать, там картинок достаточно. Добился кодирования изображений в RLE-сжатии до 8-ми цветов. Но это уже совсем другая история.. ))
0
 Аватар для COKPOWEHEU
4078 / 2676 / 432
Регистрация: 09.09.2017
Сообщений: 11,887
26.09.2025, 08:46
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
AVRDUDE_FLAGS = -F -V -D
# -D -- Disable auto-erase for flash. Helps save the bootloader.
Что-то глаз зацепился. Вдруг там и правда не производится стирание перед записью?
1
5 / 5 / 0
Регистрация: 03.09.2013
Сообщений: 79
26.09.2025, 10:30  [ТС]
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Что-то глаз зацепился. Вдруг там и правда не производится стирание перед записью?
Убрал флаг, попробовал с этими вариантами:
Assembler
1
2
3
4
ldi r16, (1<<3) ; В этом случае прерывание не работает. Но это вообще зарезервированный бит.
ldi r16, (1<<2) ; Прерывание по переполнению таймера работает.
ldi r16, (1<<1) ; Прерывание по переполнению таймера работает.
ldi r16, (1<<0) ; Прерывание по переполнению таймера работает.
Также просто убрал строку:
Assembler
1
sts TIMSK0, r16
в таком случае прерывание не работает.
0
1184 / 460 / 68
Регистрация: 22.09.2023
Сообщений: 1,397
26.09.2025, 19:09
Лучший ответ Сообщение было отмечено Medusa Kaiser как решение

Решение

Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
При этом с кодом на ассемблере таймер работает как надо независимо от того, какие прерывания для timer0 я разрешил, главное, что разрешил.
(с томной интонацией длинноной девочки-дизайнера) "Ну это же элементаааарно..."


Все другие прерывания тоже срабатывают пока таймер дотикает до переполнения. Просто в ассемблерном исполняемом коде у вас на месте остальных векторов пусто, там остается код "все единицы" из стертого флеша, которые (кажется) являются кодом операции NOP и при возникновении любого разрешенного прерывания исполнение "проваливается" по этим кодам до существующего обработчика переполнения, а в библиотечном коде гцц все неиспользуемые вектора забиты "заглушками" из одной команды reti и попав в любое другое прерывание ядро выполняет reti и выходит из него.
2
44 / 42 / 2
Регистрация: 23.01.2019
Сообщений: 326
26.09.2025, 19:15
Цитата Сообщение от Dushevny Посмотреть сообщение
при возникновении любого разрешенного прерывания исполнение "проваливается" по этим кодам до существующего обработчика переполнения
Тоже об этом думал.., но стеснялся высказаться.
1
44 / 42 / 2
Регистрация: 23.01.2019
Сообщений: 326
27.09.2025, 10:04
Проверил. avrasm2 у меня, поэтому адреса согласно дш.

при
Assembler
1
2
3
4
5
.ORG  0x001A reti   ; jmp TIMER1_OVF ; Timer/Counter1 Overflow
.ORG  0x001C reti   ; TIMER0_COMPA Timer/Counter0 Compare Match A
.ORG  0x001E reti   ; TIMER0_COMPB Timer/Coutner0 Compare Match B
.ORG  0x0020 jmp    T0_OVF  ; Timer/Counter0 Overflow
.ORG  0x0022 reti   ; SPI STC SPI Serial Transfer Complete
ldi R16, (1<<TOIE0) - работает
ldi R16, (1<<OCIE0A) - не работает

при
Assembler
1
2
3
4
5
.ORG  0x001A reti   ; jmp TIMER1_OVF ; Timer/Counter1 Overflow
; .ORG  0x001C reti ; TIMER0_COMPA Timer/Counter0 Compare Match A
; .ORG  0x001E reti ; TIMER0_COMPB Timer/Coutner0 Compare Match B
.ORG  0x0020 jmp    T0_OVF  ; Timer/Counter0 Overflow
.ORG  0x0022 reti   ; SPI STC SPI Serial Transfer Complete
ldi R16, (1<<TOIE0) - работает
ldi R16, (1<<OCIE0A) - работает

Полностью нужно таблицу векторов в коде писать. При сокращенном написании место во флеш не увеличится.
1
5 / 5 / 0
Регистрация: 03.09.2013
Сообщений: 79
27.09.2025, 23:05  [ТС]
Цитата Сообщение от Dushevny Посмотреть сообщение
Все другие прерывания тоже срабатывают пока таймер дотикает до переполнения.
Да, спасибо, очень похоже на правду, добавил строчки:
Assembler
1
2
3
4
5
6
.org 0x038                                                                      
        jmp reset                                                               
.org 0x03c                                                                      
        jmp reset                                                               
.org 0x040                                                                      
        jmp tim0ovf
После этого светодиод начал моргать, только когда я ставлю прерыванию по переполнению, в остальных случаях не работает!


Подскажите, пожалуйста, напоследок, как мне взять сишную программу, транслировать её сначала в ассемблерный код, а потом собрать? Я хочу в этих же местах поставить nop'ы, собрать и посмотреть что будет. :^)
0
Эксперт по электронике
6497 / 3127 / 331
Регистрация: 28.10.2011
Сообщений: 12,291
Записей в блоге: 7
28.09.2025, 00:34
Проще будет прошивку отредактировать.
2
1184 / 460 / 68
Регистрация: 22.09.2023
Сообщений: 1,397
28.09.2025, 01:35
Напишите свою таблицу векторов по примеру https://github.com/avrdudes/av... t1/gcrt1.S, подключите к проекту (с -nostartfiles, чтобы не было конфликтов) и пересоберите.

Скормить дизассемблированный код ассемблеру - задача непростая, тут уж точно, проще hex-редактором поправить двоичный код.
0
649 / 402 / 76
Регистрация: 21.09.2008
Сообщений: 1,385
28.09.2025, 09:42
Цитата Сообщение от Dushevny Посмотреть сообщение
тут уж точно, проще hex-редактором поправить двоичный код
Вангую, что следующая тема будет называться "Какой hex-редактор лучше?"
Можно попробовать 010 Editor. Испытательный срок 30 дней. Поддерживает множество форматов.
0
44 / 42 / 2
Регистрация: 23.01.2019
Сообщений: 326
28.09.2025, 09:55
Я может меркантильный , но какой практический смысл нопить сишную прошивку..
И вообще, как я раньше жил без этих знаний ..и даже писать что-то получалось
0
 Аватар для COKPOWEHEU
4078 / 2676 / 432
Регистрация: 09.09.2017
Сообщений: 11,887
28.09.2025, 11:11
Цитата Сообщение от Dushevny Посмотреть сообщение
Скормить дизассемблированный код ассемблеру - задача непростая
Но возможная. objdump плюс цепочка скриптов чтобы вычистить адреса и комментарии. Плюс еще километр костылей чтобы поправить то, что не понравилось дизассемблеру.
Но учитывая, что ТС хочет всего лишь проверить таблицу прерываний, можно и правда влезть руками в *.hex и поправить пару первых строк.
Цитата Сообщение от shonty Посмотреть сообщение
какой практический смысл нопить сишную прошивку..
Зачем же практический? Учебный. Убедиться, что проблема была именно в этом.
Цитата Сообщение от shonty Посмотреть сообщение
И вообще, как я раньше жил без этих знаний ..и даже писать что-то получалось
Ну, знания лишними не бывают.
0
44 / 42 / 2
Регистрация: 23.01.2019
Сообщений: 326
28.09.2025, 11:44
Цитата Сообщение от COKPOWEHEU Посмотреть сообщение
Ну, знания лишними не бывают.
Ллишь бы знания не были избыточными) меня на то что мне нужно не всегда хватает
Наверное многие столкнулись с такой ситуацией первый раз, невзирая на опыт. Поэтому и не сразу вопрос разрешился.

А нужно было всего лишь, или использовать gcc, или писать полную таблицу векторов на асме, или не использовать непонятную запись (1<<1), а вместо неё писать 0b0000_0001 или (1<<TOIE0).

Вобщем я за соблюдение элементарных правил + подсветку синтаксиса, тогда и отвлекаться меньше придётся
0
 Аватар для COKPOWEHEU
4078 / 2676 / 432
Регистрация: 09.09.2017
Сообщений: 11,887
28.09.2025, 14:13
Цитата Сообщение от shonty Посмотреть сообщение
Наверное многие столкнулись с такой ситуацией первый раз, невзирая на опыт.
Я, когда писал для AVR на асме, прописывал таблицу полностью, со всеми reti. Правда, без .org - не знал тогда про них. Возможно, потому и не обратил внимания.
Цитата Сообщение от shonty Посмотреть сообщение
или не использовать непонятную запись (1<<1), а вместо неё писать 0b0000_0001
Чтобы компилятор сразу ругнулся на некорректную конструкцию что ли?
Bash
1
2
3
4
5
6
7
8
9
10
$ cat main.c
#include <avr/io.h>
 
int main(){
  TIMSK0 = 0b0000_0001;
}$avr-gcc main.c -mmcu=atmega328
main.c: In function ‘main’:
main.c:4:12: error: invalid suffix "_0001" on integer constant
   TIMSK0 = 0b0000_0001;
            ^
И даже если исправить 0b0000_0001 на чуть менее синтаксически некорректное 0b00000001, по читабельности оно все равно уступит не то что человеческому варианту (1<<TOIE0), но даже (1<<1).
P.S. кстати, я не следил, в стандарт языка С ввели наконец 0b или оно так и остается "нестандартным".
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
28.09.2025, 14:13
Помогаю со студенческими работами здесь

PIC 16F876 Не работает прерывание от внутреннего TIMER0
Что я сделал не так? Работу проверяю через протеус. Компилятор XC8 из MPLAB #pragma config...

Мигание светодиода по переполнению счетчика
Проблема в том, что при проверке в AVRStudio, програмка не выходит из внутреннего цикла, где может...

Работа с прерыванием TIMER0. Atmega328p. Arduino nano
Хочу по прерыванию TIM0_OFV зажигать светодиод PB5. .equ DDRB, 0x04 ...

MP430. Timer0. Compare mode
Здравствуйте, я с вопросом по любимому msp430f5435 Настроил работу таймера на режим сравнения...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Новый ноутбук
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