コミットを比較

...

11 コミット

作成者 SHA1 メッセージ 日付
  1923777848 85b6075f9b 增加绝对模式 10時間前
  1923777848 17b02e2aed 过程性保存 1日前
  1923777848 9e3fa14782 增加减速功能 1日前
  1923777848 16daa756ed 修改输出计数误差 1日前
  1923777848 eede0ad12f 增加脉冲输出计数 1日前
  1923777848 0d58029f71 优化跳转时多段波形逻辑 2日前
  1923777848 ba4a9f0c58 增加直线加减速多段跳转功能 2日前
  1923777848 42778b3d2c 增加直线加减速功能 3日前
  1923777848 49d9775f1f 添加PLSR.c 6日前
  1923777848 62d4addc0c 添加PLSR.c 6日前
  1923777848 8b72eb7900 增加定时器配置 1週間前
16個のファイルの変更1382行の追加409行の削除
分割表示
  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. +621
    -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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();
}


+ 621
- 0
TrainCamp_zhangcheng_PLSR/app/src/plsr.c ファイルの表示

@@ -0,0 +1,621 @@
/**
* @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"
#include "../../system/inc/usart.h"

/* 速度波形发送任务使能 */
#define SPEED_SEND_TASK 0

#if (SPEED_SEND_TASK)
#define SPEED_SEND_MODULE_PRIO 20
#define SPEED_SEND_MODULE_STACK_SIZE 200
static OS_STK SpeedSendModuleStack[SPEED_SEND_MODULE_STACK_SIZE];
static void SpeedSendModuleTask(void * pArg);
void UsartSend(uint32_t data)
{
extern usart_obj_t *usart1;
uint8_t buff[4];
buff[0] = (uint8_t)((data) >> 24);
buff[1] = (uint8_t)((data) >> 16);
buff[2] = (uint8_t)((data) >> 8);
buff[3] = (uint8_t)((data));
for (uint8_t i = 0; i < 4; i++)
{
USART_SendData(USART1, buff[i]);//发送一个字节
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) != SET);
}
}
#define USART_SEND_SPEED(x) UsartSend(x)
#endif


