STM32MP157C-DK2->Develop on Arm® Cortex®-A7之 C語言開發uart例程

編寫C代碼開啓STM32MP157C-DK2開發板上的uart7的接收功能,並將收到的數據打印的控制檯,並通過uart7發送出"uart"字符串。

STM32MP157C-DK2的系統只開啓了uart4作爲serial0,用於Console,如果需要使用uart7,需要在DTS中使能uart7並生成DTB,然後更新到開發板,再重啓開發板。具體步驟參考:STM32MP157C-DK2->Develop on Arm® Cortex®-A7之 開啓UART7串口功能

開發步驟可參考官方wiki教程<Create a simple hello-world application>,連接:https://wiki.st.com/stm32mpu/wiki/Getting_started/STM32MP1_boards/STM32MP157C-DK2/Develop_on_Arm%C2%AE_Cortex%C2%AE-A7/Create_a_simple_hello-world_application

以STM32MP15-Ecosystem-v1.1.0開發包爲例做講解,步驟如下:

1.創建一個目錄用於存放源代碼

caiyong@caiyong-virtual-machine:/$ mkdir $HOME/STM32MPU_workspace/STM32MP15-Ecosystem-v1.1.0/Developer-Package/stm32mp1-openstlinux-4.19-thud-mp1-19-10-09
caiyong@caiyong-virtual-machine:/$ mkdir $HOME/STM32MPU_workspace/STM32MP15-Ecosystem-v1.1.0/Developer-Package/stm32mp1-openstlinux-4.19-thud-mp1-19-10-09/sources

如果按官方步驟下載了並提取了SDK源碼,則此文件夾已經存在,不需要再創建。

2.爲例程創建一個目錄

caiyong@caiyong-virtual-machine:/$ mkdir $HOME/STM32MPU_workspace/STM32MP15-Ecosystem-v1.1.0/Developer-Package/stm32mp1-openstlinux-4.19-thud-mp1-19-10-09/sources/uart_example
caiyong@caiyong-virtual-machine:/$ cd $HOME/STM32MPU_workspace/STM32MP15-Ecosystem-v1.1.0/Developer-Package/stm32mp1-openstlinux-4.19-thud-mp1-19-10-09/sources/uart_example

3.爲例程創建一個源文件(led_toogle.c)

caiyong@caiyong-virtual-machine:~/STM32MPU_workspace/STM32MP15-Ecosystem-v1.1.0/Developer-Package/stm32mp1-openstlinux-4.19-thud-mp1-19-10-09/sources$ touch uart.c

4.編寫C代碼

在Ubuntu桌面,通過文件進入uart_example目錄,選擇uart.c文件,然後右鍵用文本編輯器打開,如下圖所示:

用文本編輯器打開uart.c後,編寫如下代碼:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <ctype.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/times.h>
#include <unistd.h>
#include <termios.h>

void set_baudrate(struct termios *set_serial, unsigned long int baud_rate)
{
    int baud = B115200;
    switch(baud_rate)
    {
        case 2400:
            baud = B2400;
            break;
        case 4800:
            baud = B4800;
            break;
        case 9600:
            baud = B9600;
            break;
        case 19200:
            baud = B19200;
            break;
        case 38400:
            baud = B38400;
            break;
        case 57600:
            baud = B57600;
            break;
        case 115200:
            baud = B115200;
            break;
        default:
            baud = B115200;
            break;
    }
    cfsetispeed(set_serial, baud);
    cfsetospeed(set_serial, baud);
}

void set_databits(struct termios *set_serial, unsigned int data_bits)
{
    switch(data_bits)
    {
        case 5:
            set_serial->c_cflag |= CS5;
            break;
        case 6:
            set_serial->c_cflag |= CS6;
            break;
        case 7:
            set_serial->c_cflag |= CS7;
            break;
        case 8:
            set_serial->c_cflag |= CS8;
            break;
        default:
            set_serial->c_cflag |= CS8;
            break;
    }
}

void set_parity(struct termios *set_serial, char parity)
{
    switch(parity)
    {
        case 'N':
            set_serial->c_cflag &= ~PARENB;     //no parity check
            break;
        case 'O':
            set_serial->c_cflag |= PARENB;      //odd check
            set_serial->c_cflag &= ~PARODD;
            break;
        case 'E':
            set_serial->c_cflag |= PARENB;      //even check
            set_serial->c_cflag |= PARODD;
            break;
        default:
            set_serial->c_cflag &= ~PARENB;
            break;
    }
}

void set_stopbits(struct termios *set_serial, unsigned int stop_bits)
{
    if(stop_bits == 2)
    {
        set_serial->c_cflag |= CSTOPB;  //2 stop bits
    }
    else
    {
        set_serial->c_cflag &= ~CSTOPB; //1 stop bits
    }
}

void set_option(int fd, unsigned int baud_rate, unsigned int data_bits, char parity, unsigned int stop_bits)
{
    struct termios opts;
    tcgetattr(fd, &opts);

    set_baudrate(&opts, baud_rate);

    opts.c_cflag |= CLOCAL|CREAD;

    set_parity(&opts, parity);
    set_stopbits(&opts, stop_bits);
    set_databits(&opts, data_bits);

    opts.c_cflag &= ~CRTSCTS;

    opts.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); //raw input
    opts.c_oflag &= ~OPOST; // raw output

    opts.c_cc[VTIME]=1;
    opts.c_cc[VMIN]=1023;

    tcsetattr(fd, TCSANOW, &opts);
}

