Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Мой первый блин)
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
Страницы: 1, 2
novlev
CODE
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/wdt.h>
volatile int i = 0;
int main()
{
PORTE = 0x01;
DDRE = 0x7F;

wdt_disable();


TCNT0 = 0x00;
TCCR0A = 0;
TCCR0B = 3;
TIFR0 = 0;
TIMSK0 = 0x01;
sei();
//cli();
while (1)
{

if (PORTK == 255)
PORTK = 0;
else
PORTK++;

}
}


ISR(TIMER0_OVF_vect)
{
//TCNT0 = 0x00;

if(i++ == 0xFF55)
{
PORTE ^= 0x01;
i = 0;
}
}


Суть проблемы - прерывание срабатывает, но на ноге порта Е никаких изменений, а если убрать условие (if) то все норм. Чиво не так сделал?
Заранее спасибо.
OLEG_BOS
Цитата(novlev @ Oct 6 2009, 16:08) *
Чиво не так сделал?
Заранее спасибо.

Попробуйте так :
Код
ISR(TIMER0_OVF_vect)
{
    static unsigned int i = 0;                // i - используется только в обработчике прерывания и является статической
                                                       //  с локальной областью  видимости.
    //TCNT0 = 0x00;

    if(i++ == 0xFF55)
        {
            PORTE ^= 0x01;
            i = 0;
        }
}
novlev
static unsigned int i = 0; // i - используется только в обработчике прерывания и является статической
// с локальной областью видимости.

тогда она будет объявляться каждый раз при входе в обработчик, а при выходе она не будет сохранена. Надо чтобы при каждом переходе по прерыванию был один инкремент и сравнение. По "Си"шному синтаксису вроде как и правильно, может что-то не то с обьявлением переменной, типом, оптимизацией, самим транслятором-компилятором...
_Pasha
Цитата(novlev @ Oct 6 2009, 16:08) *
Суть проблемы - прерывание срабатывает, но на ноге порта Е никаких изменений, а если убрать условие (if) то все норм. Чиво не так сделал?

Могли в ком.строке поставить 8-битный int
Лучше смотреть листинг того, что получилось. Блины будут вкуснее smile.gif
Костян
Цитата(novlev @ Oct 6 2009, 12:53) *
static unsigned int i = 0;
тогда она будет объявляться каждый раз при входе в обработчик, а при выходе она не будет сохранена.

