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

2014.11.05 업무일지 - 한솔

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

                    

-> STM32F1xx_DFP     Install 하기
-> MDK_Middleware은 update해준다.



(새 프로젝트 생성)
- 이름 임의 -

(모델 설정)
Z - 144pin
E - 512KB
T - LQFP
6 - 영하 40˚~ 85˚
     


( 프로젝트 생성 끝 )





( New file생성)

( New file생성 끝 )







* 데이터시트 or 소스 *

-LED 켜기 위해 사용할 PORT는 PORT C 12-





     0X4002 1000 - Base Address 
         - Base Address를 참조하여 앞으로의 Address를 설정해준다.
          -> ex) RCC_APB2ENR = 0x4002 1018

어떤 Port를 사용하는지 확인하기 - port C 12로 위에서 확인함







- Sorce -
#define RCC_APB2ENR  (*(volatile unsigned *)0x40021018)     // Clock Enable
#define GPIOC_CRH        (*(volatile unsigned *)0x40011004)      // PORT C Mode결정(I/O결정)
#define GPIOC_BSRR    (*(volatile unsigned *)0x40011010)      // PORT C Set설정(Enable)      
#define GPIOC_BRR        (*(volatile unsigned *)0x40011014)      // PORT C Reset설정

static void Delay(volatile unsigned int a)
{
  for( ; a > 0 ; a--);
}

int main()
{  
    RCC_APB2ENR = RCC_APB2ENR | 0x10;              // PORT C의 Clock이 공급
    // GPIOC_CRH      = GPIOC_CRH & (~0xF0000);
    GPIOC_CRH      = 0x10000;        // CRH_MODE12(PORTC 12번이라서), 01 설정되어서 출력 Speed 10MHz
    // or걸면 원래있던 CRH의 값 (4444 4444)와 or되어 이상한 값이됨
     
 
  while(1)
  {
    GPIOC_BSRR = GPIOC_BSRR | 0x1000;    // BSRR의  BS12번 사용 (Set)
    Delay(4000000);
    GPIOC_BRR = GPIOC_BRR | 0x1000;      // BRR의 BR12번 사용 (Reset)
    Delay(4000000);
  }
  
  return 0;
}
    


RCC_APB2ENR  (*(volatile unsigned *)0x40021018)
-> Clock Enable레지스터


RCC_APB2ENR = RCC_APB2ENR | 0x10
     -> Clock Enable




GPIOC_CRH        (*(volatile unsigned *)0x40011004)
-> 출력속도설정하는 레지스터


GPIOC_CRH      = 0x10000 -> MODE12번을 01값으로 초기화
     -> 01은 Push - pull을 Max. Output Speed 10MHz로 설정 (임의로..?)

     *MODE12, CNF12의 12는 PORT번호를 의미하는 듯.. 






GPIOC_BSRR    (*(volatile unsigned *)0x40011010)
-> Set/Reset레지스터
     -> BSRR에서도 Reset사용 가능하지만, 밀어주는 불편함 때문에 Reset레지스터(BRR)를 따로 사용

GPIOC_BSRR = GPIOC_BSRR | 0x1000; -> BS12 사용하려고 1000으로 초기화 시켜줌
-> BS0~15 = Set설정, BR0 ~ 15 = Reset설정
-> BS12로 Port 12 Set설정 걸어줌




GPIOC_BRR        (*(volatile unsigned *)0x40011014)
-> Reset레지스터
     -> BSRR에서도 Reset사용 가능하지만, 밀어주는 불편함 때문에 따로 사용

GPIOC_BRR = GPIOC_BRR | 0x1000; -> BS12사용
     -> Reset설정 초기화





(컴파일 후 실행 동영상 & 사진)





- 제대로 동작 하지 않으면 Reset버튼 눌러 볼 것 -






- Key 설정을 위한 PA2 (Port A 2) 설정해주기 -

-> 전류가 PA2 방향으로 흐르다가 Key1에 Input신호가 오면 전류가 Key1쪽으로 꺾여 흐르게됨,
     그렇게 되면 PA2쪽으로 가는 전류가 차단되어 PA2는 0값이 된다.
          -> 즉 0값이 되면 Key1에 Input이 왔다는 것 (스위치를 눌렀다는 것)




#define RCC_APB2ENR  (*(volatile unsigned *)0x40021018)     // Clock Enable
//  PORT C - 4001 1000 - LED 조절을 위한 PORT
#define GPIOC_CRH        (*(volatile unsigned *)0x40011004)      // PORT C Mode결정(I/O결정)
#define GPIOC_BSRR    (*(volatile unsigned *)0x40011010)      // PORT C Set설정(Enable)      
#define GPIOC_BRR        (*(volatile unsigned *)0x40011014)      // PORT C Reset설정

