Compare commits

...

9 Commits

Author SHA1 Message Date
  1923777848 9e3fa14782 增加减速功能 11 hours ago
  1923777848 16daa756ed 修改输出计数误差 15 hours ago
  1923777848 eede0ad12f 增加脉冲输出计数 17 hours ago
  1923777848 0d58029f71 优化跳转时多段波形逻辑 1 day ago
  1923777848 ba4a9f0c58 增加直线加减速多段跳转功能 1 day ago
  1923777848 42778b3d2c 增加直线加减速功能 2 days ago
  1923777848 49d9775f1f 添加PLSR.c 5 days ago
  1923777848 62d4addc0c 添加PLSR.c 5 days ago
  1923777848 8b72eb7900 增加定时器配置 1 week ago
16 changed files with 1335 additions and 409 deletions
Split View
  1. +2
    -1
      .gitignore
  2. +182
    -0
      TrainCamp_zhangcheng_PLSR/app/inc/plsr.h
  3. +2
    -31
      TrainCamp_zhangcheng_PLSR/app/src/main.c
  4. +574
    -0
      TrainCamp_zhangcheng_PLSR/app/src/plsr.c
  5. +60
    -0
      TrainCamp_zhangcheng_PLSR/bsp/inc/time.h
  6. +26
    -1
      TrainCamp_zhangcheng_PLSR/bsp/src/gpio.c
  7. +438
    -0
      TrainCamp_zhangcheng_PLSR/bsp/src/time.c
  8. +6
    -0
      TrainCamp_zhangcheng_PLSR/iar/PLSR.ewp
  9. +0
    -11
      TrainCamp_zhangcheng_PLSR/modbus/inc/modbus.h
  10. +1
    -3
      TrainCamp_zhangcheng_PLSR/modbus/src/modbus_ack_module.c
  11. +1
    -3
      TrainCamp_zhangcheng_PLSR/modbus/src/modbus_link_check_module.c
  12. +1
    -3
      TrainCamp_zhangcheng_PLSR/modbus/src/modbus_operate_module.c
  13. +0
    -350
      TrainCamp_zhangcheng_PLSR/modbus/src/modbus_operate_module.c~RF1ad0af.TMP
  14. +40
    -4
      TrainCamp_zhangcheng_PLSR/modbus/src/modbus_request_module.c
  15. +1
    -1
      TrainCamp_zhangcheng_PLSR/system/src/system.c
  16. +1
    -1
      TrainCamp_zhangcheng_PLSR/system/src/usart.c

+ 2
- 1
.gitignore View File

@@ -2,4 +2,5 @@ TrainCamp_zhangcheng_PLSR/.vscode
TrainCamp_zhangcheng_PLSR/iar/Debug
TrainCamp_zhangcheng_PLSR/iar/settings
TrainCamp_zhangcheng_PLSR/iar/PLSR.dep
TrainCamp_zhangcheng_PLSR/iar/PLSR.ewt
TrainCamp_zhangcheng_PLSR/iar/PLSR.ewt
.TMP

+ 182
- 0
TrainCamp_zhangcheng_PLSR/app/inc/plsr.h View File

@@ -0,0 +1,182 @@
/**
* @file plsr.h
* @author zhangcheng
* @brief PLSR指令功能接口文件
* @version v0.1
* @date 2025-08-06
*
* @copyright Copyright (c) 2025
*/


#include "../../modbus/inc/modbus.h"


/**
* @brief 最大支持脉冲段
* @details
* @note
* @attention
*/
#define PLSR_PULSE_MAX_SEGMENT_NUM 10


/**
* @brief 系统参数块
* @details
* @note
* @attention
*/
typedef enum {
SYSTEM_PARAM_BLOCK_0 = 0, ///< 系统参数块0,默认参数块,不可修改
SYSTEM_PARAM_BLOCK_1, ///< 系统参数块1
SYSTEM_PARAM_BLOCK_2, ///< 系统参数块2
SYSTEM_PARAM_BLOCK_3, ///< 系统参数块3
SYSTEM_PARAM_BLOCK_4 ///< 系统参数块4
} PLSR_SYSTEM_PARAM_BLOCK;



/**
* @brief 输出端口
* @details
* @note
* @attention
*/
typedef enum {
OUTPUT_PORT_Y0 = 0, ///< 输出端子Y0
OUTPUT_PORT_Y1, ///< 输出端子Y1
OUTPUT_PORT_Y2, ///< 输出端子Y2
OUTPUT_PORT_Y3 ///< 输出端子Y3
} PLSR_OUTPUT_PORT;


/**
* @brief 输出方向端口
* @details
* @note
* @attention
*/
typedef enum {
OUTPUT_DIR_PORT_Y12 = 0, ///< 输出方向端子Y12
OUTPUT_DIR_PORT_Y13, ///< 输出方向端子Y13
OUTPUT_DIR_PORT_Y14, ///< 输出方向端子Y14
OUTPUT_DIR_PORT_Y15 ///< 输出方向端子Y15
} PLSR_OUTPUT_DIR_PORT;


/**
* @brief 方向端子方向逻辑
* @details
* @note
* @attention
*/
typedef enum {
OUTPUT_DIR_CORRECT = 0, ///< 正逻辑
OUTPUT_DIR_NEGATIVE, ///< 负逻辑
} PLSR_OUTPUT_DIR_PORT_LOGIC;


/**
* @brief 输入信号端口
* @details
* @note
* @attention
*/
typedef enum {
INPUT_EXT_PORT_X4 = 0, ///< 输入端子X4
INPUT_EXT_PORT_X5, ///< 输入端子X5
} PLSR_INPUT_EXT_PORT;


/**
* @brief 加减速模式模式
* @details
* @note
* @attention
*/
typedef enum {
STRAIGHT_LINE_MODE = 0, ///< 直线加减速模式
S_CURVE_MODE, ///< S曲线加减速模式
SINE_CURVE_MODE ///< 正弦曲线加减速模式
} PLSR_ACC_DEC_SPEED_MODE;


/**
* @brief 输出模式
* @details
* @note
* @attention
*/
typedef enum {
RELATIVE_MODE = 0, ///< 相对模式
ABSOLUTE_MODE ///< 绝对模式
} PLSR_OUTPUT_MODE;


/**
* @brief 参数错误类型
* @details
* @note
* @attention
*/
typedef enum {
PLSR_ERROR_NONE = 0, ///< 无错误
PLSR_FREQ_EXCE_MAX_VALUE ///< 超过最大输出频率
} PLSR_ERROR_TYPE;


/**
* @brief PLSR脉冲段
* @details
* @note
* @attention
*/
typedef struct
{
int32_t pulseFreq;
int32_t pulseNumber;
int16_t waitType;
int16_t jumpNumber;
} PLSR_SEGMENT;


