블로그 이미지
안녕1999

카테고리

전체 (3067)
자바스크립트 (20)
안드로이드 (14)
WebGL (4)
변비 (17)
정치,경제 (35)
C언어,ARM (162)
컴퓨터(PC, Note Book, 윈.. (41)
전자회로, PCB (27)
유머,안웃긴,GIF,동영상 (118)
국부론60 (71)
모듈(PCB) (3)
건강 (2)
FreeCAD (25)
PADS (43)
퇴직,퇴사,구직,취업 활동 (3)
C# (86)
엑셀 (8)
워드 (0)
LabView (6)
레고 (30)
FPGA (0)
Total
Today
Yesterday

달력

« » 2025.5
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

공지사항

최근에 올라온 글

※이 문서에는 오류가 있을 수 있습니다. 

STM32F4은 23개의 외부 인터럽트 이벤트 소스(edge-detector 회로)를 가지고있다.
모든 GPIO 핀을 외부인터럽트로 사용할 수 있다.
(외부인터럽트핀이 지정되어 있는 CPU와 달리,
 데이터 시트에는 외부인터럽트용 핀이 따로 표시되어 있지 않다. )
GPIO를 외부인터럽트로 사용할 수 있다. (모든 핀을 외부인터럽트로 사용할 수 는 없다)

인터럽트 핸들러함수는 EXTI0_IRQn,EXTI1_IRQn,EXTI2_IRQn,
EXTI3_IRQn,EXTI4_IRQn,EXTI9_5_IRQn,EXTI15_10_IRQn등이 있다.

EXTI_Line0~EXTI_Line22
edge-detector 회로의 개수(외부인터럽트의 최대 개수)
동시에 사용가능한 외부 인터럽트의 개수는 23개
(그러나, EXTI_PinSource 중복으로 사실상 16개(?))
부연설명:나머지 16~21번은 특정 용도로 지정되어 있다.
• EXTI line 16 is connected to the PVD output
• EXTI line 17 is connected to the RTC Alarm event
• EXTI line 18 is connected to the USB OTG FS Wakeup event
• EXTI line 19 is connected to the Ethernet Wakeup event
• EXTI line 20 is connected to the USB OTG HS (configured in FS) Wakeup event
• EXTI line 21 is connected to the RTC Tamper and TimeStamp events
• EXTI line 22 is connected to the RTC Wakeup event
• EXTI line 23 is connected to the LPTIM1 asynchronous event



EXTI_PinSource0~EXTI_PinSource15는 각 포트의 핀번호와 1:1대응된다.
(1포트는 16개)
EXTI_PinSource = interrupt line
예) PB2 <=> EXTI_PinSource2
따라서, 동일한 EXTI_PinSource*을 사용하는 포트는 동시에 사용이 불가능하다.
예) PB2, PC2를 동시에 사용불가
    PB2, PC3은 동시에 사용가능

인터럽트 함수는 7개 있음
EXTI 다음 숫자는 line번호(GPIO 핀번호)
EXTI0_IRQHandler
EXTI1_IRQHandler
EXTI2_IRQHandler
EXTI3_IRQHandler
EXTI4_IRQHandler
EXTI9_5_IRQHandler
EXTI15_10_IRQHandler

예) 8,9,10번을 사용하려면, EXTI9_5_IRQHandler,EXTI15_10_IRQHandler2개의함수를사용해야한다.
부연설명 : PA0번은 EXTI0_IRQHandler함수에서 처리해야한다.
              PA3번은 EXTI3_IRQHandler함수에서 처리해야한다.

위 그림을 살펴보면, EXTI0은 A~K포트중 1개만 입력받을 수 있다.

void EXTI15_10_IRQHandler(void)
{
  if(HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13) != RESET)
  {
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_13);
    //do somthing
  }
}
위의 경우에는 PA5~PK5, ... PA10~PK10번핀들 중에 1개만 입력받을 수 있다.
"입력받은 핀이 PA5인지, PB5인지 어떻게 알 수 있지?"
=>PA5나 PB5나 둘중에 하나만 설정할 수 있다.
   결론은 EXTI는 16개 사용가능하다.

 


IrqHandlerDescription