// PORT A - 4001 0800 - 키 설정을 위한 PORT
#define GPIOA_CRL        (*(volatile unsigned *)0x40010800)      // PORT A Mode결정(I/O결정)
#define GPIOA_BSRR      (*(volatile unsigned *)0x40010810)      // PORT A Set설정(Enable)      
#define GPIOA_BRR        (*(volatile unsigned *)0x40010814)      // PORT A Reset설정
#define GPIOA_IDR        (*(volatile unsigned *)0x40010808)    // PORT A Input Data설정

static void Delay(volatile unsigned int a)
{
  for( ; a > 0 ; a--);
}

int main()
{  
    // GPIO A Initaize  
    RCC_APB2ENR = RCC_APB2ENR | 0x04;              // PORT A의 Clock이 공급
    GPIOA_CRL = 0x400// Input Switch Setting
  
    // GPIO C Initaize
    RCC_APB2ENR = RCC_APB2ENR | 0x10;              // PORT C의 Clock이 공급
  
  // GPIOC_CRH      = GPIOC_CRH & (~0xF0000);
    GPIOC_CRH      = 0x10000;        // CRH_MODE12(PORTC 12번이라서), 01 설정되어서 출력 Speed 10MHz
  
  

  // LED On/Off
  while(1)
  {
//    if( (2 >> GPIOA_IDR) != 0)                        // BS2까지 밀어줌
      if((GPIOA_IDR & 0x04)==0)
      {
        GPIOC_BSRR = GPIOC_BSRR | 0x1000;    // BSRR의  BS12번 사용 (Set)
//      Delay(4000000);
      }
      else 
      {
      GPIOC_BRR = GPIOC_BRR | 0x1000;      // BRR의 BR12번 사용 (Reset)
//    Delay(4000000);
      }
}
  
  return 0;
}
   

   


RCC_APB2ENR  (*(volatile unsigned *)0x40021018)

RCC_APB2ENR = RCC_APB2ENR | 0x04;   
     ->  PORT A를 사용할 것이기 때문에 bit 2를 Set해준다.




#define GPIOA_CRL        (*(volatile unsigned *)0x40010800)
-> PROT A를 사용할때는 2번 PIN이라 CRH모드가 아닌 CRL모드를 사용해 준다.


 GPIOA_CRL = 0x400 
-> 입력(Input)을 설정할 때는 MODE1(0)의 값이 00으로 설정된다는 것을 알아두기
     -> MODE의 값이 00이 되니까 CNF의 값만 설정해주면 되는데, 00, 01, 10중에 결정한다.
     -> 위 소스는 01으로 input floating설정 해준 것, 즉 0x400



GPIOA_IDR        (*(volatile unsigned *)0x40010808)
-> PORT A의 Input data설정


if((GPIOA_IDR & 0x04)==0)
-> 2번 bit의 신호를 받으면 (Key1 스위치를 눌렀을 경우   - IDR2 = PORT A2)  








* 주석참고 *

-> 한번누르면 USER_LED_144P가 켜지고 두번누르면 LED2가 켜지며, 세번누를 때 USER_LED_144P가 꺼지고 네번누르면 LED2가 꺼지는 동작을 하는 소스 

-> LED2 는 PA0 으로 동작하게 하면 됨

#define RCC_APB2ENR  (*(volatile unsigned *)0x40021018)     // Clock Enable
//  PORT C - 4001 1000 - LED 조절을 위한 PORT
#define GPIOC_CRH        (*(volatile unsigned *)0x40011004)      // PORT C Mode결정(I/O결정)
#define GPIOC_BSRR    (*(volatile unsigned *)0x40011010)      // PORT C Set설정(Enable)      
#define GPIOC_BRR        (*(volatile unsigned *)0x40011014)      // PORT C Reset설정
// PORT A - 4001 0800 - 키 설정을 위한 PORT
#define GPIOA_CRL        (*(volatile unsigned *)0x40010800)      // PORT A Mode결정(I/O결정)
#define GPIOA_BSRR      (*(volatile unsigned *)0x40010810)      // PORT A Set설정(Enable)      
#define GPIOA_BRR        (*(volatile unsigned *)0x40010814)      // PORT A Reset설정
#define GPIOA_IDR        (*(volatile unsigned *)0x40010808)    // PORT A Input Data설정

static void Delay(volatile unsigned int a)
{
  for( ; a > 0 ; a--);
}

