반응형

https://youtube.com/live/p5zGr7EtAIY

[STM32#09] 스탭모터(28byj-48)를 폴링방식과 타이머인터럽트(TIM2 global interrupt)를 이용한 방식으로 각도제어 해보기!(녹칸다 내맘대로 STM32)

심심한녹칸다의 내맘대로 STM32시리즈이다!

STM32시리즈의 모든 자료는 구글 슬라이드에 작성하고 모두에게 공유되어있음!
https://docs.google.com/presentation/d/1myA5iYbjuKsLWLqtRLKAiRfwUwvqB1d1RGjiMIIgp3I/edit?slide=id.g3a1b0dc0a1e_1_75#slide=id.g3a1b0dc0a1e_1_75

이번편은 녹칸다의 STM32쉴드에 스탭모터(28bjy-48)와 드라이버(ULN2003)을 연결해서 각도를 제어해보도록 한다!

 

 

(스탭모터 제어신호)

 

(스탭모터 신호의 해석)

1.녹칸다가 제시한 표에서 빼기기호(-)가 있는건 HIGH신호이고 비워져있는건 LOW신호를 의미한다!
2.스탭모터제어에는 한 주기에 8개의 신호를 전송해야하는데, 1~8순으로 전송하면 시계(CW)방향, 8~1순으로 전송하면 반시계(CCW)방향으로 회전하게된다!
3.STM32에서는 HIGH신호를 숫자1로 해석하고, LOW신호를 숫자 0으로 해석한다!
4.그러면 보내줘야할 1번신호의 경우 IN1,IN2,IN3,IN4순서로 보았을때 IN1은 0, IN2는 0, IN3은 0, IN4는 1이라는 것을 전송해야함을 의미한다!
5.IN1이 PC10이고, IN2가 PC11이고, IN3이 PC12고, IN4가 PD2로 지정되어있으므로 해당되는 GPIO에 해당되는 신호가 타이밍에 맞게 출력되면 되는 것이다!
6.신호의 시퀀스를 빠르게 보내주면 모터가 빠르게 회전하고 천천히 보내주면 천천히 회전한다!
7.사용하는 스탭모터 자체가 고속으로 회전할수 없는 모터이기 때문에 하한값이 존재한다! (작동불능상태가 된다)
8.그러면 신호를 가장 빠르게 전송할 수 있는 간격이 몇이냐? (녹칸다도 모름)
9.시퀀스를 1~8순으로 순서대로 1개씩 보낼때 1씩 카운트를 한다면 4096회 전송했을때 스탭모터는 360도 회전한다!(한바퀴에 대한 스탭량이 4096이다)

 

(예제목차)

1.녹칸다와 함께 1차원배열과 2차원배열에 대해서 아주 간단히 알아보도록 하자!

//1-1)배열은 크기를 미리 정해두고 사용하는 것이다!
	//1-1)크기를 미리 정해두지 않더라도 추측이 가능하면 생략이 가능하다!
	uint8_t array1[8]; //8개의 배열을 생성하겠다!
	//배열을 생성하는데, 1부터 8까지 8개를 담을 배열을 만들어라!
	uint8_t array2[] = {1,2,3,4,5,6,7,8};
	//배열을 지정된 갯수대로 생성하고 초기값을 안넣어주면 확정적이지 않은 값이 들어갔다!
	//배열을 선언하면서 초기값으로 모두 0을 입력을 하고싶다!
	uint8_t array3[8] = {0};
	
	//메인함수 안에서는 배열값의 대입이 가능하지만, 밖에서는 불가능하다!
	array1[0] = 10;
	array1[1] = 20;
//1-2) 2차원배열은 엑셀과 같은 모양을 딱 떠올리면 된다!
 uint8_t array1[2][2]; //2*2 배열이 만들어진다!
 //2차원배열의 선언과 초기화는 두번째 차원의 갯수를 확정해야한다!
 //2차원배열의 두번째차원은 갯수가 가변적일 수 없다!
 uint8_t array2[][3] = {
		  {1,2,3},
		  {4,5,6}
 };
 //녹칸다가 array2에서 1,2,3과 4,5,6을 그릅으로 다루고자 한다면
 //아래와 같이 2중 loop로 순회할 수 있음!
 for(int i = 0;i<2;i++){
	  for(int j = 0;j<3;j++){
		  //array2[i][j]
		  //i=0,j=0 array2[0][0] : 1
		  //i=0,j=1 array2[0][1] : 2
		  //i=0,j=2 array2[0][2] : 3
		  /////////////////////////
		  //i=1,j=0 array2[1][0] : 4
		  //i=1,j=1 array2[1][1] : 5
		  //i=1,j=2 array2[1][2] : 6
	  }
 }


2.IOC에서 스탭모터 제어핀을 출력으로 설정하고 폴링방식으로 시계방향으로 한바퀴, 반시계방향으로 한바퀴 무한반복하는데 전송간격을 1밀리초로 하시오!

/* USER CODE BEGIN 2 */
 uint8_t seq[][4]={
 		{0,0,0,1}, //1
 		{0,0,1,1}, //2
 		{0,0,1,0}, //3
 		{0,1,1,0}, //4
 		{0,1,0,0}, //5
 		{1,1,0,0}, //6
 		{1,0,0,0}, //7
 		{1,0,0,1}  //8
 };
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //시계방향으로 한바퀴 회전
	  //시퀀스 8개 보낸게 8회니까 8회세트를 512번하면 4096회이다!
	  for(int i = 0;i<512;i++){
		  for(int j =0;j<8;j++){
			  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,seq[j][0]);//IN1
			  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11,seq[j][1]);//IN2
			  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_12,seq[j][2]);//IN3
			  HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,seq[j][3]);//IN4
			  HAL_Delay(1); //HAL_Delay가 지연할수 있는 최소 시간은 1밀리초이다!
		  }
	  }

	  //1초쉬고
	  HAL_Delay(1000);
	  //반시계방향으로 한바퀴 회전
	  for(int i = 0;i<512;i++){
		  for(int j =7;j>=0;j--){
			  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,seq[j][0]);//IN1
			  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_11,seq[j][1]);//IN2
			  HAL_GPIO_WritePin(GPIOC,GPIO_PIN_12,seq[j][2]);//IN3
			  HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,seq[j][3]);//IN4
			  HAL_Delay(1); //HAL_Delay가 지연할수 있는 최소 시간은 1밀리초이다!
		  }
	  }
	  //1초쉬고
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }


