5 / 5 / 0
Регистрация: 03.09.2013
Сообщений: 79

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

23.09.2025, 17:24. Показов 2973. Ответов 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
51 / 49 / 2
Регистрация: 23.01.2019
Сообщений: 380
25.09.2025, 11:35
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
можете перевести собранную прошивку в формат `base64`
Почему не 128
IntelHex 32-х битный, а avrasm2 создаёт 16-ти битные, если я ничего не путаю..
Возможно, если вы переведёте в другую битность, то и адреса поменяются. Я так глубоко не вникаю. Просто мне интереснее заниматься более творческими занятиями, чем биться с разными форматами и создавать и преодолевать прочие ненужные сложности.

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

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

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

test.rar

Но повторюсь, вы сами себе придумываете сложности.
0
1509 / 526 / 76
Регистрация: 22.09.2023
Сообщений: 1,669
25.09.2025, 11:39
В документации указаны адреса векторов в словах. гцц использует байтовую адресацию. Одно слово из документации (и avrasm) равно двум байтам гцц. Знатная подлянка, подложенная авторами ядра AVR.
1
51 / 49 / 2
Регистрация: 23.01.2019
Сообщений: 380
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
1509 / 526 / 76
Регистрация: 22.09.2023
Сообщений: 1,669
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
51 / 49 / 2
Регистрация: 23.01.2019
Сообщений: 380
25.09.2025, 12:51
Цитата Сообщение от shonty Посмотреть сообщение
Почему не 128
Цитата Сообщение от Medusa Kaiser Посмотреть сообщение
Вы меня совсем неправильно поняли. :^)
Так и есть Скажу больше, число 64 меня несколько возмутило

Объясню почему.
Не так давно я пытался преобразовывать *.bmp изображения для вывода на дисплей. Сначала решил "выдирать" данные из бмп при помощи хекс-редактора. Но то что я увидел под виндой, было далеко от 8-ми или 16-ти бит
В результате пришлось поизучать паскаль Работа с *.bmp изображением
В содержание темы можно не вникать, там картинок достаточно. Добился кодирования изображений в RLE-сжатии до 8-ми цветов. Но это уже совсем другая история.. ))
0
 Аватар для COKPOWEHEU
4148 / 2726 / 433
Регистрация: 09.09.2017
Сообщений: 12,080
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
1509 / 526 / 76
Регистрация: 22.09.2023
Сообщений: 1,669
26.09.2025, 19:09
Лучший ответ Сообщение было отмечено Medusa Kaiser как решение

Решение

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


Все другие прерывания тоже срабатывают пока таймер дотикает до переполнения. Просто в ассемблерном исполняемом коде у вас на месте остальных векторов пусто, там остается код "все единицы" из стертого флеша, которые (кажется) являются кодом операции NOP и при возникновении любого разрешенного прерывания исполнение "проваливается" по этим кодам до существующего обработчика переполнения, а в библиотечном коде гцц все неиспользуемые вектора забиты "заглушками" из одной команды reti и попав в любое другое прерывание ядро выполняет reti и выходит из него.
2
51 / 49 / 2
Регистрация: 23.01.2019
Сообщений: 380
26.09.2025, 19:15
Цитата Сообщение от Dushevny Посмотреть сообщение
при возникновении любого разрешенного прерывания исполнение "проваливается" по этим кодам до существующего обработчика переполнения
Тоже об этом думал.., но стеснялся высказаться.
1
51 / 49 / 2
Регистрация: 23.01.2019
Сообщений: 380
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
Эксперт по электронике
7178 / 3354 / 346
Регистрация: 28.10.2011
Сообщений: 13,215
Записей в блоге: 7
28.09.2025, 00:34
Проще будет прошивку отредактировать.
2
1509 / 526 / 76
Регистрация: 22.09.2023
Сообщений: 1,669
28.09.2025, 01:35
Напишите свою таблицу векторов по примеру https://github.com/avrdudes/av... t1/gcrt1.S, подключите к проекту (с -nostartfiles, чтобы не было конфликтов) и пересоберите.

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

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

Вобщем я за соблюдение элементарных правил + подсветку синтаксиса, тогда и отвлекаться меньше придётся
0
 Аватар для COKPOWEHEU
4148 / 2726 / 433
Регистрация: 09.09.2017
Сообщений: 12,080
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
Ответ Создать тему
Опции темы

Новые блоги и статьи
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru