Labwindows CVI写上位机与STM32下位机通信(一)
来源:互联网 发布:那个程序员txt总攻大人 编辑:程序博客网 时间:2024/05/17 08:14
最近在用Labwindows CVI写一个多串口的上位机程序,主要实现如下功能:(1) 上位机与下位机STM32通信,上位机通过串口发送控制命令(LED矩阵图形选择、电磁阀控制信号)给下位机,下位机回发控制信息。(2)上位机通过modbus通信协议485通信接口,读取MEMS流量计瞬时流量和总流量数据,并显示到面板上。
一. STM32下位机
考虑到LED矩阵面板上有40*10个LED,要控制每只LED的亮灭来显示不同图案,这样就需要至少需要50个IO口,之所以选择STM32做下位机是因为STM32F407的GPIO达到96个,出去JTAG等一些固定用处的GPIO外,我们的板子引出了66个可自由使用的GPIO。
1.1 驱动电路
选好控制器后,我们发现当LED全亮时,电路上流过的电流会很大,假设每个LED亮时的功率为10mW,全亮的情况下功率达到了4W,STM32的GPIO最大输出电流不超过25mA,因此不能直接使用GPIO驱动,而且LED矩阵的电流不能通过STM32到地,否则会烧坏器件。最终我们选择如下驱动电路:
图1. 大电流(1A左右)驱动电路
电路中NPN管S9013极限输出电流可达500mA,当一列LED全亮时(10个),电流大概50mA;PNP管子S8550极限输出电流700mA,当一行LED全亮时,电流大概200mA,满足要求;选用这种结构的驱动电路有两个作用:(1)电流放大,提高驱动能力。(2)GPIO只控制管子的基极,但GPIO采用上拉输出,上拉电阻20K~50K,流过GPIO的电流很小,起到隔离大电流作用。
1.2 下位机编程
二.Labwindows CVI上位机
之前用过Labwindows CVI写TCP服务器作为上位机,这次试用串口通信;综合整个工程考虑,与下位机通信要用一个串口,读流量计数据要用两个串口(两个流量计),因此需要3个串口端口。上位机截图如下:
2.1 Labwindows CVI串口通信编程:
(1)配置串口,建立串口端口函数
//配置uartint CVICALLBACK PortEnable (int panel, int control, int event, void *callbackData, int eventData1, int eventData2){ switch (event) { case EVENT_COMMIT: //注意:多次打开串口会出错 uartPort.port_open = 0; //未打开 GetCtrlVal(panelHandle,PANEL_PORT_NUM,&uartPort.portNum); //获取端口号 GetCtrlIndex(panelHandle,PANEL_PORT_NUM,&uartPort.portIndex); GetLabelFromIndex(panelHandle,PANEL_PORT_NUM,uartPort.portIndex,uartPort.deviceName); DisableBreakOnLibraryErrors(); uartPort.RS232Error = OpenComConfig(uartPort.portNum,uartPort.deviceName,115200,0,8,1,512,512); //STM32控制,打开串口 EnableBreakOnLibraryErrors(); if(uartPort.RS232Error == 0) //串口打开成功 { uartPort.port_open = 1; SetXMode(uartPort.portNum,0); //关闭XOFF SetCTSMode(uartPort.portNum,0); SetComTime(uartPort.portNum,5); SetCtrlVal(panelHandle,PANEL_UART_LED,1); //点亮指示灯 //清空串口的TxBuffer、RxBuffer FlushInQ(uartPort.portNum); FlushOutQ(uartPort.portNum); //建立串口回调函数 InstallComCallback(uartPort.portNum,LWRS_RXFLAG,0,10,UartComCallback,0); //以回车为标志位,接收到回车就产生中断,调用中断函数UartComCall. } else { MessagePopup("Error","该COM口已被占用,请选择其他COM口!"); SetCtrlVal(panelHandle,PANEL_UART_LED,0); //关闭指示灯 uartPort.port_open = 0; } break; } return 0;}查看CVI中给的API知道:调用
int InstallComCallback (int Port_Number, int Event_Mask, int Notify_Count, int Event_Character, ComCallbackPtr Callback_Function, void *Callback_Data);可建立端口回调函数,注意参数:
--eventMask :可取LWRS_RXCHAR,LWRS_RXFLAG,LWRS_RECEIVE等;其中LWRS_RXCHAR表示接收1个字符放入到输入队列时就执行回调函数,但是当接收到一个字符串时,并不会每接收一个字符就调用一次回调函数;LWRS_RXFLAGS与Event_Character配合,当接收序列中有Event_Character时就会执行回调函数;LWRS_RECEIVE与notifyCount配合使用,当接收缓存中至少有notifyCount Byte个数据时,就执行回调函数,即每接收notifyCount个数据就执行一次回调函数。
--callbackFunction: 回调函数名
(2)编写端口回调函数
回调函数相当于串口中断函数,只是没有中断优先级这种的说法,只要满足执行条件就会触发回调函数执行,但回调函数的执行不能打断正在其他的其他程序,要等其他程序执行完才能执行。
//发送一个char数据void SendByte(portInfo port,char ch){ if(port.port_open == 0) MessagePopup("Error","串口还未打开!"); else { FlushOutQ(port.portNum); //清空发送缓存区 ComWrt(port.portNum,&ch,sizeof(ch)); }}void CVICALLBACK UartComCallback(int portNo, int eventMask, void *callbackData){ char readBuf[256] = {0}; int strLen; strLen = GetInQLen(uartPort.portNum); ComRd(uartPort.portNum,readBuf,strLen); SetCtrlVal(panelHandle,PANEL_RECEIVE_MESSAGE,readBuf);}
- Labwindows CVI写上位机与STM32下位机通信(一)
- Labwindows CVI写上位机与STM32下位机通信(二)
- Labwindows CVI 2013 一
- 智能车上位机与下位机通信的例子
- 【自己动手写上位机】串口通信
- LabWindows/CVI 下载与安装方法详解
- java实现上位机与下位机串口通信
- PC机与下位单片机异步串行通信
- PC机与下位单片机异步串行通信[摘]
- PC机与下位单片机异步串行通信
- labview与下位机通信的格式问题处理
- Labview通过RS422通讯接口PC与下位机通信
- Labview通过RS422通讯接口PC与下位机通信
- labwindows/CVI excel报表
- LabWindows/CVI 下载
- LabWindows/CVI线程操作
- LabWindows/CVI对话框
- Visual C++、LabVIEW、LabWindows/CVI与MATLAB接口技术[zhuan]
- 二进制表示中的1的个数
- 无人车、自动驾驶相关的文章整理
- 普及NOIP 2004 火星人
- dbcp配置
- HDU2085 核反应堆 数列 水题
- Labwindows CVI写上位机与STM32下位机通信(一)
- 利用opencv实现RGB图片滤波前和滤波后直方图显示
- Android电子拍卖系统总结四
- Linux的常用命令
- HDU2086 找规律 好心酸!!!!!
- muduo源码中的时间类
- windows下解决端口被占用
- 第九周项目2- 对称矩阵压缩存储的实现与应用(2)
- Retrofit网络框架搭建