3.예제2에서 IN1부터 IN4까지의 출력내용을 z-loop로 묶으시오! 

/* USER CODE BEGIN 2 */
 uint8_t seq[][4]={
 		{0,0,0,1}, //1
 		{0,0,1,1}, //2
 		{0,0,1,0}, //3
 		{0,1,1,0}, //4
 		{0,1,0,0}, //5
 		{1,1,0,0}, //6
 		{1,0,0,0}, //7
 		{1,0,0,1}  //8
 };
 GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
 uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //시계방향으로 한바퀴 회전
	  //시퀀스 8개 보낸게 8회니까 8회세트를 512번하면 4096회이다!
	  for(int i = 0;i<512;i++){
		  //시퀀스 1~8까지를 1밀리초 간격으로 연속으로 전송함!
		  for(int j =0;j<8;j++){
			  //IN1~IN4까지의 출력을 동시에 결정
			  for(int z = 0; z<4;z++){
				  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[j][z]);
			  }
			  HAL_Delay(1); //HAL_Delay가 지연할수 있는 최소 시간은 1밀리초이다!
		  }
	  }

	  //1초쉬고
	  HAL_Delay(1000);
	  //반시계방향으로 한바퀴 회전
	  for(int i = 0;i<512;i++){
		  for(int j =7;j>=0;j--){
			  for(int z = 0; z<4;z++){
				  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[j][z]);
			  }
			  HAL_Delay(1); //HAL_Delay가 지연할수 있는 최소 시간은 1밀리초이다!
		  }
	  }
	  //1초쉬고
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }


4.기판에 붙어있는 버튼1번(PB1)을 누르면 스탭모터가 시계방향으로 360도 회전하고, 버튼2번(PA8)을 누르면 반시계방향으로 회전하는데, 버튼을 누를때마다 연속적으로 회전시키시오!( 블록킹 문제가 생기게됨)

