반응형

1. avrstudio 환경에서 delay 함수 사용시 

 

 

F_CPU를 선언하지 않는 경우, 또는 F_CPU를 delay.h 이후에 선언하는경우
-> 컴파일 옵션(project 속성에서)으로 -DF_CPU=xxx 가 되도록 하시거나,
#define F_CPU 16000000UL // 실제 동작 clock hz
#include <util/delay.h>

위 F_CPU 정의 및 delay.h 와의 순서 지킬것.

2. avrstudio 환경에서 인터럽트 문맥과 비 인터럽트 문맥에서 공유하는 변수 사용시 volatile 

인터럽트 문맥과 비 인터럽트 문맥에서 공유하는 변수는 volatile 수형을 붙여 주거나,
컴파일 옵션에서 -O0(옵티마이저 끄기)를 주거나

3. 빠른 속도로 인터럽트(타이머 같은) 에서 변경되는 변수를 비 인터럽트 루틴에서 exact match 비교

volatile int cnt  = 0;
ISR(TIMER0_COMPA_vect)
{
    cnt ++;
}

main()
{
    while(1)
    {
        if(cnt == 100) //  자원 공유(바로 이전 보충자료(13)참조 문제 및, 실행되는 코드에 따라서는 cnt 변화를 따라 갈수 없는 경우발생
    }
}

4.  uart 의 buffer 동작 잘못 이해
 
main()
{
     if(UDR0 == 'a') { } 
     else if(UDR0 == 'b') {}
}
=> UDR은 마치 fifo와 같아서 읽으면 수신된 데이타가 buffer에서 없어짐.
  즉 첫번째 UDR0 를 읽으면 그 다음 else if의 UDR0는 이전 UDR0 에 저장된 값이 아님.

5.  atmega8 계열의 UCSRC와 UBRRH 가 같은 주소를 공유함. 
최상위 한비트에 따라 1이면 UCSRC가, 0이면 UBRRH가 선택됨
=> UCSRC = (1 << 7) | 원하는 값;

6. 16MHz 동작 avr 칩의 uart  115200 baud 인 경우 
16X 로 동작시 error 율이 3% 넘어서 데이타 깨질수 있음.
=> U2X = 1로 설정(UCSRA) 및 ubrr = SYS_CLK / 8.0 / baud - 1 + 0.5;
 U2X를 1로 하고 8로 나눠서 에러율을 낮출수 있음. 위 0.5는 반올림용.


7. 칩을 새로 붙인후 fuse 비트 외부 crytal이 16MHz라고 16Mhz로 동작한다고 생각하는 경우

#include <avr/io.h>
#define F_CPU 16000000UL
#include <util/delay.h>
main()
{
    DDRA = 1;
    while(1) { PORTA ^= 1; _delay_ms(1000); }
}
포트 A의 핀 0에 LED가 있다고 가정하고
1초 켜지고 1초 꺼지면, 16MHz
2초 켜지고 2초 꺼지면, 8MHz
4,
8
16초 켜지고, 16초 꺼지면, 1MHz(보통 내부)

8. 인터럽트 루틴내에서 처리시간 많이 넣기.

ISR()
{
    while(1)
    {
        _delay_ms(x); 
        기타 시간소모하는 코드들.
    }
}
=> 가능하면 인터럽트 루틴 코드는 간단히, 시간 적게 걸리게 하기
하지만 그렇다고 너무 지나치게 ISR에서 코드 넣는걸 싫어할 필요는 없음.

즉 사용하고자 하는 다른 인터럽트 종류, 또는 controller의 오동작 유발하지 않는 범위면 상관없음.


9. atmega128 함수 호출만 하지 않으면 정상 동작하는 경우

fuse 비트의 M103C 가 체크 되어 있으면, 내부 sram주소 영역이 0x100 만큼 줄어든다.
이 상태에서 atmega128로 코딩하면 stack이 정상 동작하지 않는다.

=> M103C 를 uncheck 상태로 

10. avrstudio/winavr 환경에서 _delay_ms , _delay_us 의 인자가 변수가 허용되지 않는 경우
#define __DELAY_BACKWARD_COMPATIBLE__
이걸 delay.h앞에 추가


11. avr 16비트 레지스터 access 시 주의 

11.1 16비트 레지스터중 주의 읽기 주의해야 하는 레지스터
    
  ADCL, ADCH 경우 ADCL를 읽으면, 내부의 ADC값이 하위값이 읽히고, 상위는 내부에 latch 됨
  상위를 읽지 않으면 ADCL을 읽어도 새로운 ADC값이 읽히지 않음..
  즉 불필요하더라도 ADCL 만 읽는 형태로 코딩하면 안됨.

  16비트 단위로 읽거나, 하위, 상위 순서대로 읽기를 할것.(상위가 필요없어도 꼭 읽어줘야 함)

11.2 16비트 읽기,쓰기 바이트 단위로 접근시 주의 할 레지스터