/**
* @brief PLSR指令结构类型
* @details
* @note
* @attention
*/
typedef struct
{
PLSR_OUTPUT_PORT outputPort; ///< 输出端子
PLSR_OUTPUT_DIR_PORT dirPort; ///< 输出方向端子
PLSR_INPUT_EXT_PORT extPort; ///< 输入端子
PLSR_OUTPUT_DIR_PORT_LOGIC dirLogic; ///< 输出方向端子逻辑
PLSR_ACC_DEC_SPEED_MODE accDecSpeedMode; ///< 加减速模式
PLSR_OUTPUT_MODE outMode; ///< 输出模式
uint16_t dirDelayTime; ///< 方向延时时间
uint16_t segmentAllNum; ///< 总段数
uint16_t startRunSegment; ///< 起始执行段编号
uint16_t previouSegment; ///< 上一段编号
uint16_t currentSegment; ///< 当前执行段编号
uint32_t defaultSpeed; ///< 默认速度
uint16_t defaultAccSpeedTime; ///< 默认加速时间
uint16_t defaultDecSpeedTime; ///< 默认减速时间
int32_t monitorPulseNum; ///< 监控脉冲数量
uint16_t sendEnableState; ///< 脉冲发送使能
PLSR_SEGMENT segment[PLSR_PULSE_MAX_SEGMENT_NUM]; ///< 各段数参数
} PLSR;


/**
* @brief PLSR功能初始化
* @details
*
* @param[in] 无
*
* @return RESUIL 初始化结果
* @retval MODBUS_TURE 成功
* @retval MODBUS_FALSE 失败
*/
RESUIL PLSRInit(void);

+ 2
- 31
TrainCamp_zhangcheng_PLSR/app/src/main.c View File

@@ -4,37 +4,7 @@
#include "../modbus/inc/modbus_operate_module.h"
#include "../modbus/inc/modbus_ack_module.h"
#include "../modbus/inc/modbus_link_check_module.h"


// PVD初始化函数,设置PVD阈值和中断模式
void PVD_Init(void)
{
// 使能PWR时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
// 设置PVD阈值为2.9V,可以根据你的电源电压选择其他值
PWR_PVDLevelConfig(PWR_PVDLevel_7);
// 使能PVD
PWR_PVDCmd(ENABLE);
// 使能PVD外部中断线
EXTI_ClearITPendingBit(EXTI_Line16); // 清除中断标志位
EXTI_InitTypeDef EXTI_InitStructure; // 定义外部中断结构体
EXTI_InitStructure.EXTI_Line = EXTI_Line16; // PVD连接到外部中断线16
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; // 设置为中断模式
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; // 设置为上升沿触发,即电压低于阈值时触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE; // 使能外部中断线
EXTI_Init(&EXTI_InitStructure); // 初始化外部中断
// 设置PVD中断优先级和使能
NVIC_InitTypeDef NVIC_InitStructure; // 定义中断控制器结构体
NVIC_InitStructure.NVIC_IRQChannel = PVD_IRQn; // PVD中断通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 6; // 抢占优先级为0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 子优先级为0
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能中断通道
NVIC_Init(&NVIC_InitStructure); // 初始化中断控制器
}
#include "../inc/plsr.h"


int main(void)
@@ -60,6 +30,7 @@ int main(void)
OperateProcModuleInit();
AckProcModuleInit();
linkCheckModuleInit();
PLSRInit();
OSStart();
}


+ 574
- 0
TrainCamp_zhangcheng_PLSR/app/src/plsr.c View File

@@ -0,0 +1,574 @@
/**
* @file plsr.c
* @author zhangcheng
* @brief PLSR指令功能源文件
* @version v0.1
* @date 2025-08-06
*
* @copyright Copyright (c) 2025
*/

#include "../../system/inc/system.h"
#include "../../bsp/inc/time.h"
#include "../inc/plsr.h"
#include "../../bsp/inc/gpio.h"

/* 求x绝对值 */
#define ABS(x) do { \
if ((x) < 0) \
((x) = 0 - (x)); \
} while(0)

typedef struct {
int32_t inc;
int32_t dec;
int32_t currentSpeed;
uint8_t currentState; ///< 0:无操作 1:匀速 2:加速 3:减速
uint8_t currentPart;
int32_t firstPartNum;
int32_t secondPartNum;
int32_t thirdPartNum;
} SEGMENT_PART;


#define PLSR_MODULE_PRIO 5
#define PLSR_MODULE_STACK_SIZE 1024
static OS_STK PlsrModuleStack[PLSR_MODULE_STACK_SIZE];
static void PlsrModuleTask(void * pArg);

static void TimCallBack(void *pArg);
static void Tim2CntCallBack(void *pArg);
static void ReadRegisterParam(PLSR *plsr);
static void configPulsePort(PLSR *plsr);
static void ComputePartNum(PLSR *plsr, SEGMENT_PART *segmentPart);
static void FirstSegmentProc(SEGMENT_PART *segmentPart);
static void SecondSegmentProc(SEGMENT_PART *segmentPart);
static void ThirdSegmentProc(SEGMENT_PART *segmentPart);


/**
* @brief PLSR功能初始化
* @details
*
* @param[in] 无
*
* @return RESUIL 初始化结果
* @retval MODBUS_TURE 成功
* @retval MODBUS_FALSE 失败
*/
RESUIL PLSRInit(void)
{
INT8U err;

OS_CPU_SR cpu_sr;
OS_ENTER_CRITICAL();

err = OSTaskCreate(
PlsrModuleTask,
NULL,
&PlsrModuleStack[PLSR_MODULE_STACK_SIZE - 1],
PLSR_MODULE_PRIO);

if(err != OS_ERR_NONE)
{
MODBUS_LOG("PlsrcModule init fail\r\n");
OS_EXIT_CRITICAL();
return MODBUS_FALSE;
}

OS_EXIT_CRITICAL();

return MODBUS_TURE;
}


/**
* @brief PLSR处理任务
* @details
*
* @param[in] *pArg 任务参数
*
* @return RESUIL 初始化结果
* @retval MODBUS_TURE 成功
* @retval MODBUS_FALSE 失败
*/
TIM_OBJ tim2;
int32_t tim2OverCnt = 0;
int32_t CumulativePulseCount = 0;
TIM_OBJ tim10;
int32_t accSpeedSlope = 0;
int32_t decSpeedSlope = 0;
int32_t accTime = 0;
int32_t decTime = 0;
int32_t accPulse = 0;
int32_t decPulse = 0;
int32_t uniformTime = 0;
int32_t uniformPulse = 0;
uint8_t currentSegment = 0;
uint32_t currentSpeed = 0;
uint8_t RunFlag = 0;