int send_data(int fd, const char *data, int datalen)
{
    int len = 0;
    len = write(fd, data, datalen);
    if(len == datalen)
    {
        return 0;
    }
    else
    {
        tcflush(fd, TCOFLUSH);
        return -1;
    }
}

int receive(int fd, uint8_t *data, int datalen)
{
    int read_len;
    if((read_len = read(fd, data, datalen))>0)
    {
        return read_len;
    }
    else
    {
        return -1;
    }
}

int main( int argc, char *argv[])
{
    int fd;
    int ret;
    uint8_t buff[1024];
    uint8_t senddata[] = "uart";


    fd= open("/dev/ttySTM2", O_RDWR | O_NOCTTY | O_NONBLOCK);
    if(fd <= 0)
    {
        printf("uart open fail\n");
        return -1;
    }
    fcntl(fd, F_SETFL, 0);

    set_option(fd, 115200, 8, 'N', 1);


    while (1)
    {
       ret = receive(fd, buff, sizeof(buff));
       buff[ret] = 0;
       printf("receive data : %s\n", buff);

       send_data(fd, senddata, sizeof(senddata));
    }
    close(fd);
    return 0;
}

 然後關閉編輯器,選擇保存。

5.爲例程創建Makefile文件

caiyong@caiyong-virtual-machine:~/STM32MPU_workspace/STM32MP15-Ecosystem-v1.1.0/Developer-Package/stm32mp1-openstlinux-4.19-thud-mp1-19-10-19/sources/uart_example$ touch Makefile

6.編寫Makefile

  在Ubuntu桌面,通過文件進入uart_example目錄,選擇Makefile文件,然後右鍵用文本編輯器打開。用文本編輯器打開Makefile後,編寫如下內容:

PROG = uart
SRCS = uart.c
 
CLEANFILES = $(PROG)
 
# Add / change option in CFLAGS and LDFLAGS
 
all: $(PROG)
 
$(PROG): $(SRCS)
	$(CC) -o $@ $^ $(CFLAGS) $(LDFLAGS)
 
clean:
	rm -f $(CLEANFILES) $(patsubst %.c,%.o, $(SRCS))

然後關閉編輯器,選擇保存。

7.編譯工程

  先回到主目錄配置好SDK的環境變量:

caiyong@caiyong-virtual-machine:~/STM32MPU_workspace/STM32MP15-Ecosystem-v1.1.0/Developer-Package/stm32mp1-openstlinux-4.19-thud-mp1-19-10-09/sources/uart_example$ source /home/caiyong/STM32MPU_workspace/STM32MP15-Ecosystem-v1.1.0/Developer
-Package/SDK/environment-setup-cortexa7t2hf-neon-vfpv4-openstlinux_weston-linux-gnueabi 

然後執行make命令生成bin:

caiyong@caiyong-virtual-machine:~/STM32MPU_workspace/STM32MP15-Ecosystem-v1.1.0/Developer-Package/stm32mp1-openstlinux-4.19-thud-mp1-19-10-09/sources/uart_example$ make

可以看到uart_example文件夾下生成了uart可執行文件:

8.將生成的uart可執行文件拷貝到開發板的/usr/local目錄下

需要通過網絡連接來執行文件的拷貝工作,有兩種連接方式:

一種是通過USB來連接,電腦的USB口連接到開發板的CN7(USB)上,開發板作爲RNDIS(USB以太網)功能,將顯示出來的RNDIS網卡配置成192.168.7.90。(演示例程沒有使用此方式,不做詳細描述)

另一種是開發板通過網線連接到電腦所連接的路由器,路由器會爲開發板分配一個IP地址,然後電腦通過此IP地址登錄到開發板。(演示例程使用的是此方式,這樣在開發時電腦可以上網)

將開發板連接到路由器,通過串口終端獲取開發板的ip地址(在windows上使用SecureCRT):

開發板當前eth0的ip地址爲192.168.2.60。

在Ubuntu的命令終端上執行命令拷貝文件:

caiyong@caiyong-virtual-machine:~/STM32MPU_workspace/STM32MP15-Ecosystem-v1.1.0/Developer-Package/stm32mp1-openstlinux-4.19-thud-mp1-19-10-09/sources/uart_example$ scp uart [email protected]:/usr/local/
The authenticity of host '192.168.2.60 (192.168.2.60)' can't be established.
RSA key fingerprint is SHA256:fTCDMyz/jBAgyJaCs6KwGS1dkhTGcov4Cl7IQb51ffc.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.2.60' (RSA) to the list of known hosts.
uart                                          100%   19KB 385.5KB/s   00:00    

9.在開發板上執行文件

  通過串口終端進入開發板的usr/local目錄,會發現uart存在:

root@stm32mp1:~# cd /usr/local/
root@stm32mp1:/usr/local# ls
Cube-M4-examples  Linux-A7-examples  demo  lost+found  uart  weston-start-at-startup

執行uart

root@stm32mp1:/usr/local# ./uart 

10.測試uart7的收發功能

通過調試助手的發送窗口向開發板的uart7發送"123456789"字符串,可看到控制檯上顯示了"receive data : 123456789",並且調試助手的接收窗口顯示了“uart”

 

火柴棍科技工作室:www.huochaigun.top

技術交流羣

STM32MP1:861926625

ESP8266:476685983

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章