dev
This commit is contained in:
parent
6f73c30de2
commit
a25b09477b
@ -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×
|
||||
|
||||
69
src/rtu.c
69
src/rtu.c
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user