반응형

https://youtube.com/live/bcttbM80CgY

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

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

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

이번편은 9편에 이어서 스탭모터(28byj-48)를 위치제어, 속도제어 해보도록 한다!

 

1.예를들어 버튼1을 계속 누르고 있으면 "누르고 있는 동안”에 스탭모터가 시계방향으로 회전하고 버튼2를 계속 누르고 있으면 “누르는 동안” 반시계방향으로 회전한다!

/* 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; //0~7
//0이면 정지, 1이면 정회전, -1이면 역회전
int direct = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(direct == 1){
		//정회전 시퀀스를 전송한다
		for(int i = 0;i<4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num++;
		if(seq_num == 8) seq_num = 0;
	}else if(direct == -1){
		//역회전 시퀀스를 전송한다
		for(int i = 0;i<4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num--;
		if(seq_num == -1) seq_num = 7;
	}
}
/* 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)
 {
	  //PB1을 누르면 direct가 1이되고 안누르면 0이된다!
	  //PA8을 누르면 direct가 -1이되고 안누르면 0이된다!
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  //정회전
		  direct = 1;
	  }else if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  //역회전
		  direct = -1;
	  }else{
		  //정지
		  direct = 0;
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }


2.예제1에서 스탭모터의 현재 위치값을 100밀리초간격으로 시리얼출력해서 PC에서 스탭모터의 현재 위치를 알 수 있도록 하시오!

/* 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; //0~7
//0이면 정지, 1이면 정회전, -1이면 역회전
int direct = 0;
int32_t now_pos = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(direct == 1){
		//정회전 시퀀스를 전송한다
		for(int i = 0;i<4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num++;
		if(seq_num == 8) seq_num = 0;
		now_pos++;
	}else if(direct == -1){
		//역회전 시퀀스를 전송한다
		for(int i = 0;i<4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num--;
		if(seq_num == -1) seq_num = 7;
		now_pos--;
	}
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&htim2);
 uint32_t nockanda_t = 0;
 char buff[50];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //100밀리초 간격으로 전송한다
	  if(HAL_GetTick()-nockanda_t > 100){
		  nockanda_t = HAL_GetTick();
		  //녹칸다가 위치를 계속 올려서 32000정도를 넘겼을때 이상한값이 나온다면 %d가 아닌것이다!
		  sprintf(buff,"now_pos = %d\n",now_pos);
		  HAL_UART_Transmit(&huart2, buff, strlen(buff), 100);
	  }
	  //PB1을 누르면 direct가 1이되고 안누르면 0이된다!
	  //PA8을 누르면 direct가 -1이되고 안누르면 0이된다!
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  //정회전
		  direct = 1;
	  }else if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  //역회전
		  direct = -1;
	  }else{
		  //정지
		  direct = 0;
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }


3.로터리엔코더(PA11,PA12)를 시계방향으로 회전하면 스탭모터도 시계방향으로 회전하고 반시계방향이면 반시계방향으로 회전한다!

/* 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; //0~7
int32_t now_pos = 0;
int32_t target_pos = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(now_pos < target_pos){
		//정회전 시퀀스를 전송한다
		for(int i = 0;i<4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num++;
		if(seq_num == 8) seq_num = 0;
		now_pos++;
	}else if(now_pos > target_pos){
		//역회전 시퀀스를 전송한다
		for(int i = 0;i<4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num--;
		if(seq_num == -1) seq_num = 7;
		now_pos--;
	}
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&htim2);
 uint32_t nockanda_t = 0;
 char buff[50];
 uint8_t old_A = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //100밀리초 간격으로 전송한다
	  if(HAL_GetTick()-nockanda_t > 100){
		  nockanda_t = HAL_GetTick();
		  //녹칸다가 위치를 계속 올려서 32000정도를 넘겼을때 이상한값이 나온다면 %d가 아닌것이다!
		  sprintf(buff,"now_pos = %d, target_pos = %d\n",now_pos, target_pos);
		  HAL_UART_Transmit(&huart2, buff, strlen(buff), 100);
	  }
	  //A의 상승엣지가 검출되었을때 B가 LOW면 시계방향, HIGH면 반시계방향
	  uint8_t now_A = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11);
	  if(now_A == 1 && old_A == 0){
		  uint8_t now_B = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12);
		  if(now_B == 0){
			  //시계
			  target_pos += 8;
		  }else{
			  //반시계
			  target_pos -= 8;
		  }
	  }
	  old_A = now_A;
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }


4.예제3번처럼 로터리엔코더를 돌리면 실시간으로 따라가는게 아니라 로터리엔코더에 붙어있는 스위치(PC7)를 눌렀을때 스탭모터가 회전되도록 하시오!

/* 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; //0~7
int32_t now_pos = 0;
int32_t target_pos = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(now_pos < target_pos){
		//정회전 시퀀스를 전송한다
		for(int i = 0;i<4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num++;
		if(seq_num == 8) seq_num = 0;
		now_pos++;
	}else if(now_pos > target_pos){
		//역회전 시퀀스를 전송한다
		for(int i = 0;i<4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num--;
		if(seq_num == -1) seq_num = 7;
		now_pos--;
	}
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&htim2);
 uint32_t nockanda_t = 0;
 char buff[50];
 uint8_t old_A = 0;
 int32_t rotary_pos = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //100밀리초 간격으로 전송한다
	  if(HAL_GetTick()-nockanda_t > 100){
		  nockanda_t = HAL_GetTick();
		  sprintf(buff,"now_pos = %d, rotary_pos = %d\n",now_pos, rotary_pos);
		  HAL_UART_Transmit(&huart2, buff, strlen(buff), 100);
	  }
	  //PC7을 누르면 rotary_pos가 target_pos로 copy된다
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 0){
		  target_pos = rotary_pos;
	  }
	  //A의 상승엣지가 검출되었을때 B가 LOW면 시계방향, HIGH면 반시계방향
	  uint8_t now_A = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11);
	  if(now_A == 1 && old_A == 0){
		  uint8_t now_B = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12);
		  if(now_B == 0){
			  //시계
			  rotary_pos += 8;
		  }else{
			  //반시계
			  rotary_pos -= 8;
		  }
	  }
	  old_A = now_A;
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }


5.스탭모터가 시계방향으로 항상 회전을 하는데, 버튼1을 누르면 타이머인터럽트의 주기가 1.5밀리초로하고, 버튼2를 누르면 800마이크로초로하고, 버튼3을 누르면 10밀리초로 하시오!(TIM2의 ARR을 수정)

/* 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; //0~7
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	for(int i = 0;i<4;i++){
		HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
	}
	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)
 {
	  //PB1을 누르면 ARR이 1500-1이 된다!
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  TIM2->ARR = 1500-1;
	  }
	  //PA8을 누르면 ARR이 800-1이 된다
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  TIM2->ARR = 800-1;
	  }
	  //PB2을 누르면 ARR이 10000-1이 된다
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
		  TIM2->ARR = 10000-1;
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }


6.버튼1을 누르면 스탭모터가 반시계방향으로 회전한다! 버튼2를 누르면 정지한다! 버튼3을 누르면 시계방향으로 회전한다! 이때 가변저항을 이용해서 속도를 0.8밀리초~10밀리초 범위로 조절하시오!(속도제어)

/* 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; //0~7
int direct = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(direct == 1){
		for(int i = 0;i<4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num++;
		if(seq_num == 8) seq_num = 0;
	}else if(direct == -1){
		for(int i = 0;i<4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num--;
		if(seq_num == -1) seq_num = 7;
	}
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&htim2);
 HAL_ADC_Start(&hadc1);
 uint16_t adc_value0 = 0;
 uint32_t nockanda_t = 0;
 char buff[50];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_GetTick() - nockanda_t > 100){
		  nockanda_t = HAL_GetTick();
		  if(HAL_ADC_PollForConversion(&hadc1, 10) == HAL_OK)
		  {
			  // 값 처리
			  adc_value0 = HAL_ADC_GetValue(&hadc1); //0~4095
			  //0 ~ 4095구간을 10000 ~ 800으로 바꾼다
			  adc_value0 = 10000 - (10000-800) * adc_value0 / 4095.0;
			  sprintf(buff,"A0 = %d\n",adc_value0);
			  HAL_UART_Transmit(&huart2, buff, strlen(buff), 100);
			  if(adc_value0 >= 800 && adc_value0 <= 10000){
				  TIM2->ARR = adc_value0;
			  }
		  }
	  }
	  //PB1을 누르면 역회전
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  direct = -1;
	  }
	  //PA8을 누르면 정지
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  direct = 0;
	  }
	  //PB2을 누르면 정회전
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
		  direct = 1;
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }


7.녹칸다가 스탭모터의 목표위치를 putty에서 입력한다! 그 목표 위치대로 스탭모터가 회전하도록 하시오!

/* 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; //0~7
int32_t now_pos = 0;
int32_t target_pos = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(now_pos < target_pos){
		for(int i = 0;i<4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num++;
		if(seq_num == 8) seq_num = 0;
		now_pos++;
	}else if(now_pos > target_pos){
		for(int i = 0;i<4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num--;
		if(seq_num == -1) seq_num = 7;
		now_pos--;
	}
}
/* USER CODE END 0 */

/* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&htim2);
 char rx_buff[50];
 char tx_buff[50];
 char recv = 0;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //녹칸다가 입력한 숫자대로 스탭모터가 목표위치로 이동한다!
	  //녹칸다가 보낸 숫자를 그대로 echo해서 출력해라!
	  int rx_index = 0;
	  while(HAL_UART_Receive(&huart2, &recv, 1, 100) == HAL_OK){
		  rx_buff[rx_index] = recv;
		  rx_index++;
		  if(recv == '\r'){
			  //putty에서 마지막 종료문자가 왔다!
			  rx_buff[rx_index] = '\0';
			  sprintf(tx_buff,"SET TARGET_POS = %s\n",rx_buff);
			  HAL_UART_Transmit(&huart2, tx_buff, strlen(tx_buff), 100);
			  target_pos = atoi(rx_buff);
			  break;
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }


8.예제6에서 시계방향으로 회전할때 리미트스위치 역할을 버튼4가 하고, 반시계방향으로 회전할때 리미트스위치 역할을 버튼5가 할때 리미트스위치에 감지되면 스탭모터가 정지하도록 하시오!

/* 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; //0~7
int32_t direct = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(direct == 1){
		if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6) == 1){
			for(int i = 0;i<4;i++){
				HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
			}
			seq_num++;
			if(seq_num == 8) seq_num = 0;
		}
	}else if(direct == -1){
		if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_5) == 1){
			for(int i = 0;i<4;i++){
				HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
			}
			seq_num--;
			if(seq_num == -1) seq_num = 7;
		}
	}
}
/* 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)
 {
	  //PB1을 누르면 역회전
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  direct = -1;
	  }
	  //PA8을 누르면 정지
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  direct = 0;
	  }
	  //PB2을 누르면 정회전
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_2) == 0){
		  direct = 1;
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }


9.로터리엔코더를 돌려서 LED 8개중 1개의 LED만 켜지도록 하고, 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; //0~7
int32_t now_pos = 0;
int32_t target_pos = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
	if(now_pos < target_pos){
		for(int i = 0;i<4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num++;
		if(seq_num == 8) seq_num = 0;
		now_pos++;
	}else if(now_pos > target_pos){
		for(int i = 0;i<4;i++){
			HAL_GPIO_WritePin(mygroup[i], mypin[i], seq[seq_num][i]);
		}
		seq_num--;
		if(seq_num == -1) seq_num = 7;
		now_pos--;
	}
}
/* USER CODE END 0 */
/* USER CODE BEGIN 2 */
 HAL_TIM_Base_Start_IT(&htim2);
 uint8_t old_A = 0;
 int32_t rotary_pos = 0;
 GPIO_TypeDef *mygroup[] = {GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOB,GPIOC,GPIOB};
 uint16_t mypin[] = {GPIO_PIN_3,GPIO_PIN_13,GPIO_PIN_5,GPIO_PIN_14,GPIO_PIN_4,GPIO_PIN_15,GPIO_PIN_4,GPIO_PIN_7};
 char buff[50];
 int led_pos = 0;
 HAL_GPIO_WritePin(mygroup[0],mypin[0], 1);
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) == 0){
		  target_pos = rotary_pos;
	  }
	  //A의 상승엣지가 검출되었을때 B가 LOW면 시계방향, HIGH면 반시계방향
	  uint8_t now_A = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11);
	  if(now_A == 1 && old_A == 0){
		  uint8_t now_B = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_12);
		  if(now_B == 0){
			  //시계
			  rotary_pos += 512;
			  led_pos++;
			  if(led_pos == 8) led_pos = 0;
		  }else{
			  //반시계
			  rotary_pos -= 512;
			  led_pos--;
			  if(led_pos == -1) led_pos = 7;
		  }
		  for(int i = 0;i<8;i++){
			  if(i == led_pos) HAL_GPIO_WritePin(mygroup[i],mypin[i], 1);
			  else HAL_GPIO_WritePin(mygroup[i],mypin[i], 0);
		  }
		  //현재 스탭모터의 각도(디그리)를 출력한다!
		  sprintf(buff,"degree = %d\n",360*rotary_pos/4096);
		  HAL_UART_Transmit(&huart2, buff, strlen(buff), 100);
	  }
	  old_A = now_A;
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }
반응형
Posted by 덕력킹
,