int32_t pulseFreq = 168 - 1;
uint32_t pulseReload = 20;
SEGMENT_PART currentSeg = {
.currentState = 2,
.currentPart = 1
};
PLSR plsr = {
.segmentAllNum = 4,
.defaultSpeed = 1000,
.defaultAccSpeedTime = 5,
.defaultDecSpeedTime = 10,
.segment[0].pulseFreq = 2000,
.segment[0].pulseNumber = 1000,
.segment[0].jumpNumber = 0,
.segment[1].pulseFreq = 1000,
.segment[1].pulseNumber = 2000,
.segment[1].jumpNumber = 0,
.segment[2].pulseFreq = 6000,
.segment[2].pulseNumber = 2000,
.segment[2].jumpNumber = 0,
.segment[3].pulseFreq = 6000,
.segment[3].pulseNumber = 10000,
.segment[3].jumpNumber = 0,
.startRunSegment = 0
};
void PlsrModuleTask(void *pArg)
{
int8_t res;
uint8_t pArgment = 0;

uint8_t nextSegment = plsr.startRunSegment;

// ReadRegisterParam(&plsr);

res = GetTimObj("tim2", &tim2);
res = GetTimObj("tim10", &tim10);
tim2.init(&tim2, 0, 50000 - 1);
tim2.open(&tim2);
tim2.registerIrq(&tim2, Tim2CntCallBack, NULL);
tim2.openIrq(&tim2);
tim10.init(&tim10, 168 - 1, 65535);
tim10.registerIrq(&tim10, TimCallBack, &currentSeg);
tim10.pwmInit(&tim10);
tim10.pwmSetPulse(&tim10, TIM10->ARR);

plsr.sendEnableState = 1;
plsr.accDecSpeedMode = STRAIGHT_LINE_MODE;
currentSegment = plsr.startRunSegment;

while (1)
{
// ReadRegisterParam(&plsr);
CumulativePulseCount = tim2OverCnt * (TIM2->ARR + 1) + TIM2->CNT;
plsr.monitorPulseNum = CumulativePulseCount;
if (plsr.segment[currentSegment].pulseFreq <= 1000)
pulseFreq = 2625 - 1;
else if ((plsr.segment[currentSegment].pulseFreq > 1000)
&& (plsr.segment[currentSegment].pulseFreq <= 100000))
pulseFreq = 4 - 1;
else
continue;

if (plsr.outMode == ABSOLUTE_MODE)
{
if (plsr.monitorPulseNum
>= plsr.segment[currentSegment].pulseNumber)
{
continue;
}
}

/* 配置输入输出相关端子 */
if ((plsr.sendEnableState != 1) || (RunFlag == 1))
{
continue;
}

configPulsePort(&plsr);

if ((plsr.accDecSpeedMode == STRAIGHT_LINE_MODE) && (RunFlag == 0))
{
RunFlag = 1;

ComputePartNum(&plsr, &currentSeg);

switch (currentSeg.currentPart)
{
case 1:
{
FirstSegmentProc(&currentSeg);
break;
}
case 2:
{
SecondSegmentProc(&currentSeg);
break;
}
case 3:
{
ThirdSegmentProc(&currentSeg);
break;
}
}
}
}
}

//1HZ
//psc 1680 一次10us
//per 50000
//5KHZ
//psc 1680
//per 10
//100KHZ
//psc 168 一次0.5us
//per 10
//定时器3 外部输入时钟源ETR引脚PB4,定时器11输出
//定时器4 外部输入时钟源ETR引脚PB6,定时器14输出
//定时器9 内部输入时钟源ITx主从模式定时器10
//定时器12 内部输入时钟源ITx主从模式定时器13

static void Tim2CntCallBack(void *pArg)
{
tim2OverCnt++;
}

static void TimCallBack(void *pArg)
{
uint16_t reloadValue = 0;
static int32_t pulseCount = 0;
static int32_t allcount = 0;

if (currentSeg.currentPart == 1)
{
switch (currentSeg.currentState)
{
case 2: ///< 加速
{
if ((currentSpeed + currentSeg.inc) >= plsr.segment[currentSegment].pulseFreq)
{
currentSpeed = plsr.segment[currentSegment].pulseFreq;
currentSeg.currentPart = 2;
}
else
currentSpeed += currentSeg.inc;
if (currentSpeed <= 1000)
tim10.setPsc(&tim10, 2625 - 1);
else
tim10.setPsc(&tim10, 3 - 1);
reloadValue = 168000000 / (TIM10->PSC + 1) / (currentSpeed);
tim10.setPer(&tim10, reloadValue - 1);
tim10.pwmSetPulse(&tim10, TIM10->ARR / 2 + 1);
allcount++;
pulseCount++;
if (pulseCount > currentSeg.firstPartNum - 1)
pulseCount = 0;
break;
}
case 3: ///< 减速
{
if ((currentSpeed - currentSeg.dec) < plsr.segment[currentSegment].pulseFreq)
{
currentSpeed = plsr.segment[currentSegment].pulseFreq;
currentSeg.currentPart = 2;
}
else
currentSpeed -= currentSeg.dec;
if (currentSpeed <= 1000)
tim10.setPsc(&tim10, 2625 - 1);
else
tim10.setPsc(&tim10, 3 - 1);
reloadValue = 168000000 / (TIM10->PSC + 1) / (currentSpeed);
tim10.setPer(&tim10, reloadValue - 1);
tim10.pwmSetPulse(&tim10, TIM10->ARR / 2 + 1);
allcount++;
pulseCount++;
if (pulseCount > currentSeg.firstPartNum - 1)
pulseCount = 0;
break;
}
default:
{
break;
}
}
}
else if (currentSeg.currentPart == 2)
{
if (pulseCount > currentSeg.secondPartNum - 1)
{
if ((currentSegment == (plsr.segmentAllNum -1))
&& (plsr.segment[currentSegment].jumpNumber == 0))
{
currentSeg.currentPart = 3;
pulseCount = 0;
currentSeg.dec = currentSpeed / currentSeg.thirdPartNum;
return;
}

currentSeg.currentPart = 1;
pulseCount = 0;
RunFlag = 0;
if (plsr.segment[currentSegment].jumpNumber == 0)
currentSegment++;
else
currentSegment = plsr.segment[currentSegment].jumpNumber;
}
allcount++;
pulseCount++;
}
else if (currentSeg.currentPart == 3)
{
if (((currentSpeed - currentSeg.dec) <= 0)
|| (pulseCount > currentSeg.thirdPartNum - 2))
{
currentSpeed = 0;
pulseCount = 0;
currentSeg.currentPart = 1;
tim10.setPer(&tim10, 100);
tim10.pwmSetPulse(&tim10, 65535);
tim10.closeIrq(&tim10);
allcount++;
return;
}
currentSpeed -= currentSeg.dec;
if (currentSpeed <= 1000)
tim10.setPsc(&tim10, 2625 - 1);
else
tim10.setPsc(&tim10, 3 - 1);

reloadValue = 168000000 / (TIM10->PSC + 1) / (currentSpeed);
tim10.setPer(&tim10, reloadValue - 1);
tim10.pwmSetPulse(&tim10, TIM10->ARR / 2 + 1);
allcount++;
pulseCount++;
}
}


static void ReadRegisterParam(PLSR *plsr)
{
int16_t *pDataRegister = (uint16_t *)(DATA_REGISTER_ADRR + 0x1000);

plsr->outputPort = pDataRegister[0];
plsr->dirPort = pDataRegister[1];
plsr->extPort = pDataRegister[2];
plsr->dirDelayTime = pDataRegister[3];
plsr->dirLogic = pDataRegister[4];
plsr->accDecSpeedMode = pDataRegister[5];
plsr->outMode = pDataRegister[6];
plsr->segmentAllNum = pDataRegister[7];
plsr->startRunSegment = pDataRegister[8];
plsr->defaultSpeed = *((uint32_t *)pDataRegister[9]);
plsr->defaultAccSpeedTime = pDataRegister[11];
plsr->defaultDecSpeedTime = pDataRegister[12];
plsr->monitorPulseNum = *((int32_t *)(pDataRegister + 0x1000));
plsr->sendEnableState = *(pDataRegister + 0x2000);

pDataRegister += 0x100;
for (uint8_t i = 0; i < PLSR_PULSE_MAX_SEGMENT_NUM; i++)
{
plsr->segment[i].pulseFreq = *((uint32_t *)pDataRegister[i]);
plsr->segment[i].pulseNumber = *((int32_t *)pDataRegister[i + 2]);
plsr->segment[i].waitType = pDataRegister[i + 4];
plsr->segment[i].jumpNumber = pDataRegister[i + 5];

pDataRegister += 0x10;
}
}