/* 求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 StartPulseOutput(void);
static void StopPulseOutput(void);

/**
* @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;
}

#if (SPEED_SEND_TASK)
err = OSTaskCreate(
SpeedSendModuleTask,
NULL,
&SpeedSendModuleStack[SPEED_SEND_MODULE_STACK_SIZE - 1],
SPEED_SEND_MODULE_PRIO);

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

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;
uint8_t currentSegmentID = 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 = 3000,
.segment[2].jumpNumber = 0,
.segment[3].pulseFreq = 6000,
.segment[3].pulseNumber = 100000,
.segment[3].jumpNumber = 0,
.startRunSegment = 1,
.outMode = ABSOLUTE_MODE,
.accDecSpeedMode = STRAIGHT_LINE_MODE,
.sendEnableState = 1
};
static void PlsrModuleTask(void *pArg)
{
//ReadRegisterParam(&plsr);

GetTimObj("tim2", &tim2);
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);

currentSegmentID = plsr.startRunSegment;
currentSegment = currentSegmentID - 1;

int tmpTIMARR = 0;
while (1)
{
// ReadRegisterParam(&plsr);
tmpTIMARR = TIM2->ARR + 1;
CumulativePulseCount = tim2OverCnt * tmpTIMARR + 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.sendEnableState != 1) || (RunFlag == 1))
{
continue;
}
if (plsr.outMode == ABSOLUTE_MODE)
{
if (plsr.monitorPulseNum
== plsr.segment[currentSegment].pulseNumber)
{
plsr.sendEnableState = 0;
StopPulseOutput();
continue;
}
}

if ((plsr.accDecSpeedMode == STRAIGHT_LINE_MODE) && (RunFlag == 0))
{
RunFlag = 1;
configPulsePort(&plsr);
ComputePartNum(&plsr, &currentSeg);
StartPulseOutput();
}
}
}

static void SpeedSendModuleTask(void * pArg)
{
while(1)
{
#if (SPEED_SEND_TASK)
if (plsr.sendEnableState == 1)
USART_SEND_SPEED(currentSpeed);
#endif
}
}
//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;
// currentSeg.currentPart = 2;
}

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;
// currentSeg.currentPart = 2;
}

break;
}
default:
{
break;
}
}
}
else if (currentSeg.currentPart == 2)
{
if (pulseCount > currentSeg.secondPartNum - 1)
{
if ((currentSegmentID == (plsr.segmentAllNum))
&& (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 - 1;
currentSegmentID = currentSegment + 1;
}
allcount++;
pulseCount++;
}
else if (currentSeg.currentPart == 3)
{
if (((currentSpeed - currentSeg.dec) <= 0)
|| (pulseCount > currentSeg.thirdPartNum - 2))
{
currentSpeed = 0;
pulseCount = 0;
currentSeg.currentPart = 1;

StopPulseOutput();

allcount++;
plsr.sendEnableState = 0;
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 = (int16_t *)(DATA_REGISTER_ADRR + 0x1000);

plsr->outputPort = (PLSR_OUTPUT_PORT)pDataRegister[0];
plsr->dirPort = (PLSR_OUTPUT_DIR_PORT)pDataRegister[1];
plsr->extPort = (PLSR_INPUT_EXT_PORT)pDataRegister[2];
plsr->dirDelayTime = pDataRegister[3];
plsr->dirLogic = (PLSR_OUTPUT_DIR_PORT_LOGIC)pDataRegister[4];
plsr->accDecSpeedMode = (PLSR_ACC_DEC_SPEED_MODE)pDataRegister[5];
plsr->outMode = (PLSR_OUTPUT_MODE)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)
{
int32_t targetFreq = plsr->segment[currentSegment].pulseFreq;
int32_t targetPulseCount = plsr->segment[currentSegment].pulseNumber;

if (plsr->outMode == ABSOLUTE_MODE)
targetPulseCount -= plsr->monitorPulseNum;

ABS(targetPulseCount);

accSpeedSlope = plsr->defaultSpeed / plsr->defaultAccSpeedTime;
decSpeedSlope = plsr->defaultSpeed / plsr->defaultDecSpeedTime;

/* 计算每段脉冲三个部分脉冲数量 */
/* 最后一段 */
if ((currentSegmentID == (plsr->segmentAllNum))
&& (plsr->segment[currentSegment].jumpNumber == 0))
{
decTime = targetFreq / decSpeedSlope;
segmentPart->thirdPartNum = targetFreq / 2 * decTime / 1000;
if (segmentPart->thirdPartNum > targetPulseCount)
{
segmentPart->thirdPartNum = targetPulseCount;
}
}
else
{
segmentPart->thirdPartNum = 0;
}

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

if ((segmentPart->firstPartNum + segmentPart->thirdPartNum)
>= (targetPulseCount ))
segmentPart->firstPartNum = targetPulseCount - segmentPart->thirdPartNum;

segmentPart->secondPartNum = targetPulseCount
- segmentPart->firstPartNum
- segmentPart->thirdPartNum;

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 :
{
segmentPart->inc = ((targetFreq - currentSpeed) / accSpeedSlope)
* ((targetFreq + currentSpeed) / 2) / 1000;
segmentPart->inc = (targetFreq - currentSpeed) / segmentPart->inc;

break;
}
/* 减速处理 */
case 3 :
{
segmentPart->dec = ((currentSpeed - targetFreq) / decSpeedSlope)
* ((currentSpeed + targetFreq) / 2) / 1000;
segmentPart->dec = (currentSpeed - targetFreq) / segmentPart->dec;

break;
}
}
}


static void StartPulseOutput(void)
{
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 StopPulseOutput(void)
{
currentSpeed = 0;
tim10.setPer(&tim10, 10);
tim10.pwmSetPulse(&tim10, 65535);
tim10.close(&tim10);
tim10.openIrq(&tim10);
}

+ 60
- 0
TrainCamp_zhangcheng_PLSR/bsp/inc/time.h ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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;
}


読み込み中…
キャンセル
保存