The TCNTn, OCRnA/B/C, and ICRn 16bit 레지스터는 직접 8비트 단위로 접근시,
읽기 : 하위 먼저, 다음 바로 해당 레지스터 상위
쓰기 : 상위 먼저, 다음 바로 해당 레지스터 하위

- 쓰기
   상위 쓰기 하면 내부 임시 레지스터에 들어 있다가, 하위 쓰기 하면 16비트 쓰기가 실제로 이루어짐.
   이 임시 레지스터는 여러 16bit 레지스터간 공유이므로,  다음과 같은 건 문제가 있겠죠.
    TCNT1H = 0x10;
    TCNT3H = 0x20;
    TCNT1L = 0x34;
    TCNT3L = 0x56; 
   위 임시저장이 하나이므로 이 경우 TCNT1은 0x2034(0x1034가 아님), TCNT3은 0x02056이 들어갈것 
 (확인 한게 아니라 나중에 확인 하겠음) 


12. 인터럽트 루틴에서 cli(), sei() 사용하기

ISR()
{
    cli();
    할일들
    sei();
}

ISR에 들어가면 자동으로 cli()와 같은 효과, 나올때 sei() 효과와 동일한 일이 하드웨어적으로 이루어 집니다,.
따라서 ISR내에서 cli(), sei()로 critical section 화 하는건 의미가 없습니다.


13. 상태 flag 지우기

13.1 uart 수신 flag 지우기
ISR(USARTx_RXC_vect)
{
    UCSRxA = UCSRxA & ~0x80;
    ch = UDRx;
}
이런식으로 해당 수신 flag을 지울려고 노력하는 사람들이 보이는데, 해당 flag는 UDR(실제로 두바이트 버퍼)에 
데이타가 없을때 자동으로 지워집니다. 위처럼 해당 비트를 0으로 쓰기한다고 지워지지 않습니다.

13.2 EIFR, TIFR 의 특정 flag 비트 지우기
 
mcu/controller 등에 익숙하지 않은 분들은 13.1 처럼 flag 성격의 비트를 지울때 0을 쓰기 하면 된다고 생각하는 
사람들이 있습니다.
 EIFR = EIFR & ~1; // 최하위 한비트 지울려고 이렇게 함. 이렇게 하면 원하는 동작이 안됨.

 flag 성격의 비트들은 s/w가 clear 할 수 있는 경우 보통 해당 비트를 1로 쓰기하면 지워집니다.
 즉
 EIFR = EIFR;
이렇게 하면. 1로 설정된 비트들에 모두 1을 쓰기 한 결과가 되어서, 그전에 설정된 모든 flag(EIFR을 읽을떄)를  clear  하는 효과가 있습니다.

 원하는 비트만 clear 할려면
 EIFR = 1 << 원하는 비트위치;
 이렇게 합니다.

 즉 정리하면 
 일반 레지스터(모드 설정등)는 해당 비트를 0을 쓰기 하면 0이 쓰여지고, 1을 쓰기 하면 1이 쓰여지는 게 있지만
 flag(인터럽트를 발생시키기 위한 비트로도 사용되는 경우가 많은)은 
 인터럽트 발생시 clear 되거나(EIFR), program에서 직접 clear 하고자 하는 비트만 1이 되도록 해서 쓰기를 하거나,
 해당 조건이 사라지는(UCSRnA 의 RXC 비트 같은 경우 데이타를 읽어내면 저절로 지워짐) 해당 flag가 clear 됩니다.
 해당 레지스터를 잘 읽는게 좋습니다.


반응형

'개발환경 > AVR Studio 4.19' 카테고리의 다른 글

No such file 오류시 및 환경 설정  (0) 2021.01.25
_delay_ms() 인자로 변수 사용하기  (0) 2021.01.25
반응형

경로  및 MCU 미설정시 build 실행시 오류가 생길 수 있음

 



 

avr-gcc 에는 C: inAVR-20100110\bin\avr-gcc.exe 로 경로를 입력

 


make 에는 C: inAVR-20100110\utils\bin\make.exe 로 경로를 입력

반응형

'개발환경 > AVR Studio 4.19' 카테고리의 다른 글

실수 하기 쉬운 것들 참고  (0) 2021.01.25
_delay_ms() 인자로 변수 사용하기  (0) 2021.01.25
반응형

_delay_ms() 함수에 상수가 아닌 변수를 입력 하려고 할때,

ex) int delay = 100;

_delay_ms(delay);

이경우 빌드시 _delay_ms(delay); 구문에서 에러가 발생하게 됩니다.



#include <util/delay.h>위에 

#define __DELAY_BACKWARD_COMPATIBLE__ 이 코드를 추가해주면 된다.

반응형

'개발환경 > AVR Studio 4.19' 카테고리의 다른 글

실수 하기 쉬운 것들 참고  (0) 2021.01.25
No such file 오류시 및 환경 설정  (0) 2021.01.25

+ Recent posts