static void configPulsePort(PLSR *plsr)
{
uint8_t pulseDir = 1;
gpio_obj_t *outDirPort = NULL;

outDirPort = get_gpio_obj("gpio_h");

if ((outDirPort == NULL) || (plsr == NULL))
return;

if (plsr->segment[currentSegment].pulseNumber >= 0)
pulseDir = 1;
else
pulseDir = 0;
switch (plsr->dirPort)
{
case OUTPUT_DIR_PORT_Y12:
{
outDirPort->gpio_init(outDirPort, gpio_pin_9, "OUT_PP", "UP");
break;
}
case OUTPUT_DIR_PORT_Y13:
{
outDirPort->gpio_init(outDirPort, gpio_pin_8, "OUT_PP", "UP");
break;
}
case OUTPUT_DIR_PORT_Y14:
{
outDirPort->gpio_init(outDirPort, gpio_pin_7, "OUT_PP", "UP");
break;
}
case OUTPUT_DIR_PORT_Y15:
{
outDirPort->gpio_init(outDirPort, gpio_pin_6, "OUT_PP", "UP");
break;
}
default:
{
break;
}
}
outDirPort->gpio_set_output(outDirPort, outDirPort->gpio_pin,
plsr->dirLogic ^ pulseDir);
if (currentSegment == plsr->startRunSegment)
return;
if (((plsr->segment[currentSegment].pulseNumber >= 0)
&& (plsr->segment[plsr->previouSegment].pulseNumber >= 0)))
return;

if ((plsr->segment[currentSegment].pulseNumber < 0)
&& (plsr->segment[plsr->previouSegment].pulseNumber < 0))
return;

// tim10.pwmSetPulse(&tim10, 65535);
OSTimeDly(plsr->dirDelayTime);
}


static void ComputePartNum(PLSR *plsr, SEGMENT_PART *segmentPart)
{
uint32_t target = plsr->segment[currentSegment].pulseFreq;
uint32_t targetPulseCount = plsr->segment[currentSegment].pulseNumber;
ABS(targetPulseCount);
accSpeedSlope = plsr->defaultSpeed / plsr->defaultAccSpeedTime;
decSpeedSlope = plsr->defaultSpeed / plsr->defaultDecSpeedTime;

/* 最后一段 */
if ((currentSegment == (plsr->segmentAllNum -1))
&& (plsr->segment[currentSegment].jumpNumber == 0))
{
decTime = target / decSpeedSlope;
segmentPart->thirdPartNum = target / 2 * decTime / 1000;
}
else
{
segmentPart->thirdPartNum = 0;
}

if (currentSpeed < target)
{
accTime = (target - currentSpeed) / accSpeedSlope;
segmentPart->firstPartNum = (target + currentSpeed) / 2 * accTime / 1000;
}
else if (currentSpeed > target)
{
decTime = (currentSpeed - target) / decSpeedSlope;
segmentPart->firstPartNum = (target + currentSpeed) / 2 * decTime / 1000;
}
else
{
segmentPart->firstPartNum = 0;
}
segmentPart->secondPartNum = targetPulseCount
- segmentPart->firstPartNum
- segmentPart->thirdPartNum;
}


static void FirstSegmentProc(SEGMENT_PART *segmentPart)
{
int32_t targetFreq = 0;
int32_t slope = 0;
int32_t diffValue = 0;

if (currentSpeed == plsr.segment[currentSegment].pulseFreq)
segmentPart->currentState = 1;
else if ((currentSpeed < plsr.segment[currentSegment].pulseFreq))
segmentPart->currentState = 2;
else
segmentPart->currentState = 3;
switch (segmentPart->currentState)
{
/* 匀速处理 */
case 1 :
{
segmentPart->currentPart = 2;
break;
}
/* 加速处理 */
case 2 :
{
targetFreq = plsr.segment[currentSegment].pulseFreq;
slope = plsr.defaultSpeed / plsr.defaultAccSpeedTime;
segmentPart->inc = ((targetFreq - currentSpeed) / slope)
* ((targetFreq + currentSpeed) / 2) / 1000;
segmentPart->inc = (targetFreq - currentSpeed) / segmentPart->inc;

break;
}
/* 减速处理 */
case 3 :
{
targetFreq = plsr.segment[currentSegment].pulseFreq;
slope = plsr.defaultSpeed / plsr.defaultDecSpeedTime;
segmentPart->dec = ((currentSpeed - targetFreq) / slope)
* ((currentSpeed + targetFreq) / 2) / 1000;
segmentPart->dec = (currentSpeed - targetFreq) / segmentPart->dec;

break;
}
}

if (currentSpeed <= 1000)
{
tim10.setPsc(&tim10, 2625 - 1);
}
else
{
tim10.setPsc(&tim10, 3 - 1);
}
if (currentSpeed != 0)
tim10.setPer(&tim10, 168000000 / (TIM10->PSC + 1) / currentSpeed);
else
tim10.setPer(&tim10, 1000);
tim10.registerIrq(&tim10, TimCallBack, &currentSeg.currentPart);
tim10.open(&tim10);
tim10.openIrq(&tim10);
}


static void SecondSegmentProc(SEGMENT_PART *segmentPart)
{

}


static void ThirdSegmentProc(SEGMENT_PART *segmentPart)
{

}

+ 60
- 0
TrainCamp_zhangcheng_PLSR/bsp/inc/time.h View File

@@ -0,0 +1,60 @@
/**
* @file time.h
* @author zhangcheng
* @brief 定时器及PWM输出接口文件
* @version v0.1
* @date 2025-08-06
*
* @copyright Copyright (c) 2025
*/


#ifndef _time_H
#define _time_H

#include "stm32f4xx.h"


/**
* @brief 定时器数据结构
* @details
* @note
* @attention
*/
typedef struct TIM
{
TIM_TypeDef *TIM;
int8_t (*init)(struct TIM *tim, uint16_t psc, uint32_t per);
void (*deInit)(struct TIM *tim);
void (*setPsc)(struct TIM *tim, uint16_t psc);
void (*setPer)(struct TIM *tim, uint32_t per);
void (*open)(struct TIM *tim);
void (*close)(struct TIM *tim);
void (*openIrq)(struct TIM *tim);
void (*closeIrq)(struct TIM *tim);
void (*registerIrq)(struct TIM *tim, void (*registerFunc)(void *pArg),
void *pArg);
void (*pwmInit)(struct TIM *tim);
void (*pwmDeInit)(struct TIM *tim);
void (*pwmSetPulse)(struct TIM *tim, uint32_t pulse);
} TIM_OBJ;


/**
* @brief 获取定时器
* @details
*
* @param[in] *timName 定时器名称
*
* @param[out] *timObj 接收定时器参数地址
*
* @return int8_t 返回结果
* @retval 0 成功
* @retval -1 失败
*
* @note *timName "timx" x : 10、11、13、14
*/
int8_t GetTimObj(char *timName, TIM_OBJ *timObj);

#endif


+ 26
- 1
TrainCamp_zhangcheng_PLSR/bsp/src/gpio.c View File

@@ -187,6 +187,30 @@ static gpio_obj_t g_stm32f103_gpio_g = {
&g_stm32f103_gpio_g_priv
};