она не будет сохранена , если бы не было "static".
novlev
Вот дизасм -
CODE
+00000072: 2411 CLR R1 Clear Register
+00000073: BE1F OUT 0x3F,R1 Out to I/O location
+00000074: EFCF SER R28 Set Register
+00000075: E2D1 LDI R29,0x21 Load immediate
+00000076: BFDE OUT 0x3E,R29 Out to I/O location
+00000077: BFCD OUT 0x3D,R28 Out to I/O location
+00000078: E012 LDI R17,0x02 Load immediate
+00000079: E0A0 LDI R26,0x00 Load immediate
+0000007A: E0B2 LDI R27,0x02 Load immediate
+0000007B: C001 RJMP PC+0x0002 Relative jump
+0000007C: 921D ST X+,R1 Store indirect and postincrement
+0000007D: 30A2 CPI R26,0x02 Compare with immediate
+0000007E: 07B1 CPC R27,R17 Compare with carry
+0000007F: F7E1 BRNE PC-0x03 Branch if not equal
+00000080: 940E0086 CALL 0x00000086 Call subroutine
+00000082: 940C0103 JMP 0x00000103 Jump
+00000084: 940C0000 JMP 0x00000000 Jump
+00000086: 93DF PUSH R29 Push register on stack
+00000087: 93CF PUSH R28 Push register on stack
+00000088: B7CD IN R28,0x3D In from I/O location
+00000089: B7DE IN R29,0x3E In from I/O location
+0000008A: E2EE LDI R30,0x2E Load immediate
+0000008B: E0F0 LDI R31,0x00 Load immediate
+0000008C: E081 LDI R24,0x01 Load immediate
+0000008D: 8380 STD Z+0,R24 Store indirect with displacement
+0000008E: E2ED LDI R30,0x2D Load immediate
+0000008F: E0F0 LDI R31,0x00 Load immediate
+00000090: E78F LDI R24,0x7F Load immediate
+00000091: 8380 STD Z+0,R24 Store indirect with displacement
+00000092: E188 LDI R24,0x18 Load immediate
+00000093: B60F IN R0,0x3F In from I/O location
+00000094: 94F8 CLI Global Interrupt Disable
+00000095: 93800060 STS 0x0060,R24 Store direct to data space
+00000097: 92100060 STS 0x0060,R1 Store direct to data space
+00000099: BE0F OUT 0x3F,R0 Out to I/O location
+0000009A: E4E6 LDI R30,0x46 Load immediate
+0000009B: E0F0 LDI R31,0x00 Load immediate
+0000009C: 8210 STD Z+0,R1 Store indirect with displacement
+0000009D: E4E4 LDI R30,0x44 Load immediate
+0000009E: E0F0 LDI R31,0x00 Load immediate
+0000009F: 8210 STD Z+0,R1 Store indirect with displacement
+000000A0: E4E5 LDI R30,0x45 Load immediate
+000000A1: E0F0 LDI R31,0x00 Load immediate
+000000A2: E085 LDI R24,0x05 Load immediate
+000000A3: 8380 STD Z+0,R24 Store indirect with displacement
+000000A4: E3E5 LDI R30,0x35 Load immediate
+000000A5: E0F0 LDI R31,0x00 Load immediate
+000000A6: 8210 STD Z+0,R1 Store indirect with displacement
+000000A7: E6EE LDI R30,0x6E Load immediate
+000000A8: E0F0 LDI R31,0x00 Load immediate
+000000A9: E081 LDI R24,0x01 Load immediate
+000000AA: 8380 STD Z+0,R24 Store indirect with displacement
+000000AB: 9478 SEI Global Interrupt Enable
+000000AC: E0E8 LDI R30,0x08 Load immediate
+000000AD: E0F1 LDI R31,0x01 Load immediate
+000000AE: 8180 LDD R24,Z+0 Load indirect with displacement
+000000AF: 3F8F CPI R24,0xFF Compare with immediate
+000000B0: F421 BRNE PC+0x05 Branch if not equal
+000000B1: E0E8 LDI R30,0x08 Load immediate
+000000B2: E0F1 LDI R31,0x01 Load immediate
+000000B3: 8210 STD Z+0,R1 Store indirect with displacement
+000000B4: CFF7 RJMP PC-0x0008 Relative jump
+000000B5: E0E8 LDI R30,0x08 Load immediate
+000000B6: E0F1 LDI R31,0x01 Load immediate
+000000B7: 8180 LDD R24,Z+0 Load indirect with displacement
+000000B8: 5F8F SUBI R24,0xFF Subtract immediate
+000000B9: 8380 STD Z+0,R24 Store indirect with displacement
+000000BA: CFF1 RJMP PC-0x000E Relative jump
+000000BB: 921F PUSH R1 Push register on stack
+000000BC: 920F PUSH R0 Push register on stack
+000000BD: B60F IN R0,0x3F In from I/O location
+000000BE: 920F PUSH R0 Push register on stack
+000000BF: 2411 CLR R1 Clear Register
+000000C0: 932F PUSH R18 Push register on stack
+000000C1: 938F PUSH R24 Push register on stack
+000000C2: 939F PUSH R25 Push register on stack
+000000C3: 93AF PUSH R26 Push register on stack
+000000C4: 93BF PUSH R27 Push register on stack
+000000C5: 93EF PUSH R30 Push register on stack
+000000C6: 93FF PUSH R31 Push register on stack
+000000C7: 93DF PUSH R29 Push register on stack
+000000C8: 93CF PUSH R28 Push register on stack
+000000C9: D000 RCALL PC+0x0001 Relative call subroutine
+000000CA: 920F PUSH R0 Push register on stack
+000000CB: B7CD IN R28,0x3D In from I/O location
+000000CC: B7DE IN R29,0x3E In from I/O location
+000000CD: 91800200 LDS R24,0x0200 Load direct from data space
+000000CF: 91900201 LDS R25,0x0201 Load direct from data space
+000000D1: 839B STD Y+3,R25 Store indirect with displacement
+000000D2: 838A STD Y+2,R24 Store indirect with displacement
+000000D3: 8219 STD Y+1,R1 Store indirect with displacement
+000000D4: 818A LDD R24,Y+2 Load indirect with displacement
+000000D5: 819B LDD R25,Y+3 Load indirect with displacement
+000000D6: EF2F SER R18 Set Register
+000000D7: 3F80 CPI R24,0xF0 Compare with immediate
+000000D8: 0792 CPC R25,R18 Compare with carry
+000000D9: F411 BRNE PC+0x03 Branch if not equal
+000000DA: E081 LDI R24,0x01 Load immediate
+000000DB: 8389 STD Y+1,R24 Store indirect with displacement
+000000DC: 818A LDD R24,Y+2 Load indirect with displacement
+000000DD: 819B LDD R25,Y+3 Load indirect with displacement
+000000DE: 9601 ADIW R24,0x01 Add immediate to word
+000000DF: 93900201 STS 0x0201,R25 Store direct to data space
+000000E1: 93800200 STS 0x0200,R24 Store direct to data space
+000000E3: 8199 LDD R25,Y+1 Load indirect with displacement
+000000E4: 2399 TST R25 Test for Zero or Minus
+000000E5: F061 BREQ PC+0x0D Branch if equal
+000000E6: E2AE LDI R26,0x2E Load immediate
+000000E7: E0B0 LDI R27,0x00 Load immediate
+000000E8: E2EE LDI R30,0x2E Load immediate
+000000E9: E0F0 LDI R31,0x00 Load immediate
+000000EA: 8190 LDD R25,Z+0 Load indirect with displacement
+000000EB: E081 LDI R24,0x01 Load immediate
+000000EC: 2789 EOR R24,R25 Exclusive OR
+000000ED: 938C ST X,R24 Store indirect
+000000EE: 92100201 STS 0x0201,R1 Store direct to data space
+000000F0: 92100200 STS 0x0200,R1 Store direct to data space
+000000F2: 900F POP R0 Pop register from stack
+000000F3: 900F POP R0 Pop register from stack
+000000F4: 900F POP R0 Pop register from stack
+000000F5: 91CF POP R28 Pop register from stack
+000000F6: 91DF POP R29 Pop register from stack
+000000F7: 91FF POP R31 Pop register from stack
+000000F8: 91EF POP R30 Pop register from stack
+000000F9: 91BF POP R27 Pop register from stack
+000000FA: 91AF POP R26 Pop register from stack
+000000FB: 919F POP R25 Pop register from stack
+000000FC: 918F POP R24 Pop register from stack
+000000FD: 912F POP R18 Pop register from stack
+000000FE: 900F POP R0 Pop register from stack
+000000FF: BE0F OUT 0x3F,R0 Out to I/O location
+00000100: 900F POP R0 Pop register from stack
+00000101: 901F POP R1 Pop register from stack
+00000102: 9518 RETI Interrupt return
+00000103: 94F8 CLI Global Interrupt Disable
+00000104: CFFF RJMP PC-0x0000 Relative jump
+00000105: 90FF POP R15 Pop register from stack
+00000106: BE0F OUT 0x3F,R0 Out to I/O location
+00000107: 900F POP R0 Pop register from stack
+00000108: 901F POP R1 Pop register from stack
+00000109: 9518 RETI Interrupt return
+0000010A: 921F PUSH R1 Push register on stack
+0000010B: 920F PUSH R0 Push register on stack
+0000010C: B60F IN R0,0x3F In from I/O location
+0000010D: 920F PUSH R0 Push register on stack
+0000010E: 2411 CLR R1 Clear Register
+0000010F: 932F PUSH R18 Push register on stack
+00000110: 938F PUSH R24 Push register on stack
+00000111: 939F PUSH R25 Push register on stack
+00000112: 93AF PUSH R26 Push register on stack
+00000113: 93BF PUSH R27 Push register on stack
+00000114: 93EF PUSH R30 Push register on stack
+00000115: 93FF PUSH R31 Push register on stack
+00000116: 93DF PUSH R29 Push register on stack
+00000117: 93CF PUSH R28 Push register on stack
+00000118: D000 RCALL PC+0x0001 Relative call subroutine
+00000119: 920F PUSH R0 Push register on stack
+0000011A: B7CD IN R28,0x3D In from I/O location
+0000011B: B7DE IN R29,0x3E In from I/O location
+0000011C: 91800200 LDS R24,0x0200 Load direct from data space
+0000011E: 91900201 LDS R25,0x0201 Load direct from data space
+00000120: 839B STD Y+3,R25 Store indirect with displacement
+00000121: 838A STD Y+2,R24 Store indirect with displacement
+00000122: 8219 STD Y+1,R1 Store indirect with displacement
+00000123: 818A LDD R24,Y+2 Load indirect with displacement
+00000124: 819B LDD R25,Y+3 Load indirect with displacement
+00000125: EF2F SER R18 Set Register
+00000126: 3F80 CPI R24,0xF0 Compare with immediate
+00000127: 0792 CPC R25,R18 Compare with carry
+00000128: F411 BRNE PC+0x03 Branch if not equal
+00000129: E081 LDI R24,0x01 Load immediate
+0000012A: 8389 STD Y+1,R24 Store indirect with displacement
+0000012B: 818A LDD R24,Y+2 Load indirect with displacement
+0000012C: 819B LDD R25,Y+3 Load indirect with displacement
+0000012D: 9601 ADIW R24,0x01 Add immediate to word
+0000012E: 93900201 STS 0x0201,R25 Store direct to data space
+00000130: 93800200 STS 0x0200,R24 Store direct to data space
+00000132: 8199 LDD R25,Y+1 Load indirect with displacement
+00000133: 2399 TST R25 Test for Zero or Minus
+00000134: F061 BREQ PC+0x0D Branch if equal
+00000135: E2AE LDI R26,0x2E Load immediate
+00000136: E0B0 LDI R27,0x00 Load immediate
+00000137: E2EE LDI R30,0x2E Load immediate
+00000138: E0F0 LDI R31,0x00 Load immediate
+00000139: 8190 LDD R25,Z+0 Load indirect with displacement
+0000013A: E081 LDI R24,0x01 Load immediate
+0000013B: 2789 EOR R24,R25 Exclusive OR
+0000013C: 938C ST X,R24 Store indirect
+0000013D: 92100201 STS 0x0201,R1 Store direct to data space
+0000013F: 92100000 STS 0x0000,R1 Store direct to data space
+00000141: 900F POP R0 Pop register from stack
+00000142: 900F POP R0 Pop register from stack
+00000143: 900F POP R0 Pop register from stack
+00000144: 91CF POP R28 Pop register from stack
+00000145: 91DF POP R29 Pop register from stack
+00000146: 91FF POP R31 Pop register from stack
+00000147: 91EF POP R30 Pop register from stack
+00000148: 91BF POP R27 Pop register from stack
+00000149: 91AF POP R26 Pop register from stack
+0000014A: 919F POP R25 Pop register from stack
+0000014B: 918F POP R24 Pop register from stack
+0000014C: 912F POP R18 Pop register from stack
+0000014D: 900F POP R0 Pop register from stack
+0000014E: BE0F OUT 0x3F,R0 Out to I/O location
+0000014F: 900F POP R0 Pop register from stack
+00000150: 901F POP R1 Pop register from stack
+00000151: 9518 RETI Interrupt return
+00000152: 94F8 CLI Global Interrupt Disable
+00000153: CFFF RJMP PC-0x0000 Relative jump


Может надо стек настроить? или еще что...
Ledmaster
Смысл не в том, где объявлять i, а в том, что она должна быть объявлена unsigned, поскольку тип int - это 15 бит плюс знак, вероятно, он не может корректно быть сравнен с 0xFF55
_Pasha
нужен не дизасм, а *.lss
novlev
вот листинг, прикрепить файл не получилось.
CODE
tst_gcc.elf: file format elf32-avr

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 000001a8 00000000 00000000 00000074 2**1
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 .bss 00000001 00800200 00800200 0000021c 2**0
ALLOC

Disassembly of section .text:

00000000 <__vectors>:
0: 0c 94 72 00 jmp 0xe4; 0xe4 <__ctors_end>
4: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
8: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
c: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
10: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
14: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
18: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
1c: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
20: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
24: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
28: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
2c: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
30: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
34: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
38: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
3c: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
40: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
44: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
48: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
4c: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
50: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
54: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
58: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
5c: 0c 94 bb 00 jmp 0x176; 0x176 <__vector_23>
60: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
64: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
68: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
6c: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
70: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
74: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
78: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
7c: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
80: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
84: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
88: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
8c: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
90: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
94: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
98: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
9c: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
a0: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
a4: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
a8: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
ac: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
b0: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
b4: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
b8: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
bc: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
c0: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
c4: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
c8: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
cc: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
d0: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
d4: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
d8: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
dc: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>
e0: 0c 94 84 00 jmp 0x108; 0x108 <__bad_interrupt>

