본문 바로가기
코스웨어/14년 스마트컨트롤러

2014.11.11 출석번호 8번 김진철 일일보고서

by 알 수 없는 사용자 2014. 11. 11.
728x90
반응형

ARM(STM32F103ZE)



소스코드와 실행순서 먼저 보겠다




#define RCC_APB2ENR    (*(volatile unsigned int *)0x40021018)  // power supply?
#define USART_SR          (*(volatile unsigned int *)0x40013800)
#define USART_DR          (*(volatile unsigned int *)0x40013804)
#define USART1_BRR      (*(volatile unsigned int *)0x40013808)
#define USART1_CR1        (*(volatile unsigned int *)0x4001380C)
#define USART1_CR2        (*(volatile unsigned int *)0x40013810)
#define USART1_CR3        (*(volatile unsigned int *)0x40013814)
#define GPIOA_CRH          (*(volatile unsigned int *)0x40010804)  // bit setting
#define GPIOC_CRH          (*(volatile unsigned int *)0x40011004)  // bit setting
#define GPIOC_BSRR      (*(volatile unsigned int *)0x40011010)  // bit set
#define GPIOC_BRR          (*(volatile unsigned int *)0x40011014)  // bit reset

void Usart_Init(void/*isr_function usart1_isr*/)
{
  /* Rx, Tx Pin setting */
   GPIOA_CRH = 0xB0;
   GPIOA_CRH |= 0x400;

  /* Configure the USART1 */
  USART1_CR2 = (0x00<<12);  // Stop Bit 1
  USART1_CR1 = (0x00<<12)  //WordLength_8b
                          | (0x00<<10)  //No Pariy
                          | (0x01<<3| (0x01<<2);    // Rx/Tx Enable
  
  USART1_CR3 = (0x00<<8);      // USART_HardwareFlowControl_None

  USART1_BRR = 0x0271;    // 115,200bps  at PLLCLK is 72MHz

  /* Enable the USART1 */
  USART1_CR1 |= (1<<13);
}

void Usart_Tx(unsigned char ucBuff)
{
  USART_DR = ucBuff;
  while(0x00 == (USART_SR  & 0x80));
}

void Usart_Str(const unsigned char * cString)
{
  while(0 != *cString)
  {
    Usart_Tx(*cString);
    ++cString;
  }
}

unsigned char Usart_Rx(void)
{
  while(0x00 == (USART_SR & 0x20));
  
  return (unsigned char)USART_DR;
}



int main()
{
  RCC_APB2ENR |= ((0x01<<14| (0x01<<2));// |(0x01<<0));    // USART1, GPIOA,   Enable
  
  Usart_Init();
  
  Usart_Tx('T');
  Usart_Tx('E');
  Usart_Tx('S');
  Usart_Tx('T');
  Usart_Tx(' ');
  Usart_Str("Hello~ ");
  
  while(1)
  {
    Usart_Tx(Usart_Rx());
  }
  
  return 0;
}


결과 : 


RESET버튼을 누를 때 마다



그리고 'aaa'를입력하니 하이퍼 터미널에 그대로 출력이 된 것을 확인할 수 있다.




찬찬히 소스분석을 해보겠다


일단 define은 Datasheet를 참조했다고 가정하고 define에 대한 것은 건너 뛰겠다.

먼저 분석을 하기 위해서는 main() 부터 볼 필요가 있다.


  RCC_APB2ENR |= ((0x01<<14| (0x01<<2));// |(0x01<<0));    // USART1, GPIOA,   Enable


이 레지스터는 데이터시트 p.112 하단에 있으며



현재 USART 기능과 GPIO포트를 Enable 해주고 있다.


다음은 Usart_Init(); 을 호출하는데 이 함수를 또 살펴보자


void Usart_Init(void/*isr_function usart1_isr*/)
{
  /* Rx, Tx Pin setting */
   GPIOA_CRH = 0xB0;
   GPIOA_CRH |= 0x400;

  /* Configure the USART1 */
  USART1_CR2 = (0x00<<12);  // Stop Bit 1
  USART1_CR1 = (0x00<<12)  //WordLength_8b
                          | (0x00<<10)  //No Pariy
                          | (0x01<<3| (0x01<<2);    // Rx/Tx Enable
  
  USART1_CR3 = (0x00<<8);      // USART_HardwareFlowControl_None

  USART1_BRR = 0x0271;    // 115,200bps  at PLLCLK is 72MHz

  /* Enable the USART1 */
  USART1_CR1 |= (1<<13);

}


GPIOA_CRH 는 p.172 에 있다

주석에 달아놓았 듯이 Rx와 Tx 설정을 다루는 레지스터인데


우리는 Altermate functions를 사용하기로 했으니 다음 표를 봐야 한다.

130쪽짜리 데이터시트 p.33 을 보면 Altermate functions 라고 되어 있는 부분에

PA9와 PA10 의 기능이 USART의 Tx와 Rx라는 것을 볼 수 있다.


그러므로 여기서는 PA9 와 PA10 을 사용할 것이다.




본격적으로 레지스터를 살펴보도록 한다.

PA9 와 10을 쓰기로 했으면 해당 비트에 '1'을주든 '0'을 주든 해야할 것이다.

먼저 Tx에 해당하는 PA9 부터 보면 CNF라는 비트와 MODE라는 비트가 있다

화살표를 따라가보자


MODE의 설명을 사펴보면 전송속도가 50MHz라고 되있다. 

어찌됐든 우린 50MHz를 선택했고 CNF에는 General purpose가 아닌 Altermate Function을 사용하기로 했으니

그쪽 표를 봐야할 것이다. Push-pull을 선택한 이유는 아직 자세히 모르겠다.

나중에 검색해봐야지 

결과적으로 4~7bit에는 0xB0 ( 1011 0000 ) 가 들어가겠다. 소스코드를 보면 그러하다.


이제 Rx를 의미하는 CNF10과 MODE10 을 건드릴 차례다

이것 역시 마찬가지로 데이터시트를 참조하여 입력한다.

Floating input을 선택한 이유또한 모르겠다 나중에 또 검색해봐야지


Rx는 데이터를 받아야 하니까 Input mode 라고 되어있는 곳을 참조해서 시킨대로 '00'을 넣을 것이다.

그러므로 PA10에는 0x400 (1000 0000 000) 이 들어간 것이다.



< 데이터시트에서 팔나색 글찌를 클릭하면 아래그림처럼 표가 나타날 것이다. >



아직 갈길이 많이 남았음

다음은 USART1_CR2 레지스터다



<이미지 줄이기 귀찮음..크게볼려면 클릭>


STOP비트를 위와 같이셋팅 했음







C++ (형 변환)


형 변환 

C언어의 형 변환은 강제적으로 형 변환한다.

dynamic_cast는  상속관계에서 상위 클래스를 참조하는 경우만 허용
static_cast는 기본 자료형 간의 형 변환 또는 상속 관계에서의 형 변환만을 허용함
#include <iostream>
using namespace std;

class Car
{
private:
                 int fuelGauge;
public:
                Car( int fuel) : fuelGauge(fuel)
                {}
                 void ShowCarState() { cout<<"잔여 연료량 : " <<fuelGauge<<endl;}
};

class Truck : public Car
{
private:
                 int freightWeight;

public:
                Truck( int fuel, int weight)
                                : Car(fuel), freightWeight(weight)
                { }
                 void ShowTruckState()
                {
                                ShowCarState();
                                cout<< "화물의 무게 : " <<freightWeight<<endl;
                }
};

int main()
{
                 /*
                Car * pcar1=new Truck(80,200);
                Truck * ptruck1=(Truck *)pcar1;
                ptruck1->ShowTruckState();
                cout<<endl;
                Car * pcar2=new Car(120);
                Truck * ptruck2=(Truck *)pcar2; // 형변환이 맞지는 않지만 강제캐스팅을 했기에 컴파일시 문제는 없다.
                ptruck2->ShowTruckState();
                */
                 /*
                //Car * pcar1= new Truck(80,200);
                //Truck * ptruck1=dynamic_cast<Truck*>(pcar1);       // 컴파일 에러

                //Car * pcar2= new Car(120);
                //Truck * ptruck2=dynamic_cast<Truck*>(pcar2); // 컴파일 에러

                Truck * pcar3= new Truck(70,150);
                Car * ptruck3=dynamic_cast<Car*>(pcar3);   // 상위 클래스의 객체포인터는 허용 나머지는 불허
                */

                Car * pcar1= new Truck(80,200);
                Truck * ptruck1= static_cast<Truck*>(pcar1);               
                ptruck1->ShowTruckState();
                cout<<endl;

                Car * pcar2= new Car(120);
                Truck * ptruck2= static_cast<Truck*>(pcar2);
                ptruck2->ShowTruckState();
                
                 return 0;
}

const_cast는 const 성향을 삭제한다. 부가적으로 volatile 성향도 제거할수가 있다.
#include <iostream>
using namespace std;

void ShowString(char * str)
{
                cout<<str<<endl;
}

void ShowAddResult(int & n1, int& n2)
{
                cout<<n1+n2<<endl;
}

int main()
{
                 const char * name = "Lee Sung Ju";
                ShowString( const_cast<char *>(name));

                 const int & num1=100;
                 const int & num2=200;
                ShowAddResult( const_cast<int &>(num1),const_cast< int&>(num2));
                 return 0;
}

<소스파일>


728x90