/* USER CODE BEGIN 2 */
 uint8_t seq[][4]={
 		{0,0,0,1}, //1
 		{0,0,1,1}, //2
 		{0,0,1,0}, //3
 		{0,1,1,0}, //4
 		{0,1,0,0}, //5
 		{1,1,0,0}, //6
 		{1,0,0,0}, //7
 		{1,0,0,1}  //8
 };
 GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
 uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1을 누르면 시계방향으로 회전한다
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  for(int i = 0;i<512;i++){
			  //시퀀스 1~8까지를 1밀리초 간격으로 연속으로 전송함!
			  for(int j =0;j<8;j++){
				  //IN1~IN4까지의 출력을 동시에 결정
				  for(int z = 0; z<4;z++){
					  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[j][z]);
				  }
				  HAL_Delay(1); //HAL_Delay가 지연할수 있는 최소 시간은 1밀리초이다!
			  }
		  }
	  }


	  //PA8을 누르면 반시계방향으로 한바퀴 회전
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  for(int i = 0;i<512;i++){
			  for(int j =7;j>=0;j--){
				  for(int z = 0; z<4;z++){
					  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[j][z]);
				  }
				  HAL_Delay(1); //HAL_Delay가 지연할수 있는 최소 시간은 1밀리초이다!
			  }
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }


5.예제4번에서 모터신호의 전송간격이 1밀리초인데, 더 내려서 최소로 보낼 수 있는 간격이 몇인지를 실험적으로 파악하시오!(모터마다 다를수있음)

#define delay_ms HAL_Delay
#define SYS_CLOCK    64
#define SYSTICK_LOAD 63999
uint32_t millis_cnt = 0;
uint32_t millis() {
 return millis_cnt;
}
uint32_t micros() {
 return (millis_cnt & 0x3FFFFF) * 1000 + (SYSTICK_LOAD - SysTick->VAL) / SYS_CLOCK;
}
void delay_us(uint32_t us) {  // 64MHz 보정
 if (us > 1) {
   uint32_t count = us * 7 - 6;
   while (count--);
 } else {
   uint32_t count = 2;
   while (count--);
 }
}

//delay_us관련 코드는 BEGIN 0쪽에 알아서 넣기~
/* USER CODE BEGIN 2 */
 uint8_t seq[][4]={
 		{0,0,0,1}, //1
 		{0,0,1,1}, //2
 		{0,0,1,0}, //3
 		{0,1,1,0}, //4
 		{0,1,0,0}, //5
 		{1,1,0,0}, //6
 		{1,0,0,0}, //7
 		{1,0,0,1}  //8
 };
 GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
 uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1을 누르면 시계방향으로 회전한다
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  for(int i = 0;i<512;i++){
			  //시퀀스 1~8까지를 1밀리초 간격으로 연속으로 전송함!
			  for(int j =0;j<8;j++){
				  //IN1~IN4까지의 출력을 동시에 결정
				  for(int z = 0; z<4;z++){
					  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[j][z]);
				  }
				  delay_us(750);
			  }
		  }
	  }


	  //PA8을 누르면 반시계방향으로 한바퀴 회전
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  for(int i = 0;i<512;i++){
			  for(int j =7;j>=0;j--){
				  for(int z = 0; z<4;z++){
					  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[j][z]);
				  }
				  delay_us(750);
			  }
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }


6.예제5번에서 버튼3(PB2)을 누르면 PB3에 연결된 LED가 ON되고, 버튼4(PB6)를 누르면 LED가 OFF되도록 하시오!(모터가 돌아가는중에닌 LED 제어가 안될텐데 일단 무시~)

