Цитата($ilent @ Jul 11 2006, 13:29)
Этот код был написан не мной и под WINAVR и был только перенесён мной на ICC без изменений. Не заработает ваш код, у меня вызовы 4-х параметровые, и по любому их надо собирать в нутри этой функции. И задержки у меня большие не потому, что руки кривые, а по тому, что так надо, и от них ни как не уйти.
Как это - "так надо"? У вас быстродействие упало в 10 раз! Все из-за того, что вы неграмотно работаете с аппаратным SPI. Пока передается байт, надо готовить следующий, а не тупо ждать. В результате ваш код должен выглядеть так:
Код
void transSPI(CMDT command, MyByte8T address,
MyByte8T *buffer, MyByte8T len)
{
MyByte8T dummyRX;
MyByte8T dummyTX = 0xFF;
if (len > 0x80 || len == 0) return;
PORTB &= ~(1<<3);
SPDR = command | (len & 0x7F);
while(!(SPSR &(1 << SPIF)));
SPDR = address;
switch(command)
{
case READ_CMD:
while(!(SPSR &(1 << SPIF)));
SPDR=dummyTX; //Для приема первого байта
if (--len)
{
do
{
while(!(SPSR &(1 << SPIF)));
dummyRX=SPDR;
SPDR=dummyTX;
*buffer++=dummyRX;
}
while(--len);
}
while(!(SPSR &(1 << SPIF)));
dummyRX=SPDR;
*buffer++=dummyRX;
break;
case WRITE_CMD:
do
{
dummyTX=*buffer++;
while(!(SPSR &(1 << SPIF)));
SPDR=dummyTX;
}
while(--len);
break;
}
PORTB |= 1<<3;
}
Ну и конечно, возьмите IAR - код выглядит отлично:
Код
3 typedef char CMDT;
4 typedef char MyByte8T;
5
6 #define READ_CMD 0x55
7 #define WRITE_CMD 0xAA
8
\ In segment CODE, align 2, keep-with-next
9 void transSPI(CMDT command, MyByte8T address,
\ transSPI:
10 MyByte8T *buffer, MyByte8T len)
11 {
\ 00000000 2F51 MOV R21, R17
12 MyByte8T dummyRX;
13 MyByte8T dummyTX = 0xFF;
14
15 if (len > 0x80 || len == 0) return;
\ 00000002 3841 CPI R20, 129
\ 00000004 F560 BRCC ??transSPI_0
\ 00000006 2344 TST R20
\ 00000008 F151 BREQ ??transSPI_0
16
17 PORTB &= ~(1<<3);
\ 0000000A 98C3 CBI 0x18, 0x03
18
19 SPDR = command | (len & 0x7F);
\ 0000000C 2F14 MOV R17, R20
\ 0000000E 771F ANDI R17, 0x7F
\ 00000010 2B10 OR R17, R16
\ 00000012 B91F OUT 0x0F, R17
20 while(!(SPSR &(1 << SPIF)));
\ ??transSPI_1:
\ 00000014 9B77 SBIS 0x0E, 0x07
\ 00000016 CFFE RJMP ??transSPI_1
21 SPDR = address;
\ 00000018 B95F OUT 0x0F, R21
22
23 switch(command)
\ 0000001A 5A0A SUBI R16, 170
\ 0000001C F0B9 BREQ ??transSPI_2
\ 0000001E 5A0B SUBI R16, 171
\ 00000020 F4E9 BRNE ??transSPI_3
24 {
25 case READ_CMD:
26 while(!(SPSR &(1 << SPIF)));
\ ??transSPI_4:
\ 00000022 9B77 SBIS 0x0E, 0x07
\ 00000024 CFFE RJMP ??transSPI_4
27 SPDR=dummyTX; //Для приема первого байта
\ 00000026 EF0F LDI R16, 255
\ 00000028 B90F OUT 0x0F, R16
28 if (--len)
\ 0000002A 954A DEC R20
\ 0000002C F049 BREQ ??transSPI_5
29 {
30 do
31 {
32 while(!(SPSR &(1 << SPIF)));
\ ??transSPI_6:
\ 0000002E 9B77 SBIS 0x0E, 0x07
\ 00000030 CFFE RJMP ??transSPI_6
33 dummyRX=SPDR;
\ 00000032 B11F IN R17, 0x0F
34 SPDR=dummyTX;
\ 00000034 B90F OUT 0x0F, R16
35 *buffer++=dummyRX;
\ 00000036 01F9 MOVW R31:R30, R19:R18
\ 00000038 9311 ST Z+, R17
\ 0000003A 019F MOVW R19:R18, R31:R30
36 }
37 while(--len);
\ 0000003C 954A DEC R20
\ 0000003E F7B9 BRNE ??transSPI_6
38 }
39 while(!(SPSR &(1 << SPIF)));
\ ??transSPI_5:
\ 00000040 9B77 SBIS 0x0E, 0x07
\ 00000042 CFFE RJMP ??transSPI_5
40 dummyRX=SPDR;
\ 00000044 B11F IN R17, 0x0F
41 *buffer++=dummyRX;
\ 00000046 01F9 MOVW R31:R30, R19:R18
\ 00000048 8310 ST Z, R17
\ 0000004A C008 RJMP ??transSPI_3
42 break;
43 case WRITE_CMD:
44 do
45 {
46 dummyTX=*buffer++;
\ ??transSPI_2:
\ 0000004C 01F9 MOVW R31:R30, R19:R18
\ 0000004E 9101 LD R16, Z+
\ 00000050 019F MOVW R19:R18, R31:R30
47 while(!(SPSR &(1 << SPIF)));
\ ??transSPI_7:
\ 00000052 9B77 SBIS 0x0E, 0x07
\ 00000054 CFFE RJMP ??transSPI_7
48 SPDR=dummyTX;
\ 00000056 B90F OUT 0x0F, R16
49 }
50 while(--len);
\ 00000058 954A DEC R20
\ 0000005A F7C1 BRNE ??transSPI_2
51 break;
52 }
53 PORTB |= 1<<3;
\ ??transSPI_3:
\ 0000005C 9AC3 SBI 0x18, 0x03
54 }
\ ??transSPI_0:
\ 0000005E 9508 RET
А если __z модификатор поставить, то вообще ляпота:
Код
3 typedef char CMDT;
4 typedef char MyByte8T;
5
6 #define READ_CMD 0x55
7 #define WRITE_CMD 0xAA
8
\ In segment CODE, align 2, keep-with-next
9 __z void transSPI(CMDT command, MyByte8T address,
\ transSPI:
10 MyByte8T *buffer, MyByte8T len)
11 {
\ 00000000 2F31 MOV R19, R17
12 MyByte8T dummyRX;
13 MyByte8T dummyTX = 0xFF;
14
15 if (len > 0x80 || len == 0) return;
\ 00000002 3821 CPI R18, 129
\ 00000004 F538 BRCC ??transSPI_0
\ 00000006 2322 TST R18
\ 00000008 F129 BREQ ??transSPI_0
16
17 PORTB &= ~(1<<3);
\ 0000000A 98C3 CBI 0x18, 0x03
18
19 SPDR = command | (len & 0x7F);
\ 0000000C 2F12 MOV R17, R18
\ 0000000E 771F ANDI R17, 0x7F
\ 00000010 2B10 OR R17, R16
\ 00000012 B91F OUT 0x0F, R17
20 while(!(SPSR &(1 << SPIF)));
\ ??transSPI_1:
\ 00000014 9B77 SBIS 0x0E, 0x07
\ 00000016 CFFE RJMP ??transSPI_1
21 SPDR = address;
\ 00000018 B93F OUT 0x0F, R19
22
23 switch(command)
\ 0000001A 5A0A SUBI R16, 170
\ 0000001C F0A1 BREQ ??transSPI_2
\ 0000001E 5A0B SUBI R16, 171
\ 00000020 F4C1 BRNE ??transSPI_3
24 {
25 case READ_CMD:
26 while(!(SPSR &(1 << SPIF)));
\ ??transSPI_4:
\ 00000022 9B77 SBIS 0x0E, 0x07
\ 00000024 CFFE RJMP ??transSPI_4
27 SPDR=dummyTX; //Для приема первого байта
\ 00000026 EF0F LDI R16, 255
\ 00000028 B90F OUT 0x0F, R16
28 if (--len)
\ 0000002A 952A DEC R18
\ 0000002C F039 BREQ ??transSPI_5
29 {
30 do
31 {
32 while(!(SPSR &(1 << SPIF)));
\ ??transSPI_6:
\ 0000002E 9B77 SBIS 0x0E, 0x07
\ 00000030 CFFE RJMP ??transSPI_6
33 dummyRX=SPDR;
\ 00000032 B11F IN R17, 0x0F
34 SPDR=dummyTX;
\ 00000034 B90F OUT 0x0F, R16
35 *buffer++=dummyRX;
\ 00000036 9311 ST Z+, R17
36 }
37 while(--len);
\ 00000038 952A DEC R18
\ 0000003A F7C9 BRNE ??transSPI_6
38 }
39 while(!(SPSR &(1 << SPIF)));
\ ??transSPI_5:
\ 0000003C 9B77 SBIS 0x0E, 0x07
\ 0000003E CFFE RJMP ??transSPI_5
40 dummyRX=SPDR;
\ 00000040 B11F IN R17, 0x0F
41 *buffer++=dummyRX;
\ 00000042 8310 ST Z, R17
\ 00000044 C006 RJMP ??transSPI_3
42 break;
43 case WRITE_CMD:
44 do
45 {
46 dummyTX=*buffer++;
\ ??transSPI_2:
\ 00000046 9101 LD R16, Z+
47 while(!(SPSR &(1 << SPIF)));
\ ??transSPI_7:
\ 00000048 9B77 SBIS 0x0E, 0x07
\ 0000004A CFFE RJMP ??transSPI_7
48 SPDR=dummyTX;
\ 0000004C B90F OUT 0x0F, R16
49 }
50 while(--len);
\ 0000004E 952A DEC R18
\ 00000050 F7D1 BRNE ??transSPI_2
51 break;
52 }
53 PORTB |= 1<<3;
\ ??transSPI_3:
\ 00000052 9AC3 SBI 0x18, 0x03
54 }
\ ??transSPI_0:
\ 00000054 9508 RET