伺服电机驱动修改,取消发送缓冲区(数据缓冲和DMA缓冲),将接收缓冲区改为双缓冲区,未测试
This commit is contained in:
parent
bd1d26de10
commit
3e88c8cd50
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"workspace": {
|
||||||
|
"path": "${workspaceFolder}\\PROJECT\\OS2.eww"
|
||||||
|
},
|
||||||
|
"workspaces": {
|
||||||
|
"${workspaceFolder}\\PROJECT\\OS2.eww": {
|
||||||
|
"configs": {
|
||||||
|
"${workspaceFolder}\\PROJECT\\OS2.ewp": "Debug"
|
||||||
|
},
|
||||||
|
"selected": {
|
||||||
|
"path": "${workspaceFolder}\\PROJECT\\OS2.ewp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"workbench": {
|
||||||
|
"path": "D:\\IAR"
|
||||||
|
}
|
||||||
|
}
|
|
@ -46,6 +46,16 @@
|
||||||
"comm_cfginfo.h": "c",
|
"comm_cfginfo.h": "c",
|
||||||
"servomotor.h": "c",
|
"servomotor.h": "c",
|
||||||
"pdebug.h": "c",
|
"pdebug.h": "c",
|
||||||
"limits": "c"
|
"limits": "c",
|
||||||
|
"motorcommu.h": "c",
|
||||||
|
"stdbool.h": "c",
|
||||||
|
"cfifo.h": "c",
|
||||||
|
"servomotor_recv.h": "c",
|
||||||
|
"ucos_ii.h": "c",
|
||||||
|
"__config": "c",
|
||||||
|
"utility": "c",
|
||||||
|
"exception": "c",
|
||||||
|
"new": "c",
|
||||||
|
"cstdio": "c"
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
#include "ptz_header_file.h"
|
#include "ptz_header_file.h"
|
||||||
#include "servoMotor.h"
|
#include "servoMotor.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef PTZ_SERVO_MOTOR
|
#ifdef PTZ_SERVO_MOTOR
|
||||||
|
|
||||||
//电机数据解析任务互斥量
|
//电机数据解析任务互斥量
|
||||||
|
|
|
@ -1,15 +1,16 @@
|
||||||
#ifndef __DEVICE_SPEED_SERVOMOTOR_H_
|
#ifndef __SERVOMOTOR_RECV_H_
|
||||||
#define __DEVICE_SPEED_SERVOMOTOR_H_
|
#define __SERVOMOTOR_RECV_H_
|
||||||
#include "ptz_type_select.h"
|
#include "ptz_type_select.h"
|
||||||
|
#include "bsp_os.h"
|
||||||
|
|
||||||
|
#ifdef PTZ_SERVO_MOTOR
|
||||||
|
|
||||||
|
extern BSP_OS_SEM g_horiMotorMutex;
|
||||||
|
extern BSP_OS_SEM g_vertMotorMutex;
|
||||||
|
|
||||||
|
void Init_ServoMotorRecv(void);
|
||||||
|
|
||||||
|
|
||||||
#ifdef PTZ_SERVO_MOTOR
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Init_ServoMotorRecv(void);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#include "motorCommu.h"
|
#include "motorCommu.h"
|
||||||
|
#include "servoMotor_recv.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
********************************************************************************************************
|
********************************************************************************************************
|
||||||
|
@ -99,11 +98,12 @@ static MotorCommuDmaHwInfo_t g_MotorDmaBuff[] =
|
||||||
* 电机串口通讯缓冲区初始化结构体
|
* 电机串口通讯缓冲区初始化结构体
|
||||||
********************************************************************************************************
|
********************************************************************************************************
|
||||||
*/
|
*/
|
||||||
/* dma发送与接收缓冲区 */
|
/* dma接收缓冲区 */
|
||||||
static uint8_t g_horiDmaTxBuff[DMA_BUFF_SIZE] = {0};//水平电机DMA发送缓存区
|
static uint8_t g_horiDmaRxBuff1[DMA_BUFF_SIZE] = {0};//水平电机DMA接受缓存区1
|
||||||
static uint8_t g_horiDmaRxBuff[DMA_BUFF_SIZE] = {0};//水平电机DMA接受缓存区
|
static uint8_t g_horiDmaRxBuff2[DMA_BUFF_SIZE] = {0};//水平电机DMA接受缓存区2
|
||||||
static uint8_t g_vertDmaTxBuff[DMA_BUFF_SIZE] = {0};//垂直电机DMA发送缓存区
|
|
||||||
static uint8_t g_vertDmaRxBuff[DMA_BUFF_SIZE] = {0};//垂直电机DMA接受缓存区
|
static uint8_t g_vertDmaRxBuff1[DMA_BUFF_SIZE] = {0};//垂直电机DMA接受缓存区1
|
||||||
|
static uint8_t g_vertDmaRxBuff2[DMA_BUFF_SIZE] = {0};//垂直电机DMA接受缓存区2
|
||||||
/* 处理串口通讯与数据缓冲的数据结构 */
|
/* 处理串口通讯与数据缓冲的数据结构 */
|
||||||
static CommuInfo_t g_horiCommuDeal; //水平电机
|
static CommuInfo_t g_horiCommuDeal; //水平电机
|
||||||
static CommuInfo_t g_vertCommuDeal; //垂直电机
|
static CommuInfo_t g_vertCommuDeal; //垂直电机
|
||||||
|
@ -111,22 +111,22 @@ static CommuInfo_t g_vertCommuDeal; //
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
CommuInfo_t* pCommuInfo; //串口通讯与数据缓冲相关的数据结构
|
CommuInfo_t* pCommuInfo; //串口通讯与数据缓冲相关的数据结构
|
||||||
uint8_t* dmaTxBuff; //dma发送缓存区指针
|
uint8_t* dmaRxBuff1; //dma接受缓存区1指针
|
||||||
uint8_t* dmaRxBuff; //dma接受缓存区指针
|
uint8_t* dmaRxBuff2; //dma接受缓存区2指针
|
||||||
}CommuHwInfo_t;//方便缓冲区初始化的结构体
|
}CommuHwInfo_t;//方便缓冲区初始化的结构体
|
||||||
static CommuHwInfo_t g_commuInfoBuff[] =
|
static CommuHwInfo_t g_commuInfoBuff[] =
|
||||||
{
|
{
|
||||||
//水平电机
|
//水平电机
|
||||||
{
|
{
|
||||||
.pCommuInfo = &g_horiCommuDeal,
|
.pCommuInfo = &g_horiCommuDeal,
|
||||||
.dmaTxBuff = g_horiDmaTxBuff,
|
.dmaRxBuff1 = g_horiDmaRxBuff1,
|
||||||
.dmaRxBuff = g_horiDmaRxBuff,
|
.dmaRxBuff2 = g_horiDmaRxBuff2,
|
||||||
},
|
},
|
||||||
//垂直电机串口5
|
//垂直电机串口5
|
||||||
{
|
{
|
||||||
.pCommuInfo = &g_vertCommuDeal,
|
.pCommuInfo = &g_vertCommuDeal,
|
||||||
.dmaTxBuff = g_vertDmaTxBuff,
|
.dmaRxBuff1 = g_vertDmaRxBuff1,
|
||||||
.dmaRxBuff = g_vertDmaRxBuff,
|
.dmaRxBuff2 = g_vertDmaRxBuff2,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -219,7 +219,7 @@ static void DmaCofig(void)
|
||||||
//dma配置
|
//dma配置
|
||||||
dma_deinit(g_MotorDmaBuff[i].dmaNo, g_MotorDmaBuff[i].dmaRxch);
|
dma_deinit(g_MotorDmaBuff[i].dmaNo, g_MotorDmaBuff[i].dmaRxch);
|
||||||
dmaStruct.direction = DMA_PERIPH_TO_MEMORY;
|
dmaStruct.direction = DMA_PERIPH_TO_MEMORY;
|
||||||
dmaStruct.memory0_addr = (uint32_t)(g_commuInfoBuff[i].pCommuInfo->pDmaRsvBuff);
|
dmaStruct.memory0_addr = (uint32_t)(g_commuInfoBuff[i].pCommuInfo->pDmaRsvBuff1);
|
||||||
dmaStruct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
|
dmaStruct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
|
||||||
dmaStruct.number = DMA_BUFF_SIZE;
|
dmaStruct.number = DMA_BUFF_SIZE;
|
||||||
dmaStruct.periph_addr = g_MotorDmaBuff[i].periphAddr;
|
dmaStruct.periph_addr = g_MotorDmaBuff[i].periphAddr;
|
||||||
|
@ -229,7 +229,7 @@ static void DmaCofig(void)
|
||||||
dma_memory_width_config(g_MotorDmaBuff[i].dmaNo, g_MotorDmaBuff[i].dmaRxch, DMA_MEMORY_WIDTH_8BIT);
|
dma_memory_width_config(g_MotorDmaBuff[i].dmaNo, g_MotorDmaBuff[i].dmaRxch, DMA_MEMORY_WIDTH_8BIT);
|
||||||
dma_periph_width_config(g_MotorDmaBuff[i].dmaNo, g_MotorDmaBuff[i].dmaRxch, DMA_PERIPH_WIDTH_8BIT);
|
dma_periph_width_config(g_MotorDmaBuff[i].dmaNo, g_MotorDmaBuff[i].dmaRxch, DMA_PERIPH_WIDTH_8BIT);
|
||||||
dma_single_data_mode_init(g_MotorDmaBuff[i].dmaNo, g_MotorDmaBuff[i].dmaRxch, &dmaStruct);
|
dma_single_data_mode_init(g_MotorDmaBuff[i].dmaNo, g_MotorDmaBuff[i].dmaRxch, &dmaStruct);
|
||||||
dma_circulation_enable(g_MotorDmaBuff[i].dmaNo, g_MotorDmaBuff[i].dmaRxch);//循环模式
|
dma_circulation_disable(g_MotorDmaBuff[i].dmaNo, g_MotorDmaBuff[i].dmaRxch);//非循环模式
|
||||||
dma_channel_subperipheral_select(g_MotorDmaBuff[i].dmaNo, g_MotorDmaBuff[i].dmaRxch, g_MotorDmaBuff[i].dmaPeriph);
|
dma_channel_subperipheral_select(g_MotorDmaBuff[i].dmaNo, g_MotorDmaBuff[i].dmaRxch, g_MotorDmaBuff[i].dmaPeriph);
|
||||||
//中断配置
|
//中断配置
|
||||||
nvic_irq_enable(g_MotorDmaBuff[i].dmaRxIrq, 4, 2);
|
nvic_irq_enable(g_MotorDmaBuff[i].dmaRxIrq, 4, 2);
|
||||||
|
@ -244,7 +244,7 @@ static void DmaCofig(void)
|
||||||
********************************************************************************************************
|
********************************************************************************************************
|
||||||
*/
|
*/
|
||||||
/*!
|
/*!
|
||||||
\brief 初始化串口的缓冲区指针、DMA的空间大小、DMA偏移量、发送接收队列的初始化
|
\brief 初始化串口的缓冲区
|
||||||
\param[in] none
|
\param[in] none
|
||||||
\param[out] none
|
\param[out] none
|
||||||
\retval none
|
\retval none
|
||||||
|
@ -255,13 +255,11 @@ static void CommuStructInit()
|
||||||
{
|
{
|
||||||
/*为属性的参数附初值*/
|
/*为属性的参数附初值*/
|
||||||
CommuInfo_t *pCommuDeal = g_commuInfoBuff[i].pCommuInfo;
|
CommuInfo_t *pCommuDeal = g_commuInfoBuff[i].pCommuInfo;
|
||||||
pCommuDeal->dmaOffset = 0;
|
|
||||||
pCommuDeal->dmaTranFlag = DMA_TRANS_IDLE;
|
pCommuDeal->dmaTranFlag = DMA_TRANS_IDLE;
|
||||||
pCommuDeal->dmaSize = DMA_BUFF_SIZE;
|
pCommuDeal->dmaSize = DMA_BUFF_SIZE;
|
||||||
pCommuDeal->pDmaRsvBuff = g_commuInfoBuff[i].dmaRxBuff;
|
pCommuDeal->pDmaRsvBuff1 = g_commuInfoBuff[i].dmaRxBuff1;
|
||||||
pCommuDeal->pDmaTraBuff = g_commuInfoBuff[i].dmaTxBuff;
|
pCommuDeal->pDmaRsvBuff2 = g_commuInfoBuff[i].dmaRxBuff2;
|
||||||
CfifoBuffInit(&pCommuDeal->dataRsvCfifo); //用于数据接受
|
pCommuDeal->pDmaRsvBuffSelect = DMA_RSVBUFF_SELECT1;//默认使用缓冲区1
|
||||||
CfifoBuffInit(&pCommuDeal->dataTraCfifo); //用于数据发送
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,26 +303,15 @@ void DMA0_Channel3_IRQHandler(void)
|
||||||
* 配合串口的发送。功能是继续发送缓冲区未发送的数据。
|
* 配合串口的发送。功能是继续发送缓冲区未发送的数据。
|
||||||
* 发送完成配置的CNT次数后,会进入此中断函数
|
* 发送完成配置的CNT次数后,会进入此中断函数
|
||||||
*/
|
*/
|
||||||
int32_t TransNum = 0;//从&pCommuDeal->dataTraCfifo.BUFF[]中获取多少数据
|
|
||||||
if(dma_interrupt_flag_get(g_MotorDmaBuff[H_MOTOR].dmaNo, g_MotorDmaBuff[H_MOTOR].dmaTxch, DMA_INT_FLAG_FTF))
|
if(dma_interrupt_flag_get(g_MotorDmaBuff[H_MOTOR].dmaNo, g_MotorDmaBuff[H_MOTOR].dmaTxch, DMA_INT_FLAG_FTF))
|
||||||
{
|
{
|
||||||
dma_interrupt_flag_clear(g_MotorDmaBuff[H_MOTOR].dmaNo, g_MotorDmaBuff[H_MOTOR].dmaTxch, DMA_INT_FLAG_FTF);
|
dma_interrupt_flag_clear(g_MotorDmaBuff[H_MOTOR].dmaNo, g_MotorDmaBuff[H_MOTOR].dmaTxch, DMA_INT_FLAG_FTF);
|
||||||
|
|
||||||
CommuInfo_t *pCommuDeal = g_commuInfoBuff[H_MOTOR].pCommuInfo;
|
CommuInfo_t *pCommuDeal = g_commuInfoBuff[H_MOTOR].pCommuInfo;
|
||||||
|
|
||||||
/*从发送循环缓冲区中获取数据*/
|
|
||||||
TransNum = CfifoBuffRead(&pCommuDeal->dataTraCfifo,(char *)(pCommuDeal->pDmaTraBuff),pCommuDeal->dmaSize);
|
|
||||||
if(TransNum > 0)
|
|
||||||
{
|
|
||||||
CommuDmaTra(H_MOTOR, pCommuDeal->pDmaTraBuff, TransNum);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while(usart_flag_get(g_motorCommuBuff[H_MOTOR].uartNo, USART_FLAG_TC) == RESET); // 等待串口发送完成
|
while(usart_flag_get(g_motorCommuBuff[H_MOTOR].uartNo, USART_FLAG_TC) == RESET); // 等待串口发送完成
|
||||||
H_COMMU_RS485_RX; //485切换为接收
|
H_COMMU_RS485_RX; //485切换为接收
|
||||||
pCommuDeal->dmaTranFlag = DMA_TRANS_IDLE;
|
pCommuDeal->dmaTranFlag = DMA_TRANS_IDLE;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -334,43 +321,47 @@ void DMA0_Channel3_IRQHandler(void)
|
||||||
* @return
|
* @return
|
||||||
***********************************************************
|
***********************************************************
|
||||||
*/
|
*/
|
||||||
static uint16_t g_hFrameRcvNum = 0;
|
|
||||||
void USART2_IRQHandler(void)
|
void USART2_IRQHandler(void)
|
||||||
{
|
{
|
||||||
/* 串口的接收空闲中断方式进行了数据缓存。*/
|
/* 串口的接收空闲中断方式进行了数据缓存。*/
|
||||||
int32_t RecvNum = 0;//dma缓冲区收到多少数据
|
dma_single_data_parameter_struct dmaStruct;
|
||||||
int32_t WriteNum = 0;//向数据循环接收区写入的数据数,正常WriteNum==RecvNum
|
|
||||||
int32_t DmaIdleNum = 0;//dmasize减已经传输的数据就是DmaIdleNum
|
|
||||||
if(RESET != usart_interrupt_flag_get(g_motorCommuBuff[H_MOTOR].uartNo, USART_INT_FLAG_IDLE))
|
if(RESET != usart_interrupt_flag_get(g_motorCommuBuff[H_MOTOR].uartNo, USART_INT_FLAG_IDLE))
|
||||||
{
|
{
|
||||||
/* clear IDLE flag */
|
/* clear IDLE flag */
|
||||||
usart_interrupt_flag_clear(g_motorCommuBuff[H_MOTOR].uartNo, USART_INT_FLAG_IDLE); //第一步,读取stat0寄存器,清除IDLE标志位
|
usart_interrupt_flag_clear(g_motorCommuBuff[H_MOTOR].uartNo, USART_INT_FLAG_IDLE); //第一步,读取stat0寄存器,清除IDLE标志位
|
||||||
usart_data_receive(g_motorCommuBuff[H_MOTOR].uartNo); //第二步,读取数据寄存器,清除IDLE标志位
|
usart_data_receive(g_motorCommuBuff[H_MOTOR].uartNo); //第二步,读取数据寄存器,清除IDLE标志位
|
||||||
|
|
||||||
g_hFrameRcvNum++;
|
//释放信号量,通知接收到一包数据,任务可以处理了
|
||||||
|
OSSemPost(g_horiMotorMutex);
|
||||||
CommuInfo_t *pCommuDeal = g_commuInfoBuff[H_MOTOR].pCommuInfo;
|
CommuInfo_t *pCommuDeal = g_commuInfoBuff[H_MOTOR].pCommuInfo;
|
||||||
|
/* 切换使用接收缓冲区,这样上层的解析永远从第一个字节起*/
|
||||||
|
if ( pCommuDeal->pDmaRsvBuffSelect == DMA_RSVBUFF_SELECT1 )
|
||||||
|
{
|
||||||
|
pCommuDeal->pDmaRsvBuffSelect = DMA_RSVBUFF_SELECT2;
|
||||||
|
dma_channel_disable(g_MotorDmaBuff[H_MOTOR].dmaNo, g_MotorDmaBuff[H_MOTOR].dmaRxch);//切换缓冲区,配置缓冲区长度需要先禁用DMA
|
||||||
|
dmaStruct.memory0_addr = (uint32_t)(pCommuDeal->pDmaRsvBuff2);
|
||||||
|
dma_single_data_mode_init(g_MotorDmaBuff[H_MOTOR].dmaNo, g_MotorDmaBuff[H_MOTOR].dmaRxch, &dmaStruct);
|
||||||
|
dma_channel_enable(g_MotorDmaBuff[H_MOTOR].dmaNo, g_MotorDmaBuff[H_MOTOR].dmaRxch);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pCommuDeal->pDmaRsvBuffSelect = DMA_RSVBUFF_SELECT1;
|
||||||
|
dma_channel_disable(g_MotorDmaBuff[H_MOTOR].dmaNo, g_MotorDmaBuff[H_MOTOR].dmaRxch);//切换缓冲区,配置缓冲区长度需要先禁用DMA
|
||||||
|
dmaStruct.memory0_addr = (uint32_t)(pCommuDeal->pDmaRsvBuff1);
|
||||||
|
dma_single_data_mode_init(g_MotorDmaBuff[H_MOTOR].dmaNo, g_MotorDmaBuff[H_MOTOR].dmaRxch, &dmaStruct);
|
||||||
|
dma_channel_enable(g_MotorDmaBuff[H_MOTOR].dmaNo, g_MotorDmaBuff[H_MOTOR].dmaRxch);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*计算在DMA缓冲区需要获取的数据长度*/
|
/*计算在DMA缓冲区需要获取的数据长度*/
|
||||||
DmaIdleNum = dma_transfer_number_get(g_MotorDmaBuff[H_MOTOR].dmaNo, g_MotorDmaBuff[H_MOTOR].dmaRxch);//获取的是还有多少个没传输,而不是已经传输了多少
|
// DmaIdleNum = dma_transfer_number_get(g_MotorDmaBuff[H_MOTOR].dmaNo, g_MotorDmaBuff[H_MOTOR].dmaRxch);//获取的是还有多少个没传输,而不是已经传输了多少
|
||||||
RecvNum = pCommuDeal->dmaSize - DmaIdleNum - pCommuDeal->dmaOffset;
|
|
||||||
/*将获取到的数据放到数据接收缓冲区中*/
|
|
||||||
WriteNum = CfifoBuffWrite(&pCommuDeal->dataRsvCfifo,(char *)(pCommuDeal->pDmaRsvBuff + pCommuDeal->dmaOffset), RecvNum);
|
|
||||||
|
|
||||||
if(WriteNum != RecvNum)
|
|
||||||
{
|
|
||||||
printf("Uart ReadFifo is not enough\r\n");
|
|
||||||
}
|
|
||||||
/*计算获取数据位置的偏移量*/
|
|
||||||
pCommuDeal->dmaOffset += RecvNum;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DMA0_Channel1_IRQHandler(void)
|
void DMA0_Channel1_IRQHandler(void)
|
||||||
{
|
{
|
||||||
int32_t RecvNum = 0;
|
dma_single_data_parameter_struct dmaStruct;
|
||||||
int32_t WriteNum = 0;
|
|
||||||
/*
|
/*
|
||||||
* 配合串口1的接收空闲中断。功能是复位DMA的偏移量
|
* 配合串口1的接收空闲中断。功能是复位DMA的偏移量
|
||||||
* 1、为了串口1的空闲中断在处理数据时防止越界,将 pUartAttr->DamOffset置为0;
|
* 1、为了串口1的空闲中断在处理数据时防止越界,将 pUartAttr->DamOffset置为0;
|
||||||
|
@ -383,17 +374,28 @@ void DMA0_Channel1_IRQHandler(void)
|
||||||
dma_interrupt_flag_clear(g_MotorDmaBuff[H_MOTOR].dmaNo, g_MotorDmaBuff[H_MOTOR].dmaRxch, DMA_INT_FLAG_FTF);
|
dma_interrupt_flag_clear(g_MotorDmaBuff[H_MOTOR].dmaNo, g_MotorDmaBuff[H_MOTOR].dmaRxch, DMA_INT_FLAG_FTF);
|
||||||
|
|
||||||
CommuInfo_t *pCommuDeal = g_commuInfoBuff[H_MOTOR].pCommuInfo;
|
CommuInfo_t *pCommuDeal = g_commuInfoBuff[H_MOTOR].pCommuInfo;
|
||||||
|
//释放信号量,通知接收到一包数据,任务可以处理了
|
||||||
/* 将dma缓冲马上传输完成剩余最后一截子的数据,拷贝到缓冲区中,在进行偏移量的复位 */
|
OSSemPost(g_horiMotorMutex);
|
||||||
RecvNum = pCommuDeal->dmaSize - pCommuDeal->dmaOffset;
|
/* 切换使用接收缓冲区,这样上层的解析永远从第一个字节起*/
|
||||||
/*将获取到的数据放到数据接收缓冲区中*/
|
if ( pCommuDeal->pDmaRsvBuffSelect == DMA_RSVBUFF_SELECT1 )
|
||||||
WriteNum = CfifoBuffWrite(&pCommuDeal->dataRsvCfifo,(char *)(pCommuDeal->pDmaRsvBuff + pCommuDeal->dmaOffset), RecvNum);
|
|
||||||
if(WriteNum != RecvNum)
|
|
||||||
{
|
{
|
||||||
/*add deal here*/
|
pCommuDeal->pDmaRsvBuffSelect = DMA_RSVBUFF_SELECT2;
|
||||||
|
dma_channel_disable(g_MotorDmaBuff[H_MOTOR].dmaNo, g_MotorDmaBuff[H_MOTOR].dmaRxch);//切换缓冲区,配置缓冲区长度需要先禁用DMA
|
||||||
|
dmaStruct.memory0_addr = (uint32_t)(pCommuDeal->pDmaRsvBuff2);
|
||||||
|
dmaStruct.number = DMA_BUFF_SIZE;
|
||||||
|
dma_single_data_mode_init(g_MotorDmaBuff[H_MOTOR].dmaNo, g_MotorDmaBuff[H_MOTOR].dmaRxch, &dmaStruct);
|
||||||
|
dma_channel_enable(g_MotorDmaBuff[H_MOTOR].dmaNo, g_MotorDmaBuff[H_MOTOR].dmaRxch);
|
||||||
}
|
}
|
||||||
/*复位DMA偏移量*/
|
else
|
||||||
pCommuDeal->dmaOffset = 0;
|
{
|
||||||
|
pCommuDeal->pDmaRsvBuffSelect = DMA_RSVBUFF_SELECT1;
|
||||||
|
dma_channel_disable(g_MotorDmaBuff[H_MOTOR].dmaNo, g_MotorDmaBuff[H_MOTOR].dmaRxch);//切换缓冲区,配置缓冲区长度需要先禁用DMA
|
||||||
|
dmaStruct.memory0_addr = (uint32_t)(pCommuDeal->pDmaRsvBuff1);
|
||||||
|
dmaStruct.number = DMA_BUFF_SIZE;
|
||||||
|
dma_single_data_mode_init(g_MotorDmaBuff[H_MOTOR].dmaNo, g_MotorDmaBuff[H_MOTOR].dmaRxch, &dmaStruct);
|
||||||
|
dma_channel_enable(g_MotorDmaBuff[H_MOTOR].dmaNo, g_MotorDmaBuff[H_MOTOR].dmaRxch);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -414,27 +416,16 @@ void DMA1_Channel7_IRQHandler(void)
|
||||||
* 配合串口的发送。功能是继续发送缓冲区未发送的数据。
|
* 配合串口的发送。功能是继续发送缓冲区未发送的数据。
|
||||||
* 发送完成配置的CNT次数后,会进入此中断函数
|
* 发送完成配置的CNT次数后,会进入此中断函数
|
||||||
*/
|
*/
|
||||||
int32_t TransNum = 0;//从&pCommuDeal->dataTraCfifo.BUFF[]中获取多少数据
|
|
||||||
if(dma_interrupt_flag_get(g_MotorDmaBuff[V_MOTOR].dmaNo, g_MotorDmaBuff[V_MOTOR].dmaTxch, DMA_INT_FLAG_FTF))
|
if(dma_interrupt_flag_get(g_MotorDmaBuff[V_MOTOR].dmaNo, g_MotorDmaBuff[V_MOTOR].dmaTxch, DMA_INT_FLAG_FTF))
|
||||||
{
|
{
|
||||||
dma_interrupt_flag_clear(g_MotorDmaBuff[V_MOTOR].dmaNo, g_MotorDmaBuff[V_MOTOR].dmaTxch, DMA_INT_FLAG_FTF);
|
dma_interrupt_flag_clear(g_MotorDmaBuff[V_MOTOR].dmaNo, g_MotorDmaBuff[V_MOTOR].dmaTxch, DMA_INT_FLAG_FTF);
|
||||||
|
|
||||||
CommuInfo_t *pCommuDeal = g_commuInfoBuff[V_MOTOR].pCommuInfo;
|
CommuInfo_t *pCommuDeal = g_commuInfoBuff[V_MOTOR].pCommuInfo;
|
||||||
|
|
||||||
/*从发送循环缓冲区中获取数据*/
|
|
||||||
TransNum = CfifoBuffRead(&pCommuDeal->dataTraCfifo,(char *)(pCommuDeal->pDmaTraBuff),pCommuDeal->dmaSize);
|
|
||||||
if(TransNum > 0)
|
|
||||||
{
|
|
||||||
CommuDmaTra(V_MOTOR, pCommuDeal->pDmaTraBuff, TransNum);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while(usart_flag_get(g_motorCommuBuff[V_MOTOR].uartNo, USART_FLAG_TC) == RESET); // 等待串口发送完成
|
while(usart_flag_get(g_motorCommuBuff[V_MOTOR].uartNo, USART_FLAG_TC) == RESET); // 等待串口发送完成
|
||||||
V_COMMU_RS485_RX; //485切换为接收
|
V_COMMU_RS485_RX; //485切换为接收
|
||||||
pCommuDeal->dmaTranFlag = DMA_TRANS_IDLE;
|
pCommuDeal->dmaTranFlag = DMA_TRANS_IDLE;
|
||||||
}
|
|
||||||
// pCommuDeal->dmaTranFlag = DMA_TRANS_IDLE;
|
|
||||||
// V_COMMU_RS485_RX; //485切换为接收
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,35 +436,36 @@ void DMA1_Channel7_IRQHandler(void)
|
||||||
* @return
|
* @return
|
||||||
***********************************************************
|
***********************************************************
|
||||||
*/
|
*/
|
||||||
static uint16_t g_vFrameRcvNum = 0;
|
|
||||||
void USART5_IRQHandler(void)
|
void USART5_IRQHandler(void)
|
||||||
{
|
{
|
||||||
|
dma_single_data_parameter_struct dmaStruct;
|
||||||
/* 串口的接收空闲中断方式进行了数据缓存。*/
|
/* 串口的接收空闲中断方式进行了数据缓存。*/
|
||||||
int32_t RecvNum = 0;//dma缓冲区收到多少数据
|
|
||||||
int32_t WriteNum = 0;//向数据循环接收区写入的数据数,正常WriteNum==RecvNum
|
|
||||||
int32_t DmaIdleNum = 0;//dmasize减已经传输的数据就是DmaIdleNum
|
|
||||||
if(RESET != usart_interrupt_flag_get(g_motorCommuBuff[V_MOTOR].uartNo, USART_INT_FLAG_IDLE))
|
if(RESET != usart_interrupt_flag_get(g_motorCommuBuff[V_MOTOR].uartNo, USART_INT_FLAG_IDLE))
|
||||||
{
|
{
|
||||||
/* clear IDLE flag */
|
/* clear IDLE flag */
|
||||||
usart_interrupt_flag_clear(g_motorCommuBuff[V_MOTOR].uartNo, USART_INT_FLAG_IDLE); //第一步,读取stat0寄存器,清除IDLE标志位
|
usart_interrupt_flag_clear(g_motorCommuBuff[V_MOTOR].uartNo, USART_INT_FLAG_IDLE); //第一步,读取stat0寄存器,清除IDLE标志位
|
||||||
usart_data_receive(g_motorCommuBuff[V_MOTOR].uartNo); //第二步,读取数据寄存器,清除IDLE标志位
|
usart_data_receive(g_motorCommuBuff[V_MOTOR].uartNo); //第二步,读取数据寄存器,清除IDLE标志位
|
||||||
|
|
||||||
g_vFrameRcvNum++;
|
//释放信号量,通知接收到一包数据,任务可以处理了
|
||||||
|
OSSemPost(g_horiMotorMutex);
|
||||||
CommuInfo_t *pCommuDeal = g_commuInfoBuff[V_MOTOR].pCommuInfo;
|
CommuInfo_t *pCommuDeal = g_commuInfoBuff[V_MOTOR].pCommuInfo;
|
||||||
|
/* 切换使用接收缓冲区,这样上层的解析永远从第一个字节起*/
|
||||||
/*计算在DMA缓冲区需要获取的数据长度*/
|
if ( pCommuDeal->pDmaRsvBuffSelect == DMA_RSVBUFF_SELECT1 )
|
||||||
DmaIdleNum = dma_transfer_number_get(g_MotorDmaBuff[V_MOTOR].dmaNo, g_MotorDmaBuff[V_MOTOR].dmaRxch);//获取的是还有多少个没传输,而不是已经传输了多少
|
|
||||||
RecvNum = pCommuDeal->dmaSize - DmaIdleNum - pCommuDeal->dmaOffset;
|
|
||||||
/*将获取到的数据放到数据接收缓冲区中*/
|
|
||||||
WriteNum = CfifoBuffWrite(&pCommuDeal->dataRsvCfifo,(char *)(pCommuDeal->pDmaRsvBuff + pCommuDeal->dmaOffset), RecvNum);
|
|
||||||
|
|
||||||
if(WriteNum != RecvNum)
|
|
||||||
{
|
{
|
||||||
printf("Uart ReadFifo is not enough\r\n");
|
pCommuDeal->pDmaRsvBuffSelect = DMA_RSVBUFF_SELECT2;
|
||||||
|
dma_channel_disable(g_MotorDmaBuff[V_MOTOR].dmaNo, g_MotorDmaBuff[V_MOTOR].dmaRxch);//切换缓冲区,配置缓冲区长度需要先禁用DMA
|
||||||
|
dmaStruct.memory0_addr = (uint32_t)(pCommuDeal->pDmaRsvBuff2);
|
||||||
|
dma_single_data_mode_init(g_MotorDmaBuff[V_MOTOR].dmaNo, g_MotorDmaBuff[V_MOTOR].dmaRxch, &dmaStruct);
|
||||||
|
dma_channel_enable(g_MotorDmaBuff[V_MOTOR].dmaNo, g_MotorDmaBuff[V_MOTOR].dmaRxch);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pCommuDeal->pDmaRsvBuffSelect = DMA_RSVBUFF_SELECT1;
|
||||||
|
dma_channel_disable(g_MotorDmaBuff[V_MOTOR].dmaNo, g_MotorDmaBuff[V_MOTOR].dmaRxch);//切换缓冲区,配置缓冲区长度需要先禁用DMA
|
||||||
|
dmaStruct.memory0_addr = (uint32_t)(pCommuDeal->pDmaRsvBuff1);
|
||||||
|
dma_single_data_mode_init(g_MotorDmaBuff[V_MOTOR].dmaNo, g_MotorDmaBuff[V_MOTOR].dmaRxch, &dmaStruct);
|
||||||
|
dma_channel_enable(g_MotorDmaBuff[V_MOTOR].dmaNo, g_MotorDmaBuff[V_MOTOR].dmaRxch);
|
||||||
}
|
}
|
||||||
/*计算获取数据位置的偏移量*/
|
|
||||||
pCommuDeal->dmaOffset += RecvNum;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,8 +473,7 @@ void USART5_IRQHandler(void)
|
||||||
// uint8_t rx_OK = 0;
|
// uint8_t rx_OK = 0;
|
||||||
void DMA1_Channel1_IRQHandler(void)
|
void DMA1_Channel1_IRQHandler(void)
|
||||||
{
|
{
|
||||||
int32_t RecvNum = 0;
|
dma_single_data_parameter_struct dmaStruct;
|
||||||
int32_t WriteNum = 0;
|
|
||||||
/*
|
/*
|
||||||
* 配合串口1的接收空闲中断。功能是复位DMA的偏移量
|
* 配合串口1的接收空闲中断。功能是复位DMA的偏移量
|
||||||
* 1、为了串口1的空闲中断在处理数据时防止越界,将 pUartAttr->DamOffset置为0;
|
* 1、为了串口1的空闲中断在处理数据时防止越界,将 pUartAttr->DamOffset置为0;
|
||||||
|
@ -493,20 +484,31 @@ void DMA1_Channel1_IRQHandler(void)
|
||||||
if(dma_interrupt_flag_get(g_MotorDmaBuff[V_MOTOR].dmaNo, g_MotorDmaBuff[V_MOTOR].dmaRxch, DMA_INT_FLAG_FTF))
|
if(dma_interrupt_flag_get(g_MotorDmaBuff[V_MOTOR].dmaNo, g_MotorDmaBuff[V_MOTOR].dmaRxch, DMA_INT_FLAG_FTF))
|
||||||
{
|
{
|
||||||
dma_interrupt_flag_clear(g_MotorDmaBuff[V_MOTOR].dmaNo, g_MotorDmaBuff[V_MOTOR].dmaRxch, DMA_INT_FLAG_FTF);
|
dma_interrupt_flag_clear(g_MotorDmaBuff[V_MOTOR].dmaNo, g_MotorDmaBuff[V_MOTOR].dmaRxch, DMA_INT_FLAG_FTF);
|
||||||
// rx_OK++;
|
|
||||||
|
|
||||||
CommuInfo_t *pCommuDeal = g_commuInfoBuff[V_MOTOR].pCommuInfo;
|
CommuInfo_t *pCommuDeal = g_commuInfoBuff[V_MOTOR].pCommuInfo;
|
||||||
|
//释放信号量,通知接收到一包数据,任务可以处理了
|
||||||
/* 将dma缓冲马上传输完成剩余最后一截子的数据,拷贝到缓冲区中,在进行偏移量的复位 */
|
OSSemPost(g_horiMotorMutex);
|
||||||
RecvNum = pCommuDeal->dmaSize - pCommuDeal->dmaOffset;
|
/* 切换使用接收缓冲区,这样上层的解析永远从第一个字节起*/
|
||||||
/*将获取到的数据放到数据接收缓冲区中*/
|
if ( pCommuDeal->pDmaRsvBuffSelect == DMA_RSVBUFF_SELECT1 )
|
||||||
WriteNum = CfifoBuffWrite(&pCommuDeal->dataRsvCfifo,(char *)(pCommuDeal->pDmaRsvBuff + pCommuDeal->dmaOffset), RecvNum);
|
|
||||||
if(WriteNum != RecvNum)
|
|
||||||
{
|
{
|
||||||
/*add deal here*/
|
pCommuDeal->pDmaRsvBuffSelect = DMA_RSVBUFF_SELECT2;
|
||||||
|
dma_channel_disable(g_MotorDmaBuff[V_MOTOR].dmaNo, g_MotorDmaBuff[V_MOTOR].dmaRxch);//切换缓冲区,配置缓冲区长度需要先禁用DMA
|
||||||
|
dmaStruct.memory0_addr = (uint32_t)(pCommuDeal->pDmaRsvBuff2);
|
||||||
|
dmaStruct.number = DMA_BUFF_SIZE;
|
||||||
|
dma_single_data_mode_init(g_MotorDmaBuff[V_MOTOR].dmaNo, g_MotorDmaBuff[V_MOTOR].dmaRxch, &dmaStruct);
|
||||||
|
dma_channel_enable(g_MotorDmaBuff[V_MOTOR].dmaNo, g_MotorDmaBuff[V_MOTOR].dmaRxch);
|
||||||
}
|
}
|
||||||
/*复位DMA偏移量*/
|
else
|
||||||
pCommuDeal->dmaOffset = 0;
|
{
|
||||||
|
pCommuDeal->pDmaRsvBuffSelect = DMA_RSVBUFF_SELECT1;
|
||||||
|
dma_channel_disable(g_MotorDmaBuff[V_MOTOR].dmaNo, g_MotorDmaBuff[V_MOTOR].dmaRxch);//切换缓冲区,配置缓冲区长度需要先禁用DMA
|
||||||
|
dmaStruct.memory0_addr = (uint32_t)(pCommuDeal->pDmaRsvBuff1);
|
||||||
|
dmaStruct.number = DMA_BUFF_SIZE;
|
||||||
|
dma_single_data_mode_init(g_MotorDmaBuff[V_MOTOR].dmaNo, g_MotorDmaBuff[V_MOTOR].dmaRxch, &dmaStruct);
|
||||||
|
dma_channel_enable(g_MotorDmaBuff[V_MOTOR].dmaNo, g_MotorDmaBuff[V_MOTOR].dmaRxch);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -529,20 +531,14 @@ void CommuDrvInit(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 通过循环队列的方式进行数据的发送
|
* @brief 数据的发送
|
||||||
数据,表示已经接收到的包数量的变量减1
|
|
||||||
* @param motorNo:电机号,H_MOTOR:水平电机,V_MOTOR:垂直电机
|
* @param motorNo:电机号,H_MOTOR:水平电机,V_MOTOR:垂直电机
|
||||||
* @param buffer:发送缓冲区
|
* @param buffer:需要发送的数据
|
||||||
* @param len:发送数据的长度(不得大于DMA_BUFF_SIZE)
|
* @param len:发送数据的长度
|
||||||
* @return 写入发送缓冲区的长度
|
* @return ture:DMA空闲当前数据可以发送;false:DMA正在发送数据,当前数据不能发送
|
||||||
*/
|
*/
|
||||||
int32_t CommuTransData(uint8_t motorNo, uint8_t* buffer, int32_t len)
|
bool CommuTransData(uint8_t motorNo, uint8_t* buffer, int32_t len)
|
||||||
{
|
{
|
||||||
int32_t TransNum = 0;
|
|
||||||
int32_t TransLen = 0;
|
|
||||||
// 使用数组为每个电机分配独立的计数器
|
|
||||||
static int32_t s_addUpDataNum[MOTOR_NUM] = {0};
|
|
||||||
|
|
||||||
if( motorNo == H_MOTOR )
|
if( motorNo == H_MOTOR )
|
||||||
{
|
{
|
||||||
H_COMMU_RS485_TX;
|
H_COMMU_RS485_TX;
|
||||||
|
@ -553,22 +549,15 @@ int32_t CommuTransData(uint8_t motorNo, uint8_t* buffer, int32_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
CommuInfo_t *pCommuDeal = g_commuInfoBuff[motorNo].pCommuInfo;
|
CommuInfo_t *pCommuDeal = g_commuInfoBuff[motorNo].pCommuInfo;
|
||||||
/*将要发送的数据写入循环缓冲区*/
|
|
||||||
TransNum = CfifoBuffWrite(&pCommuDeal->dataTraCfifo, (char *) buffer, len);
|
|
||||||
s_addUpDataNum[motorNo] += len; // 使用对应电机的计数器
|
|
||||||
|
|
||||||
/*如果DMA未在发送中,触发发送*/
|
/*如果DMA未在发送中,触发发送*/
|
||||||
if(pCommuDeal->dmaTranFlag == DMA_TRANS_IDLE)
|
if(pCommuDeal->dmaTranFlag == DMA_TRANS_IDLE)
|
||||||
{
|
{
|
||||||
TransLen = CfifoBuffRead(&pCommuDeal->dataTraCfifo,(char *)(pCommuDeal->pDmaTraBuff), s_addUpDataNum[motorNo]);
|
|
||||||
s_addUpDataNum[motorNo] = 0; // 清零对应电机的计数器
|
|
||||||
if(TransLen > 0)
|
|
||||||
{
|
|
||||||
pCommuDeal->dmaTranFlag = DMA_TRANS_BUSY;
|
pCommuDeal->dmaTranFlag = DMA_TRANS_BUSY;
|
||||||
CommuDmaTra(motorNo, pCommuDeal->pDmaTraBuff, TransLen);
|
CommuDmaTra(motorNo, buffer, len);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
return false;
|
||||||
return TransNum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -580,55 +569,14 @@ int32_t CommuTransData(uint8_t motorNo, uint8_t* buffer, int32_t len)
|
||||||
*/
|
*/
|
||||||
void CommuRsvData(uint8_t motorNo, uint8_t* userBuff, uint32_t len)
|
void CommuRsvData(uint8_t motorNo, uint8_t* userBuff, uint32_t len)
|
||||||
{
|
{
|
||||||
// if ( motorNo == H_MOTOR )
|
|
||||||
// {
|
|
||||||
// H_COMMU_RS485_RX;
|
|
||||||
// }
|
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// V_COMMU_RS485_RX;
|
|
||||||
// }
|
|
||||||
CommuInfo_t *pCommuDeal = g_commuInfoBuff[motorNo].pCommuInfo;
|
CommuInfo_t *pCommuDeal = g_commuInfoBuff[motorNo].pCommuInfo;
|
||||||
CfifoBuffRead(&pCommuDeal->dataRsvCfifo, (char*)userBuff, len);
|
if ( pCommuDeal->pDmaRsvBuffSelect == DMA_RSVBUFF_SELECT1 )
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 与外部通讯的485或422接口,接收到的包数量
|
|
||||||
* @param motorNo:电机号,H_MOTOR:水平电机,V_MOTOR:垂直电机
|
|
||||||
* @return rs485或rs422接收到的包数量
|
|
||||||
*/
|
|
||||||
uint16_t GetRsvFrameNum(uint8_t motorNo)
|
|
||||||
{
|
|
||||||
if (motorNo == H_MOTOR)
|
|
||||||
{
|
{
|
||||||
return g_hFrameRcvNum;
|
memcpy(userBuff, pCommuDeal->pDmaRsvBuff2, len);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
return g_vFrameRcvNum;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @brief 与外部通讯的485或422接口,每从缓冲区读出一包
|
|
||||||
数据,表示已经接收到的包数量的变量减1
|
|
||||||
* @param motorNo:电机号,H_MOTOR:水平电机,V_MOTOR:垂直电机
|
|
||||||
* @return null
|
|
||||||
*/
|
|
||||||
void DecRsvFrameNum(uint8_t motorNo)
|
|
||||||
{
|
|
||||||
if (motorNo == H_MOTOR && g_hFrameRcvNum > 0)
|
|
||||||
{
|
{
|
||||||
g_hFrameRcvNum--;
|
memcpy(userBuff, pCommuDeal->pDmaRsvBuff1, len);
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (motorNo == V_MOTOR && g_vFrameRcvNum > 0)
|
|
||||||
{
|
|
||||||
g_vFrameRcvNum--;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///*用于结构体数组赋值,方便外部使用此结构体数组*/
|
|
||||||
//CommuHwInfo_t GetMotorCommuBuffStr(uint8_t motorNo)
|
|
||||||
//{
|
|
||||||
// return g_commuInfoBuff[motorNo];
|
|
||||||
//}
|
|
|
@ -1,8 +1,9 @@
|
||||||
#ifndef _MOTORCOMMU_
|
#ifndef _MOTORCOMMU_H_
|
||||||
#define _MOTORCOMMU_
|
#define _MOTORCOMMU_H_
|
||||||
|
|
||||||
#include "gd32f4xx.h"
|
#include "gd32f4xx.h"
|
||||||
#include "cfifo.h"
|
#include "stdbool.h"
|
||||||
|
#include "string.h"
|
||||||
/*
|
/*
|
||||||
********************************************************************************************************
|
********************************************************************************************************
|
||||||
* dma缓冲区相关
|
* dma缓冲区相关
|
||||||
|
@ -11,18 +12,19 @@
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
int16_t dmaTranFlag; /*dma发送是否在工作的标志位*/
|
int16_t dmaTranFlag; /*dma发送是否在工作的标志位*/
|
||||||
int32_t dmaSize; /*DMA缓冲区的大小*/
|
int32_t dmaSize; /*DMA接收缓冲区的大小*/
|
||||||
int32_t dmaOffset; /*获取数据在DMA缓冲区的偏移量*/
|
uint8_t *pDmaRsvBuff1; /*指向接收DMA缓冲区1的首地址*/
|
||||||
uint8_t *pDmaRsvBuff; /*指向接收DMA缓冲区的首地址*/
|
uint8_t *pDmaRsvBuff2; /*指向接收DMA缓冲区2的首地址*/
|
||||||
uint8_t *pDmaTraBuff; /*指向发送DMA缓冲区的首地址*/
|
uint8_t pDmaRsvBuffSelect; /*表示当前正在使用哪个接收缓冲区*/
|
||||||
CfifoBuff dataRsvCfifo; /*接受数据的循环缓冲区,串口---(dma搬运)--->pDmaRsvBuff[]--->dataRsvCfifo.BUFF[]*/
|
|
||||||
CfifoBuff dataTraCfifo; /*发送数据的循环缓冲区,dataTraCfifo.BUFF[]--->pDmaTraBuff[]---(dma搬运)--->串口*/
|
|
||||||
}CommuInfo_t;
|
}CommuInfo_t;
|
||||||
|
|
||||||
#define DMA_TRANS_IDLE 0//dma当前未在发送数据
|
#define DMA_TRANS_IDLE 0//dma当前未在发送数据
|
||||||
#define DMA_TRANS_BUSY 1//dma当前正在发送数据
|
#define DMA_TRANS_BUSY 1//dma当前正在发送数据
|
||||||
#define DMA_BUFF_SIZE 256//dma缓冲区大小
|
#define DMA_BUFF_SIZE 64//dma缓冲区大小
|
||||||
extern CommuInfo_t g_commuDeal;//来自motorCommu.c
|
#define DMA_RSVBUFF_SELECT1 (uint8_t)(0)//当前使用dma接收缓冲区1
|
||||||
|
#define DMA_RSVBUFF_SELECT2 (uint8_t)(1)//当前使用dma接收缓冲区2
|
||||||
|
|
||||||
|
//extern CommuInfo_t g_commuDeal;//来自motorCommu.c
|
||||||
|
|
||||||
/*
|
/*
|
||||||
********************************************************************************************************
|
********************************************************************************************************
|
||||||
|
@ -46,14 +48,13 @@ extern CommuInfo_t g_commuDeal;//
|
||||||
void CommuDrvInit(void);
|
void CommuDrvInit(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 通过循环队列的方式进行数据的发送
|
* @brief 数据的发送
|
||||||
数据,表示已经接收到的包数量的变量减1
|
|
||||||
* @param motorNo:电机号,H_MOTOR:水平电机,V_MOTOR:垂直电机
|
* @param motorNo:电机号,H_MOTOR:水平电机,V_MOTOR:垂直电机
|
||||||
* @param buffer:发送缓冲区
|
* @param buffer:需要发送的数据
|
||||||
* @param len:发送数据的长度(不得大于DMA_BUFF_SIZE)
|
* @param len:发送数据的长度
|
||||||
* @return 写入发送缓冲区的长度
|
* @return ture:DMA空闲当前数据可以发送;false:DMA正在发送数据,当前数据不能发送
|
||||||
*/
|
*/
|
||||||
int32_t CommuTransData(uint8_t motorNo, uint8_t* buffer, int32_t len);
|
bool CommuTransData(uint8_t motorNo, uint8_t* buffer, int32_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 从接收循环缓冲区中读取指定长度的数据到用户数组
|
* @brief 从接收循环缓冲区中读取指定长度的数据到用户数组
|
||||||
|
@ -64,20 +65,6 @@ int32_t CommuTransData(uint8_t motorNo, uint8_t* buffer, int32_t len);
|
||||||
*/
|
*/
|
||||||
void CommuRsvData(uint8_t motorNo, uint8_t* userBuff, uint32_t len);
|
void CommuRsvData(uint8_t motorNo, uint8_t* userBuff, uint32_t len);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 与外部通讯的485或422接口,接收到的包数量
|
|
||||||
* @param motorNo:电机号,H_MOTOR:水平电机,V_MOTOR:垂直电机
|
|
||||||
* @return rs485或rs422接收到的包数量
|
|
||||||
*/
|
|
||||||
uint16_t GetRsvFrameNum(uint8_t motorNo);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 与外部通讯的485或422接口,每从缓冲区读出一包
|
|
||||||
数据,表示已经接收到的包数量的变量减1
|
|
||||||
* @param motorNo:电机号,H_MOTOR:水平电机,V_MOTOR:垂直电机
|
|
||||||
* @return null
|
|
||||||
*/
|
|
||||||
void DecRsvFrameNum(uint8_t motorNo);
|
|
||||||
|
|
||||||
///*用于结构体数组赋值,方便外部使用此结构体数组*/
|
///*用于结构体数组赋值,方便外部使用此结构体数组*/
|
||||||
//CommuHwInfo_t GetMotorCommuBuffStr(uint8_t motorNo);
|
//CommuHwInfo_t GetMotorCommuBuffStr(uint8_t motorNo);
|
||||||
|
|
|
@ -16,42 +16,71 @@ static void MotorSwitchGpioCofig(void)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8_t g_writeOneRegBuff[WRITE_ONE_REG_BUFFNUM];//由于写寄存器,电机返回的数据和写入的数据完全一致,故设此数组
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
从机地址 功能码 寄存器地址高 寄存器地址低 数据高位 数据低位 crc校验高位 crc校验低位
|
从机地址 功能码 寄存器地址高 寄存器地址低 数据高位 数据低位 crc校验高位 crc校验低位
|
||||||
01H 06H 02H 00H 00H 01H 49H B2H
|
01H 06H 02H 00H 00H 01H 49H B2H
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* @brief 伺服电机速度模式写单个寄存器
|
||||||
|
* @param motorNo:写垂直电机还是水平电机
|
||||||
|
* @param regAddr:要写的寄存器
|
||||||
|
* @param data:要向寄存器写入的数据
|
||||||
|
* @return false:写失败,当前DMA正在发送数据
|
||||||
|
*/
|
||||||
bool WriteMotorOneReg(uint8_t motorNo, uint16_t regAddr, uint16_t data)
|
bool WriteMotorOneReg(uint8_t motorNo, uint16_t regAddr, uint16_t data)
|
||||||
{
|
{
|
||||||
uint8_t frameBuff[8] = {0};
|
uint8_t frameBuff[WRITE_ONE_REG_BUFFNUM] = {0};
|
||||||
uint8_t replyTemp[8];
|
|
||||||
uint16_t crc;
|
uint16_t crc;
|
||||||
frameBuff[0] = 0x01;//由于采用一主一从模式,所以水平电机垂直电机从机地址都是0x01,云台后期也不会扩展
|
if ( motorNo == H_MOTOR )
|
||||||
|
{
|
||||||
|
frameBuff[0] = H_MOTOR_ADDR;//由于采用一主一从模式,所以水平电机垂直电机从机地址都是0x01,云台后期也不会扩展
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
frameBuff[0] = V_MOTOR_ADDR;
|
||||||
|
}
|
||||||
frameBuff[1] = WRITE_ONE_REG;
|
frameBuff[1] = WRITE_ONE_REG;
|
||||||
frameBuff[2] = regAddr >> 8;
|
frameBuff[2] = regAddr >> WRITE_ONE_REG_BUFFNUM;
|
||||||
frameBuff[3] = regAddr & 0xff;
|
frameBuff[3] = regAddr & 0xff;
|
||||||
frameBuff[4] = data >> 8;
|
frameBuff[4] = data >> WRITE_ONE_REG_BUFFNUM;
|
||||||
frameBuff[5] = data & 0xff;
|
frameBuff[5] = data & 0xff;
|
||||||
crc = ModbusCRC16(frameBuff, 6);
|
crc = ModbusCRC16(frameBuff, WRITE_ONE_REG_BUFFNUM - 2);
|
||||||
frameBuff[6] = crc & 0xff;
|
frameBuff[6] = crc & 0xff;
|
||||||
frameBuff[7] = crc >> 8;
|
frameBuff[7] = crc >> WRITE_ONE_REG_BUFFNUM;
|
||||||
|
|
||||||
CommuTransData(motorNo, frameBuff, 8);
|
if ( CommuTransData(motorNo, frameBuff, WRITE_ONE_REG_BUFFNUM) == false)
|
||||||
OSTimeDlyHMSM(0u, 0u, 0u, 5u);//发送数据完成需要2ms,接收电机返回的数据需要2ms,延时5ms足够
|
|
||||||
|
|
||||||
CommuRsvData(motorNo, replyTemp, 8);//数据缓冲区已经有数据了才能调用此函数提取数据进行解析
|
|
||||||
for( uint8_t i = 0; i < 8; i++)
|
|
||||||
{
|
{
|
||||||
if ( frameBuff[i] != replyTemp[i] )
|
return false;
|
||||||
|
}
|
||||||
|
memcpy(g_writeOneRegBuff, frameBuff, WRITE_ONE_REG_BUFFNUM);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief 写单个寄存器成功后,电机会返回一帧与写格式完全一致的数据
|
||||||
|
* @param motorNo:写垂直电机还是水平电机
|
||||||
|
* @param userBuff:用来接收返回的数据的数组
|
||||||
|
* @param len:接收的数据长度,对于此函数必须为WRITE_ONE_REG_BUFFNUM
|
||||||
|
* @return false:错误,读出的内容与写入的内容不一致
|
||||||
|
*/
|
||||||
|
bool MotorReplyForWrite(uint8_t motorNo, uint8_t* userBuff, uint8_t len)
|
||||||
|
{
|
||||||
|
CommuRsvData(motorNo, userBuff, len);
|
||||||
|
for( uint8_t i = 0; i < len; i++ )
|
||||||
{
|
{
|
||||||
H_MOTOR_STOP;
|
if ( userBuff[i] != g_writeOneRegBuff[i] )
|
||||||
|
{
|
||||||
|
memset(g_writeOneRegBuff, 0x00, len);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
memset(g_writeOneRegBuff, 0x00, len);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 伺服电机驱动初始化
|
* @brief 伺服电机驱动初始化
|
||||||
* @param
|
* @param
|
||||||
|
@ -67,14 +96,20 @@ void servoMotorInit(void)
|
||||||
CommuDrvInit();//伺服电机RS485通讯初始化
|
CommuDrvInit();//伺服电机RS485通讯初始化
|
||||||
OSTimeDlyHMSM(0u, 0u, 0u, 500u);//等待硬件初始化成功
|
OSTimeDlyHMSM(0u, 0u, 0u, 500u);//等待硬件初始化成功
|
||||||
WriteMotorOneReg(H_MOTOR, H02_CONTR_MODE_SELEC, 0);//H0200,选择速度模式
|
WriteMotorOneReg(H_MOTOR, H02_CONTR_MODE_SELEC, 0);//H0200,选择速度模式
|
||||||
|
OSTimeDlyHMSM(0u, 0u, 0u, 5u);
|
||||||
|
|
||||||
WriteMotorOneReg(H_MOTOR, H04_DO1_FUNC_SELEC, 19);
|
WriteMotorOneReg(H_MOTOR, H04_DO1_FUNC_SELEC, 19);
|
||||||
|
OSTimeDlyHMSM(0u, 0u, 0u, 5u);
|
||||||
|
|
||||||
WriteMotorOneReg(H_MOTOR, H06_SPEED_COMMU_SET_VALUE, 100);//速度设置为100rpm
|
WriteMotorOneReg(H_MOTOR, H06_SPEED_COMMU_SET_VALUE, 100);//速度设置为100rpm
|
||||||
|
OSTimeDlyHMSM(0u, 0u, 0u, 5u);
|
||||||
|
|
||||||
WriteMotorOneReg(H_MOTOR, H06_SPEED_UP_SLOPE_VALUE, 3000);//加速度3000
|
WriteMotorOneReg(H_MOTOR, H06_SPEED_UP_SLOPE_VALUE, 3000);//加速度3000
|
||||||
|
OSTimeDlyHMSM(0u, 0u, 0u, 5u);
|
||||||
|
|
||||||
WriteMotorOneReg(H_MOTOR, H06_SPEED_DOWN_SLOPE_VALUE, 2000);//减速度2000
|
WriteMotorOneReg(H_MOTOR, H06_SPEED_DOWN_SLOPE_VALUE, 2000);//减速度2000
|
||||||
|
OSTimeDlyHMSM(0u, 0u, 0u, 5u);
|
||||||
|
|
||||||
WriteMotorOneReg(H_MOTOR, H03_DI1_LOGICAL_SELEC, 1);//只启动水平电机
|
WriteMotorOneReg(H_MOTOR, H03_DI1_LOGICAL_SELEC, 1);//只启动水平电机
|
||||||
|
OSTimeDlyHMSM(0u, 0u, 0u, 5u);
|
||||||
}
|
}
|
|
@ -14,6 +14,8 @@
|
||||||
#define V_MOTOR_OPEN gpio_bit_set(GPIOE,GPIO_PIN_1) //垂直电机电源打开
|
#define V_MOTOR_OPEN gpio_bit_set(GPIOE,GPIO_PIN_1) //垂直电机电源打开
|
||||||
#define V_MOTOR_STOP gpio_bit_reset(GPIOE,GPIO_PIN_1) //垂直电机电源关闭
|
#define V_MOTOR_STOP gpio_bit_reset(GPIOE,GPIO_PIN_1) //垂直电机电源关闭
|
||||||
|
|
||||||
|
#define H_MOTOR_ADDR 0x01//水平电机地址
|
||||||
|
#define V_MOTOR_ADDR 0x01//垂直电机地址
|
||||||
/*
|
/*
|
||||||
********************************************************************************************************
|
********************************************************************************************************
|
||||||
* 功能码命令
|
* 功能码命令
|
||||||
|
@ -24,6 +26,7 @@
|
||||||
#define WRITE_ONE_REG 0X06//写单个寄存器
|
#define WRITE_ONE_REG 0X06//写单个寄存器
|
||||||
#define WRITE_MULT_CONSE_REG 0x10//写多个连续的寄存器
|
#define WRITE_MULT_CONSE_REG 0x10//写多个连续的寄存器
|
||||||
|
|
||||||
|
#define WRITE_ONE_REG_BUFFNUM 8//写单个寄存器,数据帧的字节个数
|
||||||
/*
|
/*
|
||||||
********************************************************************************************************
|
********************************************************************************************************
|
||||||
* 寄存器参数
|
* 寄存器参数
|
||||||
|
@ -49,12 +52,26 @@
|
||||||
#define H0C_COMMU_PARAM_EEPR_UPDATE 0X0C13//MODBUS通讯写入是否更新到 EEPROM,设置1为写入
|
#define H0C_COMMU_PARAM_EEPR_UPDATE 0X0C13//MODBUS通讯写入是否更新到 EEPROM,设置1为写入
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
从机地址 功能码 寄存器地址高 寄存器地址低 数据高位 数据低位 crc校验高位 crc校验低位
|
|
||||||
01H 06H 02H 00H 00H 01H 49H B2H
|
/**
|
||||||
|
* @brief 伺服电机速度模式写单个寄存器
|
||||||
|
* @param motorNo:写垂直电机还是水平电机
|
||||||
|
* @param regAddr:要写的寄存器
|
||||||
|
* @param data:要向寄存器写入的数据
|
||||||
|
* @return false:写失败,当前DMA正在发送数据
|
||||||
*/
|
*/
|
||||||
bool WriteMotorOneReg(uint8_t motorNo, uint16_t regAddr, uint16_t data);
|
bool WriteMotorOneReg(uint8_t motorNo, uint16_t regAddr, uint16_t data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 写单个寄存器成功后,电机会返回一帧与写格式完全一致的数据
|
||||||
|
* @param motorNo:写垂直电机还是水平电机
|
||||||
|
* @param userBuff:用来接收返回的数据的数组
|
||||||
|
* @param len:接收的数据长度,对于此函数必须为WRITE_ONE_REG_BUFFNUM
|
||||||
|
* @return false:错误,读出的内容与写入的内容不一致
|
||||||
|
*/
|
||||||
|
bool MotorReplyForWrite(uint8_t motorNo, uint8_t* userBuff, uint8_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 伺服电机驱动初始化
|
* @brief 伺服电机驱动初始化
|
||||||
* @param
|
* @param
|
||||||
|
|
|
@ -826,7 +826,7 @@
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>IlinkIcfFile</name>
|
<name>IlinkIcfFile</name>
|
||||||
<state>D:\psx\Pan-Tilt\1.software\HY\new_ptz\servoMotor\BSP\IAR\GD32F450xE.icf</state>
|
<state>D:\CompanyCode\newPro\servoMotor_xr\BSP\IAR\GD32F450xE.icf</state>
|
||||||
</option>
|
</option>
|
||||||
<option>
|
<option>
|
||||||
<name>IlinkIcfFileSlave</name>
|
<name>IlinkIcfFileSlave</name>
|
||||||
|
@ -2927,12 +2927,6 @@
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<name>servoMotor</name>
|
<name>servoMotor</name>
|
||||||
<file>
|
|
||||||
<name>$PROJ_DIR$\..\BSP\Driver\servoMotor\cfifo.c</name>
|
|
||||||
</file>
|
|
||||||
<file>
|
|
||||||
<name>$PROJ_DIR$\..\BSP\Driver\servoMotor\cfifo.h</name>
|
|
||||||
</file>
|
|
||||||
<file>
|
<file>
|
||||||
<name>$PROJ_DIR$\..\BSP\Driver\servoMotor\modbus_crc.c</name>
|
<name>$PROJ_DIR$\..\BSP\Driver\servoMotor\modbus_crc.c</name>
|
||||||
</file>
|
</file>
|
||||||
|
|
|
@ -3196,12 +3196,6 @@
|
||||||
</group>
|
</group>
|
||||||
<group>
|
<group>
|
||||||
<name>servoMotor</name>
|
<name>servoMotor</name>
|
||||||
<file>
|
|
||||||
<name>$PROJ_DIR$\..\BSP\Driver\servoMotor\cfifo.c</name>
|
|
||||||
</file>
|
|
||||||
<file>
|
|
||||||
<name>$PROJ_DIR$\..\BSP\Driver\servoMotor\cfifo.h</name>
|
|
||||||
</file>
|
|
||||||
<file>
|
<file>
|
||||||
<name>$PROJ_DIR$\..\BSP\Driver\servoMotor\modbus_crc.c</name>
|
<name>$PROJ_DIR$\..\BSP\Driver\servoMotor\modbus_crc.c</name>
|
||||||
</file>
|
</file>
|
||||||
|
|
Loading…
Reference in New Issue