EXTI0_IRQn EXTI0_IRQHandler Handler for pins connected to line 0
EXTI1_IRQn EXTI1_IRQHandler Handler for pins connected to line 1
EXTI2_IRQn EXTI2_IRQHandler Handler for pins connected to line 2
EXTI3_IRQn EXTI3_IRQHandler Handler for pins connected to line 3
EXTI4_IRQn EXTI4_IRQHandler Handler for pins connected to line 4
EXTI9_5_IRQn EXTI9_5_IRQHandler Handler for pins connected to line 5 to 9
EXTI15_10_IRQn EXTI15_10_IRQHandler Handler for pins connected to line 10 to 15



인터럽트 함수 내부에서 EXTI_GetITStatus()함수를 사용하여,
어떤 인터럽트가 발생했는지 확인 가능.
(인터럽트 함수 1개는 여러개의 GPIO인터럽트 처리가 가능하다)
예) 

 

 

#include "stm32f4xx.h" 
#include "stm32f4xx_exti.h" 
#include "stm32f4xx_syscfg.h" 
#include "misc.h" 

//IAR, Keill 소스코드가 달라서 추가
#ifndef EXTI_GetITStatus
	#define EXTI_GetITStatus	__HAL_GPIO_EXTI_GET_IT
#endif
#ifndef EXTI_ClearITPendingBit
	#define EXTI_ClearITPendingBit	__HAL_GPIO_EXTI_CLEAR_IT
#endif
#ifndef EXTI_Line0
	#define EXTI_Line0	GPIO_PIN_0
	#define EXTI_Line1	GPIO_PIN_1
	#define EXTI_Line2	GPIO_PIN_2
	#define EXTI_Line3	GPIO_PIN_3
	#define EXTI_Line4	GPIO_PIN_4
	#define EXTI_Line5	GPIO_PIN_5
	#define EXTI_Line6	GPIO_PIN_6
	#define EXTI_Line7	GPIO_PIN_7
	#define EXTI_Line8	GPIO_PIN_8
	#define EXTI_Line9	GPIO_PIN_9
	#define EXTI_Line10	GPIO_PIN_10
	#define EXTI_Line11	GPIO_PIN_11
	#define EXTI_Line12	GPIO_PIN_12
	#define EXTI_Line13	GPIO_PIN_13
	#define EXTI_Line14	GPIO_PIN_14
	#define EXTI_Line15	GPIO_PIN_15
#endif
/* 참고
#define 	EXTI_Line0   ((uint32_t)0x00001)
#define 	EXTI_Line1   ((uint32_t)0x00002)
...
#define 	EXTI_Line14   ((uint32_t)0x04000)
#define 	EXTI_Line15   ((uint32_t)0x08000)
#define 	EXTI_Line16   ((uint32_t)0x10000)
#define 	EXTI_Line17   ((uint32_t)0x20000)
#define 	EXTI_Line18   ((uint32_t)0x40000)
#define 	EXTI_Line19   ((uint32_t)0x80000)
#define 	EXTI_Line20   ((uint32_t)0x00100000)
#define 	EXTI_Line21   ((uint32_t)0x00200000)
#define 	EXTI_Line22   ((uint32_t)0x00400000)
*/



/* Configure pins to be interrupts */ 
void Configure_PD0(void) 
{ 
    /* Set variables used */ 
    GPIO_InitTypeDef GPIO_InitStruct; 
    EXTI_InitTypeDef EXTI_InitStruct; 
    NVIC_InitTypeDef NVIC_InitStruct; 
    
    /* Enable clock for GPIOD */ 
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); 
    /* Enable clock for SYSCFG */ 
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); 
    
    /* Set pin as input */ 
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN; 
    GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; 
    GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0; 
    GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; 
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz; 
    GPIO_Init(GPIOD, &GPIO_InitStruct); 
    
    /* Tell system that you will use PD0 for EXTI_Line0 */ 
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOD, EXTI_PinSource0); 
    
    /* PD0 is connected to EXTI_Line0 */ 
    EXTI_InitStruct.EXTI_Line = EXTI_Line0; 
    /* Enable interrupt */ 
    EXTI_InitStruct.EXTI_LineCmd = ENABLE; 
    /* Interrupt mode */ 
    EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt; 
    /* Triggers on rising and falling edge */ 
    EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling; 
    /* Add to EXTI */ 
    EXTI_Init(&EXTI_InitStruct); 
    
    /* Add IRQ vector to NVIC */ 
    /* PD0 is connected to EXTI_Line0, which has EXTI0_IRQn vector */ 
    NVIC_InitStruct.NVIC_IRQChannel = EXTI0_IRQn; 
    /* Set priority */ 
    NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 0x00; 
    /* Set sub priority */ 
    NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0x00; 
    /* Enable interrupt */ 
    NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE; 
    /* Add to NVIC */ 
    NVIC_Init(&NVIC_InitStruct); 
} 
/* Set interrupt handlers */ 
/* Handle PD0 interrupt */ 
void EXTI0_IRQHandler(void) 
{ 
    /* Make sure that interrupt flag is set */ 
    if (EXTI_GetITStatus(EXTI_Line0) != RESET)
    { 
        /* Do your stuff when PD0 is changed */ 
        
        
        /* Clear interrupt flag */ 
        EXTI_ClearITPendingBit(EXTI_Line0); 
    } 
}

 

