20141031 (C++ Template 분할 컴파일, ARM PWM)

170일차









-----------

C++

-----------



------- Template class 분할 컴파일


다음 예제 확인


예제)

--- PointTemlate.h


#ifndef __POINT_TEMPLATE_H
#define __POINT_TEMPLATE_H

template <typename T>
class Point
{
	private:
		T xpos, ypos;

	public:
		Point(T x = 0, T y = 0);

		void ShowPosition() const;
};

#endif




--- PointTemlate.cpp


#include <iostream>
#include "PointTemplate.h"

using namespace std;

template <typename T>
Point<T>::Point(T x = 0, T y = 0) : xpos(x), ypos(y)
{ }

template <typename T>
void Point<T>::ShowPosition() const
{
	cout << "[" << xpos << ", " << ypos << "]" << endl;
}




--- main.cpp


#include <iostream> #include "PointTemplate.h" using namespace std; int main() { Point<int> pos1(3, 4); pos1.ShowPosition(); Point<double> pos2(3.1, 4.2); pos2.ShowPosition(); Point<char> pos3('P', 'T'); pos3.ShowPosition(); return 0; }





이대로 컴파일하면 에러다.

템플릿에 대한 정보가 부족해서 그렇다.


해결 방법은 두 가지로

1. main.cpp에 #include "PointTemplate.cpp" 추가

2. PointTemplate.h 에 정의 내용 추가


그럼 에러없이 잘된다.

















------------

ARM

------------




------- PWM


Pulse Width Modulation의 뜻으로 주파수 변조이다. 예를 들어 5V의 신호를

High, Low 로 밖에 처리하지 못했었는데,

만약 High인 시간이 아주 짧게 계속 반복 된다면 어떻게 될까?

그냥 깜빡거림이 짧아질까??




하지만 깜빡거림이 짧아지면서 5V의 효과가 아닌 0.5V의 효과, 전압을 제어하게 된다!!

그래서 LED의 밝기가 약해지고 밝아지고를 할 수 있게 된다.




PWM은 두 가지 방법으로 사용 가능하다

1. PWM device를 사용

2. TC device를 사용


이번엔 TC device를 사용해서 해본다.



--- 먼저 TC Block Diagram



전에는 Interrupt 발생(보라색)으로 시간 계산을 했었는데

이제는 (빨강색) 내부 clock을 가공하여 외부로 출력해 일정 전압이 발생하는 것처럼 처리한다.



각 신호에 대한 설명




- 각 핀 설명







- 주파수가 발생하는 과정?



TC_CV Reg 값이 증가하다가 Ra Reg에 설정해 놓은 값을 만나면 TIOA에 High가 걸린다.

TC_CV Reg 값이 증가하다가 Rb Reg에 설정해 놓은 값을 만나면 TIOB에 High가 걸린다.

TC_CV Reg 값이 증가하다가 Rc Reg에 설정해 놓은 값을 만나면 TIOA, TIOB에 Low가 걸린다.

TC_CV Reg 값이 증가하다가 0xFFFF 인 최대 값에 도달하면 0으로 됨.


이때 이 High 걸리는 시간에 따라 전압이 달라지게 된다.




예제 소스)

#include "AT91SAM7S256.h"


#define MASTERCLOCK     48000000


void Delay_ms(unsigned int ms)

{

volatile unsigned int count;

volatile unsigned int countmax = (MASTERCLOCK / 10000) * ms;

for(count = 0; count < countmax; count++);

}


int main(void)

{

unsigned int RA = 1000;         // initial register value

unsigned int RB = 0xFFFF;

unsigned int RC = 0xFFFF;

unsigned int uiCnt = 1000;


*AT91C_PMC_PCER = (1 << AT91C_ID_TC0); // TC0 전원 공급

*AT91C_PIOA_PDR = 0xFFFFFFFF; // PA0, PA1 PIO비활성화

*AT91C_PIOA_BSR = AT91C_PIO_PA0 | AT91C_PIO_PA1;  // TIOA0,TIOB0 output(Peripheral B모드 사용)


   // TC0 Channel Control Register

//*AT91C_TC0_CMR =0x89898402;

*AT91C_TC0_CMR = AT91C_TC_BSWTRG_NONE |

AT91C_TC_BEEVT_NONE |

AT91C_TC_BCPC_CLEAR |

AT91C_TC_BCPB_SET |

AT91C_TC_ASWTRG_NONE |

AT91C_TC_AEEVT_NONE |

AT91C_TC_ACPC_CLEAR |

AT91C_TC_ACPA_SET |

AT91C_TC_WAVE |

AT91C_TC_WAVESEL_UP |

AT91C_TC_EEVT_XC0 |

AT91C_TC_CLKS_TIMER_DIV1_CLOCK;


*AT91C_TC0_CCR = 5;


*AT91C_TC0_RA = RA; // set TC0 RA register

*AT91C_TC0_RB = RB; // set TC0 RB register

*AT91C_TC0_RC = RC; // set TC0 RC register

*AT91C_TC0_SR = AT91C_TC_CLKSTA; // TC0 clock enable and start


while(1)

{

RA = RA + uiCnt;

RB = RB - uiCnt;

Delay_ms(250);


if(RA > RC)

{

RA = 1000;      // RA(PA0)은 점점 어두워지고

RB = 0xFFFF;    // RB(PA1)은 점점 밝아진다.

uiCnt = uiCnt + 2000;    // 밝아지고 어두워지는 속도가 점점 빨라짐

if(uiCnt > RC) // 속도 초기화

{

uiCnt = 1000;

}

}

*AT91C_TC0_RA = RA;

*AT91C_TC0_RB = RB;

}

}






설정

트랙백

댓글