M3通过串口多线程互斥实现流水灯

博客介绍利用线程互斥实现串口多线程收发数据以达到流水灯效果。多线程串口编程分三步,包括连接串口与开发板确定设备号、设置串口参数、进行多线程数据收发,还给出完整代码实现,并提及编译时链接线程库等注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

利用线程的互斥实现串口多线程收发数据从而达到流水灯的效果。多线程串口编程主要分为三步,第一部分,连接串口及开发板,确定设备号;第二部分为串口参数的设置;第三部分为多线程数据的收发。下方有完整代码实现。


目录

一、设置设备号及头文件

二、串口参数设置及串口收发函数

三、多线程部分(此处仅以一个线程为例)

四、整体思路

五、具体实现代码

六、注意


一、设置设备号及头文件

在连接好串口与开发板,确定接入linux下后,可输入如下命令查询当前设备号并设置设备号。

二、串口参数设置及串口收发函数

三、多线程部分(此处仅以一个线程为例)

buff数组存放应以具体协议为准:如0x3d,0x11,0x11,0x22,0x00,0x21可以亮灯1。

这里不涉及具体协议。

四、整体思路

五、具体实现代码

/*********************************************************************************
 *    Copyright:  (C) 2019 zyjin
 *                  All rights reserved.
 *
 *    Filename:  main.c
 *    Description:  多线程互斥锁点灯,一次只能亮一个,前提是M3板子要有对应的协议及程序
 *           Multi-threaded mutex lock lights, only one light at a time, provided that
 *           the M3 board has a corresponding protocol and program
 *
 *    Created by zyjin on 19-7-9.
 *
 *    Version:  1.0.0(2019年7月9日)
 *    Author:  zyjin <jzy2410723051@163.com><zzzzyjin@foxmail.com>
 *    ChangeLog:  1, Release initial version on "2019年7月9日 10时27分00秒"
 *
 ********************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <time.h>
#include <termios.h>
#include <sys/select.h>
#include <sys/types.h>
#include <pthread.h>

#define UART_DEVICE	"/dev/ttyUSB0"

static int init_ttyS(int fd_com1)
{
    struct termios newtio;  //termios结构体
    bzero(&newtio, sizeof(newtio));//将此区域置0
    tcgetattr(fd_com1, &newtio);//保存原先串口设置
    cfsetispeed(&newtio, B115200);//设置波特率
    cfsetospeed(&newtio, B115200);//设置波特率
    newtio.c_cflag |= (CLOCAL | CREAD);//激活本地连接和接受使能
    newtio.c_cflag &= ~PARENB;//设置奇偶校验位
    newtio.c_cflag &= ~CSTOPB;//设置停止位
    newtio.c_cflag &= ~CSIZE;//设置字符大小
    newtio.c_cflag |= CS8;//设置字符大小
    newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    newtio.c_oflag &= ~(OPOST);
    newtio.c_cc[VTIME]   = 0;//设置等待时间
    newtio.c_cc[VMIN]     = 0;//设置最小字符
    tcflush(fd_com1, TCIFLUSH);//刷新收到的数据但是不读
    tcsetattr(fd_com1,TCSANOW,&newtio);//激活配置,使改变的配置立即生效
    return 0;
}

pthread_mutex_t mutex;
int fd_com1;

int uart_send(int fd_com1,unsigned char * bufp, unsigned int bufsize)
{
    int r = write(fd_com1, bufp, bufsize);
    if(r > 0)
    {

        printf("%s\r\n","send success");
    }
    else  perror("error to write fd_com1");
    return 0;
}

int uart_read(int fd_com1,unsigned char * bufp, unsigned int bufsize)
{
    if(read(fd_com1, bufp, bufsize)>0)
    {
        printf("receive:%s\r\n",bufp);
    }
    else  perror("error to read fd_com1");
    return 0;
}

void *s1(char *buff)
{
    while(1)
    {
        sleep(1);
        pthread_mutex_lock(&mutex);
        buff[1] = 0X11;
        buff[2] = 0X22;
        buff[3] = 0X11;
        uart_send(fd_com1,buff,6);
        pthread_mutex_unlock(&mutex);
        sleep(3);
    }
}

void *s2(char *buff)
{
    while(1)
    {
        sleep(2);
        pthread_mutex_lock(&mutex);
        buff[1] = 0X22;
        buff[2] = 0X11;
        buff[3] = 0X11;
        uart_send(fd_com1,buff,6);
        pthread_mutex_unlock(&mutex);
        sleep(2);
    }
}

void *s3(char *buff)
{
    while(1)
    {
        sleep(3);
        pthread_mutex_lock(&mutex);
        buff[1] = 0X22;
        buff[2] = 0X22;
        buff[3] = 0X22;

        uart_send(fd_com1,buff,6);
        pthread_mutex_unlock(&mutex);
        sleep(1);
    }
}

int main(int argc,char ** argv)
{
    fd_com1 = open(UART_DEVICE, O_CREAT | O_APPEND |O_RDWR);//打开串口
    if(!fd_com1)
    {
        return 0;
    }
    init_ttyS(fd_com1);
    pthread_t id1,id2,id3;
    char buff[6] = {0x3d,0x11,0x11,0x22,0x00,0x21};
    pthread_mutex_init(&mutex,NULL);
    /*创建线程一*/
    if(pthread_create(&id1,NULL,(void *)s1,(void*) &buff))
    {
        printf("Create pthread error!\n");
        exit(1);
    }

    /*创建线程2*/
    if(pthread_create(&id2,NULL,(void *)s2,(void*) &buff))
    {
        printf ("Create pthread error!\n");
        exit (1);
    }

    /*创建线程3*/
    if(pthread_create(&id3,NULL,(void *)s3,(void*) &buff))
    {
        printf ("Create pthread error!\n");
        exit (1);
    }

    pthread_join(id1,NULL);
    pthread_join(id2,NULL);
    pthread_join(id3,NULL);
    pthread_mutex_destroy(&mutex);
    close(fd_com1);
    return 0;

}

六、注意

1)如已经在头文件中包含了线程的头文件<pthread.h>,可是编译的时候却显示对pthread_create等未定义的引用,则需使用libpthread.a库,在CMakeList.txt中加入target_link_libraries(projectname pthread),即链接线程库。

2)此处我用的是stm32f103zet6,且在板子中有对应的代码,即接收到对应的数据,做出什么反应,但此处不涉及这块内容。

3)新手小白,不喜勿喷,如有哪个地方出了错,请指出,代码中有邮箱,也可通过邮箱联系。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值