공부방/ARM_STM32 노진호교수님_필기

240422_LL GPIO

맘스터치보단파파이스 2024. 4. 22. 17:00

ds p.15
ds p.53 Memory map

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

ds p.54

ADDRESS를 주면 해당 peripheral을 선택할 수 있다.

사용하는 peripherial에 대해서 CLK 설정 --> RCC

peripherial -->RCC설정이 필요하다.  ds p.54                            rm p.93

<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)

rm p.102

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

rm p.117

GPIOA 사용 + CLK 인가

다음 : GPIOA OUTPUT 설정

rm p.145
rm p.146
rm p.157
rm p.163

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