Posted by 안녕1999
, |

STM32 - GPIO togle

C언어,ARM / 2020. 1. 31. 23:32

togle : 바꾸다. 0이면 1로, 1이면 0으로 변경.

ODR 레지스터를 xor연산으로 변경 가능.

#define GPIO_togle(port,pin) (port)->ODR^=(1<<(pin))

 

'C언어,ARM' 카테고리의 다른 글

Warning: hDC is NULL in ...  (0) 2020.02.08
stm32-외부 인터럽트  (0) 2020.02.08
GetTickCount, GetTickCount64 뭐가 다른가?  (1) 2020.01.19
error C2144: 구문 오류 : int'은(는) ';' 다음에 와야 합니다.  (0) 2020.01.18
UPDI  (0) 2020.01.18
Posted by 안녕1999
, |

결론만 말하면, 똑같다.
어차피 정말하지도 않고, 10~16msec 오차가 발생한다.

 

그러나, 32비트에서도 동작하는 프로그램을 만들려면, 32비트용 함수를 사용하는것이 좋다.

난 아직도 32비트 PC를 사용한다.

 

GetTickCount64

 

 

'C언어,ARM' 카테고리의 다른 글

stm32-외부 인터럽트  (0) 2020.02.08
STM32 - GPIO togle  (0) 2020.01.31
error C2144: 구문 오류 : int'은(는) ';' 다음에 와야 합니다.  (0) 2020.01.18
UPDI  (0) 2020.01.18
std::string, std::wstring에 대해 알아보자  (0) 2020.01.18
Posted by 안녕1999
, |

error C2144: 구문 오류 : int'은(는) ';' 다음에 와야 합니다.

 

원인 : 다른 헤더 파일에서 함수명 뒤에 ; 을 안붙여서 발생.

Posted by 안녕1999
, |

UPDI

C언어,ARM / 2020. 1. 18. 23:25

- Unified Program and Debug Interface (UPDI)