000000e4 <__ctors_end>:
e4: 11 24 eor r1, r1
e6: 1f be out 0x3f, r1; 63
e8: cf ef ldi r28, 0xFF; 255
ea: d1 e2 ldi r29, 0x21; 33
ec: de bf out 0x3e, r29; 62
ee: cd bf out 0x3d, r28; 61

000000f0 <__do_clear_bss>:
f0: 12 e0 ldi r17, 0x02; 2
f2: a0 e0 ldi r26, 0x00; 0
f4: b2 e0 ldi r27, 0x02; 2
f6: 01 c0 rjmp .+2 ; 0xfa <.do_clear_bss_start>

000000f8 <.do_clear_bss_loop>:
f8: 1d 92 st X+, r1

000000fa <.do_clear_bss_start>:
fa: a1 30 cpi r26, 0x01; 1
fc: b1 07 cpc r27, r17
fe: e1 f7 brne .-8 ; 0xf8 <.do_clear_bss_loop>
100: 0e 94 86 00 call 0x10c; 0x10c <main>
104: 0c 94 d2 00 jmp 0x1a4; 0x1a4 <_exit>

00000108 <__bad_interrupt>:
108: 0c 94 00 00 jmp 0; 0x0 <__vectors>

0000010c <main>:
10c: df 93 push r29
10e: cf 93 push r28
110: cd b7 in r28, 0x3d; 61
112: de b7 in r29, 0x3e; 62
114: ee e2 ldi r30, 0x2E; 46
116: f0 e0 ldi r31, 0x00; 0
118: 81 e0 ldi r24, 0x01; 1
11a: 80 83 st Z, r24
11c: ed e2 ldi r30, 0x2D; 45
11e: f0 e0 ldi r31, 0x00; 0
120: 8f e7 ldi r24, 0x7F; 127
122: 80 83 st Z, r24
124: 88 e1 ldi r24, 0x18; 24
126: 0f b6 in r0, 0x3f; 63
128: f8 94 cli
12a: 80 93 60 00 sts 0x0060, r24
12e: 10 92 60 00 sts 0x0060, r1
132: 0f be out 0x3f, r0; 63
134: e6 e4 ldi r30, 0x46; 70
136: f0 e0 ldi r31, 0x00; 0
138: 10 82 st Z, r1
13a: e4 e4 ldi r30, 0x44; 68
13c: f0 e0 ldi r31, 0x00; 0
13e: 10 82 st Z, r1
140: e5 e4 ldi r30, 0x45; 69
142: f0 e0 ldi r31, 0x00; 0
144: 85 e0 ldi r24, 0x05; 5
146: 80 83 st Z, r24
148: e5 e3 ldi r30, 0x35; 53
14a: f0 e0 ldi r31, 0x00; 0
14c: 10 82 st Z, r1
14e: ee e6 ldi r30, 0x6E; 110
150: f0 e0 ldi r31, 0x00; 0
152: 81 e0 ldi r24, 0x01; 1
154: 80 83 st Z, r24
156: 78 94 sei
158: e8 e0 ldi r30, 0x08; 8
15a: f1 e0 ldi r31, 0x01; 1
15c: 80 81 ld r24, Z
15e: 8f 3f cpi r24, 0xFF; 255
160: 21 f4 brne .+8 ; 0x16a <main+0x5e>
162: e8 e0 ldi r30, 0x08; 8
164: f1 e0 ldi r31, 0x01; 1
166: 10 82 st Z, r1
168: f7 cf rjmp .-18 ; 0x158 <main+0x4c>
16a: e8 e0 ldi r30, 0x08; 8
16c: f1 e0 ldi r31, 0x01; 1
16e: 80 81 ld r24, Z
170: 8f 5f subi r24, 0xFF; 255
172: 80 83 st Z, r24
174: f1 cf rjmp .-30 ; 0x158 <main+0x4c>

00000176 <__vector_23>:
176: 1f 92 push r1
178: 0f 92 push r0
17a: 0f b6 in r0, 0x3f; 63
17c: 0f 92 push r0
17e: 11 24 eor r1, r1
180: 8f 93 push r24
182: df 93 push r29
184: cf 93 push r28
186: cd b7 in r28, 0x3d; 61
188: de b7 in r29, 0x3e; 62
18a: 80 91 00 02 lds r24, 0x0200
18e: 8f 5f subi r24, 0xFF; 255
190: 80 93 00 02 sts 0x0200, r24
194: cf 91 pop r28
196: df 91 pop r29
198: 8f 91 pop r24
19a: 0f 90 pop r0
19c: 0f be out 0x3f, r0; 63
19e: 0f 90 pop r0
1a0: 1f 90 pop r1
1a2: 18 95 reti

