舵机调试上位机
舵机调试上位机
作者:歌者
舵机调试上位机
- 说明
- 上位机部分
- 主控部分
- 说明
- 步骤
说明
本文将详细说明利用MATLAB制作一款用于舵机调试的上位机,可以同时连接3个舵机进行控制,同时会有配合使用的主控开发教程。
上位机部分
1.打开MATLAB软件,在命令行中输入“ guide ”,打开GUI设计工具。
2.新建一个空白项目,点击确定即可。
3.从左侧工具栏中选择相关GUI图形进行防止,按自己喜好需求进行设计。
注意:放置滑动条控件后可以修改其滑动范围数值,默认为0-1.
4.右键相应控件,打开回调函数进行功能函数的编写。
·连接按钮回调函数:
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global S
global COM
global CK
COM = get(handles.edit2,'string');
CK = ['com',COM];
delete(instrfindall)
S = serial(CK,'Parity','none','BaudRate',115200,'DataBits',8,'StopBits',1);
try
fopen(S);
set(handles.text2,'string','串口连接成功')
catch
set(handles.text2,'string','串口连接失败,请检查此串口是否占用')
end
一号舵机滑动条回调函数:
function slider1_Callback(hObject, eventdata, handles)
% hObject handle to slider1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'Value') returns position of slider
% get(hObject,'Min') and get(hObject,'Max') to determine range of slider
global SLI1
global DATA1
global S
global a
SLI1=get(handles.slider1,'value');
SLI1=SLI1+10;
SLI1 = ceil(SLI1);
SLI1 = num2str(SLI1)
set(handles.edit1,'string',SLI1)
DATA1 = ['1',SLI1]
fprintf(S,'%s',DATA1);
二号舵机滑动条回调函数:
function slider2_Callback(hObject, eventdata, handles)
% hObject handle to slider2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'Value') returns position of slider
% get(hObject,'Min') and get(hObject,'Max') to determine range of slider
global SLI2
global DATA2
global S
global a
SLI2=get(handles.slider2,'value');
SLI2=SLI2+10;
SLI2 = ceil(SLI2);
SLI2 = num2str(SLI2)
set(handles.edit3,'string',SLI2)
DATA2 = ['2',SLI2]
fprintf(S,'%s',DATA2);
三号舵机滑动条回调函数:
function slider4_Callback(hObject, eventdata, handles)
% hObject handle to slider4 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: get(hObject,'Value') returns position of slider
% get(hObject,'Min') and get(hObject,'Max') to determine range of slider
global SLI4
global DATA4
global S
global a
SLI4=get(handles.slider4,'value')
SLI4=SLI4+10
SLI4 = ceil(SLI4)
SLI4 = num2str(SLI4)
set(handles.edit5,'string',SLI4)
DATA4 = ['4',SLI4]
fprintf(S,'%s',DATA4);
连接断开按钮回调函数:
function pushbutton2_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton2 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global S
try
fclose(S);
set(handles.text2,'string','串口断开成功')
catch
set(handles.text2,'string','串口断开失败')
end
由于串口占用时无法在其他地方再打开此串口,所以再连接之前要先断开其他地方的串口。
如果不知道在哪里占用了,无法关闭,则可以删除所有串口,解除占用,所以有一个删除所有按钮的功能。
删除所有串口回调函数:
function pushbutton3_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton3 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
delete(instrfindall)
set(handles.text2,'string','删除所有串口OK!')
`
5.保存,运行,即可以使用该上位机。
6.上位机展示:
-滑动滑动条,舵机就会旋转相应角度,滑动条右侧的数字为得到的计数值,可以直接使用。
至此,上位机制作完成,下面开始主控开发。
主控部分
说明
直接存储器访问(DMA)用于在外设与存储器之间以及存储器与存储器之间提供高速数据传输。可以在无需任何CPU操作的情况下通过DMA快速传输传输。这样节省的CPU资源可供其它操作使用。
DMA允许在后台执行数据传输,无需Cortex-MO处理器干预。在此操作过程中,主处理器可以执行其它任务,仅当整个数据块需要处理时,才会中断主处理器。这样即使传输大量数据也不会对系统性能造成太大影响。
DMA主要用于为不同的外设模块实现集中数据缓冲存储(通常在系统SRAM中)。与分布式解决方案(其中每个外设都需要实现自己的本地数据存储)相比,DMA解决方案在硅片成本和功耗方面的成本较低。
根据使用的产品型号的不同,有一个或两个DMA模块。
STM32F0XX DMA控制器总共有5个通道用于DMA1,每个通道都专门管理来自一个或多个外设的存储器访问请求。它具有一个仲裁器,用于处理不同的DMA请求的优先级。
这里主要介绍如何使用STM32CubeMX实现串口DMA读取,并且打印出去。
步骤
1.配置串口。
2.配置DMA
3.生成代码,进行修改:
3.1.添加头文件。
/* USER CODE BEGIN Includes */
#include "stdio.h"
/* USER CODE END Includes */
3.2.变量定义
/* USER CODE BEGIN PV */
#define BUFFERSIZE 64 //可以接收的最大字符个数
uint8_t ReceiveBuff[BUFFERSIZE]; //接收缓冲区
uint8_t recv_end_flag = 0,Rx_len;//接收完成中断标志,接收到字符长度
/* USER CODE END PV */
3.3.串口声明及重定向
/* USER CODE BEGIN PFP */
void uart1_data(void); //接收函数
#ifdef __GNUC__ //串口重定向
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart1 , (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/* USER CODE END PFP */
3.4.DMA函数
/* USER CODE BEGIN 4 */
void uart1_data(void)
{
if(recv_end_flag ==1)//接收完成标志
{
printf("数据长度=%d\r\n",Rx_len);//打印接收到的数据长度
printf("数据内容:");
for(int i=0;i<Rx_len;i++)
{
printf("%c",ReceiveBuff[i]);//向串口打印接收到的数据
}
printf("\r\n");
for(int i = 0; i < Rx_len ; i++) //清空接收缓存区
ReceiveBuff[i]=0;//置0
Rx_len=0;//接收数据长度清零
recv_end_flag=0;//接收标志位清零
}
//开启下一次接收
HAL_UART_Receive_DMA(&huart1,(uint8_t*)ReceiveBuff,BUFFERSIZE);
}
/* USER CODE END 4 */
3.5.串口中断函数。
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
uint32_t temp;
if(USART1 == huart1.Instance)//判断是否为串口1中断
{
if(RESET != __HAL_UART_GET_FLAG(&huart1,UART_FLAG_IDLE))//如果为串口1
{
__HAL_UART_CLEAR_IDLEFLAG(&huart1);//清除中断标志
HAL_UART_DMAStop(&huart1);//停止DMA接收
temp = __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);//获取DMA当前还有多少未填充
Rx_len = BUFFERSIZE - temp; //计算串口接收到的数据个数
recv_end_flag = 1;
}
}
/* USER CODE END USART1_IRQn 1 */
}
编译下载,主控部分开发完成,在主控相应端口连接舵机,打开上位机可以进行调试。