|
9 | 9 | #include "AvrModbus.h" |
10 | 10 | #include "crc16.h" |
11 | 11 | /*********************************************************************************/ |
12 | | -#if(AVR_MODBUS_REVISION_DATE != 20191010) |
| 12 | +#if(AVR_MODBUS_REVISION_DATE != 20200623) |
13 | 13 | #error wrong include file. (AvrModbus.h) |
14 | 14 | #endif |
15 | 15 | /*********************************************************************************/ |
@@ -243,6 +243,46 @@ static void SlavePresetMultiple(tag_AvrModbusSlaveCtrl *Slave) |
243 | 243 | } |
244 | 244 | } |
245 | 245 | /*********************************************************************************/ |
| 246 | +static void SlaveReadSerialNumber(tag_AvrModbusSlaveCtrl *Slave) |
| 247 | +{ |
| 248 | + tag_AvrUartRingBuf *TxQue = &Slave->Uart->TxQueue; |
| 249 | + tag_AvrUartRingBuf *RxQue = &Slave->Uart->RxQueue; |
| 250 | + tU16 StartAddr, NumberOfPoint, Crc16, i; |
| 251 | + tU8 *BaseAddr; |
| 252 | + |
| 253 | + StartAddr = (tU16) (RxQue->Buf[2] << 8) + RxQue->Buf[3]; |
| 254 | + NumberOfPoint = (tU16) (RxQue->Buf[4] << 8) + RxQue->Buf[5]; |
| 255 | + |
| 256 | + if(Slave->Bit.InitSerialNumber == false) |
| 257 | + { |
| 258 | + ErrorException(Slave, 0x0E); |
| 259 | + } |
| 260 | + else if(StartAddr != 0x0F0C) |
| 261 | + { |
| 262 | + ErrorException(Slave, 0x0F); |
| 263 | + } |
| 264 | + else |
| 265 | + { |
| 266 | + NumberOfPoint *= 2; |
| 267 | + BaseAddr = Slave->SerialNumberAddr; |
| 268 | + |
| 269 | + AvrUartPutChar(Slave->Uart, RxQue->Buf[0]); //Slave Address |
| 270 | + AvrUartPutChar(Slave->Uart, RxQue->Buf[1]); //Function |
| 271 | + AvrUartPutChar(Slave->Uart, NumberOfPoint); //Byte Count |
| 272 | + |
| 273 | + for(i = 0; i < NumberOfPoint; i++) |
| 274 | + { |
| 275 | + AvrUartPutChar(Slave->Uart, *(BaseAddr + i)); |
| 276 | + } |
| 277 | + |
| 278 | + Crc16 = Crc16Check(TxQue->OutPtr, TxQue->Buf, &TxQue->Buf[TxQue->Size - 1], TxQue->Ctr); |
| 279 | + |
| 280 | + AvrUartPutChar(Slave->Uart, (Crc16 >> 8)); |
| 281 | + AvrUartPutChar(Slave->Uart, (Crc16 & 0x00FF)); |
| 282 | + AvrUartStartTx(Slave->Uart); |
| 283 | + } |
| 284 | +} |
| 285 | +/*********************************************************************************/ |
246 | 286 | tU8 AvrModbusSlaveGeneralInit(tag_AvrModbusSlaveCtrl *Slave, tag_AvrUartCtrl *Uart, tU8 *BaseAddr, tU32 SlaveProcTick_us) |
247 | 287 | { |
248 | 288 | /* |
@@ -416,6 +456,32 @@ tU8 AvrModbusSlaveLinkCustomFrameCheck(tag_AvrModbusSlaveCtrl *Slave, tU16 (*Cus |
416 | 456 | return Slave->Bit.InitCustomFrameCheck; |
417 | 457 | } |
418 | 458 | /*********************************************************************************/ |
| 459 | +tU8 AvrModbusSlaveLinkSerialNumber(tag_AvrModbusSlaveCtrl *Slave, tU8 *SerialNumberAddr) |
| 460 | +{ |
| 461 | + /* |
| 462 | + 1) 인수 |
| 463 | + - Slave : tag_AvrModbusSlaveCtrl 인스턴스의 주소. |
| 464 | + - CustomFrameCheck : 사영자 정의 프레임 에러 검출 함수 주소. |
| 465 | +
|
| 466 | + 2) 반환 |
| 467 | + - 0 : 초기화 실패 |
| 468 | + - 1 : 초기화 성공 |
| 469 | +
|
| 470 | + 3) 설명 |
| 471 | + - 사용자 정의 프레임 에러 검출 함수 연결. |
| 472 | + */ |
| 473 | + |
| 474 | + if(Slave->Bit.InitComplete == false) |
| 475 | + { |
| 476 | + return false; |
| 477 | + } |
| 478 | + |
| 479 | + Slave->SerialNumberAddr = SerialNumberAddr; |
| 480 | + Slave->Bit.InitSerialNumber = true; |
| 481 | + |
| 482 | + return Slave->Bit.InitSerialNumber; |
| 483 | +} |
| 484 | +/*********************************************************************************/ |
419 | 485 | void AvrModbusSlaveProc(tag_AvrModbusSlaveCtrl *Slave, tU8 SlaveId) |
420 | 486 | { |
421 | 487 | tag_AvrUartRingBuf *RxQue = &Slave->Uart->RxQueue; |
@@ -474,6 +540,10 @@ void AvrModbusSlaveProc(tag_AvrModbusSlaveCtrl *Slave, tU8 SlaveId) |
474 | 540 | case AVR_MODBUS_PresetMultiple : |
475 | 541 | SlavePresetMultiple(Slave); |
476 | 542 | break; |
| 543 | + |
| 544 | + case AVR_MODBUS_ReadSerialNumber : |
| 545 | + SlaveReadSerialNumber(Slave); |
| 546 | + break; |
477 | 547 |
|
478 | 548 | default : |
479 | 549 | ErrorException(Slave, 1); |
|
0 commit comments