000001a4 <_exit>:
1a4: f8 94 cli

000001a6 <__stop_program>:
1a6: ff cf rjmp .-2 ; 0x1a6 <__stop_program>


Перебрал все типы данных, по логике оставил unsigned short int, результата нет
OLEG_BOS
Цитата(Ledmaster @ Oct 6 2009, 17:04) *
Смысл не в том, где объявлять i,

Смысл в том что нужно точно указать компилятору как используется переменная, тогда точно небудет "неожиданностей" от оптимизации smile.gif
_Pasha
Код
18a:    80 91 00 02     lds    r24, 0x0200
18e:    8f 5f           subi    r24, 0xFF; 255
190:    80 93 00 02     sts    0x0200, r24

На основании этого я делаю вывод, что инт у Вас 8-битный. Поправьте опции
Кстати - про UNSIGNED - Ledmaster абсолютно прав
novlev
Кто такой этот "00000108 <__bad_interrupt>:", просто первый день как заглянул в авр студию, до это в блокноте писал для анлог девайсов всяких(те что по сути МК51).
_Pasha
Цитата(novlev @ Oct 6 2009, 17:27) *
Кто такой этот "00000108 <__bad_interrupt>:"

Заглушка для неиспользуемых прерываний
ЗЫ судя по листингу, уровень оптимизации включен не тот. Практика показывает, что надо -Os - в большинстве случаев оно же и быстрее выполняется smile.gif
novlev
Код
unsigned char i = 0x00;
ISR(TIMER0_OVF_vect)
{
    if(i++ == 0x55)
        {
            PORTE ^= 0x01;
            i = 0;
        }
}

и так не хочет. Уровни оптимизации попробовал все. Прикольная ситуация))
_Pasha
Цитата(novlev @ Oct 6 2009, 17:32) *
и так не хочет.

Объявите в теле прерывания как static. Или глобально volatile unsigned char i=0;
Ledmaster
А так?
Код
unsigned char i = 0x00;
ISR(TIMER0_OVF_vect)
{
    i++;
    if(i == 0x55)
        {
            PORTE ^= 0x01;
            i = 0;
        }
}
novlev
Цитата(_Pasha @ Oct 6 2009, 17:37) *
Объявите в теле прерывания как static. Или глобально volatile unsigned char i=0;


Я проверил оба эти варианта, на осмыслографе ожидаемы пеньки не появились...


Цитата(Ledmaster @ Oct 6 2009, 17:43) *
А так?

Пробовал, но без комбинации глобальная/статическая переменная.

Последняя на сегодня мысль, поставлю 16 вместо 17 студии, проверю еще так. И WinAVR переставлю.
OLEG_BOS
Цитата(novlev @ Oct 6 2009, 17:48) *
Последняя на сегодня мысль, поставлю 16 вместо 17 студии, проверю еще так. И WinAVR переставлю.


ОFFTOP a14.gif
Если не получится попробуйте еще и Windows переставить. А если и это не поможет то и комп. сменить biggrin.gif

А если серьезно - откройте книжку по "Си" и почитайте там об типах переменных, их расположением в памяти ( я имею ввиду ключевые слова static и volatile) . Тогда и не надо будет ничего переставлять - путь длинный но зато надежный и с малым количеством "грабель" в будущем wink.gif

P.S. Кстати у Вас там используется порт E контроллера. А у Вас какой контроллер ( я так думаю Atmega64(128)) - есть там порт Е ? smile.gif
novlev
Цитата(OLEG_BOS @ Oct 6 2009, 18:16) *
ОFFTOP a14.gif
Если не получится попробуйте еще и Windows переставить. А если и это не поможет то и комп. сменить biggrin.gif

А если серьезно - откройте книжку по "Си" и почитайте там об типах переменных, их расположением в памяти ( я имею ввиду ключевые слова static и volatile) . Тогда и не надо будет ничего переставлять - путь длинный но зато надежный и с малым количеством "грабель" в будущем wink.gif

P.S. Кстати у Вас там используется порт E контроллера. А у Вас какой контроллер ( я так думаю Atmega64(128)) - есть там порт Е ? smile.gif


Спасибо за помощь, но ерничать все же не стоит.. С типами данных я знаком, на сях пишу достаточно долго (С#), таких вот проблем))) с типами не встречал. Просто в первый же день захотел много). А проц обычная атмега640. Задача у меня - бутлоадер написать, поэтому и решил на си. Если кто сталкивался или сразу видит причину - ткните уже носом меня, и если есть дока по подводным камням авр студии - поделитесь, пожалуйста. Всем еще раз спасибо.
INT1
Я конечно не спец по Си , но чегото бросилось в глаза, PORTK++;, а так можно делать? И не плохо бы указать, какому компилятору(реализации) вы это поручаете, а то я чегото все время уверен, что это наверняка ИАР smile.gif.
novlev
Цитата(INT1 @ Oct 6 2009, 21:31) *
Я конечно не спец по Си , но чегото бросилось в глаза, PORTK++;, а так можно делать? И не плохо бы указать, какому компилятору(реализации) вы это поручаете, а то я чегото все время уверен, что это наверняка ИАР smile.gif.

PORTK++ - думаю можно, взяли что было, инкремент и перезаписали. По поводу чему я это поручаю... Есть в студии привязка к WinAVR-20090313, там есть утилиты avr-gcc.exe(компилятор
языков C и C++ для AVR) и make.exe(автоматический генератор Make-файлов for AVR GCC), пока это все что я знаю) я пока еще не освоился во всем обилии средств рвзработки...
А что посоветуете? просто "будет работать из коробки" не состоялось))
INT1
Насколько помнится операции над портом (если мы говорим про МК) типа инкркемент и т.п. напрямую производить нельзя. Т.е. туда(в регистр порта) можно или писать или читать. Т.е. нужно объявить переменную, сделать с ней что захотеть, а потом значенеие записать в порт.
ЗЫ, хотя компилятор должен был бы заматериться на это дело (почему и спросил про реализацию). Но подробно в вашу проблему не вникал, извините ...smile.gif
novlev
Цитата(INT1 @ Oct 6 2009, 22:08) *
насколько помнится операции над портом (если мы говорим проМК) типа инкркемент и т.п. напрямую производить нельзя. Т.е. туда можно или писать или читать. Т.е. объявить переменную, сделать с ней что захотеть, а потом значенеие записать в порт.


Ничего утверждать не берусь, но вот пример дизасма:
Код
23:       if (PORTK == 255)
+00000099:   91800108    LDS       R24,0x0108     Load direct from data space
+0000009B:   3F8F        CPI       R24,0xFF       Compare with immediate
+0000009C:   F419        BRNE      PC+0x04        Branch if not equal
24:       PORTK = 0;
+0000009D:   92100108    STS       0x0108,R1      Store direct to data space
+0000009F:   CFF9        RJMP      PC-0x0006      Relative jump
26:       PORTK++;
+000000A0:   91800108    LDS       R24,0x0108     Load direct from data space
+000000A2:   5F8F        SUBI      R24,0xFF       Subtract immediate
+000000A3:   93800108    STS       0x0108,R24     Store direct to data space
+000000A5:   CFF3        RJMP      PC-0x000C      Relative jump

Никаких замечаний и ошибок нет, эмулятор все корректно отображает. И под volatile unsigned int выделил 2 байта. Т е в теории все красиво.

Вот пример моего мейкфайла.
314
Попробовал Ваш пример на отладчике в AVR Studio, только под мегу168 сменил таргет в makefile и порты К и Е заменил на В и С (новый WinAVR еще не поставил, нет библиотеки под м640). В отладчике все идет без проблем, значение пина меняется как и ожидалось.
novlev
Да, более того, статическая переменная действительно оказалась статической, код генерируется адекватный(на эмуляторе). Никаких допущений и упращений. Я просто думал поначалу, что компилятор упрощенный или что-то такое, все оказалось нормально. По коду при одна инициализация и сохранение, все честно.
singlskv
Цитата(novlev @ Oct 6 2009, 17:08) *
CODE

if (PORTK == 255)
PORTK = 0;
else
PORTK++;
А зачем здесь вобще нужен if ? достаточно просто PORTK++;
или Вы думаете что прибавление 1 к unsigned volatile char переменной в которой уже 255 может дать что-нить кроме 0 ?



Цитата(INT1 @ Oct 6 2009, 23:08) *
Насколько помнится операции над портом (если мы говорим про МК) типа инкркемент и т.п. напрямую производить нельзя. Т.е. туда(в регистр порта) можно или писать или читать. Т.е. нужно объявить переменную, сделать с ней что захотеть, а потом значенеие записать в порт.
Это верно только для процов в которых разделены регистры записи/стирания бита (ARM непример),
для AVR здесь все валидно,
PORTK++; <=> PORTK = PORTK + 1;
то есть сначала считать, инкрементировать и затем записать
novlev
Код
if (PORTK == 255)
PORTK = 0;
else
PORTK++;


Ну если честно, эта конструкция там просто так, чтобы небыло пустого цикла while(1). Предметом обсуждения была многострадальная переменная i, из-за которой
if не давал истину.
314
Как-то это все больше смахивает на какие-то внешние причины. Например: использование альтернативной функции порта, наличие сбросов и перезапусков программы, так что переменная i просто не успевает накопиться и т.д. (кстати, может, когда увеличили частоту переключения, то начало успевать переключаться до сброса). Это можно проверить, вставив в начало программы до начала основного кода сигнал 1 на какой-нибудь безобидный пин. При перезапуске выходы переводятся в состяние входов (можно сказать Z-состояние)где-то на 100мкс-10мс, смотря как задали стартовые задержки, и осциллографом это можно увидеть (подтяжку на -5В 1-5к не забудьте). И наверное есть смысл отключить WDR timer в фусовых битах (галочку на WDTON снимите, если стоит, или впишите в обработчик прерывания wdt_reset () ).

Вот Вам еще довесок из даташита на м640

The Watchdog always on (WDTON) fuse, if programmed, will force the Watchdog Timer to Sys-
tem Reset mode. With the fuse programmed the System Reset mode bit (WDE) and Interrupt

Если не ошибаюсь, то WDTON для м640 из программы не доступен, только с программатора.
novlev
Цитата(314 @ Oct 7 2009, 08:49) *
И наверное есть смысл отключить WDR timer в фусовых битах (галочку на WDTON снимите, если стоит, или впишите в обработчик прерывания wdt_reset () ).


