본문 바로가기
나의 전자 공부방/STM32

1. [stm32] 동기방식, 비동기방식, LED_processing 동영상 첨부

by 나만의생각 2023. 4. 5.

오늘은 Uart통신과 블루투스를 통해서 stm32를 제어하는 것을 알아보겠습니다.

 

uart통신은 다음과 같은 방식이있는데 비동기방식입니다.

 

송신 : polling방식

수신 : interrupt 수신 (RX Interrupt)

 

1.비동기 방식 : 클릭 신호에 맞춰 데이터를 송수신 하지않고 별도의 부호비트(start/stop bit)를 붙여서 데이터를 보내고 받는 방식. 오실로스코프로 Raw Data를 확인작업.

 

2. 동기식 : 클럭 신호에 맞춰서 데이터를 송수신하는 방식

 

 

led.c

/*
 * led_control.c
 *
 *  Created on: Apr 3, 2023
 *      Author: kccistc
 */

#include "led_control.h"
#include "button.h"

static int state =0;
int i=0;
extern unsigned char current_button_status[BUTTON_NUMBER];  //가져올 때 변수값은 빼야 함
extern volatile int t1ms_counter;
extern volatile int t11ms_counter;


void led_main(void)
{
	t1ms_counter=0;
	t11ms_counter=0;
	while(1)
	{
		//printf("1234");
		//HAL_Delay(100);
		//led_all_on_off();
		btn_led_eventCheck();
//		one_button_processing();
//		button0_ledall_on_off();
//		led_all_on();
//		HAL_Delay(500);
//		led_all_off();
//	    HAL_Delay(500);
//	    led_bar_blink_up();
//	    led_bar_blink_down();
	}
}

#if 0
void button0_ledall_on_off(void)
{
	if (get_button(BUTTON0_GPIO_Port, BUTTON0_Pin, BUTTON0)==BUTTON_PRESS)
	{
		current_button_status[BUTTON0] = !current_button_status[BUTTON0];  //toggle
		if(!current_button_status[BUTTON0]) // 눌린 상태가 되면
		{
			led_all_on();
		}
		else
		{
			led_all_off();
		}
	}
}
#endif

// button0  1회  led_all_on
// button0  2회  led_all_off
// button0  3회  led_bar_blink_up
// button0  4회  led_bar_blink_down
// button0  5회  led_bar_sequential_up
// button0  6회  led_bar_sequential_down
// button0  7회  flower_on
// button0  8회  flower_off

// button1  1회 led all on 1초 유지 후  led_all_off 이후 아무런 action도 하지 않는다.




void one_button_processing()
{


	btn_led_eventCheck();


}


void btn_led_eventCheck()
{
	if(get_button(BUTTON0_GPIO_Port, BUTTON0_Pin, BUTTON0) == BUTTON_PRESS)
	{
		state = (state +1)%8;
//		if(state == 9)
//		{
//			led_all_off();
//			state = 0;
//		}

	}
	else if(get_button(BUTTON0_GPIO_Port, BUTTON1_Pin, BUTTON1) == BUTTON_PRESS)
	{

		t11ms_counter=0;
		led_all_on();
		while((t11ms_counter < 1000));
		led_all_off();
		state = 0;
	}


	switch (state)
	{
	case 0:
		led_all_off();
	break;
	case 1:
		led_all_on();
		break;
	case 2:
		led_all_off();
		led_bar_blink_up();
		break;
	case 3:
		led_all_off();
		led_bar_blink_down();
		break;
	case 4:
		led_all_off();
		led_bar_sequential_up();
		break;
	case 5:
		led_all_off();
		led_bar_sequential_down();
		break;
	case 6:
		led_all_off();
		flower_on();
		break;
	case 7:
		led_all_off();
		flower_off();
		break;

	}
}




int led_indicator=0;

void led_all_on_off()
{
	if (t1ms_counter >= 200)
	{
		t1ms_counter=0;
		if (!led_indicator)
		{
			led_all_on();
			led_indicator=1;
		}
		else
		{
			led_all_off();
			led_indicator=0;
		}
	}
}

void led_all_on()
{
	//HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOB, 0xff, GPIO_PIN_SET);
}

void led_all_off()
{
	//HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7, GPIO_PIN_RESET);
	HAL_GPIO_WritePin(GPIOB, 0xff, GPIO_PIN_RESET);
}

//void led_bar_blink_up()
//{
//	static int i;
//	for (i=0; i<8;)
//	{
//		if (t1ms_counter >= 300)
//			{
//			t1ms_counter=0;
//			led_all_off();
//		HAL_GPIO_WritePin(GPIOB, 0x80 >> i, 1);
//		i++;
//			}
//	}
void led_bar_blink_up()
{
		if(t11ms_counter>200)
		{
			t11ms_counter = 0;
			i = (i+1) % 8;
			HAL_GPIO_WritePin(GPIOB, 0xff, 0x0);
		}
		HAL_GPIO_WritePin(GPIOB, 0x80>>i, 1);

}

