iT邦幫忙

2024 iThome 鐵人賽

DAY 27
0
佛心分享-SideProject30

門外漢的嵌入式地獄系列 第 27

Day 27 。初入嵌入式開發- RS232 驅動開發

  • 分享至 

  • xImage
  •  

RS232 算是比較簡單的介面,實際上所需要設定的部分也不多。我們先來看看原理圖與spec。

原理圖與Spec

在這邊假設如果你的 RS232 腳位選擇 PD0 與 PD3 , 那接下來我們就可以去看看 mp1 的 spec。

https://ithelp.ithome.com.tw/upload/images/20240821/20146325dZ1vRkVm5R.png

從Spec 中可以找到 PD0 是 UART7 , 對應的我們需要去找到 UART7 的 AF 表格以及 UART7 在設備樹當中的位置。

https://ithelp.ithome.com.tw/upload/images/20240821/20146325cckc14Nr2N.png

設備樹

uart7_idle_pins_mx: uart7_idle_mx-0 {
		pins1 {
			pinmux = <STM32_PINMUX('D', 0, AF6)>; /* UART7_RX */
			bias-disable;
			drive-push-pull;
		};
		pins2 {
			pinmux = <STM32_PINMUX('D', 3, ANALOG)>; /* UART7_TX */
		};
	};

下方的說明是替代功能怎麼看得,可以參照上方的圖片來看AF6 就是 UART。

STM32_PINMUX('D', 0, AF6)
## 'D' 表示 P'D'0 
## '0' 表示 PD'0'
## AF6 是替代功能 6

需要透過 pinctrl 控制器來控制,所以我們要先定義在 pinctrl 設備樹當中。定義如下:

uart7_pins_mx: uart7_mx-0 {
		pins1 {
			pinmux = <STM32_PINMUX('D', 0, AF6)>; /* UART7_RX */
			bias-disable;
			drive-push-pull;
		};
		pins2 {
			pinmux = <STM32_PINMUX('D', 3, AF6)>; /* UART7_TX */
			bias-disable;
			drive-push-pull;
			slew-rate = <0>;
		};
	};
	
    uart7_idle_pins_mx: uart7_idle_mx-0 {
		pins1 {
			pinmux = <STM32_PINMUX('D', 0, AF6)>; /* UART7_RX */
			bias-disable;
			drive-push-pull;
		};
		pins2 {
			pinmux = <STM32_PINMUX('D', 3, ANALOG)>; /* UART7_TX */
		};
	};
	
    uart7_sleep_pins_mx: uart7_sleep_mx-0 {
		pins {
			pinmux = <STM32_PINMUX('D', 0, ANALOG)>, /* UART7_RX */
					 <STM32_PINMUX('D', 3, ANALOG)>; /* UART7_TX */
		};
	};

上方只是定義他的群組與用途,實際上功能會寫在pinctrl外面。透過 & 去 reference

&uart7{
	pinctrl-names = "default", "idle", "sleep";
	#下方的 pinctrl 0 1 2 , 就是我們上面所定義的分組 ,
	#會依照 default idle sleep 去切換不同的使用分組設定
	pinctrl-0 = <&uart7_pins_mx>;
	pinctrl-1 = <&uart7_idle_pins_mx>;
	pinctrl-2 = <&uart7_sleep_pins_mx>;
	status = "okay";
};

最後在最上方的 aliases 當中要修改,原先是公板使用 usart6 , 我們要換成 uart7。

aliases {
		serial1 = &uart7;
	};

程式碼

接收端程式

/* rs232_recv.c */
#include 
#include 
#include 
#include 
#include 

#define BAUDRATE B38400
#define MODEMDEVICE "/dev/ttyS1"
#define _POSIX_SOURCE 1

int main()
{
    int fd, c=0, res;
    struct termios oldtio, newtio;
    char buf[256];

    printf("Start...\n");
    fd = open(MODEMDEVICE, O_RDWR|O_NOCTTY);
    if (fd < 0) {
      perror(MODEMDEVICE);
      exit(1);
    }

    printf("Open...\n");
    tcgetattr(fd, &oldtio);
    bzero(&newtio, sizeof(newtio));

    newtio.c_cflag = BAUDRATE|CS8|CLOCAL|CREAD;
    newtio.c_iflag = IGNPAR;
    newtio.c_oflag = 0;
    newtio.c_lflag = ICANON;

    tcflush(fd, TCIFLUSH);
    tcsetattr(fd, TCSANOW, &newtio);
    printf("Reading...\n");
    while(1) {
        res = read(fd, buf, 255);
        buf[res]=0;
        printf("res=%d buf=%s\n", res, buf);
        if (buf[0] == '@') break;
    }
    
    printf("Close...\n");
    close(fd);
    tcsetattr(fd, TCSANOW, &oldtio);
    return 0;
}

傳送端

/* rs232_send.c */
#include 
#include 
#include 
#include 
#include 

#define BAUDRATE B38400
#define MODEMDEVICE "/dev/ttyS0"
#define _POSIX_SOURCE 1
#define STOP '@'

int main()
{
    int fd, c=0, res;
    struct termios oldtio, newtio;
    char ch;
    static char s1[20];

    printf("Start...\n");
    fd = open(MODEMDEVICE, O_RDWR|O_NOCTTY);
    if (fd < 0) {
      perror(MODEMDEVICE);
      exit(1);
    }

    printf("Open...\n");
    tcgetattr(fd, &oldtio);
    bzero(&newtio, sizeof(newtio));

    newtio.c_cflag = BAUDRATE|CS8|CLOCAL|CREAD;
    newtio.c_iflag = IGNPAR;
    newtio.c_oflag = 0;
    newtio.c_lflag = ICANON;

    tcflush(fd, TCIFLUSH);
    tcsetattr(fd, TCSANOW, &newtio);

    printf("Writing...\n");

    while(1) {
      while((ch=getchar()) != STOP) {
        s1[0]=ch;
        res=write(fd, s1, 1); 
      }
      s1[0]=ch;
      s1[1]='\n';
      res = write(fd, s1, 2); 
      break;
    }
    printf("Close...\n");
    close(fd);
    tcsetattr(fd, TCSANOW, &oldtio);
    return 0;
}

驗證

可以直接透過指令來傳送

dmesg | grep "ttySTM"
fdtget /path/to/stm32mp1.dtb / full # 可以列出所有節點
stty -F /dev/ttyS1 # 可以查看串口設定
stty -F /dev/ttySTM1 115200 cs8 -parenb -cstopb
stty -F /dev/ttySTM1 -ixon -ixoff -crtscts
echo "helloword" > /dev/ttyS0 && cat /dev/ttyS0

上一篇
Day 26 。初入嵌入式開發- CAN 驅動開發(二)
下一篇
Day 28 。初入嵌入式開發- RS485 驅動開發
系列文
門外漢的嵌入式地獄30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言