Да, действительно - сбрасывается. Буду искать причину. Огромное спасибо.
dimka76
Цитата(novlev @ Oct 7 2009, 01:46) *
Предметом обсуждения была многострадальная переменная i, из-за которой if не давал истину.


Вы попробуйте в симуляторе AVR Studio погонять, поставьте точку останова в прерывании и посмотрите по шагам что происходит, лучше даже в дизассемблере. AVR Studio очень хорошо симулирует.
novlev
Цитата(314 @ Oct 7 2009, 08:49) *
Вот Вам еще довесок из даташита на м640

The Watchdog always on (WDTON) fuse, if programmed, will force the Watchdog Timer to Sys-
tem Reset mode. With the fuse programmed the System Reset mode bit (WDE) and Interrupt

Если не ошибаюсь, то WDTON для м640 из программы не доступен, только с программатора.


Спасибо, получилось. Я просто понял что при подключенном программаторе он в 1. Мда..тогда все работает, так его получилось отключить:
Код
    cli();
    wdt_reset();
    MCUSR &= ~(1<<WDRF);
    WDTCSR |= (1<<WDCE) | (1<<WDE);
    WDTCSR = 0x00;
    sei();
novlev
Всем доброго времени суток, подскажите в чем подвох
CODE

UBRR0 = 0x0033;
UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);//|(1<<TXCIE0);
UCSR0C = (1<<UCSZ00)|(1<<UCSZ01);


while(1)
{
if(global_flag.rx_bit)
{
PORTA ^= 0x04;
PORTG |= (1<<1);
PORTG &= ~(1<<1);
global_flag.tx_bit = 1;
global_flag.rx_bit = 0;
}

if(global_flag.tx_bit)
{
global_flag.tx_bit = 0;
for(int i =0; i< 5; i++)
USART_Transmit(data[i]);
}
//wdt_reset ();
//ProgPage(255, *buf);
}
return 0;

}
}


но в окне дизасемблера, и при прогоне на эмуляторе есть команда PORTA ^= 0x04 в месте где я ее не ожидал увидеть)...

CODE

95: UBRR0 = 0x0033;
+000000CA: E383 LDI R24,0x33 Load immediate
+000000CB: E090 LDI R25,0x00 Load immediate
+000000CC: 939000C5 STS 0x00C5,R25 Store direct to data space
+000000CE: 938000C4 STS 0x00C4,R24 Store direct to data space
96: UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);//|(1<<TXCIE0);
+000000D0: E988 LDI R24,0x98 Load immediate
+000000D1: 938000C1 STS 0x00C1,R24 Store direct to data space
97: UCSR0C = (1<<UCSZ00)|(1<<UCSZ01);
+000000D3: E086 LDI R24,0x06 Load immediate
+000000D4: 938000C2 STS 0x00C2,R24 Store direct to data space
104: PORTA ^= 0x04;
+000000D6: E024 LDI R18,0x04 Load immediate
102: if(global_flag.rx_bit)
+000000D7: 91800211 LDS R24,0x0211 Load direct from data space
+000000D9: FF80 SBRS R24,0 Skip if bit in register s


Подскажите, пожалуйста, чего на этот раз не досмотрел?
Т е при пошаговом прогоне указатель сначала переходит на строку PORTA ^= 0x04, а только затем возвращается на условие if.
Палыч
Цитата(novlev @ Oct 15 2009, 13:24) *
но в окне дизасемблера, и при прогоне на эмуляторе есть команда PORTA ^= 0x04 в месте где я ее не ожидал увидеть)...
Т е при пошаговом прогоне указатель сначала переходит на строку PORTA ^= 0x04, а только затем возвращается на условие if.
Имхо, транслятор "решил" чуть-чуть оптимизировать код. Наверное, Вас это не должно беспокоить, поскольку в листинге хотя и стоит оператор
Цитата
104: PORTA ^= 0x04;
однако само тело этого оператора, наверное, ниже if (в приведённом Вами фрагменте этого не видно).
novlev
Спасибо, пока оставлю так. Есть еще один вопрос, что означает в сообщение компилятора
Цитата
AVR Simulator: Invalid opcode 0xffff at address 0x0000e0
?
Появляется когда я вызываю процедуру ProgPage(255, buf_w);

CODE
void ProgPage(uint32_t page, uint8_t *buf)
{
eeprom_busy_wait ();
boot_page_erase (page);
boot_spm_busy_wait ();
unsigned short int i;
for (i=0; i<5; i+=2)//SPM_PAGESIZE
{
w = *buf++;
w += (*buf++) << 8;
boot_page_fill (page + i, w);
}
boot_page_write (page);
boot_spm_busy_wait();
boot_rww_enable ();
}


сам указатель обьявлен так -
Код
unsigned char data[6] = {0x01,0x02,0x03,0x04,0x05,0x06};
uint8_t *buf_w = &data[0];

может кто сталкивался - авр студия, компилятор WinAVR
Палыч
Цитата(novlev @ Oct 15 2009, 14:04) *
что означает в сообщение компилятора ?
Выполняется инструкция по адресу 0х0E, а там 0xFFFF - что не является командой МК. Адрес этот - некий вектор (зависит от типа МК); по-видимуму прерывание по событию (какому-то) разрешены, а процедуры его обработки Вы не написали (или неправильно указали вектор при процедуре)...

