2023. 8. 10. 16:20ㆍEmbedded/ARM Cortex
3일차
리셋이 되면 최초실행되는 명령어가 vectors 테이블의 0번지 - 0번지는 bin파일내용
mcu내부에 sram – sram 시작 주소 : 2천만번지
스택은 램에있어야한다. – push, pop하기 위해
스택 사이즈 -
400은 1024바이트 정도이다.
Stack_mem
ARM 프로세서
ARM에선 스택의 증가방향 – 주소가 감소
SP가 스택의 푸쉬를 하면할수록 내려간다(1024바이트의 위에서 중간으로) / 팝하면 다시 증가함
PUSH와 POP명령어가 있는데 PUSH{ }와 POP{ }의 { }는 레지스터만 들어갈 수 있다.
PUSH{R0 – R3} <-
POP {R0 – R3} ->
스택의 용도 : 전역변수는 빌드하면 주소 고정
지역변수는 빌드하면 주소가 유동적 – 스택에 사용됨
Main에 오기전에 실행되는 과정
- 전원을 껐다켜면 램의 값은 전부 쓰레기값이 된다.
- Main에 와서 해당 영역의 값을 읽어보면 5로 출력(print”%d”부분에)
- bin파일(rom에 들어갈)에 초기 값들이 들어가 있다.(rom에 존재)
- section초기화 작업
- 스택의 값이 최초에선 rom에 존재하고, 실행하면 ram에 복사되어 온다.
- 빌드를 하면 여러곳에 흩어진 전역변수들이 모이게 된다. (인접한 주소를 가지게 된다.)
- 0으로 만들어지는 변수들도 sram에서 따로 모으고, 0이아닌 값으로 만들어지는 변수들도 따로 모은다.
Int gvar = 5;
Void main (){
Printf(“%d”,gvar);
Gvar = 0;
}
SFR = SFR ^ (0x1<<6);
프리스마크(스택의 우선순위가 프리마스크의 값이 된다.)
LOAD, OPERATION. STORE
BASEPRI – 레벨 마스킹 – 만약 5를 쓴다면 우선순위가 5가 된다. 집어넣은 값만큼 우선순위가 정해진다. 시스템의 우선순위가 그값 만큼 된다.
1~255까지가 해당 값
우선순위 – IRQ에 의해서만 이루어진다.
초기 해줘야 할 설정
1. 클럭 설정
2. 디버거 설정
디버거 설정을 먼저해줘야 다운로드 받을 수 있다.
디버거 설정
위의 5개 핀이 실제 보드의 JTAG쪽과 연결되어 있다 보면 된다.
외부 크리스탈 – 우리가 사용하는 보드의
UART가 동작하기 위한 필수 설정이 빠져있으면 노란색으로 표시
UART1, Asynchronous, baud rate : 115200으로 설정한다.
Hal로 시작되는 것과 hal로 시작되지 않는 것이 있는데 hal이 없는 것은 사용하면 x
Hal은 static으로 정의되어있는데 static붙어있는 함수는 외부로 호출할 수 없음
uint8_t c;
HAL_StatusTypeDef STATUS = HAL_UART_Receive(&huart1, &c, sizeof(c), 100);
if(STATUS == HAL_OK)
{
HAL_UART_Transmit(&huart1, &c, sizeof(c), (uint32_t)-1 );
}
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5 | GPIO_PIN_6);
HAL_StatusTypeDef STATUS = HAL_UART_Receive(&huart1, &c, sizeof(c), 100);
해당 코드는 HAL_UART_Receive함수의 변환값인 HAL_StatusTypeDef를 status에 넣어 실행한다.
UART1 -> NVIC -> USART1 global interrupt check 하면 uart 인터럽트 사용 가능
Hal 드라이버의 구조 문제로 인터럽트 한번 실행하면 다음은 disable이 되어버린다.
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
if(huart == &huart1){
HAL_UART_Receive_IT(&huart1, &uart_rx_data, sizeof(uart_rx_data));
HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5 | GPIO_PIN_6);
}
}
인터럽트로 led 점등 – uart로 입력받음
- DMA
ADD 후 USART1_RX - Circular선택한다.
테라텀에 입력하면 메모리가 할당되는 것을 볼 수 있다.
2바이트 먼저 전송 하면서, 나머지 2바이트는 데이터 입력을 받는다.
위 아래 둘다 같은 기능을 한다.
Stm32내부에 adc ip가 존재한다.
DMA스타트 후 ADC컨버터 하면 종료되는데, ENABLE시켜두면 계속 ADC를 사용 가능하게 한다.
한 클럭당 한 비트가 나온다 (ADC변환 시)
변환된 레지스터의 값이 DR에 저장될 것이다..
파일 입출력을 사용하기 위해 stdio.h을 추가한다.
Adc를 스타트 시키고 adc의 값을 adc_value에 저장한 후, 그 값을 숫자로 출력시킨다.
필터 알고리즘 : adc값의 편차가 클 때 사용하면 좋다
P(n) : 예측값/ 사용자에게 보여주는 값
while (1)
{
uint8_t c;
HAL_StatusTypeDef STATUS = HAL_UART_Receive(&huart1, &c, sizeof(c), 100);
if(STATUS == HAL_OK)
{
HAL_UART_Transmit(&huart1, &c, sizeof(c), (uint32_t)-1 );
if(c == 'a'){
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5 | GPIO_PIN_6, GPIO_PIN_RESET);
}
else if(c == 'b'){
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5 | GPIO_PIN_6, GPIO_PIN_SET);
}
}
테라텀에서 값을 입력받으면 (a는 점등, b는 소등) led가 반응
HAL_ADC_GetValue(&hadc1);
float adc_value = (float)HAL_ADC_Start(&hadc1);
int count = 0;
while (1)
{
adc_value = 0.9 * adc_value + 0.1 * HAL_ADC_GetValue(&hadc1);;
HAL_Delay(10);
count = count+1;
if((count % 100)==0){
printf("%d \r\n", (int)(adc_value + 0.5));
}
uint8_t c;
HAL_StatusTypeDef STATUS = HAL_UART_Receive(&huart1, &c, sizeof(c), 0);
if(STATUS == HAL_OK)
{
HAL_UART_Transmit(&huart1, &c, sizeof(c), (uint32_t)-1 );
if(c == 'a'){
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5 | GPIO_PIN_6, GPIO_PIN_RESET);
}
else if(c == 'b'){
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5 | GPIO_PIN_6, GPIO_PIN_SET);
}
}
테라텀에 A입력 시 LED 점등, B입력 시 LED 소등 / 또한 조도센서에서 입력받는 값을 테라텀에 출력한다.
Counter period = ARR
Pulse = CCR
위 함수를 이용해 pwm 생성
GPIOA->ODR = GPIOA->ODR & ~ (0x1 << 5);
int bright = 499;
while (1)
{
uint8_t c;
HAL_StatusTypeDef STATUS = HAL_UART_Receive(&huart1, &c, sizeof(c), 0);
if(STATUS == HAL_OK)
{
HAL_UART_Transmit(&huart1, &c, sizeof(c), (uint32_t)-1 );
if(c == 'a'){
bright += 50;
if(bright > 999)
bright = 999;
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, bright);
printf("%d \r\n",bright);
}
else if(c == 'b'){
bright -= 50;
if(bright < 0)
bright = 0;
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, bright);
printf("%d \r\n",bright);
}
}
Led의 핀 밝기를 PWM의 CCR값을 조절해서 조절한다.
'Embedded > ARM Cortex' 카테고리의 다른 글
[IDEC] ARM Cortex-M 프로세서 기반의 펌웨어 설계실무 2 (0) | 2023.08.10 |
---|---|
[IDEC] ARM Cortex-M 프로세서 기반의 펌웨어 설계실무 1 (0) | 2023.08.09 |