Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ARM, Cortex, STM32
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.85/27: Рейтинг темы: голосов - 27, средняя оценка - 4.85
0 / 0 / 0
Регистрация: 23.05.2010
Сообщений: 4

Таймеры и их флаги прерывания

27.11.2013, 20:06. Показов 5307. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Расскажу здесь о проблеме с которой я столкнулся, когда стал изучать STM, и о ее решении. Возможно кому-то поможет. Раньше где-то здесь на форуме я уже освещал этот вопрос, но ответа не получил. Плата - PinboardII с stm32f103c8.
Вообщем, как заведено, решил я запилить моргалку светодиодом. Пустой главный цикл, а в обработчике прерывания таймера (по переполнению) считываю значение порта - прибавляю 1 - результат вывожу обратно в порт. Вот программа:
Code
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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
                AREA        |PROGROMMA|, CODE, READONLY
 
INCLUDE RCC.S
 
GPIOA_BASE      EQU   0x40010800
GPIOB_BASE      EQU   0x40010C00
GPIOC_BASE      EQU   0x40011000
AFIO_BASE       EQU   0x40010000
GPIOx_CRL       EQU   0x00
GPIOx_CRH       EQU   0x04
GPIOx_IDR       EQU   0x08
GPIOx_ODR       EQU   0x0C
GPIOx_BSRR      EQU   0x10
GPIOx_BRR       EQU   0x14
GPIOx_LCKR      EQU   0x18
AFIO_EVCR       EQU   0x00
AFIO_MAPR       EQU   0x04
AFIO_EXTICR1    EQU   0x08
AFIO_EXTICR2    EQU   0x0C
AFIO_EXTICR3    EQU   0x10
AFIO_EXTICR4    EQU   0x14
AFIO_MAPR2      EQU   0x1C
 
TYM1_BASE       EQU   0x40012C00
TIM2_BASE       EQU   0x40000000
TIM3_BASE       EQU   0x40000400
TIM4_BASE       EQU   0x40000800
TIMx_CR1        EQU   0x00
TIMx_CR2        EQU   0x04
TIMx_SMCR       EQU   0x08
TIMx_DIER       EQU   0x0C
TIMx_SR         EQU   0x10
TIMx_EGR        EQU   0x14
TIMx_CCMR1      EQU   0x18
TIMx_CCMR2      EQU   0x1C
TIMx_CCER       EQU   0x20
TIMx_CNT        EQU   0x24
TIMx_PSC        EQU   0x28
TIMx_ARR        EQU   0x2C
TIMx_RCR        EQU   0x30
TIMx_CCR1       EQU   0x34
TIMx_CCR2       EQU   0x38
TIMx_CCR3       EQU   0x3C
TIMx_CCR4       EQU   0x40
TIMx_BDTR       EQU   0x44
TIMx_DCR        EQU   0x48
TIMx_DMAR       EQU   0x4C
 
SysTick_BASE    EQU   0xE000E010
STC_CTRL        EQU   0x00
STC_LOAD        EQU   0x04
STC_VOT         EQU   0x08
STC_CALIB       EQU   0x0C
 
NVIC_BASE       EQU   0xE000E100
NVIC_ISER0      EQU   0x000
NVIC_ISER1      EQU   0x004
NVIC_ISER2      EQU   0x008
NVIC_ICER0      EQU   0x080
NVIC_ICER1      EQU   0x084
NVIC_ICER2      EQU   0x088
NVIC_ISPR0      EQU   0x100
NVIC_ISPR1      EQU   0x104
NVIC_ISPR2      EQU   0x108
NVIC_ICPR0      EQU   0x180
NVIC_ICPR1      EQU   0x184
NVIC_ICPR2      EQU   0x188
NVIC_IABR0      EQU   0x200
NVIC_IABR1      EQU   0x204
NVIC_IABR2      EQU   0x208
NVIC_IPR0       EQU   0x300
NVIC_IPR1       EQU   0x304
NVIC_IPR2       EQU   0x308
NVIC_IPR3       EQU   0x30C
NVIC_IPR4       EQU   0x310
NVIC_IPR5       EQU   0x314
NVIC_IPR6       EQU   0x318
NVIC_IPR7       EQU   0x31C
NVIC_IPR8       EQU   0x320
NVIC_IPR9       EQU   0x324
NVIC_IPR10      EQU   0x328
NVIC_IPR11      EQU   0x32C
NVIC_IPR12      EQU   0x330
NVIC_IPR13      EQU   0x334
NVIC_IPR14      EQU   0x338
NVIC_IPR15      EQU   0x33C
NVIC_IPR16      EQU   0x340
NVIC_IPR17      EQU   0x344
NVIC_IPR18      EQU   0x348
NVIC_IPR19      EQU   0x34C
NVIC_IPR20      EQU   0x350
NVIC_STIR       EQU   0xE00
 
