This commit is contained in:
Jonathan Roth 2026-03-10 17:31:59 +01:00
parent 6f73c30de2
commit a25b09477b
3 changed files with 47 additions and 27 deletions

View File

@ -8,12 +8,13 @@
// Configuration Modbus RTU
// ─────────────────────────────────────────────
#define RTU_SLAVE_ADDR 0xB7
#define RTU_SLAVE_ADDR 183
#define RTU_FC03 0x03
#define RTU_FC06 0x06
#define RTU_FC16 0x10
#define RTU_HR0_ADDR 0x1700 // Position QEI
#define RTU_HR1_ADDR 0x1701 // Position cible ARM (micropas)
// ─────────────────────────────────────────────
// Timer2 — timeout inter-caractère 3.5×

View File

@ -43,29 +43,30 @@ static void RTU_SendByte(uint8_t byte)
}
// ─────────────────────────────────────────────
// Réponse FC03 — 1 registre
// Réponse FC03 — N registres (max RTU_BUF_SIZE/2)
// ─────────────────────────────────────────────
static void RTU_SendFC03(uint16_t value)
static void RTU_SendFC03(uint16_t *values, uint8_t count)
{
uint8_t resp[5];
uint8_t buf[RTU_BUF_SIZE];
uint8_t byte_count = count * 2;
uint16_t crc;
uint8_t i, len;
resp[0] = RTU_SLAVE_ADDR;
resp[1] = RTU_FC03;
resp[2] = 0x02; // byte count = 2
resp[3] = (value >> 8); // high byte
resp[4] = (value & 0xFF); // low byte
buf[0] = RTU_SLAVE_ADDR;
buf[1] = RTU_FC03;
buf[2] = byte_count;
for (i = 0; i < count; i++) {
buf[3 + i * 2] = values[i] >> 8;
buf[3 + i * 2 + 1] = values[i] & 0xFF;
}
len = 3 + byte_count;
crc = RTU_CRC16(buf, len);
crc = RTU_CRC16(resp, 5);
RTU_SendByte(resp[0]);
RTU_SendByte(resp[1]);
RTU_SendByte(resp[2]);
RTU_SendByte(resp[3]);
RTU_SendByte(resp[4]);
RTU_SendByte(crc & 0xFF); // CRC low
RTU_SendByte(crc >> 8); // CRC high
for (i = 0; i < len; i++)
RTU_SendByte(buf[i]);
RTU_SendByte(crc & 0xFF);
RTU_SendByte(crc >> 8);
}
// ─────────────────────────────────────────────
@ -141,7 +142,7 @@ void RTU_Init(void)
PIE1bits.TMR2IE = 1;
// UART RX interrupt
IPR1bits.RCIP = 0; // RX basse priorité
IPR1bits.RCIP = 0; // basse priorité
PIE1bits.RCIE = 1;
}
@ -225,11 +226,26 @@ void RTU_Task(void)
switch (rx_buf[1]) {
// ── FC03 — Read Holding Registers ────────
case RTU_FC03:
if (reg_addr != RTU_HR0_ADDR || reg_count != 1)
case RTU_FC03: {
uint16_t resp[2];
uint8_t n = 0;
uint8_t i;
if (reg_count == 0 || reg_count > 2)
goto done;
RTU_SendFC03(QEI_ReadPosition());
if (reg_addr < RTU_HR0_ADDR || reg_addr + reg_count - 1 > RTU_HR1_ADDR)
goto done;
for (i = 0; i < reg_count; i++) {
switch (reg_addr + i) {
case RTU_HR0_ADDR: resp[n++] = QEI_ReadPosition(); break;
case RTU_HR1_ADDR: resp[n++] = arm_target_position; break;
default: goto done;
}
}
RTU_SendFC03(resp, n);
break;
}
// ── FC06 — Write Single Register ─────────
case RTU_FC06:
@ -243,6 +259,8 @@ void RTU_Task(void)
ARM_GoToZero();
} else if (reg_addr == SPOOL_REG_FREQ)
SPOOL_SetFreq(value);
else if (reg_addr == SPOOL_REG_RATIO)
ARM_SetRatio(value);
else if (reg_addr == ARM_REG_GEAR)
ARM_SetGear(value);
else if (reg_addr == ARM_REG_OFFSET)
@ -261,8 +279,8 @@ void RTU_Task(void)
uint8_t byte_count = rx_buf[6];
uint8_t i;
// On supporte 0x0800~0x0805, registres contigus
if (reg_addr < REG_CTRL || reg_addr + reg_count - 1 > ARM_REG_RIGHT)
// On supporte 0x0800~0x0806, registres contigus
if (reg_addr < REG_CTRL || reg_addr + reg_count - 1 > SPOOL_REG_RATIO)
goto done;
if (byte_count != reg_count * 2)
goto done;
@ -282,8 +300,9 @@ void RTU_Task(void)
if (value & CTRL_ARM_GO_TO_ZERO)
ARM_GoToZero();
break;
case SPOOL_REG_FREQ: SPOOL_SetFreq(value); break;
case ARM_REG_GEAR: ARM_SetGear(value); break;
case SPOOL_REG_FREQ: SPOOL_SetFreq(value); break;
case SPOOL_REG_RATIO: ARM_SetRatio(value); break;
case ARM_REG_GEAR: ARM_SetGear(value); break;
case ARM_REG_OFFSET: ARM_SetOffset(value); break;
case ARM_REG_LEFT: ARM_SetLeft(value); break;
case ARM_REG_RIGHT: ARM_SetRight(value); break;

View File

@ -25,8 +25,8 @@ void setup(void) {
INTCON3 = 0b11011000; // INT1 interrupt high prio, enabled , wired on DialCLK // INT2 interrupt high prio, enabled , wired on DialCLK
RCONbits.IPEN = 1;
INTCONbits.GIEH = 1; // haute priorité
INTCONbits.GIEL = 1; // basse priorité
INTCONbits.GIEH = 1; // haute priorité
__delay_ms(3000);