[AVR]/AVR_EVM2008. 3. 15. 12:50

WINAVR 버전별 사이즈 비교

3종류의WinAVR(을)를 간단하게 전환해 가능하게 되었으므로,AVRminiProg-071222의 원시 코드를 사용해 생성하는 코드 사이즈를 체크해 보았습니다.
AVRminiProg(을)를-O2옵션,mega168용으로 컴파일 한 결과입니다.
덧붙여 컴파일에는,default 디렉토리에서 작업을 실시했습니다.
또,Makefile (을)를 이하와 같이 수정해,chwinavr커멘드로,WinAVR(을)를
바꾸면서,make clean, make 의 순서로 실행했습니다.
Makefile의CFLAGS 에 이하와 같이-I.. (을)를 추가한다.
CFLAGS += -I.. -Wall -gdwarf-2 ...
          ^^^^


컴파일러 버젼 릴리스 일자 코드 사이즈 데이터 사이즈
gcc version 3.4.6 WinAVR 20060421 5604 421
gcc version 4.1.2 WinAVR 20070525 5514 421
gcc version 4.2.2 WinAVR 20071221 5816 421

지금부터 판단하면, 코드가 약간 커지고 있습니다. 많은 고려해야 할 점이 있어, 이것만으로는 판단할 수 없습니다하지만, 사이즈가 작은 것(AVR-USB(을)를tiny디바이스로 실현되는 등 )을 만들 때는, 적절한 버젼을 선택해 컴파일 할 필요가 있다고 생각합니다.

Posted by nexp

댓글을 달아 주세요

[AVR]/AVR_EVM2007. 12. 7. 15:53

printf_P() 함수를 이용한 SRAM절약

printf_P() 함수를 이용한 SRAM절약

AVR에서 문자열은 일반 컴파일러와 다르게 SRAM에 저장이 된다.
특히나 램이 적은 MCU에서는 디버깅 출력을 위한 문자열 때문에 곤욕을 치루는데...
printf_P()함수를 이용하면 쉽게 해결 할 수 있다.


printf("\n\n**  String Test - Memory Alocated FLASH. **\n");
일반적인 printf를 이용하면 문자열이 SRAM영역으로 잡힌다.


#include <avr/pgmspace.h>

printf_P(PSTR("\n\n**  String Test - Memory Alocated FLASH. **\n"));
printf_P()함수를 이용하면 문자열이 FLASH영역으로 잡히므로 램을 줄일 수 있다.