/* GPIOH私有数据 */
static gpio_priv_obj_t g_stm32f103_gpio_h_priv = {
GPIOH,
GPIO_Mode_IN,
(GPIOOType_TypeDef)0,
(GPIOPuPd_TypeDef)0,
RCC_AHB1Periph_GPIOH
};
/* GPIOH结构体对象 */
static gpio_obj_t g_stm32f103_gpio_h = {
"gpio_h",
0,
"gpio_mode",
gpio_init,
gpio_deinit,
gpio_set_output,
gpio_read_output,
gpio_read_input,
gpio_open_irq,
gpio_close_irq,
&g_stm32f103_gpio_h_priv
};

/* GPIO外设列表 */
static gpio_obj_t *g_gpio_devs[] = {
&g_stm32f103_gpio_a,
@@ -195,7 +219,8 @@ static gpio_obj_t *g_gpio_devs[] = {
&g_stm32f103_gpio_d,
&g_stm32f103_gpio_e,
&g_stm32f103_gpio_f,
&g_stm32f103_gpio_g
&g_stm32f103_gpio_g,
&g_stm32f103_gpio_h
};

/* GPIO模式私有数据列表 */


+ 438
- 0
TrainCamp_zhangcheng_PLSR/bsp/src/time.c View File

@@ -0,0 +1,438 @@
/**
* @file time.h
* @author zhangcheng
* @brief 定时器及PWM输出接口文件
* @version v0.1
* @date 2025-08-06
*
* @copyright Copyright (c) 2025
*/


#include "../../system/inc/system.h"
#include "../inc/time.h"


/* 中断注册回调函数类型 */
typedef void (*Func)(void *pArg);

/* 中断注册回调函数列表 */
static Func CallBackFuncList[] =
{
NULL, ///< TIM2
NULL ///< TIM10
};

/* 中断注册回调参数列表 */
static void *ArgList[] =
{
NULL, ///< TIM2
NULL ///< TIM10
};

/* 可用定时器列表 */
static char *TimNameList[] =
{
"tim2", ///< TIM2
"tim10", ///< TIM10
"tim11", ///< TIM11
"tim13", ///< TIM13
"tim14" ///< TIM14
};

/* 可用定时器列表参数 */
static TIM_TypeDef *TimType[] =
{
TIM2, ///< TIM2
TIM10, ///< TIM10
TIM11, ///< TIM11
TIM13, ///< TIM13
TIM14 ///< TIM14
};


/**
* @brief 定时器初始化
* @details
*
* @param[in] *tim 定时器结构体指针
* @param[in] psc 定时器预分频系数
* @param[in] per 定时器重装载值
*
* @return int8_t 返回结果
* @retval 0 成功
* @retval -1 失败
*/
int8_t TimInit(TIM_OBJ *tim, uint16_t psc, uint32_t per)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;

if (tim->TIM == TIM2)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);

GPIO_PinAFConfig(GPIOA, GPIO_PinSource15, GPIO_AF_TIM2);

TIM_SelectInputTrigger(tim->TIM, TIM_TS_ETRF);
TIM_ETRClockMode2Config(tim->TIM, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0);
}
else if (tim->TIM == TIM10)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10,ENABLE);
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
}
else if (tim->TIM == TIM11)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11,ENABLE);
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
}
else if (tim->TIM == TIM13)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13,ENABLE);
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
}
else if (tim->TIM == TIM14)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
}
else
return -1;

if (tim->TIM != TIM2)
TIM_InternalClockConfig(tim->TIM);

TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseInitStructure.TIM_Period=per;
TIM_TimeBaseInitStructure.TIM_Prescaler=psc;
TIM_TimeBaseInit(tim->TIM, &TIM_TimeBaseInitStructure);

// TIM_GenerateEvent(tim->TIM, TIM_EventSource_Update);
TIM_ClearITPendingBit(tim->TIM, TIM_IT_Update);

return 0;
}


/**
* @brief 定时器复位
* @details
*
* @param[in] *tim 定时器结构体指针
*
* @return 无
*/
void TimDeInit(TIM_OBJ *tim)
{
if (tim->TIM == TIM2)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,DISABLE);
else if (tim->TIM == TIM10)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM10,DISABLE);
else if (tim->TIM == TIM11)
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM11,DISABLE);
else if (tim->TIM == TIM13)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM13,DISABLE);
else if (tim->TIM == TIM14)
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,DISABLE);
else
return;

TIM_Cmd(tim->TIM, DISABLE);
TIM_DeInit(tim->TIM);
}


/**
* @brief 设置定时器预分频
* @details
*
* @param[in] *tim 定时器结构体指针
* @param[in] psc 定时器预分频系数
*
* @return 无
*/
void TimSetPsc(TIM_OBJ *tim, uint16_t psc)
{
TIM_ITConfig(tim->TIM, TIM_IT_Update, DISABLE);
TIM_PrescalerConfig(tim->TIM, psc, TIM_PSCReloadMode_Immediate);
TIM_ClearITPendingBit(tim->TIM, TIM_IT_Update);
TIM_ITConfig(tim->TIM, TIM_IT_Update, ENABLE);
}


/**
* @brief 设置定时器重载值
* @details
*
* @param[in] *tim 定时器结构体指针
* @param[in] per 定时器重装载值
*
* @return 无
*/
void TimSetPer(TIM_OBJ *tim, uint32_t per)
{
TIM_SetAutoreload(tim->TIM, per);
}


/**
* @brief 开启定时器
* @details
*
* @param[in] *tim 定时器结构体指针
*
* @return 无
*/
void TimOpen(TIM_OBJ *tim)
{
TIM_Cmd(tim->TIM, ENABLE);
}


/**
* @brief 关闭定时器
* @details
*
* @param[in] *tim 定时器结构体指针
*
* @return 无
*/
void TimClose(TIM_OBJ *tim)
{
TIM_Cmd(tim->TIM, DISABLE);
}


/**
* @brief 开启定时器更新中断
* @details
*
* @param[in] *tim 定时器结构体指针
*
* @return 无
*/
void TimOpenIrq(TIM_OBJ *tim)
{
NVIC_InitTypeDef NVIC_InitStructure;

TIM_ITConfig(tim->TIM, TIM_IT_Update, ENABLE);
TIM_ClearITPendingBit(tim->TIM, TIM_IT_Update);
if (tim->TIM == TIM2)
NVIC_InitStructure.NVIC_IRQChannel=TIM2_IRQn;
else if(tim->TIM == TIM10)
NVIC_InitStructure.NVIC_IRQChannel=TIM1_UP_TIM10_IRQn;
else
return;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=7;
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);
}


/**
* @brief 关闭定时器更新中断
* @details
*
* @param[in] *tim 定时器结构体指针
*
* @return 无
*/
void TimCloseIrq(TIM_OBJ *tim)
{
TIM_ITConfig(tim->TIM, TIM_IT_Update, DISABLE);
TIM_ClearITPendingBit(tim->TIM, TIM_IT_Update);
}


/**
* @brief 注册定时器中断回调函数
* @details
*
* @param[in] *tim 定时器结构体指针
* @param[in] registerFunc 回调函数地址
* @note 回调函数格式 void (*registerFunc)(void *pArg)
*
* @return 无
*/
void TimRegisterIrq(TIM_OBJ *tim, void (*registerFunc)(void *pArg), void *pArg)
{
if (tim->TIM == TIM2)
{
CallBackFuncList[0] = registerFunc;
ArgList[0] = pArg;
}
else if (tim->TIM == TIM10)
{
CallBackFuncList[1] = registerFunc;
ArgList[1] = pArg;
}
else
return;
}