- AVR XMEGA시리즈에서 사용됨.

  ATTINY402 (http://ww1.microchip.com/downloads/en/DeviceDoc/ATtiny202-402-DataSheet-DS40001969B.pdf)

  에서도 사용됨.

 

 

https://www.microchip.com/webdoc/GUID-DDB0017E-84E3-4E77-AAE9-7AC4290E5E8B/index.html?GUID-9B349315-2842-4189-B88C-49F4E1055D7F

Posted by 안녕1999
, |

 

std::string, std::wstring에 대해 알아보자 

C언어에는 char, TCHAR등의 문자열 관련 타입이 있다. 
std::string은 템플리트(template)이다. 

template은 일종의 매크로이다.(그러나 매크로와는 다르다) 
또한 클래스와 비슷하게 ::라든가, 멤버함수등을 사용할 수 있다.(정확히 멤버함수라고 하기에는 애매하다) 
어쨌든, std::string을 클래스로 봐도 거의 무방하다. 

int len; 
std::string a("abcd"); 
a+="e"; 
len=sizeof(a);//len=28 

a "abcde" std::basic_string 
[size] 5 unsigned int 
[capacity] 15 unsigned int 
[0] 97 'a' char 
[1] 98 'b' char 
[2] 99 'c' char 
[3] 100 'd' char 
[4] 101 'e' char 

위 코드에서 15바이트를 할당해 놓은것을 볼 수 있다. 
문자열 추가 연산을 할 경우, 15바이트 이하라면, 메모리할당을 하지 않아서, 빠르게 처리가 가능하다. 
물론, 미리 할당해놓은 크기를 넘어서면, 메모리할당을 해야해서, 많이 느려진다. 
std::string변수의 크기가 28이나 된다. 문자열데이터는 4+1바이트인데, 약 5~6배 더 큰것을 알 수 있다. 

std::string은 ANSI코드이고, 
std::wstring는 유니코드이다. 

_T()매크로는 유니코드로 컴파일할 경우, 유니코드 문자열로 변환되고, 
ANSI로 컴파일할 경우, ANSI문자열(char*)로 변환된다. 

std::wstring b(_T("abcd")); 
b+=_T("e"); 
len=sizeof(b); 



어셈블러(기계어)코드를 보면, 
아래와 같이, 함수 호출이 발생한다. 
문자열 추가 연산도 함수 호출. 
int len; 
std::string a("abcd"); 
009A7C4D  push        0BA6DD0h   
009A7C52  lea         ecx,[a]   
009A7C55  call        std::basic_string::basic_string (0994E2Ah)   
009A7C5A  mov         byte ptr [ebp-4],1   
a+="e"; 
009A7C5E  push        0BC7374h   
009A7C63  lea         ecx,[a]   
009A7C66  call        std::basic_string::operator+= (099988Fh)   
len=sizeof(a); 
009A7C6B  mov         dword ptr [len],1Ch   

std::string 변수 할당 과정을 따라가보면, 상당히 많은 코드를 처리한다. 
따라서, std::string가 편하다고 해도, 많은 메모리를 사용하고, 속도가 생각만큼 빠르지 않다는것이다. 



static void test0() 
{ 
	char a[16]; 
	strcpy(a,"abcd"); 
} 
static void test1() 
{ 
	std::string a("abcd"); 
	//생성, 파괴 
} 

DWORD get_func_time(void (*f)()) 
{ 
	DWORD t,i; 
	t=GetTickCount(); 
	for(i=0;i<100000;i++) 
	{ 
		f();f();f();f();f();f();f();f();f();f();f();f();f();f();f();f();f();f();f(); 
	} 
	return GetTickCount()-t; 
} 

DWORD t[2]; 
t[0]=get_func_time(test0);//125 
t[1]=get_func_time(test1);//25615 
예상대로, 약 200배이상 느리다. 
물론, 이런 코드만 사용하는것이 아니므로, std::string이 항상 느리다고 볼 수 는 없으나, 
c언어의 기본 함수만을 사용했을때가, 대부분 빠르다. 
프로그램 코드 사이즈도 c언어 기본함수만 사용했을때가 작다. 

물론 속도가 가장 중요한 것은 아니지만, std::string을 많이 사용할 수 록 
프로그램은 무거워지고, 느려진다. 200배나 느려진다. 
반대로 말하면, std::string을 사용한 프로그램보다, c언어 기본함수만을 사용한 프로그램이 
약 200배 더 빠르다는 말이다.

char* 형으로 변환 방법 : (char*)(변수.c_str())

Posted by 안녕1999
, |

cc1plus.exe: warning: command line option "-std=gnu99" is valid for C/ObjC but not for C++

 

AVR Studio 4.x

Project -> Configueration Options -> Project options -> Custopm Compiolation Options -> -std=gnu99

 

C언어는 C98, C99등의 버젼(?)이 있습니다.
gun99는 C99와 동급 또는 그 이상 버젼이라고 보면 됩니다.

 

위 경고(warning)의 내용은, "gnu99는 C언어용이지, C++용이 아니다"라는 내용입니다.

C++문법을 모두 C로 고치면 해결됩니다.

Posted by 안녕1999
, |

파일이나 리소스 추가후, 제대로 인지를 못함.

종료후 다시 컴파일하면 인식함.

Posted by 안녕1999
, |

error C2059: syntax error : 'bad suffix on number'

error C2059: syntax error : 'constant'

 

함수이름, 변수 이름을 숫자로 시작하는 경우

=>알파벳으로 시작해야함.

예) int 24v;   =>   int v24;

Posted by 안녕1999
, |

while(len--)의 함정

C언어,ARM / 2020. 1. 11. 22:53

while(len--)

{

    ...

}

 

위 코드는 문제가 발생할 소지가 있는 코드입니다.

아래와 같이 사용해야합니다.

while(len)

{

    len--;

    do_somthing(len);

}

 

이유는, while()조건을 검사하고, len=0인 경우에는 while()문의 do_somthing(len);코드를 실행하지 않습니다.

그러나, len의 값은 -1이 된 상태입니다.

len변수가 다른곳에서도 쓰인다면, 0이 아닌 -1값이 되어, 오동작을 할 수 있습니다.

 

요약 : while(), if() 안에서는 ++, --등의 증감 연산자를 사용하지 말자. 

Posted by 안녕1999
, |

최근에 달린 댓글

글 보관함