Compare commits
1 Commits
master
...
servoMotor
Author | SHA1 | Date |
---|---|---|
|
3a7438d997 |
|
@ -0,0 +1,114 @@
|
|||
#include "cfifo.h"
|
||||
|
||||
|
||||
/*环形CFIFO初始化*/
|
||||
void CfifoBuffInit(CfifoBuff* cfifoPointer)
|
||||
{
|
||||
//初始化相关信息
|
||||
cfifoPointer->Head = 0;
|
||||
cfifoPointer->Tail = 0;
|
||||
cfifoPointer->Lenght = 0;
|
||||
memset(cfifoPointer->BUFF,'\0',CFIFO_SIZE); //环形CFIFO缓存区初始化
|
||||
}
|
||||
|
||||
/*环形CFIFO数据清除*/
|
||||
void CfifoBuffClear(CfifoBuff* cfifoPointer)
|
||||
{
|
||||
//清除相关信息
|
||||
cfifoPointer->Head = 0;
|
||||
cfifoPointer->Tail = 0;
|
||||
cfifoPointer->Lenght = 0;
|
||||
memset(cfifoPointer->BUFF,'\0',CFIFO_SIZE); //环形CFIFO缓存区清除
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*环形CFIFO数据写入*/
|
||||
/*
|
||||
*参数说明:
|
||||
* Cfifo_pointer————环形CFIFO结构体
|
||||
* User_buff————待写入数据
|
||||
* num————写入数据长度
|
||||
*
|
||||
*返回值说明:正确写入到FIFO缓存区中的数据长度
|
||||
*
|
||||
*功能说明:将User_buff中的数据写入到环形CFIFO缓存区
|
||||
*
|
||||
*/
|
||||
int16_t CfifoBuffWrite(CfifoBuff* cfifoPointer, char* userBuff, int32_t num)
|
||||
{
|
||||
int16_t i , writeNum;
|
||||
|
||||
if(cfifoPointer->Lenght >= CFIFO_SIZE) //判断缓存区是否已满
|
||||
{
|
||||
writeNum = -1;
|
||||
return writeNum; //数据溢出
|
||||
}
|
||||
|
||||
if(cfifoPointer->Lenght + num < CFIFO_SIZE) //判断写入的数据长度是否超出当前可写入的最大值
|
||||
{
|
||||
writeNum = num;
|
||||
}
|
||||
else
|
||||
{
|
||||
writeNum = CFIFO_SIZE - cfifoPointer->Lenght;
|
||||
}
|
||||
|
||||
for(i=0; i<writeNum; i++)
|
||||
{
|
||||
cfifoPointer->BUFF[cfifoPointer->Tail] = *(userBuff+i);
|
||||
|
||||
cfifoPointer->Tail = (cfifoPointer->Tail+1) % CFIFO_SIZE;//防止越界非法访问
|
||||
}
|
||||
|
||||
cfifoPointer->Lenght += writeNum;
|
||||
|
||||
return writeNum; //返回正确写入的数据长度
|
||||
}
|
||||
|
||||
|
||||
/*环形CFIFO读取*/
|
||||
/*
|
||||
*参数说明:
|
||||
* Cfifo_pointer————环形CFIFO结构体
|
||||
* User_buff————读取数据存放地
|
||||
* num————读取数据长度
|
||||
*
|
||||
*返回值说明:正确读取到User_buff的数据长度
|
||||
*
|
||||
*功能说明:将环形CFIFO缓存区的数据读取到User_buff
|
||||
*
|
||||
*/
|
||||
int16_t CfifoBuffRead(CfifoBuff* cfifoPointer, char* userBuff, int32_t num)
|
||||
{
|
||||
int16_t i , readNum;
|
||||
|
||||
if(cfifoPointer->Lenght == 0) //判断非空
|
||||
{
|
||||
readNum = -1;
|
||||
|
||||
return readNum; //没有数据
|
||||
}
|
||||
|
||||
if( cfifoPointer->Lenght - num >= 0) //判断读取的数据长度是否超出当前可读取的最大值
|
||||
{
|
||||
readNum = num;
|
||||
}
|
||||
else
|
||||
{
|
||||
readNum = cfifoPointer->Lenght;
|
||||
}
|
||||
|
||||
for(i=0; i<readNum; i++)
|
||||
{
|
||||
*(userBuff+i) = cfifoPointer->BUFF[cfifoPointer->Head];
|
||||
|
||||
cfifoPointer->Head = (cfifoPointer->Head+1) % CFIFO_SIZE;//防止越界非法访问
|
||||
}
|
||||
|
||||
cfifoPointer->Lenght -= readNum;
|
||||
|
||||
return readNum; //返回正确写入的数据长度
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
#ifndef _CFIFO_H_
|
||||
#define _CFIFO_H_
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
* 包含的头文件
|
||||
*************************************************************************
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "stdint.h"
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
* 变量
|
||||
*************************************************************************
|
||||
*/
|
||||
#define CFIFO_SIZE 1024//环形队列CFIFO大小
|
||||
|
||||
/*环形CFIFO结构体*/
|
||||
typedef struct
|
||||
{
|
||||
uint16_t Head; //环形CFIFO队列头
|
||||
uint16_t Tail; //环形CFIFO队列尾
|
||||
int32_t Lenght; //环形CFIFO数据长度
|
||||
uint8_t BUFF[CFIFO_SIZE]; //环形CFIFO缓存区
|
||||
}CfifoBuff;
|
||||
|
||||
|
||||
/*
|
||||
*************************************************************************
|
||||
* 函数声明
|
||||
*************************************************************************
|
||||
*/
|
||||
void CfifoBuffInit(CfifoBuff* cfifoPointer); //CFIFO初始化
|
||||
void CfifoBuffClear(CfifoBuff* cfifoPointer); //CFIFO数据清除
|
||||
int16_t CfifoBuffWrite(CfifoBuff* cfifoPointer, char* userBuff, int32_t num); //CFIFO数据写人
|
||||
int16_t CfifoBuffRead(CfifoBuff* cfifoPointer, char* userBuff, int32_t num); //CFIFO数据读出
|
||||
|
||||
|
||||
#endif /* _CFIFO_H_ */
|
||||
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
#include "stdint.h"
|
||||
|
||||
static const uint8_t aucCRCHi[] = {
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
|
||||
0x00, 0xC1, 0x81, 0x40
|
||||
};
|
||||
|
||||
static const uint8_t aucCRCLo[] = {
|
||||
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
|
||||
0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
|
||||
0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
|
||||
0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
|
||||
0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
|
||||
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
|
||||
0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
|
||||
0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
|
||||
0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
|
||||
0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
|
||||
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
|
||||
0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
|
||||
0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
|
||||
0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
|
||||
0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
|
||||
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
|
||||
0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
|
||||
0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
|
||||
0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
|
||||
0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
|
||||
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
|
||||
0x41, 0x81, 0x80, 0x40
|
||||
};
|
||||
|
||||
uint16_t ModbusCRC16(uint8_t *pucFrame, uint16_t usLen)
|
||||
{
|
||||
uint8_t ucCRCHi = 0xFF;
|
||||
uint8_t ucCRCLo = 0xFF;
|
||||
int iIndex;
|
||||
|
||||
while(usLen--)
|
||||
{
|
||||
iIndex = ucCRCLo ^ *(pucFrame++);
|
||||
ucCRCLo = (uint8_t)(ucCRCHi ^ aucCRCHi[iIndex]);
|
||||
ucCRCHi = aucCRCLo[iIndex];
|
||||
}
|
||||
return (uint16_t)(ucCRCHi << 8 | ucCRCLo);
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
#ifndef _MODBUS_CRC_H_
|
||||
#define _MODBUS_CRC_H_
|
||||
|
||||
|
||||
uint16_t ModbusCRC16(uint8_t *pucFrame, uint16_t usLen);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,634 @@
|
|||
#include "motorCommu.h"
|
||||
|
||||
|
||||
|
||||
/*
|
||||
********************************************************************************************************
|
||||
* 电机串口通讯驱动初始化相关结构体
|
||||
********************************************************************************************************
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t gpio; //引脚端口号
|
||||
rcu_periph_enum rcuGpio; //GPIO时钟
|
||||
uint32_t uartNo; //串口号
|
||||
rcu_periph_enum rcuUart; //串口时钟
|
||||
uint32_t modePin; //rs485收发模式切换引脚
|
||||
uint32_t txPin; //串口发送引脚
|
||||
uint32_t rxPin; //串口接收引脚
|
||||
IRQn_Type uartIrq; //串口中断号
|
||||
}MotorCommuHwInfo_t;//电机与外部通讯的串口
|
||||
static MotorCommuHwInfo_t g_motorCommuBuff[] =
|
||||
{
|
||||
//水平电机串口2
|
||||
{
|
||||
.gpio = GPIOD,
|
||||
.rcuGpio = RCU_GPIOD,
|
||||
.uartNo = USART2,
|
||||
.rcuUart = RCU_USART2,
|
||||
.modePin = GPIO_PIN_10,
|
||||
.txPin = GPIO_PIN_8,
|
||||
.rxPin = GPIO_PIN_9,
|
||||
.uartIrq = USART2_IRQn,
|
||||
},
|
||||
//垂直电机串口5
|
||||
{
|
||||
.gpio = GPIOC,
|
||||
.rcuGpio = RCU_GPIOC,
|
||||
.uartNo = USART5,
|
||||
.rcuUart = RCU_USART5,
|
||||
.modePin = GPIO_PIN_8,
|
||||
.txPin = GPIO_PIN_6,
|
||||
.rxPin = GPIO_PIN_7,
|
||||
.uartIrq = USART5_IRQn,
|
||||
},
|
||||
};
|
||||
#define MOTOR_NUM ( sizeof(g_motorCommuBuff) / sizeof(g_motorCommuBuff[0]) )
|
||||
|
||||
/*
|
||||
********************************************************************************************************
|
||||
* 电机串口DMA驱动初始化结构体
|
||||
********************************************************************************************************
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t dmaNo; //dma号,dma0或dma1
|
||||
rcu_periph_enum rcuDma; //dma时钟
|
||||
dma_channel_enum dmaTxch; //dma发送通道号
|
||||
dma_channel_enum dmaRxch; //dma接收通道号
|
||||
dma_subperipheral_enum dmaPeriph; //dma外设通道号
|
||||
uint32_t periphAddr; //dma外设地址
|
||||
IRQn_Type dmaTxIrq; //dma发送通道中断号
|
||||
IRQn_Type dmaRxIrq; //dma接收通道中断号
|
||||
uint32_t dmaTxPri; //dma发送优先级
|
||||
uint32_t dmaRxPri; //dma接收优先级
|
||||
}MotorCommuDmaHwInfo_t;
|
||||
|
||||
static MotorCommuDmaHwInfo_t g_MotorDmaBuff[] =
|
||||
{
|
||||
//水平电机串口2
|
||||
{
|
||||
.dmaNo = DMA0,
|
||||
.rcuDma = RCU_DMA0,
|
||||
.dmaTxch = DMA_CH3,
|
||||
.dmaRxch = DMA_CH1,
|
||||
.dmaPeriph = DMA_SUBPERI4,
|
||||
.periphAddr = USART2 + 0x04,
|
||||
.dmaTxIrq = DMA0_Channel3_IRQn,
|
||||
.dmaRxIrq = DMA0_Channel1_IRQn,
|
||||
.dmaTxPri = 2,//0,1,2,3对于优先级低、中、高、特高
|
||||
.dmaRxPri = 2,
|
||||
},
|
||||
//垂直电机串口5
|
||||
{
|
||||
.dmaNo = DMA1,
|
||||
.rcuDma = RCU_DMA1,
|
||||
.dmaTxch = DMA_CH7,
|
||||
.dmaRxch = DMA_CH1,
|
||||
.dmaPeriph = DMA_SUBPERI5,
|
||||
.periphAddr = USART5 + 0x04,
|
||||
.dmaTxIrq = DMA1_Channel7_IRQn,
|
||||
.dmaRxIrq = DMA1_Channel1_IRQn,
|
||||
.dmaTxPri = 2,//0,1,2,3对于优先级低、中、高、特高
|
||||
.dmaRxPri = 2,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
********************************************************************************************************
|
||||
* 电机串口通讯缓冲区初始化结构体
|
||||
********************************************************************************************************
|
||||
*/
|
||||
/* dma发送与接收缓冲区 */
|
||||
static uint8_t g_horiDmaTxBuff[DMA_BUFF_SIZE] = {0};//水平电机DMA发送缓存区
|
||||
static uint8_t g_horiDmaRxBuff[DMA_BUFF_SIZE] = {0};//水平电机DMA接受缓存区
|
||||
static uint8_t g_vertDmaTxBuff[DMA_BUFF_SIZE] = {0};//垂直电机DMA发送缓存区
|
||||
static uint8_t g_vertDmaRxBuff[DMA_BUFF_SIZE] = {0};//垂直电机DMA接受缓存区
|
||||
/* 处理串口通讯与数据缓冲的数据结构 */
|
||||
static CommuInfo_t g_horiCommuDeal; //水平电机
|
||||
static CommuInfo_t g_vertCommuDeal; //垂直电机
|
||||
|
||||
typedef struct
|
||||
{
|
||||
CommuInfo_t* pCommuInfo; //串口通讯与数据缓冲相关的数据结构
|
||||
uint8_t* dmaTxBuff; //dma发送缓存区指针
|
||||
uint8_t* dmaRxBuff; //dma接受缓存区指针
|
||||
}CommuHwInfo_t;//方便缓冲区初始化的结构体
|
||||
static CommuHwInfo_t g_commuInfoBuff[] =
|
||||
{
|
||||
//水平电机
|
||||
{
|
||||
.pCommuInfo = &g_horiCommuDeal,
|
||||
.dmaTxBuff = g_horiDmaTxBuff,
|
||||
.dmaRxBuff = g_horiDmaRxBuff,
|
||||
},
|
||||
//垂直电机串口5
|
||||
{
|
||||
.pCommuInfo = &g_vertCommuDeal,
|
||||
.dmaTxBuff = g_vertDmaTxBuff,
|
||||
.dmaRxBuff = g_vertDmaRxBuff,
|
||||
},
|
||||
};
|
||||
|
||||
/*
|
||||
********************************************************************************************************
|
||||
* 电机串口通讯驱动初始化
|
||||
********************************************************************************************************
|
||||
*/
|
||||
static void GpioCofig(void)
|
||||
{
|
||||
for(uint8_t i = 0; i < MOTOR_NUM; i++)//i==0初始化水平电机IO,i==1初始化垂直电机io
|
||||
{
|
||||
/*GPIO时钟初始化*/
|
||||
rcu_periph_clock_enable(g_motorCommuBuff[i].rcuGpio);
|
||||
/*io复用为串口uart*/
|
||||
if ( i == H_MOTOR )
|
||||
{
|
||||
gpio_af_set(g_motorCommuBuff[i].gpio, GPIO_AF_7, g_motorCommuBuff[i].txPin);
|
||||
gpio_af_set(g_motorCommuBuff[i].gpio, GPIO_AF_7, g_motorCommuBuff[i].rxPin);
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio_af_set(g_motorCommuBuff[i].gpio, GPIO_AF_8, g_motorCommuBuff[i].txPin);
|
||||
gpio_af_set(g_motorCommuBuff[i].gpio, GPIO_AF_8, g_motorCommuBuff[i].rxPin);
|
||||
}
|
||||
/*tx引脚配置*/
|
||||
gpio_mode_set(g_motorCommuBuff[i].gpio, GPIO_MODE_AF, GPIO_PUPD_NONE, g_motorCommuBuff[i].txPin);
|
||||
gpio_output_options_set(g_motorCommuBuff[i].gpio, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, g_motorCommuBuff[i].txPin);
|
||||
/*rx引脚配置*/
|
||||
gpio_mode_set(g_motorCommuBuff[i].gpio, GPIO_MODE_AF, GPIO_PUPD_NONE, g_motorCommuBuff[i].rxPin);
|
||||
gpio_output_options_set(g_motorCommuBuff[i].gpio, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, g_motorCommuBuff[i].rxPin);
|
||||
/*rs485收发模式切换引脚配置*/
|
||||
gpio_mode_set(g_motorCommuBuff[i].gpio, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, g_motorCommuBuff[i].modePin);
|
||||
gpio_output_options_set(g_motorCommuBuff[i].gpio, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, g_motorCommuBuff[i].modePin);
|
||||
}
|
||||
}
|
||||
|
||||
static void UartCofig(uint32_t baud)
|
||||
{
|
||||
for(uint8_t i = 0; i < MOTOR_NUM; i++)//i==0初始化水平电机IO,i==1初始化垂直电机io
|
||||
{
|
||||
/*UART时钟初始化*/
|
||||
rcu_periph_clock_enable(g_motorCommuBuff[i].rcuUart);
|
||||
/*串口复位*/
|
||||
usart_deinit (g_motorCommuBuff[i].uartNo);
|
||||
/*串口配置*/
|
||||
usart_word_length_set(g_motorCommuBuff[i].uartNo, USART_WL_8BIT);
|
||||
usart_parity_config(g_motorCommuBuff[i].uartNo, USART_PM_NONE);
|
||||
usart_stop_bit_set(g_motorCommuBuff[i].uartNo, USART_STB_1BIT);
|
||||
usart_baudrate_set(g_motorCommuBuff[i].uartNo, baud);
|
||||
usart_hardware_flow_rts_config(g_motorCommuBuff[i].uartNo, USART_RTS_DISABLE);
|
||||
usart_hardware_flow_cts_config(g_motorCommuBuff[i].uartNo, USART_CTS_DISABLE);
|
||||
usart_transmit_config(g_motorCommuBuff[i].uartNo, USART_TRANSMIT_ENABLE);
|
||||
usart_receive_config(g_motorCommuBuff[i].uartNo, USART_RECEIVE_ENABLE);
|
||||
usart_dma_transmit_config(g_motorCommuBuff[i].uartNo, USART_DENT_ENABLE);
|
||||
usart_dma_receive_config(g_motorCommuBuff[i].uartNo, USART_DENR_ENABLE);
|
||||
/*中断配置*/
|
||||
usart_interrupt_enable(g_motorCommuBuff[i].uartNo, USART_INT_IDLE);
|
||||
nvic_irq_enable(g_motorCommuBuff[i].uartIrq, 3, 0);
|
||||
usart_enable(g_motorCommuBuff[i].uartNo);
|
||||
}
|
||||
}
|
||||
|
||||
static void DmaCofig(void)
|
||||
{
|
||||
for(uint8_t i = 0; i < MOTOR_NUM; i++)//i==0初始化水平电机IO,i==1初始化垂直电机io
|
||||
{
|
||||
dma_single_data_parameter_struct dmaStruct;
|
||||
rcu_periph_clock_enable(g_MotorDmaBuff[i].rcuDma);
|
||||
/*--------------------------------dma发送,数据完全传输中断初始化---------------------------------*/
|
||||
//dma配置
|
||||
dma_deinit(g_MotorDmaBuff[i].dmaNo, g_MotorDmaBuff[i].dmaTxch);
|
||||
dmaStruct.direction = DMA_MEMORY_TO_PERIPH;
|
||||
dmaStruct.memory0_addr = (uint32_t)0;
|
||||
dmaStruct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
|
||||
dmaStruct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;
|
||||
dmaStruct.periph_addr = g_MotorDmaBuff[i].periphAddr;
|
||||
dmaStruct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
|
||||
dmaStruct.number = 0;
|
||||
dmaStruct.priority = CHCTL_PRIO(g_MotorDmaBuff[i].dmaTxPri);
|
||||
dma_single_data_mode_init(g_MotorDmaBuff[i].dmaNo, g_MotorDmaBuff[i].dmaTxch, &dmaStruct);
|
||||
dma_circulation_disable(g_MotorDmaBuff[i].dmaNo, g_MotorDmaBuff[i].dmaTxch);
|
||||
dma_channel_subperipheral_select(g_MotorDmaBuff[i].dmaNo, g_MotorDmaBuff[i].dmaTxch, g_MotorDmaBuff[i].dmaPeriph);
|
||||
//dma中断配置
|
||||
nvic_irq_enable(g_MotorDmaBuff[i].dmaTxIrq, 4, 3);
|
||||
dma_interrupt_enable(g_MotorDmaBuff[i].dmaNo, g_MotorDmaBuff[i].dmaTxch, DMA_CHXCTL_FTFIE);//dma发送完成中断
|
||||
|
||||
|
||||
/*--------------------------------dma接收,配合串口空闲中断初始化---------------------------------*/
|
||||
//dma配置
|
||||
dma_deinit(g_MotorDmaBuff[i].dmaNo, g_MotorDmaBuff[i].dmaRxch);
|
||||
dmaStruct.direction = DMA_PERIPH_TO_MEMORY;
|
||||
dmaStruct.memory0_addr = (uint32_t)(g_commuInfoBuff[i].pCommuInfo->pDmaRsvBuff);
|
||||
dmaStruct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
|
||||
dmaStruct.number = DMA_BUFF_SIZE;
|
||||
dmaStruct.periph_addr = g_MotorDmaBuff[i].periphAddr;
|
||||
dmaStruct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
|
||||
dmaStruct.periph_memory_width = DMA_PERIPH_WIDTH_8BIT;
|
||||
dmaStruct.priority = CHCTL_PRIO(g_MotorDmaBuff[i].dmaRxPri);;
|
||||
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_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_channel_subperipheral_select(g_MotorDmaBuff[i].dmaNo, g_MotorDmaBuff[i].dmaRxch, g_MotorDmaBuff[i].dmaPeriph);
|
||||
//中断配置
|
||||
nvic_irq_enable(g_MotorDmaBuff[i].dmaRxIrq, 4, 2);
|
||||
dma_interrupt_enable(g_MotorDmaBuff[i].dmaNo, g_MotorDmaBuff[i].dmaRxch, DMA_CHXCTL_FTFIE);
|
||||
dma_channel_enable(g_MotorDmaBuff[i].dmaNo, g_MotorDmaBuff[i].dmaRxch);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
********************************************************************************************************
|
||||
* 串口缓冲区初始化
|
||||
********************************************************************************************************
|
||||
*/
|
||||
/*!
|
||||
\brief 初始化串口的缓冲区指针、DMA的空间大小、DMA偏移量、发送接收队列的初始化
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
static void CommuStructInit()
|
||||
{
|
||||
for(uint8_t i = 0; i < MOTOR_NUM; i++)//i==0初始化水平电机IO,i==1初始化垂直电机io
|
||||
{
|
||||
/*为属性的参数附初值*/
|
||||
CommuInfo_t *pCommuDeal = g_commuInfoBuff[i].pCommuInfo;
|
||||
pCommuDeal->dmaOffset = 0;
|
||||
pCommuDeal->dmaTranFlag = DMA_TRANS_IDLE;
|
||||
pCommuDeal->dmaSize = DMA_BUFF_SIZE;
|
||||
pCommuDeal->pDmaRsvBuff = g_commuInfoBuff[i].dmaRxBuff;
|
||||
pCommuDeal->pDmaTraBuff = g_commuInfoBuff[i].dmaTxBuff;
|
||||
CfifoBuffInit(&pCommuDeal->dataRsvCfifo); //用于数据接受
|
||||
CfifoBuffInit(&pCommuDeal->dataTraCfifo); //用于数据发送
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief 串口进行DMA的数据发送
|
||||
\param[in] devNo:设备号,H_MOTOR:水平电机,V_MOTOR:垂直电机
|
||||
\param[in] buffer:发送缓冲区
|
||||
\param[in] len:发送缓冲区大小
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
static void CommuDmaTra(uint8_t devNo, uint8_t *buffer,uint16_t len)
|
||||
{
|
||||
dma_channel_disable(g_MotorDmaBuff[devNo].dmaNo, g_MotorDmaBuff[devNo].dmaTxch);
|
||||
|
||||
dma_memory_address_config(g_MotorDmaBuff[devNo].dmaNo, g_MotorDmaBuff[devNo].dmaTxch, DMA_MEMORY_0, (uint32_t)buffer);
|
||||
|
||||
dma_transfer_number_config(g_MotorDmaBuff[devNo].dmaNo, g_MotorDmaBuff[devNo].dmaTxch, len);
|
||||
|
||||
/*清除DMA发送完成的标志*/
|
||||
dma_flag_clear(g_MotorDmaBuff[devNo].dmaNo, g_MotorDmaBuff[devNo].dmaTxch, DMA_FLAG_FTF);
|
||||
usart_flag_clear(g_motorCommuBuff[devNo].uartNo, USART_FLAG_TC);
|
||||
|
||||
dma_channel_enable(g_MotorDmaBuff[devNo].dmaNo, g_MotorDmaBuff[devNo].dmaTxch);
|
||||
}
|
||||
|
||||
/*
|
||||
********************************************************************************************************
|
||||
* 水平电机相关中断服务函数
|
||||
********************************************************************************************************
|
||||
*/
|
||||
/*!
|
||||
\brief this function handles DMA0_Channel3_IRQHandler interrupt
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void DMA0_Channel3_IRQHandler(void)
|
||||
{
|
||||
/*
|
||||
* 配合串口的发送。功能是继续发送缓冲区未发送的数据。
|
||||
* 发送完成配置的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))
|
||||
{
|
||||
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;
|
||||
|
||||
/*从发送循环缓冲区中获取数据*/
|
||||
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); // 等待串口发送完成
|
||||
H_COMMU_RS485_RX; //485切换为接收
|
||||
pCommuDeal->dmaTranFlag = DMA_TRANS_IDLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
***********************************************************
|
||||
* @brief 串口中断服务函数
|
||||
* @param
|
||||
* @return
|
||||
***********************************************************
|
||||
*/
|
||||
static uint16_t g_hFrameRcvNum = 0;
|
||||
void USART2_IRQHandler(void)
|
||||
{
|
||||
/* 串口的接收空闲中断方式进行了数据缓存。*/
|
||||
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[H_MOTOR].uartNo, USART_INT_FLAG_IDLE))
|
||||
{
|
||||
/* clear IDLE flag */
|
||||
usart_interrupt_flag_clear(g_motorCommuBuff[H_MOTOR].uartNo, USART_INT_FLAG_IDLE); //第一步,读取stat0寄存器,清除IDLE标志位
|
||||
usart_data_receive(g_motorCommuBuff[H_MOTOR].uartNo); //第二步,读取数据寄存器,清除IDLE标志位
|
||||
|
||||
g_hFrameRcvNum++;
|
||||
|
||||
CommuInfo_t *pCommuDeal = g_commuInfoBuff[H_MOTOR].pCommuInfo;
|
||||
|
||||
/*计算在DMA缓冲区需要获取的数据长度*/
|
||||
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)
|
||||
{
|
||||
int32_t RecvNum = 0;
|
||||
int32_t WriteNum = 0;
|
||||
/*
|
||||
* 配合串口1的接收空闲中断。功能是复位DMA的偏移量
|
||||
* 1、为了串口1的空闲中断在处理数据时防止越界,将 pUartAttr->DamOffset置为0;
|
||||
* 2、DMA为循环方式进行数据搬运的,当搬运完配置的Cnt后,会进入此中断处理函数,
|
||||
* 3、当有数据过来时,数据将会拷贝到缓冲区的起始位置;
|
||||
* 4、注意:如果DMA为正常模式,那么当完成一次拷贝后,DMA会自动disable掉。
|
||||
*/
|
||||
if(dma_interrupt_flag_get(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;
|
||||
|
||||
/* 将dma缓冲马上传输完成剩余最后一截子的数据,拷贝到缓冲区中,在进行偏移量的复位 */
|
||||
RecvNum = pCommuDeal->dmaSize - pCommuDeal->dmaOffset;
|
||||
/*将获取到的数据放到数据接收缓冲区中*/
|
||||
WriteNum = CfifoBuffWrite(&pCommuDeal->dataRsvCfifo,(char *)(pCommuDeal->pDmaRsvBuff + pCommuDeal->dmaOffset), RecvNum);
|
||||
if(WriteNum != RecvNum)
|
||||
{
|
||||
/*add deal here*/
|
||||
}
|
||||
/*复位DMA偏移量*/
|
||||
pCommuDeal->dmaOffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
********************************************************************************************************
|
||||
* 垂直电机相关中断服务函数
|
||||
********************************************************************************************************
|
||||
*/
|
||||
/*!
|
||||
\brief this function handles DMA0_Channel3_IRQHandler interrupt
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void DMA1_Channel7_IRQHandler(void)
|
||||
{
|
||||
/*
|
||||
* 配合串口的发送。功能是继续发送缓冲区未发送的数据。
|
||||
* 发送完成配置的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))
|
||||
{
|
||||
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;
|
||||
|
||||
/*从发送循环缓冲区中获取数据*/
|
||||
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); // 等待串口发送完成
|
||||
V_COMMU_RS485_RX; //485切换为接收
|
||||
pCommuDeal->dmaTranFlag = DMA_TRANS_IDLE;
|
||||
}
|
||||
// pCommuDeal->dmaTranFlag = DMA_TRANS_IDLE;
|
||||
// V_COMMU_RS485_RX; //485切换为接收
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
***********************************************************
|
||||
* @brief 串口中断服务函数
|
||||
* @param
|
||||
* @return
|
||||
***********************************************************
|
||||
*/
|
||||
static uint16_t g_vFrameRcvNum = 0;
|
||||
void USART5_IRQHandler(void)
|
||||
{
|
||||
/* 串口的接收空闲中断方式进行了数据缓存。*/
|
||||
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))
|
||||
{
|
||||
/* clear IDLE flag */
|
||||
usart_interrupt_flag_clear(g_motorCommuBuff[V_MOTOR].uartNo, USART_INT_FLAG_IDLE); //第一步,读取stat0寄存器,清除IDLE标志位
|
||||
usart_data_receive(g_motorCommuBuff[V_MOTOR].uartNo); //第二步,读取数据寄存器,清除IDLE标志位
|
||||
|
||||
g_vFrameRcvNum++;
|
||||
|
||||
CommuInfo_t *pCommuDeal = g_commuInfoBuff[V_MOTOR].pCommuInfo;
|
||||
|
||||
/*计算在DMA缓冲区需要获取的数据长度*/
|
||||
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->dmaOffset += RecvNum;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// uint8_t rx_OK = 0;
|
||||
void DMA1_Channel1_IRQHandler(void)
|
||||
{
|
||||
int32_t RecvNum = 0;
|
||||
int32_t WriteNum = 0;
|
||||
/*
|
||||
* 配合串口1的接收空闲中断。功能是复位DMA的偏移量
|
||||
* 1、为了串口1的空闲中断在处理数据时防止越界,将 pUartAttr->DamOffset置为0;
|
||||
* 2、DMA为循环方式进行数据搬运的,当搬运完配置的Cnt后,会进入此中断处理函数,
|
||||
* 3、当有数据过来时,数据将会拷贝到缓冲区的起始位置;
|
||||
* 4、注意:如果DMA为正常模式,那么当完成一次拷贝后,DMA会自动disable掉。
|
||||
*/
|
||||
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);
|
||||
// rx_OK++;
|
||||
|
||||
CommuInfo_t *pCommuDeal = g_commuInfoBuff[V_MOTOR].pCommuInfo;
|
||||
|
||||
/* 将dma缓冲马上传输完成剩余最后一截子的数据,拷贝到缓冲区中,在进行偏移量的复位 */
|
||||
RecvNum = pCommuDeal->dmaSize - pCommuDeal->dmaOffset;
|
||||
/*将获取到的数据放到数据接收缓冲区中*/
|
||||
WriteNum = CfifoBuffWrite(&pCommuDeal->dataRsvCfifo,(char *)(pCommuDeal->pDmaRsvBuff + pCommuDeal->dmaOffset), RecvNum);
|
||||
if(WriteNum != RecvNum)
|
||||
{
|
||||
/*add deal here*/
|
||||
}
|
||||
/*复位DMA偏移量*/
|
||||
pCommuDeal->dmaOffset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
********************************************************************************************************
|
||||
* 外部可调用API接口函数
|
||||
********************************************************************************************************
|
||||
*/
|
||||
/**
|
||||
* @brief 串口设备通讯驱动初始化
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void CommuDrvInit(void)
|
||||
{
|
||||
CommuStructInit();//先初始化这个缓冲区数据结构体,否则硬件配置得不到地址
|
||||
GpioCofig();
|
||||
UartCofig(57600);
|
||||
DmaCofig();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 通过循环队列的方式进行数据的发送
|
||||
数据,表示已经接收到的包数量的变量减1
|
||||
* @param motorNo:电机号,H_MOTOR:水平电机,V_MOTOR:垂直电机
|
||||
* @param buffer:发送缓冲区
|
||||
* @param len:发送数据的长度(不得大于DMA_BUFF_SIZE)
|
||||
* @return 写入发送缓冲区的长度
|
||||
*/
|
||||
int32_t 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 )
|
||||
{
|
||||
H_COMMU_RS485_TX;
|
||||
}
|
||||
else
|
||||
{
|
||||
V_COMMU_RS485_TX;
|
||||
}
|
||||
|
||||
CommuInfo_t *pCommuDeal = g_commuInfoBuff[motorNo].pCommuInfo;
|
||||
/*将要发送的数据写入循环缓冲区*/
|
||||
TransNum = CfifoBuffWrite(&pCommuDeal->dataTraCfifo, (char *) buffer, len);
|
||||
s_addUpDataNum[motorNo] += len; // 使用对应电机的计数器
|
||||
|
||||
/*如果DMA未在发送中,触发发送*/
|
||||
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;
|
||||
CommuDmaTra(motorNo, pCommuDeal->pDmaTraBuff, TransLen);
|
||||
}
|
||||
}
|
||||
return TransNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 从接收循环缓冲区中读取指定长度的数据到用户数组
|
||||
* @param motorNo:电机号,H_MOTOR:水平电机,V_MOTOR:垂直电机
|
||||
* @param userBuff:从接收循环缓冲区中接收数据的数组
|
||||
* @param len:接收数据的长度
|
||||
* @return none
|
||||
*/
|
||||
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;
|
||||
CfifoBuffRead(&pCommuDeal->dataRsvCfifo, (char*)userBuff, len);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
|
||||
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--;
|
||||
return;
|
||||
}
|
||||
if (motorNo == V_MOTOR && g_vFrameRcvNum > 0)
|
||||
{
|
||||
g_vFrameRcvNum--;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
///*用于结构体数组赋值,方便外部使用此结构体数组*/
|
||||
//CommuHwInfo_t GetMotorCommuBuffStr(uint8_t motorNo)
|
||||
//{
|
||||
// return g_commuInfoBuff[motorNo];
|
||||
//}
|
|
@ -0,0 +1,84 @@
|
|||
#ifndef _MOTORCOMMU_
|
||||
#define _MOTORCOMMU_
|
||||
|
||||
#include "gd32f4xx.h"
|
||||
#include "cfifo.h"
|
||||
/*
|
||||
********************************************************************************************************
|
||||
* dma缓冲区相关
|
||||
********************************************************************************************************
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int16_t dmaTranFlag; /*dma发送是否在工作的标志位*/
|
||||
int32_t dmaSize; /*DMA缓冲区的大小*/
|
||||
int32_t dmaOffset; /*获取数据在DMA缓冲区的偏移量*/
|
||||
uint8_t *pDmaRsvBuff; /*指向接收DMA缓冲区的首地址*/
|
||||
uint8_t *pDmaTraBuff; /*指向发送DMA缓冲区的首地址*/
|
||||
CfifoBuff dataRsvCfifo; /*接受数据的循环缓冲区,串口---(dma搬运)--->pDmaRsvBuff[]--->dataRsvCfifo.BUFF[]*/
|
||||
CfifoBuff dataTraCfifo; /*发送数据的循环缓冲区,dataTraCfifo.BUFF[]--->pDmaTraBuff[]---(dma搬运)--->串口*/
|
||||
}CommuInfo_t;
|
||||
|
||||
#define DMA_TRANS_IDLE 0//dma当前未在发送数据
|
||||
#define DMA_TRANS_BUSY 1//dma当前正在发送数据
|
||||
#define DMA_BUFF_SIZE 256//dma缓冲区大小
|
||||
extern CommuInfo_t g_commuDeal;//来自motorCommu.c
|
||||
|
||||
/*
|
||||
********************************************************************************************************
|
||||
* 串口设备驱动初始化相关
|
||||
********************************************************************************************************
|
||||
*/
|
||||
#define H_MOTOR 0//数组g_motorCommuInitBuff[MOTOR_NUM]位号
|
||||
#define V_MOTOR 1
|
||||
|
||||
/*-------------485接收发送宏开关----------------------*/
|
||||
#define H_COMMU_RS485_TX gpio_bit_set(GPIOD, GPIO_PIN_10)//水平电机485发送
|
||||
#define H_COMMU_RS485_RX gpio_bit_reset(GPIOD, GPIO_PIN_10)//水平电机485接收
|
||||
#define V_COMMU_RS485_TX gpio_bit_set(GPIOC, GPIO_PIN_8)//垂直电机485发送
|
||||
#define V_COMMU_RS485_RX gpio_bit_reset(GPIOC, GPIO_PIN_8)//垂直电机485接收
|
||||
|
||||
/**
|
||||
* @brief 串口设备通讯驱动初始化
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void CommuDrvInit(void);
|
||||
|
||||
/**
|
||||
* @brief 通过循环队列的方式进行数据的发送
|
||||
数据,表示已经接收到的包数量的变量减1
|
||||
* @param motorNo:电机号,H_MOTOR:水平电机,V_MOTOR:垂直电机
|
||||
* @param buffer:发送缓冲区
|
||||
* @param len:发送数据的长度(不得大于DMA_BUFF_SIZE)
|
||||
* @return 写入发送缓冲区的长度
|
||||
*/
|
||||
int32_t CommuTransData(uint8_t motorNo, uint8_t* buffer, int32_t len);
|
||||
|
||||
/**
|
||||
* @brief 从接收循环缓冲区中读取指定长度的数据到用户数组
|
||||
* @param motorNo:电机号,H_MOTOR:水平电机,V_MOTOR:垂直电机
|
||||
* @param userBuff:从接收循环缓冲区中接收数据的数组
|
||||
* @param len:接收数据的长度
|
||||
* @return none
|
||||
*/
|
||||
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);
|
||||
#endif
|
|
@ -1,8 +1,79 @@
|
|||
#include "servoMotor.h"
|
||||
#include <ucos_ii.h>
|
||||
/*
|
||||
水平垂直电机使能开关引脚配置
|
||||
*/
|
||||
static void MotorSwitchGpioCofig(void)
|
||||
{
|
||||
/*GPIO时钟初始化*/
|
||||
rcu_periph_clock_enable(RCU_GPIOE);
|
||||
/*水平电机打开引脚*/
|
||||
gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_0);
|
||||
gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_0);
|
||||
/*垂直电机打开引脚*/
|
||||
gpio_mode_set(GPIOE, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_PIN_1);
|
||||
gpio_output_options_set(GPIOE, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
从机地址 功能码 寄存器地址高 寄存器地址低 数据高位 数据低位 crc校验高位 crc校验低位
|
||||
01H 06H 02H 00H 00H 01H 49H B2H
|
||||
*/
|
||||
bool WriteMotorOneReg(uint8_t motorNo, uint16_t regAddr, uint16_t data)
|
||||
{
|
||||
uint8_t frameBuff[8] = {0};
|
||||
uint8_t replyTemp[8];
|
||||
uint16_t crc;
|
||||
frameBuff[0] = 0x01;//由于采用一主一从模式,所以水平电机垂直电机从机地址都是0x01,云台后期也不会扩展
|
||||
frameBuff[1] = WRITE_ONE_REG;
|
||||
frameBuff[2] = regAddr >> 8;
|
||||
frameBuff[3] = regAddr & 0xff;
|
||||
frameBuff[4] = data >> 8;
|
||||
frameBuff[5] = data & 0xff;
|
||||
crc = ModbusCRC16(frameBuff, 6);
|
||||
frameBuff[6] = crc & 0xff;
|
||||
frameBuff[7] = crc >> 8;
|
||||
|
||||
CommuTransData(motorNo, frameBuff, 8);
|
||||
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] )
|
||||
{
|
||||
H_MOTOR_STOP;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief 伺服电机驱动初始化
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void servoMotorInit(void)
|
||||
{
|
||||
MotorSwitchGpioCofig();//两个电机电源的开关PE0,1引脚,如果其它地方实现了,可以不需要
|
||||
H_MOTOR_OPEN;
|
||||
V_MOTOR_OPEN;
|
||||
|
||||
CommuDrvInit();//伺服电机RS485通讯初始化
|
||||
OSTimeDlyHMSM(0u, 0u, 0u, 500u);//等待硬件初始化成功
|
||||
WriteMotorOneReg(H_MOTOR, H02_CONTR_MODE_SELEC, 0);//H0200,选择速度模式
|
||||
|
||||
WriteMotorOneReg(H_MOTOR, H04_DO1_FUNC_SELEC, 19);
|
||||
|
||||
WriteMotorOneReg(H_MOTOR, H06_SPEED_COMMU_SET_VALUE, 100);//速度设置为100rpm
|
||||
|
||||
WriteMotorOneReg(H_MOTOR, H06_SPEED_UP_SLOPE_VALUE, 3000);//加速度3000
|
||||
|
||||
WriteMotorOneReg(H_MOTOR, H06_SPEED_DOWN_SLOPE_VALUE, 2000);//减速度2000
|
||||
|
||||
WriteMotorOneReg(H_MOTOR, H03_DI1_LOGICAL_SELEC, 1);//只启动水平电机
|
||||
}
|
|
@ -1,8 +1,66 @@
|
|||
#ifndef _DRIVER_SERVO_MOTOR_H_
|
||||
#define _DRIVER_SERVO_MOTOR_H_
|
||||
#ifndef _SERVOMOTOR_H_
|
||||
#define _SERVOMOTOR_H_
|
||||
|
||||
#include "gd32f4xx.h"
|
||||
#include "motorCommu.h"
|
||||
#include "modbus_crc.h"
|
||||
#include "stdbool.h"
|
||||
/*
|
||||
********************************************************************************************************
|
||||
* 电机硬件相关
|
||||
********************************************************************************************************
|
||||
*/
|
||||
#define H_MOTOR_OPEN gpio_bit_set(GPIOE,GPIO_PIN_0) //水平电机电源打开
|
||||
#define H_MOTOR_STOP gpio_bit_reset(GPIOE,GPIO_PIN_0) //水平电机电源关闭
|
||||
#define V_MOTOR_OPEN gpio_bit_set(GPIOE,GPIO_PIN_1) //垂直电机电源打开
|
||||
#define V_MOTOR_STOP gpio_bit_reset(GPIOE,GPIO_PIN_1) //垂直电机电源关闭
|
||||
|
||||
/*
|
||||
********************************************************************************************************
|
||||
* 功能码命令
|
||||
********************************************************************************************************
|
||||
*/
|
||||
#define READ_ONE_REG 0X03//读单个寄存器
|
||||
#define READ_MULT_CONSE_REG 0X03//读多个连续的寄存器Read multiple consecutive registers
|
||||
#define WRITE_ONE_REG 0X06//写单个寄存器
|
||||
#define WRITE_MULT_CONSE_REG 0x10//写多个连续的寄存器
|
||||
|
||||
/*
|
||||
********************************************************************************************************
|
||||
* 寄存器参数
|
||||
********************************************************************************************************
|
||||
*/
|
||||
/*基本控制参数H02*/
|
||||
#define H02_CONTR_MODE_SELEC 0X0200//(Control mode selection)控制模式选择0:速度模式,1:位置模式,2:转矩模式
|
||||
|
||||
/*DI/DO参数H03~H04*/
|
||||
#define H03_DI1_FUNC_SELEC 0X0302//DI1端子功能选择,一个 DI 功能选项只能关联一个 DI 端子,不可重复分配
|
||||
#define H03_DI1_LOGICAL_SELEC 0X0303//DI1端子逻辑选择
|
||||
#define H04_DO1_FUNC_SELEC 0X0400//DO1端子功能选择
|
||||
#define H04_DO1_LOGICAL_SELEC 0X0401//DO1端子逻辑选择
|
||||
|
||||
/*速度控制参数H06*/
|
||||
#define H06_SPEED_COMMAND_SELEC 0X0602//速度指令选择
|
||||
#define H06_SPEED_COMMU_SET_VALUE 0X0603//速度指令通讯设置值,当 H06_02=0 时,通过此参数设定电机运行转速
|
||||
#define H06_SPEED_UP_SLOPE_VALUE 0X0605//速度指令加速斜坡时间常数
|
||||
#define H06_SPEED_DOWN_SLOPE_VALUE 0X0606//速度指令减速斜坡时间常数
|
||||
#define H06_SPEED_REACH_MAX 0X0618//速度到达信号阈值
|
||||
|
||||
/*RS485通讯与功能参数H0C*/
|
||||
#define H0C_COMMU_PARAM_EEPR_UPDATE 0X0C13//MODBUS通讯写入是否更新到 EEPROM,设置1为写入
|
||||
|
||||
|
||||
/*
|
||||
从机地址 功能码 寄存器地址高 寄存器地址低 数据高位 数据低位 crc校验高位 crc校验低位
|
||||
01H 06H 02H 00H 00H 01H 49H B2H
|
||||
*/
|
||||
bool WriteMotorOneReg(uint8_t motorNo, uint16_t regAddr, uint16_t data);
|
||||
|
||||
/**
|
||||
* @brief 伺服电机驱动初始化
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void servoMotorInit(void);
|
||||
|
||||
|
||||
#endif
|
|
@ -741,7 +741,7 @@
|
|||
<data>
|
||||
<extensions></extensions>
|
||||
<cmdline></cmdline>
|
||||
<hasPrio>1</hasPrio>
|
||||
<hasPrio>200</hasPrio>
|
||||
<buildSequence>inputOutputBased</buildSequence>
|
||||
</data>
|
||||
</settings>
|
||||
|
@ -826,7 +826,7 @@
|
|||
</option>
|
||||
<option>
|
||||
<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>
|
||||
<name>IlinkIcfFileSlave</name>
|
||||
|
@ -2924,9 +2924,30 @@
|
|||
</group>
|
||||
<group>
|
||||
<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>
|
||||
<name>$PROJ_DIR$\..\BSP\Driver\servoMotor\modbus_crc.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\BSP\Driver\servoMotor\modbus_crc.h</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\BSP\Driver\servoMotor\motorCommu.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\BSP\Driver\servoMotor\motorCommu.h</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\BSP\Driver\servoMotor\servoMotor.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\BSP\Driver\servoMotor\servoMotor.h</name>
|
||||
</file>
|
||||
</group>
|
||||
<group>
|
||||
<name>timer</name>
|
||||
|
|
|
@ -3193,9 +3193,30 @@
|
|||
</group>
|
||||
<group>
|
||||
<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>
|
||||
<name>$PROJ_DIR$\..\BSP\Driver\servoMotor\modbus_crc.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\BSP\Driver\servoMotor\modbus_crc.h</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\BSP\Driver\servoMotor\motorCommu.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\BSP\Driver\servoMotor\motorCommu.h</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\BSP\Driver\servoMotor\servoMotor.c</name>
|
||||
</file>
|
||||
<file>
|
||||
<name>$PROJ_DIR$\..\BSP\Driver\servoMotor\servoMotor.h</name>
|
||||
</file>
|
||||
</group>
|
||||
<group>
|
||||
<name>timer</name>
|
||||
|
|
Loading…
Reference in New Issue