/* USER CODE BEGIN 2 */
 uint8_t seq[][4]={
 		{0,0,0,1}, //1
 		{0,0,1,1}, //2
 		{0,0,1,0}, //3
 		{0,1,1,0}, //4
 		{0,1,0,0}, //5
 		{1,1,0,0}, //6
 		{1,0,0,0}, //7
 		{1,0,0,1}  //8
 };
 GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
 uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
		  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,1);
	  }
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) == 0){
		  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0);
	  }


	  //PB1을 누르면 시계방향으로 회전한다
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  for(int i = 0;i<512;i++){
			  //시퀀스 1~8까지를 1밀리초 간격으로 연속으로 전송함!
			  for(int j =0;j<8;j++){
				  //IN1~IN4까지의 출력을 동시에 결정
				  for(int z = 0; z<4;z++){
					  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[j][z]);
				  }
				  delay_us(750);
			  }
		  }
	  }
	  //PA8을 누르면 반시계방향으로 한바퀴 회전
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  for(int i = 0;i<512;i++){
			  for(int j =7;j>=0;j--){
				  for(int z = 0; z<4;z++){
					  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[j][z]);
				  }
				  delay_us(750);
			  }
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }


7.예제6번에서 “버튼1,2를 누르면 스탭모터가 돌아간다”와 “버튼3,4를 누르면 LED가 제어된다”의 제어조건을 동시에 작동되도록 예시코드를 구현하시오!(EXIT를 활용함)

/* USER CODE BEGIN 0 */
#define delay_ms HAL_Delay
#define SYS_CLOCK    64
#define SYSTICK_LOAD 63999
uint32_t millis_cnt = 0;
uint32_t millis() {
return millis_cnt;
}
uint32_t micros() {
return (millis_cnt & 0x3FFFFF) * 1000 + (SYSTICK_LOAD - SysTick->VAL) / SYS_CLOCK;
}
void delay_us(uint32_t us) {  // 64MHz 보정
if (us > 1) {
  uint32_t count = us * 7 - 6;
  while (count--);
} else {
  uint32_t count = 2;
  while (count--);
}
}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if(GPIO_Pin == GPIO_PIN_2)
  {
      //버튼3에 대한 EXTI
	   HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,1);
  }else if(GPIO_Pin == GPIO_PIN_6)
  {
	   //버튼4에 대한 EXTI
	   HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0);
  }
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 uint8_t seq[][4]={
 		{0,0,0,1}, //1
 		{0,0,1,1}, //2
 		{0,0,1,0}, //3
 		{0,1,1,0}, //4
 		{0,1,0,0}, //5
 		{1,1,0,0}, //6
 		{1,0,0,0}, //7
 		{1,0,0,1}  //8
 };
 GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
 uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
 /* USER CODE END 2 */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1을 누르면 시계방향으로 회전한다
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  for(int i = 0;i<512;i++){
			  //시퀀스 1~8까지를 1밀리초 간격으로 연속으로 전송함!
			  for(int j =0;j<8;j++){
				  //IN1~IN4까지의 출력을 동시에 결정
				  for(int z = 0; z<4;z++){
					  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[j][z]);
				  }
				  delay_us(750);
			  }
		  }
	  }
	  //PA8을 누르면 반시계방향으로 한바퀴 회전
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  for(int i = 0;i<512;i++){
			  for(int j =7;j>=0;j--){
				  for(int z = 0; z<4;z++){
					  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[j][z]);
				  }
				  delay_us(750);
			  }
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }

 


8.타이머인터럽트를 이용해서 스탭모터를 시계방향으로 항상 회전시키는 예시를 구현하시오!(IOC설정) 버튼3과 버튼4를 누르면 LED가 제어된다는 것을 메인함수에서 표현하시오!

/* USER CODE BEGIN 0 */
uint8_t seq[][4]={
 		{0,0,0,1}, //1
 		{0,0,1,1}, //2
 		{0,0,1,0}, //3
 		{0,1,1,0}, //4
 		{0,1,0,0}, //5
 		{1,1,0,0}, //6
 		{1,0,0,0}, //7
 		{1,0,0,1}  //8
 };
GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
int seq_num = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   //타이머 인터럽트 콜백함수
	//시퀀스 0 ~ 7까지 연속적으로 전송한다!
	//IN1~IN4까지의 출력을 동시에 결정
	for(int z = 0; z<4;z++){
	  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[seq_num][z]);
	}
	seq_num++;
	if(seq_num >= 8) seq_num = 0;
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 //타이머 인터럽트 실행
 HAL_TIM_Base_Start_IT(&htim2);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
		  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,1);
	  }
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) == 0){
		  HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,0);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }


9.버튼1을 누르면 스탭모터가 시작위치에서 시계방향으로 360도 회전하고, 버튼2를 누르면 반시계방향으로 360도 회전하도록 하시오!(절대위치제어)

/* USER CODE BEGIN 0 */
uint8_t seq[][4]={
 		{0,0,0,1}, //1
 		{0,0,1,1}, //2
 		{0,0,1,0}, //3
 		{0,1,1,0}, //4
 		{0,1,0,0}, //5
 		{1,1,0,0}, //6
 		{1,0,0,0}, //7
 		{1,0,0,1}  //8
 };
GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
int now_pos = 0; //스탭모터가 알고있는 자기의 현재 위치
int target_pos = 0; //녹칸다가 설정한 목표위치
int seq_num = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   //타이머 인터럽트 콜백함수
	if(now_pos < target_pos){
		//시계방향으로 회전해야하는 상황
		for(int z = 0; z<4;z++){
		  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[seq_num][z]);
		}
		seq_num++;
		if(seq_num >= 8) seq_num = 0;
		now_pos++; //시퀀스 1회당 현재위치 1 증가
	}else if(now_pos > target_pos){
		//반시계방향으로 회전해야 하는 상황
		for(int z = 0; z<4;z++){
		  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[seq_num][z]);
		}
		seq_num--;
		if(seq_num < 0) seq_num = 7;
		now_pos--; //시퀀스 1회당 현재위치 1 감소
	}
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 //타이머 인터럽트 실행
 HAL_TIM_Base_Start_IT(&htim2);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  target_pos = 4096;
	  }
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  target_pos = 0;
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }


10.버튼1은 원점(0), 버튼2는 +90도, 버튼3은 +180도, 버튼4는 +360도, 버튼5는 -90도, 버튼6은 -180도, 버튼7은 -360도 회전하도록 설정하시오!

/* USER CODE BEGIN 0 */
uint8_t seq[][4]={
 		{0,0,0,1}, //1
 		{0,0,1,1}, //2
 		{0,0,1,0}, //3
 		{0,1,1,0}, //4
 		{0,1,0,0}, //5
 		{1,1,0,0}, //6
 		{1,0,0,0}, //7
 		{1,0,0,1}  //8
 };
GPIO_TypeDef *mygroup[] = {GPIOC,GPIOC,GPIOC,GPIOD};
uint16_t mypin[] = {GPIO_PIN_10,GPIO_PIN_11,GPIO_PIN_12,GPIO_PIN_2};
int now_pos = 0; //스탭모터가 알고있는 자기의 현재 위치
int target_pos = 0; //녹칸다가 설정한 목표위치
int seq_num = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
   //타이머 인터럽트 콜백함수
	if(now_pos < target_pos){
		//시계방향으로 회전해야하는 상황
		for(int z = 0; z<4;z++){
		  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[seq_num][z]);
		}
		seq_num++;
		if(seq_num >= 8) seq_num = 0;
		now_pos++; //시퀀스 1회당 현재위치 1 증가
	}else if(now_pos > target_pos){
		//반시계방향으로 회전해야 하는 상황
		for(int z = 0; z<4;z++){
		  HAL_GPIO_WritePin(mygroup[z],mypin[z],seq[seq_num][z]);
		}
		seq_num--;
		if(seq_num < 0) seq_num = 7;
		now_pos--; //시퀀스 1회당 현재위치 1 감소
	}
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 //타이머 인터럽트 실행
 HAL_TIM_Base_Start_IT(&htim2);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  target_pos = 0; //0
	  }
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  target_pos = 4096/4; //90
	  }
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
	  		  target_pos = 4096/2; //180
	  }
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) == 0){
	  		  target_pos = 4096; //360
	  }
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_5) == 0){
	  		  target_pos = -4096/4; //-90
	  }
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 0){
	  		  target_pos = -4096/2; //-180
	  }
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11) == 0){
	  		  target_pos = -4096; //-360
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }

 

반응형
Posted by 덕력킹
,