block 0 code : flash 영역. 그 속에서도 또 나뉘어진다.( Boot , flash )
주변장치들을 할당해둔걸 어떻게 할당 해 두었는지 알아본다.
--> MEMORY MAPPING
지금은 개념만 잡는다.
Memory 주소에 따라 peripheral을 어떻게 할당하는지 알아보자.
같은 PORT 끼리 연결 --> READ 끼리 연결, WRITE 끼리 연결.
DATA BUS
ADDRESS BUS
CPU가 DATA 와 ADDRESS 를 broadcast 하고있다. ==> BUS 라는 개념
DATA를 쫙 보냈다 --> (문제점) --> 누군껀지 모른다.
결국 기계적으로 --> 누구는 동작하고 누구는 동작하지마 : (DECODER) HD74LS138P가 이 역할을 하고 여기에서 MEMORY MAPPING 개념이 나온다.
DECODER 동작과 HARDWARE는 어떻게 연결되어있는가
CHIP ENABLE, CHIP SElECT
ADDRESS (A15) (A14) (A13) --> 0 1 1 --> ROM 동작
LOW CE --> LOW 선택 ROM이 선택되는 범위 ADDRESS 15 (A15) ? 000 ?
ROM : (A15) (A14) (A13) 0 0 0 --> (Y2) (Y1) (Y0) 1 1 0 --> 최솟값 ~ 최댓값 0x0000 ~ 0x1FFF
RAM : (A15) (A14) (A13) 0 0 1 --> (Y2) (Y1) (Y0) : 1 0 1 --> 0x2000 ~ 0x3FFF
8255: (A15) (A14) (A13) 0 1 0 --> (Y2) (Y1) (Y0) : 0 1 1 --> 0x4000 ~ 0x5FFF
<MEMORY MAPPING>
ROM : (A15) (A14) (A13) 0 0 0 --> (Y2) (Y1) (Y0) 1 1 0 --> 0x0000 ~ 0x1FFF
RAM : (A15) (A14) (A13) 0 0 1 --> (Y2) (Y1) (Y0) : 1 0 1 --> 0x2000 ~ 0x3FFF
8255: (A15) (A14) (A13) 0 1 0 --> (Y2) (Y1) (Y0) : 0 1 1 --> 0x4000 ~ 0x5FFF
ADDRESS를 주면 해당 peripheral을 선택할 수 있다.
사용하는 peripherial에 대해서 CLK 설정 --> RCC
<RCC>
< GPIOA의 5번핀을 OUTPUT MODE로 만든다. + LED Blink .>
1. GPIOA peripherial에 CLK
2. GPIOA PIN 5에 OUTPUT MODE 설정
3. GPIOA PIN 5에 HIGH or LOW 신호 출력
GPIOA : AHB1에 있다.
HSI (internal CLK):default PLL 사용 X(PLL CLK)
Reset value : XX81 : 1000 0001
RCC BASE ADDRESS : 0X4002_3800
OFFSET : : 0X00
RCC BASE ADDRESS + OFFSET
단 이 코드는 왼쪽은 숫자, 상수에 값을 대입할 수 없다.
포인터를 사용할 때 주소의 유효한 크기(= 데이터타입 =자료형)을 선언해 주어야 한다. 0~31 : 4byte
char : 1 byte
int : 4
long : 8
short : 2
float : 4
double : 8
unsigned int * 사용.
volatile : 휘발성의 --> 최적화 하지 말아라.
6.3.2~6.3.8 사용 X
GPIOA 사용 + CLK 인가
다음 : GPIOA OUTPUT 설정
MODER값 설정. ( mode register)
GPIOA의주소로 해당 메모리에 직접 접근. DATASHEET 보면서 직접 코딩중
OTYPER (output type register)
CPU MCU가 PUSH or PULL 하기도 한다. (= 전류를 내보내기도 하고 땡기기도 한다.)
MCU를 통해 내보내는 전력이 부족하면 OPEN Drain을 사용한다. ( PULL-UP Resistor)
OSPEEDR ( output speed register )
speed 뜻 : port5에서 표현가능한 것은 1 or 0 (HIGH or LOW) 0 <-> 1 되는 시간.
PUPDR
IDR, ODR
IDR, ODR : 어떠한 값이 들어오고 나감. 걸려있는 전압에 따라서 input data register로 들어옴 HIGH or LOW
ODR 값만 사용하여 LED를 끄고 키지만 너무 빨라서 켜진거 처럼 보인다.
HAL_DELAY( )를 사용할 수 없기 때문에 delay 함수를 만들어서 사용한다.
void delay(unsigned int times)
{
unsigned int temp = times*1000;
while(temp) temp--;
}
int main()
{
*(volatile unsigned int*)(0x40023800 + 0X00) |= (1<<0); //RCC_CR |= (1<<0); 0번 비트에만 1
*(volatile unsigned int*)(0x40023800 + 0X30) |= (1<<0); // AHB1_ENR , GPIOA_en
//GPIOA MODE : OUTPUT
*(volatile unsigned int*)(0x40020000 + 0X00) &= ~(1<<11); //GPIOA_MODER 11번비트에 0
*(volatile unsigned int*)(0x40020000 + 0X00) |= (1<<10); //GPIOA_MODER 10번비트에 1
//GPIOA OUTPUT TYPE REGISTER : pushpull
*(volatile unsigned int*)(0x40020000 + 0X04) &= ~(1<<5); // GPIOA의 5번 PIN pushpull로 사용한다.
//GPIOA OUTPUT SPEED
*(volatile unsigned int*)(0x40020000 + 0X08) &= ~(1<<11); //GPIOA_OSPEEDR 11번비트에 0
*(volatile unsigned int*)(0x40020000 + 0X08) &= ~(1<<10); //GPIOA_OSPEEDR 10번비트에 0
while(1)
{
//OUTPUT DATA REGISTER
*(volatile unsigned int*)(0x40020000 + 0X14) = (1<<5);
delay(1000);
*(volatile unsigned int*)(0x40020000 + 0X14) &= ~(1<<5);
delay(1000);
}
return 0;
}
int 로 자료형을 해줬기 때문에 4byte씩 쌓여간다.
typedef struct{
volatile unsigned int MODER;
volatile unsigned int OTYPER;
volatile unsigned int OSPEEDR;
volatile unsigned int PUPDR;
volatile unsigned int IDR;
volatile unsigned int ODR;
volatile unsigned int BSRR;
volatile unsigned int ICRR;
volatile unsigned int AFRL;
volatile unsigned int AFRH;
}GPIO_TypeDef;
#define AHB1_BASE 0x40020000
#define RCC_BASE (AHB1_BASE + 0x3800)
#define GPIOA_BASE (AHB1_BASE + 0x0000)
#define GPIOB_BASE (AHB1_BASE + 0x0400)
#define GPIOC_BASE (AHB1_BASE + 0x0800)
#define RCC_CR (volatile unsigned int*)(RCC_BASE + 0X00)
#define RCC_AHB1ENR (volatile unsigned int*)(RCC_BASE + 0X30)
//#define GPIOA_MODER (volatile unsigned int*)(GPIOA_BASE + 0X00)
//#define GPIOA_OTYPER (volatile unsigned int*)(GPIOA_BASE + 0X04)
//#define GPIOA_OSPEEDR (volatile unsigned int*)(GPIOA_BASE + 0X08)
//#define GPIOA_PUPDR (volatile unsigned int*)(GPIOA_BASE + 0x0C)
//#define GPIOA_IDR (volatile unsigned int*)(GPIOA_BASE + 0x10)
//#define GPIOA_ODR (volatile unsigned int*)(GPIOA_BASE + 0X14)
//#define GPIOA_BSRR (volatile unsigned int*)(GPIOA_BASE + 0x18)
//#define GPIOA_ICRR (volatile unsigned int*)(GPIOA_BASE + 0x1C)
//#define GPIOA_AFRL (volatile unsigned int*)(GPIOA_BASE + 0x20)
//#define GPIOA_AFRH (volatile unsigned int*)(GPIOA_BASE + 0x24)
#define GPIOA ((GPIO_TypeDef*)GPIOA_BASE)
#define GPIOC ((GPIO_TypeDef*)GPIOC_BASE)
//#define GPIOC_MODER (volatile unsigned int*)(GPIOC_BASE + 0X00)
//#define GPIOC_OTYPER (volatile unsigned int*)(GPIOC_BASE + 0X04)
//#define GPIOC_OSPEEDR (volatile unsigned int*)(GPIOC_BASE + 0X08)
//#define GPIOC_ODR (volatile unsigned int*)(GPIOC_BASE + 0X14)
void delay(unsigned int times)
{
unsigned int temp = times*1000;
while(temp) temp--;
}
int main()
{
*RCC_CR= (1<<0); // 0번 비트에만 1
*RCC_AHB1ENR |= (1<<0); //
//GPIOA MODE : OUTPUT
GPIOA->MODER &= ~(1<<11); //GPIOA_MODER 11번비트에 0
GPIOA->MODER |= (1<<10); //GPIOA_MODER 10번비트에 1
//GPIOA OUTPUT TYPE REGISTER : pushpull
GPIOA->OTYPER &= ~(1<<5); // GPIOA의 5번 PIN pushpull로 사용한다.
//GPIOA OUTPUT SPEED
GPIOA->OSPEEDR &= ~((1<<11)|(1<<10)); //GPIOA_OSPEEDR 11번,10번 비트에 0
*RCC_AHB1ENR |= (1<<2); //
GPIOC->MODER &= ~(1<<17);
GPIOC->MODER |= (1<<16);
GPIOC->OTYPER &= ~(1<<8);
GPIOC->OSPEEDR &= ~((1<<17)|(1<<16));
while(1)
{
//OUTPUT DATA REGISTER
GPIOA->ODR |= (1<<5);
delay(500);
GPIOA->ODR &= ~(1<<5);
delay(500);
GPIOC->ODR |= (1<<8);
delay(500);
GPIOC->ODR &= ~(1<<8);
delay(500);
}
return 0;
}
#include "stm32f4xx_hal.h"
/*
typedef struct{
volatile unsigned int MODER;
volatile unsigned int OTYPER;
volatile unsigned int OSPEEDR;
volatile unsigned int PUPDR;
volatile unsigned int IDR;
volatile unsigned int ODR;
volatile unsigned int BSRR;
volatile unsigned int ICRR;
volatile unsigned int AFRL;
volatile unsigned int AFRH;
}GPIO_TypeDef;
#define AHB1_BASE 0x40020000
#define RCC_BASE (AHB1_BASE + 0x3800)
#define GPIOA_BASE (AHB1_BASE + 0x0000)
#define GPIOB_BASE (AHB1_BASE + 0x0400)
#define GPIOC_BASE (AHB1_BASE + 0x0800)
#define RCC_CR (volatile unsigned int*)(RCC_BASE + 0X00)
#define RCC_AHB1ENR (volatile unsigned int*)(RCC_BASE + 0X30)
//#define GPIOA_MODER (volatile unsigned int*)(GPIOA_BASE + 0X00)
//#define GPIOA_OTYPER (volatile unsigned int*)(GPIOA_BASE + 0X04)
//#define GPIOA_OSPEEDR (volatile unsigned int*)(GPIOA_BASE + 0X08)
//#define GPIOA_PUPDR (volatile unsigned int*)(GPIOA_BASE + 0x0C)
//#define GPIOA_IDR (volatile unsigned int*)(GPIOA_BASE + 0x10)
//#define GPIOA_ODR (volatile unsigned int*)(GPIOA_BASE + 0X14)
//#define GPIOA_BSRR (volatile unsigned int*)(GPIOA_BASE + 0x18)
//#define GPIOA_ICRR (volatile unsigned int*)(GPIOA_BASE + 0x1C)
//#define GPIOA_AFRL (volatile unsigned int*)(GPIOA_BASE + 0x20)
//#define GPIOA_AFRH (volatile unsigned int*)(GPIOA_BASE + 0x24)
#define GPIOA ((GPIO_TypeDef*)GPIOA_BASE)
#define GPIOC ((GPIO_TypeDef*)GPIOC_BASE)
//#define GPIOC_MODER (volatile unsigned int*)(GPIOC_BASE + 0X00)
//#define GPIOC_OTYPER (volatile unsigned int*)(GPIOC_BASE + 0X04)
//#define GPIOC_OSPEEDR (volatile unsigned int*)(GPIOC_BASE + 0X08)
//#define GPIOC_ODR (volatile unsigned int*)(GPIOC_BASE + 0X14)
*/
void delay(unsigned int times)
{
unsigned int temp = times*1000;
while(temp) temp--;
}
int main()
{
RCC->CR= (1<<0); // 0번 비트에만 1
RCC->AHB1ENR |= (1<<0); //
//GPIOA MODE : OUTPUT
GPIOA->MODER &= ~(1<<11); //GPIOA_MODER 11번비트에 0
GPIOA->MODER |= (1<<10); //GPIOA_MODER 10번비트에 1
//GPIOA OUTPUT TYPE REGISTER : pushpull
GPIOA->OTYPER &= ~(1<<5); // GPIOA의 5번 PIN pushpull로 사용한다.
//GPIOA OUTPUT SPEED
GPIOA->OSPEEDR &= ~((1<<11)|(1<<10)); //GPIOA_OSPEEDR 11번,10번 비트에 0
RCC->AHB1ENR |= (1<<2); //
GPIOC->MODER &= ~(1<<17);
GPIOC->MODER |= (1<<16);
GPIOC->OTYPER &= ~(1<<8);
GPIOC->OSPEEDR &= ~((1<<17)|(1<<16));
while(1)
{
//OUTPUT DATA REGISTER
GPIOA->ODR |= (1<<5);
delay(500);
GPIOA->ODR &= ~(1<<5);
delay(500);
GPIOC->ODR |= (1<<8);
delay(500);
GPIOC->ODR &= ~(1<<8);
delay(500);
}
return 0;
}
#include "stm32f4xx_hal.h"
void delay(unsigned int times)
{
unsigned int temp = times*1000;
while(temp) temp--;
}
void clock_init()
{
}
void GPIO_init()
{
RCC->CR= (1<<0); // 0번 비트에만 1
RCC->AHB1ENR |= (1<<0); //
//GPIOA MODE : OUTPUT
GPIOA->MODER &= ~(1<<11); //GPIOA_MODER 11번비트에 0
GPIOA->MODER |= (1<<10); //GPIOA_MODER 10번비트에 1
//GPIOA OUTPUT TYPE REGISTER : pushpull
GPIOA->OTYPER &= ~(1<<5); // GPIOA의 5번 PIN pushpull로 사용한다.
//GPIOA OUTPUT SPEED
GPIOA->OSPEEDR &= ~((1<<11)|(1<<10)); //GPIOA_OSPEEDR 11번,10번 비트에 0
RCC->AHB1ENR |= (1<<2); //
GPIOC->MODER &= ~(1<<17);
GPIOC->MODER |= (1<<16);
GPIOC->OTYPER &= ~(1<<8);
GPIOC->OSPEEDR &= ~((1<<17)|(1<<16));
}
void sys_init()
{
clock_init();
GPIO_init();
}
void GPIO_WRITE(GPIO_TypeDef *GPIOx, int pin, int state)
{
if(state == SET){
GPIOx->ODR |= (1<<pin);
}
else
{
GPIOx->ODR &= ~(1<<pin);
}
}
void GPIO_TOGGLE(GPIO_TypeDef *GPIOx, int pin)
{
GPIOx->ODR ^= (1<<pin);
}
int main()
{
sys_init();
while(1)
{
/*
GPIO_WRITE(GPIOA, 5 , SET);
delay(500);
GPIO_WRITE(GPIOC, 8 , SET);
delay(500);
GPIO_WRITE(GPIOA, 5 , RESET);
delay(500);
GPIO_WRITE(GPIOC, 8 , RESET);
delay(500);
*/
GPIO_TOGGLE(GPIOC, 8);
delay(500);
GPIO_TOGGLE(GPIOA, 5);
delay(500);
}
return 0;
}
'공부방 > ARM_STM32 노진호교수님_필기' 카테고리의 다른 글
240424 과제 (0) | 2024.04.24 |
---|---|
240423 UART2_LCD (1) | 2024.04.23 |
240423 LOWLEVEL (0) | 2024.04.23 |
240422 input switch 과제 (0) | 2024.04.23 |
240422_ RCC, LED(GPIO OUTPUT_PA5) (0) | 2024.04.22 |