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

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