P.S. Извиняюсь - не доглядел: адрес то - 0xE0, вряд ли это вектор. Нужно искать: почему Ваша программа попала на столь странный адрес.
novlev
Цитата(Палыч @ Oct 15 2009, 14:12) *
Выполняется инструкция по адресу 0х0E, а там 0xFFFF - что не является командой МК. Адрес этот - некий вектор (зависит от типа МК); по-видимуму прерывание по событию (какому-то) разрешены, а процедуры его обработки Вы не написали (или неправильно указали вектор при процедуре)...

Учел и это замечание, еще я случайно цеплял программные инструкции, неудачно рассчитал адреса страниц, отсюда и фф после перезаписи страницы. Спасибо.
novlev
Снова я) Слолкнулся со следующей ситуацией - пишу страницу во флеш(уже на реальной железяке), операция проходит, но содержимое не изменяется. При верификации читаются прежние значения.Наверное я запутался с лок битами, подскажите какое значение должно вычитываться, при старте FF, это означает что запись разрешена во все области? Менял и на другие...
Вот процедура записи
CODE

void ProgPage(uint32_t page, uint8_t *buf)
{
uint8_t sreg;
sreg = SREG;
cli();

eeprom_busy_wait();
boot_page_erase(page);
boot_spm_busy_wait();
boot_rww_enable();
uint16_t i;
for (i=0; i<SPM_PAGESIZE; i+=2)//SPM_PAGESIZE
{
uint16_t w = *buf++;
w += (*buf++) << 8;
boot_page_fill (page + i, w);
}
boot_page_write (page);
boot_spm_busy_wait();
boot_rww_enable();
SREG = sreg;
}
novlev
Для перезаписи программы, код обязательно располагать в области бутлоадера, или основная программа может перезаписать сама себя?
novlev
Подскажите пожалуйста, после записи программы с адреса бутлоадера (0х7000), достаточно только выполнить установку бита IVSEL, или надо еще что-то для использования прерываний? сами обработчики я не менял. После записи программы, прерывания не вызываются((.

CODE
void Move_interrupts(void)
{
unsigned char temp;
temp = MCUCR;
MCUCR = temp|(1<<IVCE);
MCUCR = temp|(1<<IVSEL);
}


Все, спасибо всем, нашел корень всего зла))) неверно рассчитал адрес старта бута.
novlev
приветствую всех! Вопрос - как разместить по конкретному адресу в памяти программы строковые константы?Пишу на си.
novlev
Пробовал на асме, - указывал адрес один, а распологал компилятор по другому адресу.
mempfis_
Цитата(novlev @ Dec 4 2009, 15:01) *
приветствую всех! Вопрос - как разместить по конкретному адресу в памяти программы строковые константы?Пишу на си.


Код
__flash char str[20] @0x0002;


Правда если пытаться инициализировать то компилятор требует ",".
Может гуру подскажут можно ли инициализировать массив во флеш располагая его по определённому адресу.
SasaVitebsk
Так это - стандартно

uint8_t const __flash str_q[] = "Читаем вопрос" @0x2;

Или через #pragma.

Только у вас подход неправильный. Не надо этого делать. Я уже не говорю про адрес, который в области векторов находится. Я говорю вообще про абсолютные адреса.
Каждый должен заниматься своим. Вы - писать программу, LINK-ер размещать данные и код как ему удобно.

За мою практику требовалось только в одном случае фиксировать данные. Это при совместном использовании данных независимыми программами. А именно бутлоадером и приложением. Но и в этом случае необходимо передавать 1-2 значения. Например ссылку на данные.
novlev
Это не совсем программное требование, простоя горожу систему по прожигу 70 блоков (разных но за раз) одним программатором, мне нужнопросто из прошивок вычитывать версии ПО, для этого и хочу чтоб во всех хексах по одному и тому же адресу была информация. "@0x2" - чот не понимает такой синтаксис unsigned char const PROGMEM data[] = "Строка в памяти программ "; - работает, как адрес указать..еще не разобрался. Всем спасибо за помощь.
novlev
Понял, это наверное в IAR-е @0x2 такой синтаксис, у меня авр студия и вин авр, вот тут чот не выходит ничопохожего...
novlev
Спасибо, я таким образом указывал адрес для кода программы, т к бутлоадер писал. А как таким же образом переместить просто несколько строковых констант?
SysRq
Цитата(novlev @ Dec 11 2009, 15:31) *
А как таким же образом переместить просто несколько строковых констант?
Так же. Давать вместо .bootloader свои имена (.mystring1), со своими адресами, и использовать в программе.
novlev
Спасибо, получилось. В программе это выглядит следующим образом - volatile unsigned char bar[] __attribute__ ((section (".myInfo"))) = "Это должно жить по адресу 0xDEAD";, а для линкера указал - LDFLAGS += -Wl,--section-start=.myInfo=0x1DEAD -Wl,-Map=gcc_tst.map.
В хексе имеем:
Код
:10DEAD00DDF2EE20E4EEEBE6EDEE20E6E8F2FC200E
:10DEBD00EFEE20E0E4F0E5F1F32030784445414405

Огромное спасибо.
SysRq
Если:
Цитата(novlev @ Dec 11 2009, 16:41) *
char bar[] __attribute__ ((section (".myInfo"))) = "Это должно жить по адресу 0xDEAD";
Но:
Цитата(novlev @ Dec 11 2009, 16:41) *
LDFLAGS += -Wl,--section-start=.myInfo=0x1DEAD
поселит строку по дресу однако 0x1DEAD.

Не срастается у увас что-то желание с действительностью rolleyes.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.