为什么我在 AVR 中的中断无法正常工作?
Why my interrupt in AVR does not work correctly?
编辑:它正在工作
我正在与PC进行Atmega8通信编程。我使用 Treminal v1.9b 发送和接收"消息"。这是我的代码:
#include <avr/io.h>
#include <stdlib.h>
#include <util/delay.h>
#include <string.h>
#include <avr/interrupt.h>
#include <stdlib.h>
void print_char(char letter)
{
if( bit_is_set(UCSRA, UDRE) )
{
_delay_ms(10);
UDR=letter;
loop_until_bit_is_set(UCSRA, TXC);
}
}
volatile char what = 'x';
int main(void)
{
DDRC |= (1<<PC0);
DDRC |= (1<<PC1);
DDRC |= (1<<PC2);
UBRRL = 12;//4800 1mhz
UCSRB = (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);
sei();
PORTC ^= (1<<PC1);
while(1)
{
print_char(what);
PORTC ^= (1<<PC0);
_delay_ms(100);
}
}
ISR(USART_RXC_vect)
{
what = UDR;
PORTC ^= (1<<PC2);
}
打开uC后,在控制台(终端v1.9b(中出现"x",尝试发送任何内容后,"x"停止弹出。就像程序挂起或中断没有返回主程序一样。(将任何内容发送到 uC 后,给定的值应显示在控制台中(。
当 uC 接通时,PC1 处的 LED 亮起,PC0 处的 LED 闪烁,PC2 处的 LED 变暗。将任何字符发送到uC后:PC0处的led是暗的,PC1处的led是发光的,PC2处是暗的。好像功能ISR((没有启动。
问题出在哪里?
.iss 文件:
usb2.elf: file format elf32-avr
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 00000106 00000000 00000000 00000074 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .data 00000002 00800060 00000106 0000017a 2**0
CONTENTS, ALLOC, LOAD, DATA
Disassembly of section .text:
00000000 <__vectors>:
0: 29 c0 rjmp .+82 ; 0x54 <__ctors_end>
2: 00 00 nop
4: 3a c0 rjmp .+116 ; 0x7a <__bad_interrupt>
6: 00 00 nop
8: 38 c0 rjmp .+112 ; 0x7a <__bad_interrupt>
a: 00 00 nop
c: 36 c0 rjmp .+108 ; 0x7a <__bad_interrupt>
e: 00 00 nop
10: 34 c0 rjmp .+104 ; 0x7a <__bad_interrupt>
12: 00 00 nop
14: 32 c0 rjmp .+100 ; 0x7a <__bad_interrupt>
16: 00 00 nop
18: 30 c0 rjmp .+96 ; 0x7a <__bad_interrupt>
1a: 00 00 nop
1c: 2e c0 rjmp .+92 ; 0x7a <__bad_interrupt>
1e: 00 00 nop
20: 2c c0 rjmp .+88 ; 0x7a <__bad_interrupt>
22: 00 00 nop
24: 2a c0 rjmp .+84 ; 0x7a <__bad_interrupt>
26: 00 00 nop
28: 28 c0 rjmp .+80 ; 0x7a <__bad_interrupt>
2a: 00 00 nop
2c: 55 c0 rjmp .+170 ; 0xd8 <__vector_11>
2e: 00 00 nop
30: 24 c0 rjmp .+72 ; 0x7a <__bad_interrupt>
32: 00 00 nop
34: 22 c0 rjmp .+68 ; 0x7a <__bad_interrupt>
36: 00 00 nop
38: 20 c0 rjmp .+64 ; 0x7a <__bad_interrupt>
3a: 00 00 nop
3c: 1e c0 rjmp .+60 ; 0x7a <__bad_interrupt>
3e: 00 00 nop
40: 1c c0 rjmp .+56 ; 0x7a <__bad_interrupt>
42: 00 00 nop
44: 1a c0 rjmp .+52 ; 0x7a <__bad_interrupt>
46: 00 00 nop
48: 18 c0 rjmp .+48 ; 0x7a <__bad_interrupt>
4a: 00 00 nop
4c: 16 c0 rjmp .+44 ; 0x7a <__bad_interrupt>
4e: 00 00 nop
50: 14 c0 rjmp .+40 ; 0x7a <__bad_interrupt>
...
00000054 <__ctors_end>:
54: 11 24 eor r1, r1
56: 1f be out 0x3f, r1 ; 63
58: cf e5 ldi r28, 0x5F ; 95
5a: d4 e0 ldi r29, 0x04 ; 4
5c: de bf out 0x3e, r29 ; 62
5e: cd bf out 0x3d, r28 ; 61
00000060 <__do_copy_data>:
60: 10 e0 ldi r17, 0x00 ; 0
62: a0 e6 ldi r26, 0x60 ; 96
64: b0 e0 ldi r27, 0x00 ; 0
66: e6 e0 ldi r30, 0x06 ; 6
68: f1 e0 ldi r31, 0x01 ; 1
6a: 02 c0 rjmp .+4 ; 0x70 <.do_copy_data_start>
0000006c <.do_copy_data_loop>:
6c: 05 90 lpm r0, Z+
6e: 0d 92 st X+, r0
00000070 <.do_copy_data_start>:
70: a2 36 cpi r26, 0x62 ; 98
72: b1 07 cpc r27, r17
74: d9 f7 brne .-10 ; 0x6c <.do_copy_data_loop>
76: 0c d0 rcall .+24 ; 0x90 <main>
78: 44 c0 rjmp .+136 ; 0x102 <_exit>
0000007a <__bad_interrupt>:
7a: c2 cf rjmp .-124 ; 0x0 <__vectors>
0000007c <_Z10print_charc>:
7c: 5d 9b sbis 0x0b, 5 ; 11
7e: 07 c0 rjmp .+14 ; 0x8e <_Z10print_charc+0x12>
80: e4 ec ldi r30, 0xC4 ; 196
82: f9 e0 ldi r31, 0x09 ; 9
84: 31 97 sbiw r30, 0x01 ; 1
86: f1 f7 brne .-4 ; 0x84 <_Z10print_charc+0x8>
88: 8c b9 out 0x0c, r24 ; 12
8a: 5e 9b sbis 0x0b, 6 ; 11
8c: fe cf rjmp .-4 ; 0x8a <_Z10print_charc+0xe>
8e: 08 95 ret
00000090 <main>:
90: 1f 93 push r17
92: cf 93 push r28
94: df 93 push r29
96: a0 9a sbi 0x14, 0 ; 20
98: a1 9a sbi 0x14, 1 ; 20
9a: a2 9a sbi 0x14, 2 ; 20
9c: 8c e0 ldi r24, 0x0C ; 12
9e: 89 b9 out 0x09, r24 ; 9
a0: 88 e9 ldi r24, 0x98 ; 152
a2: 8a b9 out 0x0a, r24 ; 10
a4: 86 e8 ldi r24, 0x86 ; 134
a6: 80 bd out 0x20, r24 ; 32
a8: 85 b7 in r24, 0x35 ; 53
aa: 81 60 ori r24, 0x01 ; 1
ac: 85 bf out 0x35, r24 ; 53
ae: 8b b7 in r24, 0x3b ; 59
b0: 80 64 ori r24, 0x40 ; 64
b2: 8b bf out 0x3b, r24 ; 59
b4: 78 94 sei
b6: 85 b3 in r24, 0x15 ; 21
b8: 92 e0 ldi r25, 0x02 ; 2
ba: 89 27 eor r24, r25
bc: 85 bb out 0x15, r24 ; 21
be: 11 e0 ldi r17, 0x01 ; 1
c0: c8 ea ldi r28, 0xA8 ; 168
c2: d1 e6 ldi r29, 0x61 ; 97
c4: 80 91 60 00 lds r24, 0x0060
c8: d9 df rcall .-78 ; 0x7c <_Z10print_charc>
ca: 85 b3 in r24, 0x15 ; 21
cc: 81 27 eor r24, r17
ce: 85 bb out 0x15, r24 ; 21
d0: ce 01 movw r24, r28
d2: 01 97 sbiw r24, 0x01 ; 1
d4: f1 f7 brne .-4 ; 0xd2 <main+0x42>
d6: f6 cf rjmp .-20 ; 0xc4 <main+0x34>
000000d8 <__vector_11>:
d8: 1f 92 push r1
da: 0f 92 push r0
dc: 0f b6 in r0, 0x3f ; 63
de: 0f 92 push r0
e0: 11 24 eor r1, r1
e2: 8f 93 push r24
e4: 9f 93 push r25
e6: 85 b3 in r24, 0x15 ; 21
e8: 94 e0 ldi r25, 0x04 ; 4
ea: 89 27 eor r24, r25
ec: 85 bb out 0x15, r24 ; 21
ee: 8c b1 in r24, 0x0c ; 12
f0: 80 93 60 00 sts 0x0060, r24
f4: 9f 91 pop r25
f6: 8f 91 pop r24
f8: 0f 90 pop r0
fa: 0f be out 0x3f, r0 ; 63
fc: 0f 90 pop r0
fe: 1f 90 pop r1
100: 18 95 reti
00000102 <_exit>:
102: f8 94 cli
00000104 <__stop_program>:
104: ff cf rjmp .-2 ; 0x104 <__stop_program>
如您所见,在生成的向量表中:
00000000 <__vectors>:
0: 29 c0 rjmp .+82 ; 0x54 <__ctors_end>
2: 00 00 nop
4: 3a c0 rjmp .+116 ; 0x7a <__bad_interrupt>
6: 00 00 nop
8: 38 c0 rjmp .+112 ; 0x7a <__bad_interrupt>
a: 00 00 nop
...
2c: 55 c0 rjmp .+170 ; 0xd8 <__vector_11>
2e: 00 00 nop
每个中断向量使用 2 个单词:一个用于rjmp
,一个填充nop
。
因此,第 12 个向量位于 addrees 0x002C(或0x16词地址(。
在表 18的数据表中,中断向量部分在 ATmega8 的第46页中,您可以看到,在 ATmega8 中,每个向量只分配一个单词(对于rjmp
指令来说就足够了,它允许跳转到 4Kwords 地址空间内的任何地址(。
因此,USART,RXC向量应放置在0x0B字地址(或0x0016字节地址(处。
换句话说,您的编译环境设置不正确,可能是您选择了错误的CPU。
当实际中断发生时,执行向量 at(字节地址0x0016
:
16: 00 00 nop
18: 30 c0 rjmp .+96 ; 0x7a <__bad_interrupt>
导致跳过nop
操作并跳转到__bad_interrupt
标签:
0000007a <__bad_interrupt>:
7a: c2 cf rjmp .-124 ; 0x0 <__vectors>
这会导致程序停止
相关文章:
- QSqlquery prepare()和bindvalue()不工作
- 导入库可以跨dll版本工作吗
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- C++为线程工作动态地分割例程
- 为什么我的 std::ref 无法按预期工作?
- 布尔比较运算符是如何在C++中工作的
- SampleConsensusPrerejective(ext.RANSAC)是如何真正工作的
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- <<操作员在下面的行中工作
- 有人能解释一下为什么下界是这样工作的吗C++的
- ExtractIconEx:可以工作,但偶尔会崩溃
- C++中的memset函数工作不正常
- 当我在第一个循环中使用"auto"时,它工作正常,但是使用"int"它会给出错误,为什么?
- 为什么STD ::计数将常数传递给Lambda,而不是在弦上工作时而不是字符
- C++程序已停止工作-求解常微分方程