임베디드/Atmega

7월 24일 오실로스코프를 이용한 시간 지연.

송시혁 2013. 7. 24. 16:27


아래는 atmega led를 깜박이는 소스이다. 이 소스에서 완성.

이 방법은 timer counter를 이용하지 않고 시간을 지연하기 위한 것. 시간의 지연시키는 것을 모니터링

하기 위해 오실로스코프를 사용하였다. 




#define DDRA    (*((volatile unsigned char *)0x21))//DDRA 
define PORTA  (*((volatile unsigned char *)0x22))//atmegat의 portA부분의 주소를 정의. 데이터시트 참고



void my_msdelay(unsigned int uiMs);//함수 원형.

int main(void)
{
  volatile unsigned int iCnt2;
  volatile unsigned int iCnt1;
  
  DDRA= 0xFF;//8비트 모두 활성화.
  PORTA=0xFF;//8비트 모두 활성화.


  while(1)                                   
  {
          my_msdelay(1000);//delay 함수 인자를 m/s단위의 시간.

//    for(iCnt1=0;iCnt1<790;iCnt1++);//0.001초지연.                                                 
      //for(iCnt2=0;iCnt2<10;iCnt2++);
    
    PORTA=0x00;//A의 0을 넣어 led를 끄게 하기 위한 코드. 위아래코드가 while문에 의해 반복되면서 led를 깜박인다.
 
    my_msdelay(1000);
    //for(iCnt1=0;iCnt1<790;iCnt1++);
      //for(iCnt2=0;iCnt2<10;iCnt2++);
    PORTA=0xFF;


  }
  while(1);  
  return 0;
}     



void my_msdelay(unsigned int uiMs)//인자 uiMs는 말그대로 m/s단위의 시간을 뜻함. 
{
        volatile unsigned int iCnt;
        while(uiMs>0)
        {
                --uiMs;
                for(iCnt=0;iCnt<792;++iCnt);//0.001초지연. 인자로 1000을 받는다면 1000번 실행한다. 이것이 1초가 된다. 
        }
        
                
                
}
              
원래 반복문에서 for문은 이중for문이 2개가 존재하였다. 하나는 LED꺼진 상태와 켜진 상태.

  for(iCnt1=0;iCnt1<790;iCnt1++);//0.001초, 즉, 1ms로 맞추기 위하여 숫자를 최대한 낮추어가면 맞춘다.
파형의 high,low값을 맞추는 작업이다. 위아래 보이는 숫자는 790은 어느정도 맞춘 상태.

    //for(iCnt1=0;iCnt1<790;iCnt1++);
     
                        

그리고 함수 my_msdelay함수를 만들어 위에 셋팅한 for문을 비교한다. 
그러면 아래와 같은 코드가 된다.


my_msdelay(1);
//for(iCnt=0;iCnt<790;++iCnt);my_msdelay(1)함수와 맞추기 위해서 주석처리.
       //
for(iCnt=0;iCnt<1000;++iCnt) 이 부분은 필요없으로 주석처리.


for(iCnt=0;iCnt<790;++iCnt);
     //
for(iCnt=0;iCnt<100;++iCnt); 이 부분은 필요없으로 주석처리.

my_msdelay(unsigned int uims)
{
      volatile unsigned int iCnt;
      while(uims>0)
      {
         
 --uims;//while문을 탈출하기 위하여 증감한다. 예를 들어 uims가 3인 경우 아래 for문이 3번 돌고 while문이
                    //탈출된다.
         
for(iCnt=0;iCnt<790;++iCnt);//ATMEGA는 16비트이므로 최대 수치가 65535이다 그냥 단순히 for문만을
                                              //돌리면 최대치가 넘어서 제대로 출력을 할 수 없으므로 while문을 썼다.
        

       }
}

아니면 변수 iCnt를 long형으로 바꾸는 방법도 있다.