/**
* @brief PWM初始化
* @details
*
* @param[in] *tim 定时器结构体指针
* @param[in] pulse 脉冲宽度
*
* @return 无
*/
void PwmInit(TIM_OBJ *tim)
{
TIM_OCInitTypeDef TIM_OCInitStructure;

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
GPIO_PinAFConfig(GPIOF, GPIO_PinSource6, GPIO_AF_TIM10);

GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOF,&GPIO_InitStructure);

TIM_OCStructInit(&TIM_OCInitStructure);
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OutputState = ENABLE;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OC1Init(tim->TIM, &TIM_OCInitStructure);
}



/**
* @brief PWM复位
* @details
*
* @param[in] *tim 定时器结构体指针
*
* @return 无
*/
void PwmDeInit(TIM_OBJ *tim)
{
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_OCInitStructure.TIM_OutputState = DISABLE;
TIM_OCInitStructure.TIM_Pulse = 0;
TIM_OC1Init(tim->TIM, &TIM_OCInitStructure);
}


/**
* @brief 设置PWM脉冲宽度
* @details
*
* @param[in] *tim 定时器结构体指针
* @param[in] pulse PWM脉冲宽度
*
* @return 无
*/
void PwmSetPulse(TIM_OBJ *tim, uint32_t pulse)
{
TIM_SetCompare1(tim->TIM, pulse);
}


/**
* @brief 定时器2更新中断服务函数
* @details
*
* @param[in] 无
*
* @return 无
*/
void TIM2_IRQHandler(void)
{
if (TIM_GetITStatus(TIM2,TIM_IT_Update) == SET)
{
if (CallBackFuncList[0] != NULL)
CallBackFuncList[0](ArgList[0]);
TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
}
}


/**
* @brief 定时器13更新中断服务函数
* @details
*
* @param[in] 无
*
* @return 无
*/
void TIM1_UP_TIM10_IRQHandler(void)
{
if (TIM_GetITStatus(TIM10,TIM_IT_Update) == SET)
{
if (ArgList[1] != NULL)
CallBackFuncList[1](ArgList[1]);
TIM_ClearITPendingBit(TIM10, TIM_IT_Update);
}
}


/**
* @brief 获取定时器
* @details
*
* @param[in] *timName 定时器名称
* @note "timx" x : 10、11、13、14
* @param[out] *timObj 接收定时器参数地址
*
* @return int8_t 返回结果
* @retval 0 成功
* @retval -1 失败
*/
int8_t GetTimObj(char *timName, TIM_OBJ *timObj)
{
uint8_t getTimFlag = 0;

if (!timObj)
return -1;

for (uint8_t i = 0; i < sizeof(TimNameList) / sizeof(TimNameList[0]); i++)
{
if (strcmp(timName, TimNameList[i]) == 0)
{
timObj->TIM = TimType[i];
getTimFlag = 1;
break;
}
}

if (!getTimFlag)
return -1;

timObj->init = &TimInit;
timObj->deInit = &TimDeInit;
timObj->setPsc = &TimSetPsc;
timObj->setPer = &TimSetPer;
timObj->open = &TimOpen;
timObj->close = &TimClose;
timObj->openIrq = &TimOpenIrq;
timObj->closeIrq = &TimCloseIrq;
timObj->registerIrq = &TimRegisterIrq;
timObj->pwmInit = &PwmInit;
timObj->pwmDeInit = &PwmDeInit;
timObj->pwmSetPulse = &PwmSetPulse;

return 0;
}

+ 6
- 0
TrainCamp_zhangcheng_PLSR/iar/PLSR.ewp View File

@@ -2122,6 +2122,9 @@
<file>
<name>$PROJ_DIR$\..\app\src\main.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\app\src\plsr.c</name>
</file>
</group>
<group>
<name>BSP</name>
@@ -2131,6 +2134,9 @@
<file>
<name>$PROJ_DIR$\..\bsp\src\led.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\bsp\src\time.c</name>
</file>
</group>
<group>
<name>CMSIS</name>


+ 0
- 11
TrainCamp_zhangcheng_PLSR/modbus/inc/modbus.h View File

@@ -8,17 +8,6 @@
* @copyright Copyright (c) 2025
*/


/**
* @file modbus.h
* @author zhangcheng
* @brief modbus相关数据结构文件
* @version v0.1
* @date 2025-07-25
*
* @copyright Copyright (c) 2025
*/

#ifndef _MODBUS_H
#define _MODBUS_H


+ 1
- 3
TrainCamp_zhangcheng_PLSR/modbus/src/modbus_ack_module.c View File