//  for (int i=0; i<8; i++)
//		{
//			led_all_off();
//			HAL_GPIO_WritePin(GPIOB, 0x80 >> i, 1);
//			HAL_Delay(300);
//		}


void led_bar_blink_down()
 {

	if (t11ms_counter > 200) {
		t11ms_counter = 0;
		i = (i + 1) % 8;
		HAL_GPIO_WritePin(GPIOB, 0xff, 0x0);

	}

	HAL_GPIO_WritePin(GPIOB, 0x01<< i, 1);

}

void led_bar_sequential_up()
{
		if (t11ms_counter > 200) {
			t11ms_counter = 0;
			i = (i + 1) % 9;
			//HAL_GPIO_WritePin(GPIOB, 0xff, 0x0);

		}
	HAL_GPIO_WritePin(GPIOB, 0xff << i, 1);
}

void led_bar_sequential_down()
{
	if (t11ms_counter > 200) {
				t11ms_counter = 0;
				i = (i + 1) % 8;
				//HAL_GPIO_WritePin(GPIOB, 0xff, 0x0);

			}
	HAL_GPIO_WritePin(GPIOB, 0xff >> i, 1);


}

void flower_on()
{

	if (t11ms_counter > 200)
			{
		t11ms_counter =0;
				i = (i+1)%4;

			}
	HAL_GPIO_WritePin(GPIOB,((0x1f << i) & 0xf0) | ((0xf8 >> i) & 0x0f), 0x01);

}

void flower_off()
{

	if (t11ms_counter > 200)
		{
		t11ms_counter =0;
			i = (i+1)%4;
		}
	HAL_GPIO_WritePin(GPIOB, ((0xf0 >> i) & 0xf0)|((0x0f << i) & 0x0f), 0x01);
}

 

uart.c

#include "main.h"
#include "uart.h"
#include <stdio.h> // printf gets scanf fget etc..
#include <string.h>//

volatile uint8_t rx_byte;



#define COMMAND_MAX 20
#define COMMAND_LENGTH 50


volatile int input_pointer=0;  // interrupt에서 queue에 data를 저장하는 위치값
volatile int output_pointer=0;  // pc_command_processing에서 가져가는 위치값
volatile unsigned char rx_buff[COMMAND_MAX][COMMAND_LENGTH];
volatile int rx_index=0;

extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2;


//1.copy from HAL_UART_RxcpltCallback of stm32f4xx_hal_uart to her
// UART로부터 1byte를 수신하면  H/W(CPU)가 call해준다.
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	//----------------------------PC------------------------------------
	if (huart == &huart2) // PC
	{
		unsigned char rx_data;

		rx_data = rx_byte;
		if (output_pointer % COMMAND_MAX == (input_pointer + 1) % COMMAND_MAX)
		{
			printf("Queue full!!!\n");
			return;
		} else
		{
			if (rx_data == '\n' || rx_data == '\r') {
				rx_buff[input_pointer][rx_index++] = '\0'; // 문잔의 끝을 null로 replace
				rx_index = 0;
				input_pointer++;
				input_pointer %= COMMAND_MAX;
				//개선 사항 output pointer
			}
			else
			{
				rx_buff[input_pointer][rx_index++] = rx_data;
			}

		}
		HAL_UART_Receive_IT(&huart2, &rx_byte, 1);

	}
	// ----------------------------BLUETOOTH---------------------------------
	if (huart == &huart1) // bt
		{
			unsigned char rx_data;

			rx_data = rx_byte;
			if (output_pointer % COMMAND_MAX == (input_pointer + 1) % COMMAND_MAX)
			{
				printf("Queue full!!!\n");
				return;
			} else
			{
				if (rx_data == '\n' || rx_data == '\r') {
				//if(rx_data == ';')
				//{
					rx_buff[input_pointer][rx_index++] = '\0'; // 문잔의 끝을 null로 replace
					rx_index = 0;
					input_pointer++;
					input_pointer %= COMMAND_MAX;
					//개선 사항 output pointer
				}
				else
				{
					rx_buff[input_pointer][rx_index++] = rx_data;
				}

			}
			HAL_UART_Receive_IT(&huart1, &rx_byte, 1);

		}
}
extern void led_all_on();
extern void led_all_off();
extern void led_bar_blink_up();
extern void led_bar_blink_down();
extern void led_bar_sequential_up();
extern void led_bar_sequential_down();
extern void flower_on();
extern void flower_off();
uint8_t print = 1;
void pc_command_processing()
{
   if(input_pointer != output_pointer) //rx_buff에 data 가 들어 있다.
   {
      if (print)
         //rx_buff[output_pointer] ==> &rx_buff[output_pointer][0] 둘이 동일한 의미
         printf("rx_buff[%d]: %s\n",output_pointer,rx_buff[output_pointer]);

      //&rx_buff[output_pointer][0]
      if(strncmp((const char *)rx_buff[output_pointer],"print_on",strlen("print_on"))== 0)
      {
         print = 1;
      }
      else if(strncmp((const char *)rx_buff[output_pointer],"print_off",strlen("print_off"))== 0)
      {
         print = 0;
      }
      if(strncmp((const char *)rx_buff[output_pointer],"led_all_on",strlen("led_all_on"))== 0)
      {
    	  led_all_on();
      }
      else if(strncmp((const char *)rx_buff[output_pointer],"led_all_off",strlen("led_all_off"))== 0)
      {
    	  led_all_off();
      }
      else if(strncmp((const char *)rx_buff[output_pointer],"led_bar_blink_up",strlen("led_bar_blink_up"))== 0)
      {
    	  led_bar_blink_up();
      }
      else if(strncmp((const char *)rx_buff[output_pointer],"led_bar_blink_down",strlen("led_bar_blink_down"))== 0)
      {
    	  led_bar_blink_down();
      }
      else if(strncmp((const char *)rx_buff[output_pointer],"led_bar_sequential_up",strlen("led_bar_sequential_up"))== 0)
      {
    	  led_bar_sequential_up();
      }
      else if(strncmp((const char *)rx_buff[output_pointer],"led_bar_sequential_down",strlen("led_bar_sequential_down"))== 0)
      {

    	  led_bar_sequential_down();

      }
      else if(strncmp((const char *)rx_buff[output_pointer],"flower_on",strlen("flower_on"))== 0)
      {
    	  flower_on();
      }
      else if(strncmp((const char *)rx_buff[output_pointer],"flower_off",strlen("flower_off"))== 0)
      {
    	  flower_off();
      }

      output_pointer = (output_pointer+1) % COMMAND_MAX;   //next index->output_pointer를 1증가

   }
}


void bt_command_processing()
{
   if(input_pointer != output_pointer) //rx_buff에 data 가 들어 있다.
   {
      if (print)
         //rx_buff[output_pointer] ==> &rx_buff[output_pointer][0] 둘이 동일한 의미
         printf("rx_buff[%d]: %s\n",output_pointer,rx_buff[output_pointer]);

      //&rx_buff[output_pointer][0]
      if(strncmp((const char *)rx_buff[output_pointer],"print_on",strlen("print_on"))== 0)
      {
         print = 1;
      }
      else if(strncmp((const char *)rx_buff[output_pointer],"print_off",strlen("print_off"))== 0)
      {
         print = 0;
      }
      if(strncmp((const char *)rx_buff[output_pointer],"led_all_on",strlen("led_all_on"))== 0)
      {
    	  led_all_on();
      }
      else if(strncmp((const char *)rx_buff[output_pointer],"led_all_off",strlen("led_all_off"))== 0)
      {
    	  led_all_off();
      }
      else if(strncmp((const char *)rx_buff[output_pointer],"led_bar_blink_up",strlen("led_bar_blink_up"))== 0)
      {
    	  led_bar_blink_up();
      }
      else if(strncmp((const char *)rx_buff[output_pointer],"led_bar_blink_down",strlen("led_bar_blink_down"))== 0)
      {
    	  led_bar_blink_down();
      }
      else if(strncmp((const char *)rx_buff[output_pointer],"led_bar_sequential_up",strlen("led_bar_sequential_up"))== 0)
      {
    	  led_bar_sequential_up();
      }
      else if(strncmp((const char *)rx_buff[output_pointer],"led_bar_sequential_down",strlen("led_bar_sequential_down"))== 0)
      {

    	  led_bar_sequential_down();

      }
      else if(strncmp((const char *)rx_buff[output_pointer],"flower_on",strlen("flower_on"))== 0)
      {
    	  flower_on();
      }
      else if(strncmp((const char *)rx_buff[output_pointer],"flower_off",strlen("flower_off"))== 0)
      {
    	  flower_off();
      }
      else if(strncmp((const char *)rx_buff[output_pointer],"number",strlen("number"))== 0)
      {
    	  uart_data_analysis();
      }

      output_pointer = (output_pointer+1) % COMMAND_MAX;   //next index->output_pointer를 1증가

   }
}

void uart_data_analysis()
{
	while(1)
	{
		printf("2660\n");	// 자기전화번호($자리)
						//PA2과 GND단자를 오실로스코프에 연결
		HAL_Delay(200);
	}
}
//uint8_t print =1;
//void pc_command_processing()
//{
//	if(input_pointer != output_pointer)
//	{
//		printf("rx_buff[%d] : %s\n", output_pointer, rx_buff[output_pointer]);
//		//rx_buff[output_pointer] 와 동일 &rx_buff[output_pointer][0]
//		// output_pointer를 1증가
//
//		if(strncmp((const char *)rx_buff[output_pointer], "print_on",strlen("print_on"))==0)
//		{
//			print = 1;
//		}
//		else if(strncmp((const char *)rx_buff[output_pointer], "print_on",strlen("print_off"))==0)
//		{
//			print = 0;
//		}
//
//		output_pointer = (output_pointer+1)%COMMAND_MAX;
//	}
//}

https://youtu.be/gMAq4pIAi8s

https://youtu.be/rCDZfiPYwYs