int main()
{
    unsigned int iCnt = 0;
  
    // GPIO A Initaize  
    RCC_APB2ENR = RCC_APB2ENR | 0x04;              // PORT A의 Clock이 공급
    GPIOA_CRL = 0x401// PA2 - Input Switch Setting, PA0 - Push_Pull - MODE설정(output으로(CRH와 같음))
    // GPIO C Initaize
    RCC_APB2ENR = RCC_APB2ENR | 0x10;              // PORT C의 Clock이 공급
  
  // GPIOC_CRH      = GPIOC_CRH & (~0xF0000);
    GPIOC_CRH      = 0x10000;        // CRH_MODE12(PORTC 12번이라서), 01 설정되어서 출력 Speed 10MHz
  
  
  // LED On/Off
  while(1)
  {
    if( (GPIOA_IDR & 0x04== 0 )
    {
      ++iCnt;// 스위치를 누르고 있는 동안 계속 대기 중 (while안걸면 iCnt증가하는 속도가 너무 빠름)
      while(0 == (0x04 & GPIOA_IDR));
      switch (iCnt %4)
      {
       case 0:
// LED2 OFF
          GPIOA_BRR = GPIOA_BRR | 0x01 ;
          break;
// USER_LED_144P ON
        case 1:
          GPIOC_BSRR = GPIOC_BSRR | 0x1000 ;
          break;
// LED2 ON
       case 2:
          GPIOA_BSRR = GPIOA_BSRR | 0x01 ;
          break;
// USER_LED_144P OFF 
       case 3:
          GPIOC_BRR = GPIOC_BRR | 0x1000 ;
          break;
      }         
    }     
   }
         return 0;
}







(체크)

                         



(메모리 구조를 알기 위하여)






-우리 쌤 수업-
#include "AT91SAM7S256.h"

#define MASTERCLOCK     48000000
#define PREA      8
#define DIVA      0
#define CPRE      0
#define CALG      8
#define CPOL      9
#define CPD       10
#define MAX_DUTY  800
#define DFT_DUTY  100


void PWM3_INIT(void);
void PWM3_DUTY(unsigned int uiDuty);

int main(void)
{
   volatile unsigned int uiCnt2; 
   volatile unsigned int uiDuty;

   PWM3_INIT();             // INIT함수 호출해서 초기화
   uiDuty = DFT_DUTY;    
   
   while(1)
   {
      for(uiCnt2 = 0 ; uiCnt2 < 100000 ; uiCnt2++);   // for문으로 지연시간줌

      PWM3_DUTY(uiDuty);     // DUTY함수 호출

// duty값 증가
      if(uiDuty < MAX_DUTY) 
      {
         uiDuty = uiDuty + 10;
      }
      else
      {
         uiDuty = DFT_DUTY;
      }    
   }
}

void PWM3_INIT(void)
{
   *AT91C_PMC_PCER = (1<< AT91C_ID_PWMC);             // TC0 전원 공급

   *AT91C_PIOA_PPUDR = AT91C_PA14_PWM3; //  Pull-up DISABLE

   *AT91C_PIOA_BSR = AT91C_PA14_PWM3; // B모드 레지스터로 사용
   
   *AT91C_PIOA_PDR = 0xFFFFFFFF;     // PIO DISABLE 

   *AT91C_PWMC_MR = (6 << PREA ) | (10 << DIVA);         // PREA(MCK/64) , DIVA 30 클럭A사용 B 사용 x  48M/64 750000      750000/30  25kHz
   
   *AT91C_PWMC_CH3_CMR = (11 << CPRE) | (0 << CALG) | (0 << CPOL) | (0 << CPD); // CLKA사용 | 톱니그래프 | 출력모드 low 레벨로 | duty사용
   
   *AT91C_PWMC_CH3_CDTYR = DFT_DUTY;      // 기본 duty값 100
   
   *AT91C_PWMC_CH3_CPRDR = MAX_DUTY;     // 최대 duty값 800
   
   *AT91C_PWMC_ENA = AT91C_PWMC_CHID3; // 채널 ID 3 Enable
}

// (duty의 현 상태를 저는 함수)
void PWM3_DUTY(unsigned int uiDuty)
{
//duty가 최대값을 벗어나면 최대값으로 고정
   if(uiDuty > MAX_DUTY)
   {
      uiDuty = MAX_DUTY;
   }

   *AT91C_PWMC_CH3_CUPDR = uiDuty; // duty의 현재상태 값을 넘겨줌
}


728x90

'코스웨어 > 14년 스마트컨트롤러' 카테고리의 다른 글

assert함수 설명 / 김진철  (0) 2014.11.10
1107 김상엽 출석번호 5번 업무일지  (7) 2014.11.07
20141106업무일지 출석번호 1번 고윤석  (6) 2014.11.06
keil usart  (0) 2014.11.06
ARM  (0) 2014.11.05
2014.11.04. 업무일지 22번 허수웅  (8) 2014.11.05
STM32F103ZE  (3) 2014.11.04
2014.11.03 업무일지 출석번호21 이재우  (9) 2014.11.04