@@ -76,9 +76,7 @@ RESUIL AckProcModuleInit(void)
*
* @param[in] *pArg 任务参数
*
* @return RESUIL 初始化结果
* @retval MODBUS_TURE 成功
* @retval MODBUS_FALSE 失败
* @return 无
*/
static void AckProcModuleTask(void *pArg)
{


+ 1
- 3
TrainCamp_zhangcheng_PLSR/modbus/src/modbus_link_check_module.c View File

@@ -76,9 +76,7 @@ RESUIL linkCheckModuleInit(void)
*
* @param[in] *pArg 任务参数
*
* @return RESUIL 初始化结果
* @retval MODBUS_TURE 成功
* @retval MODBUS_FALSE 失败
* @return 无
*/
static void LinkCheckModuleTask(void *pArg)
{


+ 1
- 3
TrainCamp_zhangcheng_PLSR/modbus/src/modbus_operate_module.c View File

@@ -77,9 +77,7 @@ RESUIL OperateProcModuleInit(void)
*
* @param[in] *pArg 任务参数
*
* @return RESUIL 初始化结果
* @retval MODBUS_TURE 成功
* @retval MODBUS_FALSE 失败
* @return 无
*/
static void OperateProcModuleTask(void *pArg)
{


+ 0
- 350
TrainCamp_zhangcheng_PLSR/modbus/src/modbus_operate_module.c~RF1ad0af.TMP View File

@@ -1,350 +0,0 @@
/**
* @file modbus_operate_module.c
* @author zhangcheng
* @brief modbus请求操作处理模块源文件
* @version v0.1
* @date 2025-07-25
*
* @copyright Copyright (c) 2025
*/


#include "../../SYSTEM/inc/system.h"
#include "../inc/modbus_operate_module.h"
#include "../inc/modbus_request_module.h"
#include "../inc/modbus_ack_module.h"
#include "../inc/CRC16.h"

#define OPERATE_PROC_MODULE_PRIO 3
#define OPERATE_PROC_MODULE_STACK_SIZE 1024
static CPU_STK OperateProcModuleStack[OPERATE_PROC_MODULE_STACK_SIZE];
static OS_TCB OperateProcModuleTcb;
static OS_Q AckQueue;
static void OperateProcModuleTask(void * pArg);

static uint16_t FlashBuffer[10000];

/**
* @brief 操作处理模块初始化
* @details
*
* @param[in] 无
*
* @return RESUIL 初始化结果
* @retval MODBUS_TURE 成功
* @retval MODBUS_FALSE 失败
*/
RESUIL OperateProcModuleInit(void)
{
OS_ERR err;

CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();

OSTaskCreate( (OS_TCB * )&OperateProcModuleTcb,
(CPU_CHAR * )"OperateProcModule",
(OS_TASK_PTR )OperateProcModuleTask,
(void * )0,
(OS_PRIO )OPERATE_PROC_MODULE_PRIO,
(CPU_STK * )OperateProcModuleStack,
(CPU_STK_SIZE )OPERATE_PROC_MODULE_STACK_SIZE / 10,
(CPU_STK_SIZE )OPERATE_PROC_MODULE_STACK_SIZE,
(OS_MSG_QTY )0,
(OS_TICK )0,
(void * )0,
(OS_OPT )(OS_OPT_TASK_STK_CHK | OS_OPT_TASK_STK_CLR),
(OS_ERR * )&err);
if(err != OS_ERR_NONE)
{
MODBUS_LOG("OperateProcModule init fail\r\n");
return MODBUS_FALSE;
}

OSQCreate(&AckQueue, "AckQueue", 1, &err);
if(err != OS_ERR_NONE)
{
MODBUS_LOG("OperateProcModule data queue create fail\r\n");
OSTaskDel(&OperateProcModuleTcb, &err);
return MODBUS_FALSE;
}

CPU_CRITICAL_EXIT();
return MODBUS_TURE;
}



/**
* @brief 请求帧处理模块
* @details
*
* @param[in] *pArg 任务参数
*
* @return RESUIL 初始化结果
* @retval MODBUS_TURE 成功
* @retval MODBUS_FALSE 失败
*/
static void OperateProcModuleTask(void *pArg)
{
OS_ERR err = OS_ERR_NONE;

REQUEST_FRAME requestFrame;
ACK_FRAME ackFrame;
RESUIL res;

uint8_t *pCoil = (uint8_t *)COIL_REGISTER_ADRR;
uint16_t *pDataRegister = (uint16_t *)DATA_REGISTER_ADRR;
uint16_t *pKeepRegister = (uint16_t *)KEEP_REGISTER_ADRR;

while(1)
{
/* 阻塞式接收请求数据帧 */
res = RequestOperateDataRead(&requestFrame, 0);

if (res != MODBUS_TURE)
{
continue;
}
ackFrame.deviceNumber = requestFrame.deviceNumber;
ackFrame.functionCode = requestFrame.functionCode;

switch (requestFrame.functionCode)
{
case READ_COIL:
{
ackFrame.operateType = OPERATE_READ;
ackFrame.operateObjType = OPERATE_COIL;
ackFrame.format = MODBUS_STANDARD;
ackFrame.returnByteCount = requestFrame.readCount / 8;
ackFrame.data = pCoil + (requestFrame.memoryAddr / 8);
ackFrame.errorCode = ERROR_NONE;
OSQPost(&AckQueue, &ackFrame, 1,
OS_OPT_POST_FIFO | OS_OPT_POST_NO_SCHED, &err);
AckProcModuleSetFlags(NORMAL_FLAG_BIT);
break;
}
case READ_KEEP_REGISTER:
{
ackFrame.operateType = OPERATE_READ;
ackFrame.operateObjType = OPERATE_REGISTER;
ackFrame.format = MODBUS_STANDARD;
ackFrame.returnByteCount = requestFrame.readCount * 2;
if ( requestFrame.memoryAddr < 0x270F)
{
ackFrame.data = (uint8_t *)(pDataRegister + requestFrame.memoryAddr);
}
else
{
requestFrame.memoryAddr -= 0xA080;
//ackFrame.data = (uint8_t *)(pKeepRegister + requestFrame.memoryAddr);
ackFrame.data = (uint8_t *)(FlashBuffer + requestFrame.memoryAddr);
}
//ackFrame.data = (uint8_t *)(pKeepRegister + requestFrame.memoryAddr);
ackFrame.errorCode = ERROR_NONE;
OSQPost(&AckQueue, &ackFrame, 1,
OS_OPT_POST_FIFO | OS_OPT_POST_NO_SCHED, &err);
AckProcModuleSetFlags(NORMAL_FLAG_BIT);
break;
}
case WRITE_ONE_COIL:
{
ackFrame.operateType = OPERATE_WRITE;
ackFrame.operateObjType = OPERATE_COIL;
ackFrame.format = MODBUS_STANDARD;
ackFrame.returnByteCount = requestFrame.readCount;
ackFrame.memoryAddr = requestFrame.memoryAddr;
ackFrame.data = pCoil + (requestFrame.memoryAddr / 8);

if (requestFrame.data[0] == 0xFF)
{
*ackFrame.data |= (0x01 << (requestFrame.memoryAddr % 8));
}
else
{
*ackFrame.data &= ~(0x01 << (requestFrame.memoryAddr % 8));
}

ackFrame.errorCode = ERROR_NONE;
OSQPost(&AckQueue, &ackFrame, 1,
OS_OPT_POST_FIFO | OS_OPT_POST_NO_SCHED, &err);
AckProcModuleSetFlags(NORMAL_FLAG_BIT);

break;
}
case WRITE_COIL:
{
ackFrame.operateType = OPERATE_WRITE;
ackFrame.operateObjType = OPERATE_COIL;
ackFrame.format = MODBUS_STANDARD;
ackFrame.returnByteCount = requestFrame.writeCount;
ackFrame.memoryAddr = requestFrame.memoryAddr;
ackFrame.data = pCoil + (requestFrame.memoryAddr / 8);
uint8_t offset = requestFrame.memoryAddr % 8;

for (uint16_t i = 0; i < requestFrame.writeByteLenght; i++)
{
for (uint8_t j = 0; j < 8; j++)
{
if (*requestFrame.data & (0x01 << j))
{
*ackFrame.data |= (1 << offset);
}
else
{
*ackFrame.data &= ~(1 << offset);
}
offset++;
if (offset == 8)
{
offset = 0;
ackFrame.data++;
}
}
requestFrame.data++;
}
ackFrame.errorCode = ERROR_NONE;
OSQPost(&AckQueue, &ackFrame, 1,
OS_OPT_POST_FIFO | OS_OPT_POST_NO_SCHED, &err);
AckProcModuleSetFlags(NORMAL_FLAG_BIT);
break;
}
case WRITE_KEEP_REGISTER:
{
ackFrame.operateType = OPERATE_WRITE;
ackFrame.operateObjType = OPERATE_REGISTER;
ackFrame.format = MODBUS_STANDARD;
ackFrame.returnByteCount = requestFrame.writeCount;
ackFrame.memoryAddr = requestFrame.memoryAddr;

if ( requestFrame.memoryAddr < 0x270F)
{
ackFrame.data = (uint8_t *)(pDataRegister + requestFrame.memoryAddr);

for (uint16_t i = 0; i < requestFrame.writeCount; i++)
{
((uint16_t *)ackFrame.data)[i] = (requestFrame.data[2*i] << 8) | requestFrame.data[2*i+1];
}
ackFrame.errorCode = ERROR_NONE;
OSQPost(&AckQueue, &ackFrame, 1,
OS_OPT_POST_FIFO | OS_OPT_POST_NO_SCHED, &err);
AckProcModuleSetFlags(NORMAL_FLAG_BIT);
}
else
{
requestFrame.memoryAddr -= 0xA080;
//ackFrame.data = (uint8_t *)(pKeepRegister + requestFrame.memoryAddr);
ackFrame.data = (uint8_t *)(FlashBuffer + requestFrame.memoryAddr);
}
FLASH_Unlock();
FLASH_DataCacheCmd(ENABLE);

memcpy((void *)FlashBuffer, (void *)KEEP_REGISTER_ADRR, KEEP_REGISTER_SIZE);
while (FLASH_GetStatus() != FLASH_COMPLETE);

for (uint16_t i = 0; i < requestFrame.writeCount; i++)
{
FlashBuffer[requestFrame.memoryAddr + i] = (requestFrame.data[2*i] << 8) | requestFrame.data[2*i+1];
}
ackFrame.errorCode = ERROR_NONE;
OSQPost(&AckQueue, &ackFrame, 1,
OS_OPT_POST_FIFO, &err);
AckProcModuleSetFlags(NORMAL_FLAG_BIT);
// FLASH_EraseSector(FLASH_Sector_4, VoltageRange_3);
for (uint16_t i = 0; i < KEEP_REGISTER_SIZE / 2; i++)
{
// FLASH_ProgramHalfWord((uint32_t)KEEP_REGISTER_ADRR + 2 * i, FlashBuffer[i]);
while (FLASH_GetStatus() != FLASH_COMPLETE);
}

FLASH_DataCacheCmd(ENABLE);
FLASH_Lock();
break;
}
case READ_OUT_SCOPE_REGISTER: //0x10000 ~ 0x1A000 40KB
{
ackFrame.operateType = OPERATE_READ;
ackFrame.operateObjType = OPERATE_REGISTER;
ackFrame.format = MODBUS_EXT;
ackFrame.returnByteCount = requestFrame.readCount * 2;
ackFrame.data = (uint8_t *)((DATA_REGISTER_ADRR + DATA_REGISTER_NUMBER) + requestFrame.extMemoryAddr - 0x10000);
ackFrame.errorCode = ERROR_NONE;
OSQPost(&AckQueue, &ackFrame, 1,
OS_OPT_POST_FIFO | OS_OPT_POST_NO_SCHED, &err);
AckProcModuleSetFlags(NORMAL_FLAG_BIT);
break;
}
case READ_ALL_SINGULAR_REGISTER:
{
ackFrame.operateType = OPERATE_READ;
ackFrame.operateObjType = OPERATE_REGISTER;
ackFrame.format = MODBUS_STANDARD;
ackFrame.returnByteCount = 0xFFFF;
ackFrame.memoryAddr = requestFrame.memoryAddr;
ackFrame.data = (uint8_t *)(pDataRegister + requestFrame.memoryAddr);
ackFrame.errorCode = ERROR_NONE;
OSQPost(&AckQueue, &ackFrame, 1,
OS_OPT_POST_FIFO | OS_OPT_POST_NO_SCHED, &err);
AckProcModuleSetFlags(NORMAL_FLAG_BIT);
break;
}
case READ_CORRESPONDENCE_HISTORY:
{
ackFrame.data = (uint8_t *)0x08020000;
OSQPost(&AckQueue, &ackFrame, 1,
OS_OPT_POST_FIFO | OS_OPT_POST_NO_SCHED, &err);
AckProcModuleSetFlags(NORMAL_FLAG_BIT);
break;
break;
}
}
}
}


/**
* @brief 读取请求帧
* @details
*
* @param[out] *requestFrame 接收请求数据帧结构体地址
* @param[in] timeOut 读取请求帧数据超时时间
*
* @return RESUIL 读取结果
* @retval MODBUS_TURE 成功
* @retval MODBUS_FALSE 失败
*/
RESUIL OperateAckFrameRead(ACK_FRAME *ackFrame, OS_TICK timeOut)
{
OS_ERR err;
OS_MSG_SIZE msgSize;
void *pMsgAddr = NULL;

pMsgAddr = OSQPend(&AckQueue,
timeOut,
OS_OPT_PEND_BLOCKING,
&msgSize,
0,
&err);

if (err == OS_ERR_NONE)
{
memcpy(ackFrame, pMsgAddr, sizeof(ACK_FRAME));
return MODBUS_TURE;
}
else
return MODBUS_FALSE;
}

+ 40
- 4
TrainCamp_zhangcheng_PLSR/modbus/src/modbus_request_module.c View File

@@ -79,7 +79,19 @@ RESUIL RequestProcModuleInit(void)



RESUIL AddrIsTure(uint8_t *data, uint8_t dataLenght, ACK_FRAME *ackFrame)
/**
* @brief 判断地址是否合法
* @details
*
* @param[in] *data 地址起始字节
* @param[in] *dataLenght 地址长度
* @param[out] *ackFrame 异常码输出
*
* @return RESUIL 检测结果
* @retval MODBUS_TURE 成功
* @retval MODBUS_FALSE 失败
*/
static RESUIL AddrIsTure(uint8_t *data, uint8_t dataLenght, ACK_FRAME *ackFrame)
{
uint32_t addr;
if (dataLenght == 2)
@@ -114,6 +126,20 @@ RESUIL AddrIsTure(uint8_t *data, uint8_t dataLenght, ACK_FRAME *ackFrame)
return MODBUS_FALSE;
}



/**
* @brief 判断数据长度是否合法
* @details
*
* @param[in] *countLenght 计算的数据长度
* @param[in] *buffLenght 接收到的数据长度
* @param[out] *ackFrame 异常码输出
*
* @return RESUIL 检测结果
* @retval MODBUS_TURE 成功
* @retval MODBUS_FALSE 失败
*/
RESUIL DataLenghtIsTure(uint16_t countLenght, uint16_t buffLenght, ACK_FRAME *ackFrame)
{
if (countLenght != buffLenght)
@@ -128,6 +154,18 @@ RESUIL DataLenghtIsTure(uint16_t countLenght, uint16_t buffLenght, ACK_FRAME *ac
}
}


/**
* @brief 判断数据长度是否为零
* @details
*
* @param[in] *data 数据帧数据长度起始地址
* @param[out] *ackFrame 异常码输出
*
* @return RESUIL 检测结果
* @retval MODBUS_TURE 成功
* @retval MODBUS_FALSE 失败
*/
RESUIL DataCountIsZero(uint8_t *data, ACK_FRAME *ackFrame)
{
if (((data[0] << 8) | data[1]) == 0)
@@ -149,9 +187,7 @@ RESUIL DataCountIsZero(uint8_t *data, ACK_FRAME *ackFrame)
*
* @param[in] *pArg 任务参数
*
* @return RESUIL 初始化结果
* @retval MODBUS_TURE 成功
* @retval MODBUS_FALSE 失败
* @return 无
*/
static void RequestProcModuleTask(void *pArg)
{


+ 1
- 1
TrainCamp_zhangcheng_PLSR/system/src/system.c View File

@@ -8,5 +8,5 @@ void system_hardware_init(void)
usart1 = get_usart_obj("usart1");
if(NULL == usart1)
while(1);
usart1->usart_init(usart1, 19200, 9, 1, 2);
usart1->usart_init(usart1, 19200, 9, 1, 1);
}

+ 1
- 1
TrainCamp_zhangcheng_PLSR/system/src/usart.c View File

@@ -21,7 +21,7 @@ void _sys_exit(int x)
//重定义fputc函数
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);//循环发送,直到发送完毕
while((USART1->SR&0X80)==0);//循环发送,直到发送完毕
USART1->DR = (u8) ch;
return ch;
}


Loading…
Cancel
Save