따지고 보면 아래과 같은 형식이다. 예전에는 이렇게 사용했고...
static PROGMEM char  string[] = "\n\n**  String Test - Memory Alocated FLASH. **\n"
memcpy_P(buf, string, sizeof(string));
printf((buf);
Posted by nexp

댓글을 달아 주세요

[AVR]/AVR_EVM2007. 8. 14. 15:25

AVR Studio AVR GCC컴파일시 이유없는 에러 발생시 대처

AVR Studio AVR GCC컴파일시 이유없는 에러 발생

정확한 에러의 원인을 찾지 못하고 에러가 발생하는 경우가 종종 있다.

정확한 원인은 잘 모르겠지만 아무래도 AVR Studio의 문제 인것 같다.

 

error result

Loaded plugin STK500
Loaded plugin AVR GCC
gcc plug-in: Output directory D:\work\avr\evm\ftp\default\ does not exist
gcc plug-in: Created directory D:\work\avr\evm\ftp\default\
gcc plug-in: Error: Object file not found on expected location

 

 

그 에러 원인중 몇가지가 있는데 우선 함수를 중복해서 기술하면 에러를 찾지 못한다. AVR Studio에서 에러 결과를 지우는것 같다.

이때는 Command 창에서 make해서 결과를 보고 원인을 찾을 수 밖에 없다.

 

또 하나는 2007년도 컴파일러 나오면서 wait_1us()함수의 ASM심벌이 변경 되었는데... 이 심벌을 찾을 수 없어 에러를 발생하는데 그 결과를 나타내지 않아 한참을 고생 했다. default폴더를 보니 delay.o만 생성이 않되어 있어 보니 delay.c의 wait_1us()함수에 있는 ASM 심벌이 변경되었다 하고 이를 수정하니 정상 컴파일 된다.

 

 

void wait_1us(u_int cnt)
{
 /* 16MHz : 16 CLK 1us : 1 + (1 + (1+1)*4 + 1 + (2+1))*cnt + 1  + 1*/
 /*
 asm volatile
 (
  "movw r24, %A0"  "\n\t"
  "L_US:"    "\n\t"
  "ldi r26, lo8(4)"   "\n\t"
  "L_US0:"   "\n\t"
  "dec r26"   "\n\t"
  "brne L_US0"   "\n\t"
  "sbiw r24, 1"   "\n\t"
  "brne L_US"   "\n\t"
  "nop"    "\n\t"
  :  :"r" (cnt)
 );
 */

 asm volatile
 (
  "movw r24, %A0"  "\n\t"
  "L_US%=:"    "\n\t"
  "nop"    "\n\t"
  "nop"    "\n\t"
  "nop"    "\n\t"
  "nop"    "\n\t"
  "nop"    "\n\t"
  "sbiw r24, 1"   "\n\t"
  "brne L_US%="   "\n\t"
  "nop"    "\n\t"
  :  :"r" (cnt)
 );  
 
}

Posted by nexp

댓글을 달아 주세요

[AVR]/AVR_EVM2007. 5. 17. 11:28

AVR SPI관련 자료 - ATmega128, ATMega16, ATMega8 (예제 소스코드)

AVR SPI관련 자료 - ATmega128, ATMega16, ATMega8 (예제 소스코드)
AVR에서 SPI제어에 관련된 자료 정리

AVR SPI블록도



AVR ATMega128 SPI 핀맵
SPI핀 찾을것 없이 기록해 두면 편리할것 같다




관련 레지스터
SPSR

• Bit 7 – SPIF: SPI Interrupt Flag
읽을수만 있는 레지스터로 SPI인터럽트 발생 여부를 나타낸다.
• Bit 6 – WCOL: Write COLlision flag
오류 발생을 나타내는 비트
• Bit 5..1 – Res: Reserved Bits
사요하지 않는다.
• Bit 0 – SPI2X: Double SPI Speed Bit
SPI 클럭을 두배러 설정하는 비트

SPCR


• Bit 7 – SPIE: SPI Interrupt Enable
SPI인터럽트 사용여부 결정, 1일때 인터럽트 사용
• Bit 6 – SPE: SPI Enable
SPI 모듈 사용여부 결정. 1일때 SPI 사용.
• Bit 5 – DORD: Data Order
1: LSB 먼저 전송.
0: MSB 먼저 전송
• Bit 4 – MSTR: Master/Slave Select
1: Master SPI mode
0: Slave SPI mode
• Bit 3 – CPOL: Clock Polarity (SPI 모드 설정)
• Bit 2 – CPHA: Clock Phase (SPI 모드 설정)


SPI모드 설정





SPI 모드 설정 소스코드
SPI모드는 디바이스에 따라 변경해야 할 경우가 많으므로 아래 코드와 같이 정의해서 사용한다.
#define SPI0_CPOL_SET()      Sbi(SPCR, BIT3)
#define SPI0_CPHA_SET()      Sbi(SPCR, BIT2)
#define SPI0_CPOL_CLR()      Cbi(SPCR, BIT3)
#define SPI0_CPHA_CLR()      Cbi(SPCR, BIT2)

#define SPI0_MODE0()      SPI0_CPOL_CLR();SPI0_CPHA_CLR()
#define SPI0_MODE1()      SPI0_CPOL_CLR();SPI0_CPHA_SET()
#define SPI0_MODE2()      SPI0_CPOL_SET();SPI0_CPHA_CLR()
#define SPI0_MODE3()      SPI0_CPOL_SET();SPI0_CPHA_SET()


• Bits 1, 0 – SPI클럭 설정


클럭 설정 부분도 아래와 같이 정의 해 두면 편리하게 사용할 수 있다.
#define SPI0_CLK_DIV16()     Cbi(SPCR, BIT1);Sbi(SPCR, BIT0)
#define SPI0_CLK_DIV64()     Sbi(SPCR, BIT1);Cbi(SPCR, BIT0)
#define SPI0_CLK_DIV128()     Sbi(SPCR, BIT1|BIT0)

#define SPI0_CLK_DOULBE()     Sbi(SPSR, BIT0)



AVR SPI통신 초기화 함수
AVR ATMega128, ATMega8의 핀맵이 다르므로 아래와 같이 #if 문으로 정의해 두면 MCU에 따라 유용하게 사용할 수 있다.
void SPI0_Init(void) // SPI 통신 초기화 함수
{
 #if (__MCU_TYPE__ == AVR_TYPE_MEGA128)  
 // setup SPI I/O pins
 Cbi(PORTB, BIT1); // set SCK lo
 Sbi(DDRB, BIT1); // set SCK as output
 
 Sbi(DDRB, BIT2); // set MOSI as output
 Cbi(DDRB, BIT3); // set MISO as input
 
 Sbi(DDRB, BIT0); // SS must be output for Master mode to work
 Sbi(PORTB, BIT0);
 #else if (__MCU_TYPE__ == AVR_TYPE_MEGA8)
 Sbi(PORTB, BIT5); // set SCK lo
 Sbi(DDRB, BIT5); // set SCK as output
 
 Sbi(DDRB, BIT3); // set MOSI as output
 Cbi(DDRB, BIT4); // set MISO as input
 
 Sbi(DDRB, BIT2); // SS must be output for Master mode to work
 Sbi(PORTB, BIT2);
 #endif

 SPI0_ENABLE();
 SPI0_MASTER_MODE();
 
 SPI0_MODE0();
 SPI0_CLK_DOULBE();
 SPI0_CLK_DIV4();
}



SPI 데이터 송/수신 전송 함수
좀더 빠른 처리를 위해 define문으로 정의하는것이 좋다.
#define SPI0_WriteByte(Data)                             SPDR = (Data);  while(!(SPSR & (1<<SPIF)))

#define SPI0_WaitForReceive()                           while(!(SPSR & (1<<SPIF)))

#define SPI0_RxData()       (SPDR)


SPI데이터 수신 함수
보통 SPI Master의 경우 SPI데이터 전송후 수신하는 경우가 많기 때문에 WriteReadByte함수를 만들어 두면 유용하다.
unsigned char SPI0_WriteReadByte(unsigned char Data)
{
    SPI0_WriteByte(Data);
    return SPI0_RxData();
}
Posted by nexp

댓글을 달아 주세요

[AVR]/AVR_EVM2007. 4. 22. 16:01

Atmel AVR ISP 관련 자료

Atmel AVR ISP 관련 자료

STK500 표준 커넥터




AVR ISP MKII 표준 커넥터




프린트 포트용 AVR ISP 회로도



Posted by nexp

댓글을 달아 주세요