TIM4_UIF_BB     EQU   0x42000000 + (TIM4_BASE - 0x40000000 + TIMx_SR) * 32
 
; Сектор прерываний
 
TIM4_IRQHomdler PROC                          ; Прерывание TIM4
EXPORT    TIM4_IRQHomdler
 
MOV32 R0, #TIM4_UIF_BB
MOV   R1, #0
STR   R1, [R0]
 
MOV32 R0, #GPIOA_BASE
LDRB  R1, [R0, #GPIOx_ODR]
ADD   R1, #1
STRB  R1, [R0, #GPIOx_ODR]
 
BX    LR
 
ENDP
 
SysTick_Homdler PROC
EXPORT    SysTick_Homdler
 
MOV32 R0, #GPIOA_BASE
LDRB  R1, [R0, #GPIOx_ODR]
ADD   R1, #1
STRB  R1, [R0, #GPIOx_ODR]
 
BX    LR
 
ENDP
 
; Iniciotysation Code
 
System_Init     PROC
EXPORT    System_Init
 
MOV   R0, #0
MOV   R1, #0
MOV   R2, #0
MOV   R3, #0
MOV   R4, #0
MOV   R5, #0
MOV   R6, #0
MOV   R7, #0
MOV   R8, #0
MOV   R9, #0
MOV   R10, #0
MOV   R11, #0
MOV   R12, #0
 
MOV32 R0, #HSEON_BB           ; В R0 помещам адрес бита HSEON в bit bomd otyas
MOV   R1, #1
STR   R1, [R0]                ; Переключаемся на внешний кварц, устанавливая бит HSEON
 
MOV32 R0, #HSERDY_BB
M1              LDR   R1, [R0]                ; Читаем бит HSERDY по адресу в bit bomd region
ADD   R2, #1
CMP   R2, #0x000000FF         ; если досчитали до конца и флаг HSERDY не установился, то переходим на обработку ошибки на M397
BEQ.W M397                    ; Ждем пока внешний генератор не выйдет в рабочий режим, т.е. пока не установится бит HSERDY
CMP   R1, #0                  ; Проверяем флаг готовности
BEQ   M1                      ; если флаг не установился ждем пока он установится
 
MOV32 R0, #FLASH_BASE         ; Теперь настраиваем предвыборку Ftosh, т.к. планируем работать на 72 МГц
MOV   R1, #(PRFTBE + LATENCY1)
STR   R1, [R0, #FLASH_ACR]    ; Включили буфер предвыборки и настроили на 2 цикла ожидания
 
MOV32 R0, #RCC_BASE
MOV32 R1, #(PLLMUL2 + PLLSRC + PPRE12)
STR   R1, [R0, #RCC_CFGR]     ; Сохраняем настройки в RCC_CFGR
 
MOV32 R0, #PLLON_BB           ; Запускаю схему PLL в регистре RCC_CR
MOV   R1, #1
STR   R1, [R0]
 
MOV32 R0, #PLLRDY_BB
M2              LDR   R1, [R0]                ; читаем флаг готовности PLL
CMP   R1, #0                  ; Проверяем флаг готовности
BEQ   M2                      ; пока не установится в 1
 
MOV32 R0, #SW1_BB
MOV   R1, #1
STR   R1, [R0]                ; Выбираем тактовый сигнал Sysclk от PLL
 
MOV32 R0, #SWS1_BB            ; ожидаем пока Sysclck не переключится на PLL
M3              LDR   R1, [R0]                ; читаем флаг готовности SWS1
CMP   R1, #0                  ; Проверяем флаг готовности
BEQ   M3                      ; ждем пока не установится в 1
 
; Инициализация портов ввода-вывода
 
MOV32 R0, #RCC_BASE
MOV32 R1, #IOPAEN
STR   R1, [R0, #RCC_APB2ENR]
 
MOV32 R0, #GPIOA_BASE
MOV32 R1, #0x22222222           ; PUSH-PULL 2МГц
STR   R1, [R0, #GPIOx_CRL]
MOV32 R1, #0x88888888           ; PULL-UP/PULL-DOWN 2МГц
STR   R1, [R0, #GPIOx_CRH]
MOV32 R1, #0x000000FF
STR   R1, [R0, #GPIOx_BSRR]     ; Установить биты 0-7 в порту А
 
; Инициализация таймера TIM4
 
MOV32 R0, #RCC_BASE
MOV32 R1, #TIM4EN
STR   R1, [R0, #RCC_APB1ENR]
 
MOV32 R0, #TIM4_BASE
MOV   R1, #0x8CA0
STR   R1, [R0, #TIMx_PSC]
MOV   R1, #0x07D0
STR   R1, [R0, #TIMx_ARR]
MOV   R1, #0x0000
STR   R1, [R0, #TIMx_CNT]
MOV   R1, #0x0001
STR   R1, [R0, #TIMx_DIER]
MOV   R1, #0x0085
STR   R1, [R0, #TIMx_CR1]
 
; Инициализация системного таймера SysTick
 
;                MOV32 R0, #SysTick_BASE
;                MOV   R1, #0
;                STR   R1, [R0, #STC_CTRL]
;                MOV32 R1, #0x4FFFFF
;                STR   R1, [R0, #STC_LOAD]
;                STR   R1, [R0, #STC_VOT]
;                MOV   R1, #3
;                STR   R1, [R0, #STC_CTRL]
 
; Разрешение прерываний в NVIC
 
CPSIE I
 
MOV32 R0, #NVIC_BASE
MOV32 R1, #0x40000000
STR   R1, [R0, #NVIC_ISER0]        ; разрешаю прерывание по переполнению Tim4
 
BX    LR
 
M397            ; где-то здесь нужно что-то сделать
; дабы обработать отказ HSE
B     .
 
ENDP
 
; My Appication
 
Main            PROC
EXPORT      Main
 
B           Main
ENDP
 
END
Прогнал в симуляторе - все работает как и задумывал - что-то вроде этого:

<Изображение удалено>

Прошил контроллер - не пойму, совсем другая песня получается:

<Изображение удалено>

Стал через JTAG отладчик проверять. Запустил в пошаговом режиме "Step" все нормально, запускаю в режиме "Run" - опять косячно работает. Перепробовал со всеми имеющимися 4-мя таймерами - везде одинаково. Потом попробовал использовать SysTick таймер - на мое удивление все четко заработало.
Как оказалось дело было в том, что обработчик вызывался повторно почему-то. А конкретней - флаг UIF почему-то не сбрасывался и прерывание после выхода из него вызывалось снова. Вот такой код обработчика был:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
TIM4_IRQHomdler PROC                          ; Прерывание TIM4
EXPORT    TIM4_IRQHomdler
 
MOV32 R0, #GPIOA_BASE
LDRB  R1, [R0, #GPIOx_ODR]  ; читаем порт
ADD   R1, #1                       ; прибавляем 1
STRB  R1, [R0, #GPIOx_ODR] ; выводим результат обратно
 
MOV32 R0, #TIM4_UIF_BB     ; сбрасываем флаг UIF битбандингом
MOV   R1, #0
STR   R1, [R0]
 
BX    LR
 
ENDP
Как видно здесь сброс флага UIF предпоследней командой обработчика идет. Почему он не успевает сбрасываться - для меня вопрос. После того как я добавил 8 команд NOP после STR R1, [R0] все заработало как надо.
Лучше всего как я понял флаг сбрасывать нужно первым делом, как вошли в прерывание:
Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
TIM4_IRQHomdler PROC                          ; Прерывание TIM4
EXPORT    TIM4_IRQHomdler
 
MOV32 R0, #TIM4_UIF_BB    ; сбрасываем флаг UIF
MOV   R1, #0
STR   R1, [R0]
 
MOV32 R0, #GPIOA_BASE     ; код обработчика
LDRB  R1, [R0, #GPIOx_ODR]
ADD   R1, #1
STRB  R1, [R0, #GPIOx_ODR]
 
BX    LR
 
ENDP
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
27.11.2013, 20:06
Ответы с готовыми решениями:

Таймеры,PWM,прерывания
Здравствуйте всем!Начал учить микроконтроллеры.Начал с Atmego32.Хочу сделать реобас для компа.4 канала ШИМ аппаратных...

Флаги прерывания таймеров
Имеется контроллер ATtiny2313. Имеется прога для моргания диодом приблизительно раз в секунду импульсами по 300 мкс. Всё работает в...

Непонятное поведение Proteus 8.3 (INTCON-прерывания- протеус дал неверные флаги)
Всем привет. В общем ситуация следующая: ;------ настройка прерываний bsf STATUS, RP0 ; банк 1 ...

5
0 / 0 / 0
Регистрация: 14.02.2010
Сообщений: 798
27.11.2013, 20:20
Ну вообще-то в прерываниях первым делом принято сносить флаг, чтобы не вызвать повторный вход.
0
0 / 0 / 0
Регистрация: 23.05.2010
Сообщений: 4
27.11.2013, 20:26
Цитата Сообщение от sohbtixhuk
Ну вообще-то в прерываниях первым делом принято сносить флаг, чтобы не вызвать повторный вход.
Теперь-то я это знаю, но мне никто об этом не говорил. На AVR с этим я не сталкивался - он там автоматом сбрасывается. Вот и зависла у меня эта проблема надолго.
0
0 / 0 / 0
Регистрация: 14.02.2010
Сообщений: 798
27.11.2013, 21:54
Ну дык в дадташитах написано - сбрасывается оно или нет
0
0 / 0 / 0
Регистрация: 23.05.2010
Сообщений: 4
27.11.2013, 22:03
Цитата Сообщение от sohbtixhuk
Ну дык в дадташитах написано - сбрасывается оно или нет
То что сбрасывается это я прочитал. Но вот когда сбрасывается - вот что важно! А это там не уточняется.
У меня флаг сбрасывался в самом конце обработчика, поэтому на штрафной круг заходил... Стал сбрасываться в начале обработчика - все стало нормально.
0
0 / 0 / 0
Регистрация: 07.03.2013
Сообщений: 176
28.11.2013, 16:48
я свой примера таймера писал, у меня бит там в начале сбрасывался
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
28.11.2013, 16:48
Помогаю со студенческими работами здесь

Метод Backtracking, флаги: создайте все флаги с тремя цветами, которые можно сформировать используя шесть цветов
Флаги. Создайте все флаги с тремя цветами, которые можно сформировать используя шести цветов: белого, желтого, красного, зеленого, синего и...

Установить флаги OF, DF, ZF и CF. Остальные флаги сбросить
Прошу помочь со следующим заданием: Установить флаги OF, DF, ZF и CF. Остальные флаги сбросить. Как я понял, нужно использовать команды...

[Вопрос] Перехват прерывания прямым доступом к вектору прерывания
Всех приветствую! В данный момент разбираюсь с обработкой аппаратного прерывания (прерывание таймера 08h и 1Ch, -//- клавиатуры 09h). ...

Вычислить адрес вектора прерывания по номеру прерывания.
17. По заданному номеру прерывания (13 h) вычислите логические адреса хранения исходных адресов обработчиков прерывания в таблице векторов....

Вызов прерывания в обработке прерывания
В программе,нажатие кнопки вызывает прерывание,в котором оно обрабатывается.Попутно в обработке этого прерывания запускается таймер по...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru