반응형

https://youtube.com/live/Q39rzRj1ol8

[STM32#15] C# winform을 이용해서 STM32f103rb nucleo보드와 usart2로 serial통신하는 방법 알아보기!(녹칸다 내맘대로 STM32)

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

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

이번편 부터 STM32의 친구 C#윈폼이 등장합니다!

 

1.STM32가 1초간격으로 “I’m stm32 board!!”라는 문자열을 PC로 전송할때, C#윈폼으로 만든 프로그램화면에 받은 문자열을 그대로 출력하시오!

/* USER CODE BEGIN 2 */
 char msg[] = "I'm STM32 BOARD!!\n";
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //1초간격으로 지정된 문자열을 전송한다
	  HAL_UART_Transmit(&huart2,msg,strlen(msg),100);
	  HAL_Delay(1000);
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }
private void button1_Click(object sender, EventArgs e)
        {
            //button1이 클릭된게 감지되었는데 너 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            serialPort1.Open(); //포트 개방!

            if (serialPort1.IsOpen)
            {
                //버퍼에 있는 데이터를 모조리 소멸시킨다
                serialPort1.ReadExisting();
                MessageBox.Show("접속완료!");
            }
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //stm32에서 데이터가 수신되었다! 뭐할래?
            //stm32가 보낸 문자열중 종료문자가 LF일때 까지를 읽겠다!
            string data = serialPort1.ReadLine();
            richTextBox1.Text += data + "\n";
        }

2.STM32에서 PB1에 연결된 버튼을 누르면 BTN1 CLICK!이라고 전송하고 PA8에 연결된 버튼을 누르면 BTN2 CLICK이라고 전송해서 C#윈폼으로 만든 GUI에 출력한다!

/* USER CODE BEGIN 2 */
 char msg1[] = "BTN1 CLICKED!\n";
 char msg2[] = "BTN2 CLICKED!\n";
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1을 누르면~
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  HAL_UART_Transmit(&huart2,msg1,strlen(msg1),100);
		  HAL_Delay(300);
	  }
	  //PA8을 누르면~
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  HAL_UART_Transmit(&huart2,msg2,strlen(msg2),100);
		  HAL_Delay(300);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }
private void button1_Click(object sender, EventArgs e)
        {
            //button1이 클릭된게 감지되었는데 너 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            serialPort1.Open(); //포트 개방!

            if (serialPort1.IsOpen)
            {
                //버퍼에 있는 데이터를 모조리 소멸시킨다
                serialPort1.ReadExisting();
                MessageBox.Show("접속완료!");
            }
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //stm32에서 데이터가 수신되었다! 뭐할래?
            //stm32가 보낸 문자열중 종료문자가 LF일때 까지를 읽겠다!
            string data = serialPort1.ReadLine();
            richTextBox1.Text += data + "\n";
        }

3.예제2에서 PB1을 누르면 STM32내부에 있는 uint32_t num1 = 1234;의 값을 C#윈폼으로 바이너리로 전송하고, PA8을 누르면 int32_t num2 = -5678;의 값을 C#으로 전송해서 출력하시오!

/* USER CODE BEGIN 2 */
 uint32_t num1 = 1234;
 int32_t num2 = -5678;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  //PB1을 누르면~
	  if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1) == 0){
		  HAL_UART_Transmit(&huart2,(uint8_t*)&num1,sizeof(num1),100);
		  HAL_Delay(300);
	  }
	  //PA8을 누르면~
	  if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_8) == 0){
		  HAL_UART_Transmit(&huart2,(uint8_t*)&num2,sizeof(num2),100);
		  HAL_Delay(300);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }
private void button1_Click(object sender, EventArgs e)
        {
            //button1이 클릭된게 감지되었는데 너 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            serialPort1.Open(); //포트 개방!

            if (serialPort1.IsOpen)
            {
                //버퍼에 있는 데이터를 모조리 소멸시킨다
                serialPort1.ReadExisting();
                MessageBox.Show("접속완료!");
            }
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            //stm32에서 데이터가 수신되었다! 뭐할래?
            //4byte로 구성된 숫자가 날라오는 상황이 되었다!
            byte[] buff = new byte[4];
            //STM32가 보낸 데이터를 buff에 0번부터 시작해서
            //4개를 가져와서 대입하겠다!
            serialPort1.Read(buff, 0, 4);

            //buff안에 들어있는 값을 0부터 4개를 uint32로 해석!
            UInt32 num1 = BitConverter.ToUInt32(buff, 0);
            Int32 num2 = BitConverter.ToInt32(buff, 0);

            richTextBox1.Text = num1 + ", " + num2;
        }

4.C#에서 ON버튼과 OFF버튼을 2개 생성하고, ON버튼을 누르면 PB3에 연결된 LED를 ON하고 OFF버튼은 OFF시키시오!(문자 ‘0’일때 OFF, 문자 ‘1’일때 ON)

/* USER CODE BEGIN 2 */
 char recv;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_UART_Receive(&huart2, &recv, 1, 500) == HAL_OK){
		  //C#에서 보낸 데이터 1개를 성공적으로 수신함!
		  if(recv == '0'){
			  //LED OFF
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 0);
		  }else if(recv == '1'){
			  //LED ON
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 1);
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }
private void button1_Click(object sender, EventArgs e)
        {
            //button1이 클릭된게 감지되었는데 너 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            serialPort1.Open(); //포트 개방!

            if (serialPort1.IsOpen)
            {
                //버퍼에 있는 데이터를 모조리 소멸시킨다
                serialPort1.ReadExisting();
                MessageBox.Show("접속완료!");
            }
        }
private void button3_Click(object sender, EventArgs e)
        {
            //OFF버튼 문자 '0'전송
            if (serialPort1.IsOpen)
            {
                serialPort1.Write("0");
            }
            else
            {
                MessageBox.Show("접속을 해주세요!");
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //ON버튼 문자 '1'전송
            if (serialPort1.IsOpen)
            {
                serialPort1.Write("1");
            }
            else
            {
                MessageBox.Show("접속을 해주세요!");
            }
        }

5.C#에서 ON버튼과 OFF버튼을 2개 생성하고, ON버튼을 누르면 PB3에 연결된 LED를 ON하고 OFF버튼은 OFF시키시오!(숫자 0일때 OFF, 숫자 1일때 ON)

/* USER CODE BEGIN 2 */
 char recv;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_UART_Receive(&huart2, &recv, 1, 500) == HAL_OK){
		  //C#에서 보낸 데이터 1개를 성공적으로 수신함!
		  //녹칸다가 recv에 0을 보내면 LED OFF신호고 바로 적용하고
		  //1을 보내면 ON신호로 바로 적용가능하나,
		  //만약 C#에서 0,1 이외에 다른걸 보내게되면 문제가 생길수있음!
		  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, recv);
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }
private void button1_Click(object sender, EventArgs e)
        {
            //button1이 클릭된게 감지되었는데 너 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            serialPort1.Open(); //포트 개방!

            if (serialPort1.IsOpen)
            {
                //버퍼에 있는 데이터를 모조리 소멸시킨다
                serialPort1.ReadExisting();
                MessageBox.Show("접속완료!");
            }
        }

private void button3_Click(object sender, EventArgs e)
        {
            //OFF버튼 문자 '0'전송
            if (serialPort1.IsOpen)
            {
                //숫자 1개 전송하기!
                byte[] data = { 0 };
                serialPort1.Write(data, 0, 1);
            }
            else
            {
                MessageBox.Show("접속을 해주세요!");
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            //ON버튼 문자 '1'전송
            if (serialPort1.IsOpen)
            {
                //숫자 1개 전송하기!
                byte[] data = { 1 };
                serialPort1.Write(data, 0, 1);
            }
            else
            {
                MessageBox.Show("접속을 해주세요!");
            }
        }

6.PB3,PB13,PB5,PB14,PB4,PB15,PC4,PB7에 LED가 총 8개 연결되어있는데, C#윈폼에서 버튼을 이용해서 모든 LED를 제어할 수 있는 UI와 기능을 구현하시오!

   -문자0,1(LED1), 문자2,3(LED2), 문자4,5(LED3), 문자6,7(LED4), 문자8,9(LED5), 문자A,B(LED6), 문자C,D(LED7), 문자E,F(LED8)

/* USER CODE BEGIN 2 */
 char recv;
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_UART_Receive(&huart2, &recv, 1, 500) == HAL_OK){
		  if(recv == '0'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 0);
		  }else if(recv == '1'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, 1);
		  }else if(recv == '2'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, 0);
		  }else if(recv == '3'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, 1);
		  }else if(recv == '4'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, 0);
		  }else if(recv == '5'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, 1);
		  }else if(recv == '6'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, 0);
		  }else if(recv == '7'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, 1);
		  }else if(recv == '8'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, 0);
		  }else if(recv == '9'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_4, 1);
		  }else if(recv == 'A'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, 0);
		  }else if(recv == 'B'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15, 1);
		  }else if(recv == 'C'){
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, 0);
		  }else if(recv == 'D'){
			  HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, 1);
		  }else if(recv == 'E'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, 0);
		  }else if(recv == 'F'){
			  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, 1);
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }
private void button1_Click(object sender, EventArgs e)
        {
            //button1이 클릭된게 감지되었는데 너 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            serialPort1.Open(); //포트 개방!

            if (serialPort1.IsOpen)
            {
                //버퍼에 있는 데이터를 모조리 소멸시킨다
                serialPort1.ReadExisting();
                MessageBox.Show("접속완료!");
            }
        }

private void button3_Click(object sender, EventArgs e)
        {
            serialPort1.Write("0");
        }
        private void button2_Click(object sender, EventArgs e)
        {
            serialPort1.Write("1");
        }
        private void button5_Click(object sender, EventArgs e)
        {
            serialPort1.Write("2");
        }

        private void button4_Click(object sender, EventArgs e)
        {
            serialPort1.Write("3");
        }

        private void button7_Click(object sender, EventArgs e)
        {
            serialPort1.Write("4");
        }

        private void button6_Click(object sender, EventArgs e)
        {
            serialPort1.Write("5");
        }

        private void button9_Click(object sender, EventArgs e)
        {
            serialPort1.Write("6");
        }

        private void button8_Click(object sender, EventArgs e)
        {
            serialPort1.Write("7");
        }

        private void button16_Click(object sender, EventArgs e)
        {
            serialPort1.Write("8");
        }


        private void button17_Click(object sender, EventArgs e)
        {
            serialPort1.Write("9");
        }
        private void button14_Click(object sender, EventArgs e)
        {
            serialPort1.Write("A");
        }
        private void button15_Click(object sender, EventArgs e)
        {
            serialPort1.Write("B");
        }
        private void button12_Click(object sender, EventArgs e)
        {
            serialPort1.Write("C");
        }
        private void button13_Click(object sender, EventArgs e)
        {
            serialPort1.Write("D");
        }

        private void button10_Click(object sender, EventArgs e)
        {
            serialPort1.Write("E");
        }

        private void button11_Click(object sender, EventArgs e)
        {
            serialPort1.Write("F");
        }

7.예제6번을 조금더 고급스럽게, 효율적으로 바꿔보시오! 추가로 모든 LED를 ON하고나 OFF하는 기능을 추가하시오!

/* USER CODE BEGIN 2 */
 GPIO_TypeDef *mygpio[] = {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 recv[2];
 /* USER CODE END 2 */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
	  if(HAL_UART_Receive(&huart2, recv, 2, 500) == HAL_OK){
		  //recv[0] : LED번호
		  int led_num = recv[0];
		  //recv[1] : 0이면 OFF, 1이면 ON
		  int state = recv[1];
		  if(led_num == 8){
			  //led_num이 8이면 모든 LED를 제어하는 것이다!
			  for(int i = 0;i<8;i++){
				  HAL_GPIO_WritePin(mygpio[i], mypin[i], state);
			  }
		  }else{
			  HAL_GPIO_WritePin(mygpio[led_num], mypin[led_num], state);
		  }
	  }
   /* USER CODE END WHILE */
   /* USER CODE BEGIN 3 */
 }
private void button1_Click(object sender, EventArgs e)
        {
            //button1이 클릭된게 감지되었는데 너 뭐할래?
            serialPort1.PortName = textBox1.Text;
            serialPort1.BaudRate = 115200;

            serialPort1.Open(); //포트 개방!

            if (serialPort1.IsOpen)
            {
                //버퍼에 있는 데이터를 모조리 소멸시킨다
                serialPort1.ReadExisting();
                MessageBox.Show("접속완료!");
            }
        }
private void button3_Click(object sender, EventArgs e)
        {
            byte[] data = { 0, 0 };
            serialPort1.Write(data, 0, 2);
        }
        private void button2_Click(object sender, EventArgs e)
        {
            byte[] data = { 0,1 };
            serialPort1.Write(data, 0, 2);
        }
        private void button5_Click(object sender, EventArgs e)
        {
            byte[] data = { 1, 0 };
            serialPort1.Write(data, 0, 2);
        }
        private void button4_Click(object sender, EventArgs e)
        {
            byte[] data = { 1, 1 };
            serialPort1.Write(data, 0, 2);
        }
        private void button7_Click(object sender, EventArgs e)
        {
            byte[] data = { 2, 0 };
            serialPort1.Write(data, 0, 2);
        }
        private void button6_Click(object sender, EventArgs e)
        {
            byte[] data = { 2, 1 };
            serialPort1.Write(data, 0, 2);
        }
        private void button9_Click(object sender, EventArgs e)
        {
            byte[] data = { 3, 0 };
            serialPort1.Write(data, 0, 2);
        }
        private void button8_Click(object sender, EventArgs e)
        {
            byte[] data = { 3, 1 };
            serialPort1.Write(data, 0, 2);
        }
        private void button16_Click(object sender, EventArgs e)
        {
            byte[] data = { 4, 0 };
            serialPort1.Write(data, 0, 2);
        }
        private void button17_Click(object sender, EventArgs e)
        {
            byte[] data = { 4, 1 };
            serialPort1.Write(data, 0, 2);
        }
        private void button14_Click(object sender, EventArgs e)
        {
            byte[] data = { 5, 0 };
            serialPort1.Write(data, 0, 2);
        }

        private void button15_Click(object sender, EventArgs e)
        {
            byte[] data = { 5, 1 };
            serialPort1.Write(data, 0, 2);
        }
        private void button12_Click(object sender, EventArgs e)
        {
            byte[] data = { 6, 0 };
            serialPort1.Write(data, 0, 2);
        }
        private void button13_Click(object sender, EventArgs e)
        {
            byte[] data = { 6, 1 };
            serialPort1.Write(data, 0, 2);
        }
        private void button10_Click(object sender, EventArgs e)
        {
            byte[] data = { 7, 0 };
            serialPort1.Write(data, 0, 2);
        }
        private void button11_Click(object sender, EventArgs e)
        {
            byte[] data = { 7, 1 };
            serialPort1.Write(data, 0, 2);
        }
        private void button18_Click(object sender, EventArgs e)
        {
            byte[] data = { 8, 1 };
            serialPort1.Write(data, 0, 2);
        }
        private void button19_Click(object sender, EventArgs e)
        {
            byte[] data = { 8, 0 };
            serialPort1.Write(data, 0, 2);
        }
반응형
Posted by 덕력킹
,