Например TDA7294

Форум РадиоКот • Просмотр темы - Покритикуйте реализацию MODBUS в следующем коде
Форум РадиоКот
Здесь можно немножко помяукать :)





Текущее время: Ср апр 17, 2024 01:52:41

Часовой пояс: UTC + 3 часа


ПРЯМО СЕЙЧАС:



Начать новую тему Ответить на тему  [ Сообщений: 15 ] 
Автор Сообщение
Не в сети
 Заголовок сообщения: Покритикуйте реализацию MODBUS в следующем коде
СообщениеДобавлено: Сб апр 06, 2019 04:27:52 
Это не хвост, это антенна
Аватар пользователя

Карма: -16
Рейтинг сообщений: -136
Зарегистрирован: Чт фев 19, 2015 12:41:04
Сообщений: 1406
Рейтинг сообщения: 0
Код рабочий MODBUS 100 опросов в секунду и больше позволяет на скорости порта 38400. Вроде таймауты корректные, чего не всегда встретишь, разделение времени. Измерение загрузки процессора осциллографом в цикле While (1) |outport; Все на прерываниях.

Вложение:
Project1.rar [6.31 KiB]
Скачиваний: 283

_________________
"Every profession is a conspiracy against the uninitiated" (B. Shaw)
"A textbook can be defined as a book unsuitable for reading" (B. Shaw)
Tautology is humor in "this" place (Vigo Carpathian)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Покритикуйте реализацию MODBUS в следующем коде
СообщениеДобавлено: Вт апр 09, 2019 03:41:26 
Потрогал лапой паяльник
Аватар пользователя

Карма: 3
Рейтинг сообщений: 3
Зарегистрирован: Ср май 03, 2017 03:22:26
Сообщений: 303
Рейтинг сообщения: 1
Тоже долго возился с протоколом ModBus, в итоге на avrfreaks попалась хорошая реализация , работает достаточно надежно.

.h
Спойлер
Код:
#include "Macro.h"
/* define baudrate of modbus */
#define MB_ADDR      0x0F
#define BAUD      38400L
#define UBRR ((F_CPU / 8 / BAUD ) -1)
/*
* Use 485 or 232, default: 485
* Use 232 for testing purposes or very simple applications that do not require RS485 and bus topology.
*/
#define PHYSICAL_TYPE 485 //possible values: 485, 232
/*
* Definitions for transceiver enable pin.
*/
#define TRANSCEIVER_ENABLE_PORT PORTD
#define TRANSCEIVER_ENABLE_PIN PD2
#define TRANSCEIVER_ENABLE_PORT_DDR DDRD
/*
*           At the moment the user has to set the value for Baudrate and
*           speed mode manually. The values depend on the operating frequency
*           of your AVR and can be found in its datasheet.
*/
#define USART_TX      USART_TX_vect
#define USART_RX      USART_RX_vect
#define USART_UDRE      USART_UDRE_vect
#define UART_STATUS      UCSR0A
#define UART_CONTROL   UCSR0B
#define UART_DATA      UDR0
#define UART_UDRIE      UDRIE0
#define UCSRC         UCSR0C
#define RXCIE         RXCIE0
#define TXCIE         TXCIE0
#define RXEN         RXEN0
#define TXEN         TXEN0
#define UCSZ0         UCSZ00
#define U2X            U2X0
#define UBRRH         UBRR0H
#define UBRRL         UBRR0L
/*
* Available address modes.
*/
#define MULTIPLE_ADR 2
#define SINGLE_ADR 1
/*
* Use SINGLE_ADR or MULTIPLE_ADR, default: SINGLE_ADR
* This is useful for building gateways, routers or clients that for whatever reason need multiple addresses.
*/
#define ADDRESS_MODE SINGLE_ADR

#define modbusInterFrameDelayReceiveStart 16
#define modbusInterFrameDelayReceiveEnd 18
#define modbusInterCharTimeout 7

/**
* @brief    Defines the maximum Modbus frame size accepted by the device. 255 is the default
*           and also the maximum value. However, it might be useful to set this to lower
*           values, with 8 being the lowest possible value, in order to save on ram space.
*/
#define MaxFrameIndex 255

/**
*         Modbus Function Codes
*           Refer to modbus.org for further information.
*           It's good practice to return exception code 01 in case you receive a function code
*           that you haven't implemented in your application.
*/
#define fcReadCoilStatus 1 //read single/multiple coils
#define fcReadInputStatus 2 //read single/multiple inputs
#define fcReadHoldingRegisters 3 //read analog output registers
#define fcReadInputRegisters 4 //read analog input registers (2 Bytes per register)
#define fcForceSingleCoil 5 //write single bit
#define fcPresetSingleRegister 6 //write analog output register (2 Bytes)
#define fcForceMultipleCoils 15 //write multiple bits
#define fcPresetMultipleRegisters 16 //write multiple analog output registers (2 Bytes each)
#define fcReportSlaveID 17 //read device description, run status and other device specific information

/*   
*         Modbus Exception Codes
*           Refer to modbus.org for further information.
*           It's good practice to return exception code 01 in case you receive a function code
*           that you haven't implemented in your application.
*/
#define ecIllegalFunction 1
#define ecIllegalDataAddress 2
#define ecIllegalDataValue 3
#define ecSlaveDeviceFailure 4
#define ecAcknowledge 5
#define ecSlaveDeviceBusy 6
#define ecNegativeAcknowledge 7
#define ecMemoryParityError 8
/**
* @brief    Internal bit definitions
*/
#define BusTimedOut 0
#define Receiving 1
#define Transmitting 2
#define ReceiveCompleted 3
#define TransmitRequested 4
#define TimerActive 5
#define GapDetected 6
/**
* @brief    Configures the UART. Call this function only once.
*/
extern void modbusInit(void);

/**
* @brief    receive/transmit data array
*/
extern volatile uint8_t rxbuffer[MaxFrameIndex+1];

/**
* @brief    Current receive/transmit position
*/
extern volatile uint16_t DataPos;

/**
* This only applies to single address mode.
*/
#if ADDRESS_MODE == SINGLE_ADR
/**
* @brief: Read the device address
*/
extern uint8_t modbusGetAddress(void);

/**
* @brief: Set the device address
*         Arguments: - newadr: the new device address
*/
extern void modbusSetAddress(uint8_t newadr);
#endif

/* @brief: Sends a response.
*
*         Arguments: - packtop, index of the last byte in rxbuffer
*                      that contains payload. Maximum value is
*                   MaxFrameIndex-2.
*/
extern void modbusSendMessage(uint8_t packtop);

/* @brief: Sends a Modbus exception.
*
*         Arguments: - exceptionCode
*/
extern void modbusSendException(uint8_t exceptionCode);

/* @brief: Discards the current transaction. For MULTIPLE_ADR-mode and general
*         testing purposes. Call this function if you don't want to reply at all.
*/
void modbusReset(void);

/**
* @brief    Call this function whenever possible and check if its return value has the ReceiveCompleted Bit set.
*           Preferably do this in the main while. I do not recommend calling this function within ISRs.
* @example  if (modbusGetBusState() & (1<<ReceiveCompleted)) {
*           modbusSendExcepton(ecIllegalFunction);
*           }
*/
extern uint8_t modbusGetBusState(void);

/**
* @brief    Call every 100us using a timer ISR.
*/
extern void modbusTickTimer(void);
/**
* @brief    Returns amount of bits/registers requested.
*/
extern uint16_t modbusRequestedAmount(void);

/**
* @brief    Returns the address of the first requested bit/register.
*/
extern uint16_t modbusRequestedAddress(void);

/* A fairly simple and hopefully Modbus compliant 16 Bit CRC algorithm.
*  Returns 1 if the crc check is positive, returns 0 if it fails.
*  Appends two crc bytes to the array.
*/
extern uint8_t crc16(volatile uint8_t *ptrToArray,uint8_t inputSize);
/* @brief: Handles single/multiple input/coil reading and single/multiple coil writing.
*
*         Arguments: - ptrToInArray: pointer to the user's data array containing bits
*                    - startAddress: address of the first bit in the supplied array
*                    - size: input array size in the requested format (bits)
*
*/
extern uint8_t modbusExchangeBits(volatile uint8_t *ptrToInArray, uint16_t startAddress, uint16_t size);
/* @brief: Handles single/multiple register reading and single/multiple register writing.
*
*         Arguments: - ptrToInArray: pointer to the user's data array containing registers
*                    - startAddress: address of the first register in the supplied array
*                    - size: input array size in the requested format (16bit-registers)
*
*/
extern uint8_t modbusExchangeRegisters(volatile uint16_t *ptrToInArray, uint16_t startAddress, uint16_t size);



.c
Спойлер
Код:
#include <avr/io.h>
#include <avr/interrupt.h>
#include "ModBusSlave.h"
#include "Macro.h"

volatile uint8_t BusState = 0;
volatile uint16_t modbusTimer = 0;
volatile uint8_t rxbuffer[MaxFrameIndex+1];
volatile uint16_t DataPos = 0;
volatile uint8_t PacketTopIndex = 7;
volatile uint8_t modBusStaMaStates = 0;

uint8_t modbusGetBusState(void)
{
   return BusState;
}

#if ADDRESS_MODE == SINGLE_ADR
volatile uint8_t Address = 0x00;
uint8_t modbusGetAddress(void)
{
   return Address;
}

void modbusSetAddress(uint8_t newadr)
{
   Address = newadr;
}
#endif

#if PHYSICAL_TYPE == 485
void transceiver_txen(void)
{
   TRANSCEIVER_ENABLE_PORT|=(1<<TRANSCEIVER_ENABLE_PIN);
}

void transceiver_rxen(void)
{
   TRANSCEIVER_ENABLE_PORT&=~(1<<TRANSCEIVER_ENABLE_PIN);
}
#endif

/* @brief: A fairly simple Modbus compliant 16 Bit CRC algorithm.
*
*     Returns 1 if the crc check is positive, returns 0 and saves the calculated CRC bytes
*   at the end of the data array if it fails.
*
*/
uint8_t crc16(volatile uint8_t *ptrToArray,uint8_t inputSize) //A standard CRC algorithm
{
   uint16_t out=0xffff;
   uint16_t carry;
   uint8_t n;
   inputSize++;
   for (int l=0; l<inputSize; l++) {
      out ^= ptrToArray[l];
      for (n = 0; n < 8; n++) {
         carry = out & 1;
         out >>= 1;
         if (carry) out ^= 0xA001;
      }
   }
   //out=0x1234;
   if ((ptrToArray[inputSize]==out%256) && (ptrToArray[inputSize+1]==out/256)) //check
   {
      return 1;
      } else {
      ptrToArray[inputSize]=out%256; //append Lo
      ptrToArray[inputSize+1]=out/256; //append Hi
      return 0;
   }
}

/* @brief: copies a single or multiple words from one array of bytes to another array of bytes
*          amount must not be bigger than 255...
*
*/
void listRegisterCopy(volatile uint8_t *source, volatile uint8_t *target, uint8_t amount)
{
   for (uint8_t c=0; c<amount; c++)
   {
      *(target+c)=*(source+c);
   }
}

/* @brief: copies a single bit from one char to another char (or arrays thereof)
*
*
*/
void listBitCopy(volatile uint8_t *source, uint16_t sourceNr,volatile uint8_t *target, uint16_t targetNr)
{
   if(*(source+(sourceNr/8))&(1<<(sourceNr-((sourceNr/8)*8))))
   {
      *(target+(targetNr/8))|=(1<<(targetNr-((targetNr/8)*8)));
   } else *(target+(targetNr/8))&=~(1<<(targetNr-((targetNr/8)*8)));
}

/* @brief: Back to receiving state.
*
*/
void modbusReset(void)
{
   BusState=(1<<TimerActive); //stop receiving (error)
   modbusTimer=0;
}

void modbusTickTimer(void)
{
   if (BusState&(1<<TimerActive))
   {
      modbusTimer++;
      if (BusState&(1<<Receiving)) //we are in receiving mode
      {
         if ((modbusTimer==modbusInterCharTimeout)) {
            BusState|=(1<<GapDetected);
            } else if ((modbusTimer==modbusInterFrameDelayReceiveEnd)) { //end of message
            BusState=(1<<ReceiveCompleted);
            #if ADDRESS_MODE == MULTIPLE_ADR
            if (crc16(rxbuffer,DataPos-3)) { //perform crc check only. This is for multiple/all address mode.
            } else modbusReset();
            #endif
            #if ADDRESS_MODE == SINGLE_ADR
            if (rxbuffer[0]==Address && crc16(rxbuffer,DataPos-3)) { //is the message for us? => perform crc check
            } else modbusReset();
            #endif
         }
      } else if (modbusTimer==modbusInterFrameDelayReceiveStart) BusState|=(1<<BusTimedOut);
   }
}

ISR(USART_RX)
{
   uint8_t data;
   data = UART_DATA;
   modbusTimer=0; //reset timer
   if (!(BusState & (1<<ReceiveCompleted)) && !(BusState & (1<<TransmitRequested)) && !(BusState & (1<<Transmitting)) && (BusState & (1<<Receiving)) && !(BusState & (1<<BusTimedOut)))
   {
      if (DataPos>MaxFrameIndex) modbusReset();
      else
      {
         rxbuffer[DataPos]=data;
         DataPos++; //TODO: maybe prevent this from exceeding 255?
      }
   } else
   if (!(BusState & (1<<ReceiveCompleted)) && !(BusState & (1<<TransmitRequested)) && !(BusState & (1<<Transmitting)) && !(BusState & (1<<Receiving)) && (BusState & (1<<BusTimedOut)))
   {
      rxbuffer[0]=data;
      BusState=((1<<Receiving)|(1<<TimerActive));
      DataPos=1;
   }
}

ISR(USART_UDRE)
{
   BusState&=~(1<<TransmitRequested);
   BusState|=(1<<Transmitting);
   UART_DATA=rxbuffer[DataPos];
   DataPos++;
   if (DataPos==(uint8_t)(PacketTopIndex+1)) {
      UART_CONTROL&=~(1<<UART_UDRIE);
   }
}

ISR(USART_TX)
{
   #if PHYSICAL_TYPE == 485
   transceiver_rxen();
   #endif
   modbusReset();
}

void modbusInit(void)
{
   UBRRH = (uint8_t)((UBRR) >> 8);
   UBRRL = (uint8_t) UBRR;
   UART_STATUS = (1<<U2X); //double speed mode.
   #ifdef URSEL   // if UBRRH and UCSRC share the same I/O location , e.g. ATmega8
   UCSRC = (1<<URSEL)|(3<<UCSZ0); //Frame Size
   #else
   UCSRC = (3<<UCSZ0); //Frame Size
   #endif
   UART_CONTROL = (1<<TXCIE)|(1<<RXCIE)|(1<<RXEN)|(1<<TXEN); // USART receiver and transmitter and receive complete interrupt
   #if PHYSICAL_TYPE == 485
   TRANSCEIVER_ENABLE_PORT_DDR|=(1<<TRANSCEIVER_ENABLE_PIN);
   transceiver_rxen();
   #endif
   BusState=(1<<TimerActive);
}

/* @brief: Sends a response.
*
*         Arguments: - packtop: Position of the last byte containing data.
*                               modbusSendException is a good usage example.
*/
void modbusSendMessage(uint8_t packtop)
{
   PacketTopIndex=packtop+2;
   crc16(rxbuffer,packtop);
   BusState|=(1<<TransmitRequested);
   DataPos=0;
   #if PHYSICAL_TYPE == 485
   transceiver_txen();
   #endif
   UART_CONTROL|=(1<<UART_UDRIE);
   BusState&=~(1<<ReceiveCompleted);
}

/* @brief: Sends an exception response.
*
*         Arguments: - exceptionCode
*
*/
void modbusSendException(uint8_t exceptionCode)
{
   rxbuffer[1]|=(1<<7); //setting MSB of the function code (the exception flag)
   rxbuffer[2]=exceptionCode; //Exceptioncode. Also the last byte containing data
   modbusSendMessage(2);
}


/* @brief:  Returns the amount of requested data objects (coils, discretes, registers)
*
*/
uint16_t modbusRequestedAmount(void)
{
   return (rxbuffer[5]|(rxbuffer[4]<<8));
}

/* @brief: Returns the address of the first requested data object (coils, discretes, registers)
*
*/
uint16_t modbusRequestedAddress(void)
{
   return (rxbuffer[3]|(rxbuffer[2]<<8));
}

/* @brief: copies a single or multiple bytes from one array of bytes to an array of 16-bit-words
*
*/
void intToModbusRegister(volatile uint16_t *inreg, volatile uint8_t *outreg, uint8_t amount)
{
   for (uint8_t c=0; c<amount; c++)
   {
      *(outreg+c*2) = (uint8_t)(*(inreg+c) >> 8);
      *(outreg+1+c*2) = (uint8_t)(*(inreg+c));
   }
}

/* @brief: copies a single or multiple 16-bit-words from one array of integers to an array of bytes
*
*/
void modbusRegisterToInt(volatile uint8_t *inreg, volatile uint16_t *outreg, uint8_t amount)
{
   for (uint8_t c=0; c<amount; c++)
   {
      *(outreg+c) = (*(inreg+c*2) << 8) + *(inreg+1+c*2);
   }
}

/* @brief: Handles single/multiple register reading and single/multiple register writing.
*
*         Arguments: - ptrToInArray: pointer to the user's data array containing registers
*                    - startAddress: address of the first register in the supplied array
*                    - size: input array size in the requested format (16bit-registers)
*
*/
uint8_t modbusExchangeRegisters(volatile uint16_t *ptrToInArray, uint16_t startAddress, uint16_t size)
{
   uint16_t requestedAmount = modbusRequestedAmount();
   uint16_t requestedAdr = modbusRequestedAddress();
   if (rxbuffer[1]==fcPresetSingleRegister) requestedAmount=1;
   if ((requestedAdr>=startAddress) && ((startAddress+size)>=(requestedAmount+requestedAdr))) {

      if ((rxbuffer[1]==fcReadHoldingRegisters) || (rxbuffer[1]==fcReadInputRegisters) )
      {
         if ((requestedAmount*2)<=(MaxFrameIndex-4)) //message buffer big enough?
         {
            rxbuffer[2]=(uint8_t)(requestedAmount*2);
            intToModbusRegister(ptrToInArray+(uint8_t)(requestedAdr-startAddress),rxbuffer+3,requestedAmount);
            modbusSendMessage(2+rxbuffer[2]);
            return 1;
         } else modbusSendException(ecIllegalDataValue);
      }
      else if (rxbuffer[1]==fcPresetMultipleRegisters)
      {
         if (((rxbuffer[6])>=requestedAmount*2) && ((DataPos-9)>=rxbuffer[6])) //enough data received?
         {
            modbusRegisterToInt(rxbuffer+7,ptrToInArray+(uint8_t)(requestedAdr-startAddress),(uint8_t)(requestedAmount));
            modbusSendMessage(5);
            return 1;
         } else modbusSendException(ecIllegalDataValue);//too few data bytes received
      }
      else if (rxbuffer[1]==fcPresetSingleRegister)
      {
         modbusRegisterToInt(rxbuffer+4,ptrToInArray+(uint8_t)(requestedAdr-startAddress),1);
         modbusSendMessage(5);
         return 1;
      }
      //modbusSendException(ecSlaveDeviceFailure); //inapropriate call of modbusExchangeRegisters
      return 0;
      } else {
      modbusSendException(ecIllegalDataValue);
      return 0;
   }
}

/* @brief: Handles single/multiple input/coil reading and single/multiple coil writing.
*
*         Arguments: - ptrToInArray: pointer to the user's data array containing bits
*                    - startAddress: address of the first bit in the supplied array
*                    - size: input array size in the requested format (bits)
*
*/
uint8_t modbusExchangeBits(volatile uint8_t *ptrToInArray, uint16_t startAddress, uint16_t size)
{
   uint16_t requestedAmount = modbusRequestedAmount();
   uint16_t requestedAdr = modbusRequestedAddress();
   if (rxbuffer[1]==fcForceSingleCoil) requestedAmount=1;
   if ((requestedAdr>=startAddress) && ((startAddress+size)>=(requestedAmount+requestedAdr)))
   {
      if ((rxbuffer[1]==fcReadInputStatus) || (rxbuffer[1]==fcReadCoilStatus))
      {
         if (requestedAmount<=((MaxFrameIndex-4)*8)) //message buffer big enough?
         {
            rxbuffer[2]=(requestedAmount/8);
            if (requestedAmount%8>0)
            {
               rxbuffer[(uint8_t)(requestedAmount/8)+3]=0x00; //fill last data byte with zeros
               rxbuffer[2]++;
            }
            for (uint16_t c = 0; c<requestedAmount; c++)
            {
               listBitCopy(ptrToInArray,requestedAdr-startAddress+c,rxbuffer+3,c);
            }
            modbusSendMessage(rxbuffer[2]+2);
            return 1;
         } else modbusSendException(ecIllegalDataValue); //too many bits requested within single request
      }
      else if (rxbuffer[1]==fcForceMultipleCoils)
      {
         if (((rxbuffer[6]*8)>=requestedAmount) && ((DataPos-9)>=rxbuffer[6])) //enough data received?
         {
            for (uint16_t c = 0; c<requestedAmount; c++)
            {
               listBitCopy(rxbuffer+7,c,ptrToInArray,requestedAdr-startAddress+c);
            }
            modbusSendMessage(5);
            return 1;
         } else modbusSendException(ecIllegalDataValue);//exception too few data bytes received
      }
      else if (rxbuffer[1]==fcForceSingleCoil) {
         listBitCopy(rxbuffer+4,0,ptrToInArray,requestedAdr-startAddress);
         modbusSendMessage(5);
         return 1;
      }
      //modbusSendException(ecSlaveDeviceFailure); //inanpropriate call of modbusExchangeBits
      return 0;
   } else
   {
      modbusSendException(ecIllegalDataValue);
      return 0;
   }
}



main.c
Спойлер
Код:
/*************************Реализация TWI режим Slave***************************/
#define F_CPU 20000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/atomic.h>
#include <string.h>
#include <util/delay.h>
#include "IIC_ultimate.h"
#include "ModBusSlave.h"
#include "Macro.h"
/*****************************Global Variables*********************************/
struct Data {
   volatile uint8_t InState[5];            //Дискретные входа
   volatile uint8_t OutState[5];            //Дискретные выхода
   volatile uint16_t InputRegisters[4];      //Выходные 16-Битные данные.
   volatile uint16_t HoldingRegisters[4];      //Входные 16-Битные данные.
} DataBus;
uint8_t CpyComplete=0;
/***********************************TWI****************************************/
void SlaveControl(void);
void TWI_MasterRequest();
void TWI_MasterRequestComplete();
void TWI_MasterTransmit();
void TWI_MasterTransmitComplete();
void FillBufferTransmit();
/**********************************MODBUS**************************************/
void InitTimer0(void);
void modbusGet(void);

uint8_t CpyModbusToTWI(void);
ISR(TIMER0_OVF_vect)
{
   modbusTickTimer();
}
int main()
{
   Init_i2c();                     //Мастер режим
   Init_Slave_i2c(&SlaveControl);      //Слейв режим
   modbusSetAddress(MB_ADDR);
   modbusInit();
   InitTimer0();
   sei();
   DDRB|=(1<<2)|(1<<3);
   while(1)
   {
      if (BIT_IS_SET(DataBus.OutState[0],0))
      {
         SET_BIT(PORTB,2);
      }else
      {
         CLR_BIT(PORTB,2);
      }
      if (BIT_IS_SET(DataBus.OutState[0],1))
      {
         SET_BIT(PORTB,3);
      }else
      {
         CLR_BIT(PORTB,3);
      }
      modbusGet();
   }
   return 0;
}
void InitTimer0(void) {
   SET_BIT(TCCR0B, CS01);
   SET_BIT(TIMSK0, TOIE0);
}
void modbusGet(void) {
   if (modbusGetBusState() & (1 << ReceiveCompleted)) {
      switch (rxbuffer[1]) {
         case fcReadCoilStatus: {
            modbusExchangeBits(DataBus.OutState, 0,sizeof(DataBus.OutState));
            //CpyModbusToTWI();
         } break;
         case fcReadInputStatus: {
            modbusExchangeBits(DataBus.InState, 0,sizeof(DataBus.InState));
            //CpyModbusToTWI();
         } break;
         case fcReadHoldingRegisters: {
            modbusExchangeRegisters(DataBus.HoldingRegisters, 0,sizeof(DataBus.HoldingRegisters));
            //CpyModbusToTWI();
         } break;
         case fcReadInputRegisters: {
            modbusExchangeRegisters(DataBus.InputRegisters, 0,sizeof(DataBus.InputRegisters));
            //CpyModbusToTWI();
         } break;
         case fcForceSingleCoil: {
            modbusExchangeBits(DataBus.OutState, 0,sizeof(DataBus.OutState));
            //CpyModbusToTWI();
         } break;
         case fcPresetSingleRegister: {
            modbusExchangeRegisters(DataBus.HoldingRegisters,0,sizeof(DataBus.HoldingRegisters));
            CpyModbusToTWI();
            TWI_MasterTransmit();
         } break;
         case fcForceMultipleCoils: {
            modbusExchangeBits(DataBus.OutState, 0,sizeof(DataBus.OutState));
            //CpyModbusToTWI();
         } break;
         case fcPresetMultipleRegisters: {
            modbusExchangeRegisters(DataBus.HoldingRegisters,0,sizeof(DataBus.HoldingRegisters));
            CpyModbusToTWI();
            TWI_MasterTransmit();
         } break;
         default: {
            modbusSendException(ecIllegalFunction);
         } break;
      }
   }
}
void FillBufferTransmit()
{
   ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
      memcpy((i2c_Buffer), &DataBus, (sizeof(DataBus)));
   }
   return;
}
uint8_t CpyModbusToTWI()
{
   ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
      memcpy((i2c_OutBuff), &DataBus, (sizeof(DataBus)));
      CpyComplete=1;
   }
   return 1;
}
void TWI_MasterRequest()
{
   //Если шина занята, то выход из функции
   if (i2c_Do & i2c_Busy)
   {
      return;
   }
   i2c_index=0;         //Обнуляем индекс.
   i2c_ByteCount=26;      //Устанавливаем размер пакета
   i2c_SlaveAddress=0x32;   //Адресс слейва
   i2c_Do=i2c_sarp;      //Режим чтения
   MasterOutFunc=&TWI_MasterRequestComplete;
   ErrorOutFunc=&TWI_MasterRequestComplete;
   TWCR = 1<<TWSTA|0<<TWSTO|1<<TWINT|0<<TWEA|1<<TWEN|1<<TWIE;
   i2c_Do |= i2c_Busy;      //Занимаем шину.
}
void TWI_MasterRequestComplete()
{
   i2c_Do &=i2c_Free;      //Освободить шину
   //Если  был сбой, или слейв нас не услышал.
   if (i2c_Do &(i2c_ERR_BF | i2c_ERR_NA))
   {
      TWI_MasterRequest();      //Повторить  попытку считывания данных.
      return;
   }
}
void TWI_MasterTransmit()
{
   //Если передатчик занят , то выход из функции.
   if (i2c_Do & i2c_Busy)
   {
      return;
   }
   i2c_index=0;         //Обнуляем индекс
   i2c_ByteCount=26;      //Размер пакета
   i2c_SlaveAddress=0x32;   //Адрес слейва
   FillBufferTransmit();   //Заполнение массива передачи.
   i2c_Do=i2c_sawp;      //Режим простой заиси.
   MasterOutFunc=&TWI_MasterTransmitComplete;
   ErrorOutFunc=&TWI_MasterTransmitComplete;
   TWCR = 1<<TWSTA|0<<TWSTO|1<<TWINT|0<<TWEA|1<<TWEN|1<<TWIE;
   i2c_Do |= i2c_Busy;      //Занимаем шину.
}
void TWI_MasterTransmitComplete()
{
   i2c_Do &= i2c_Free;            //Освобождаем шину
   //Если  был сбой, или адрес нас не услышал.
   if (i2c_Do & (i2c_ERR_BF | i2c_ERR_NA))
   {
      TWI_MasterTransmit();      //Повторить передачу.
      return;
   }
}
void SlaveControl(void)
{
   ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
      memcpy(&DataBus,i2c_InBuff,(sizeof(DataBus)));
      DataBus.HoldingRegisters[0]*=10;
      DataBus.HoldingRegisters[1]*=10;
      DataBus.HoldingRegisters[2]*=10;
      DataBus.HoldingRegisters[3]*=10;
      CpyComplete=1;
   }
   CpyComplete=0;
   i2c_Do &= i2c_Free;               //Освобождаем шину
}


Если интересно можете посмотреть.

_________________
andrei23061996@gmail.com
.................................................................................................................


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Покритикуйте реализацию MODBUS в следующем коде
СообщениеДобавлено: Ср апр 10, 2019 17:32:10 
Это не хвост, это антенна
Аватар пользователя

Карма: -16
Рейтинг сообщений: -136
Зарегистрирован: Чт фев 19, 2015 12:41:04
Сообщений: 1406
Рейтинг сообщения: 0
Благодарю Вас, это один из немногих случаев, когда на радиокоте появляются исходники. Кстати, интересно, протестировать скорость и корректность таймаутов, так сказать конкурсные испытания провести. Есть между ними (кодами) коренное отличие, у меня, функция Main, в части цикла While, можно считать пустая и, посвящена исключительно подсчету так называемого Idle (простоя процессора смотрю осциллографом)

P.S. Ну и, конечно, все упрощено до предела реализации 3 и 6 функции с подсчетом CRC табличным методом для скорости, обратите внимание на аппаратную реализацию измерения таймаута...

_________________
"Every profession is a conspiracy against the uninitiated" (B. Shaw)
"A textbook can be defined as a book unsuitable for reading" (B. Shaw)
Tautology is humor in "this" place (Vigo Carpathian)


Вернуться наверх
 
PCBWay - всего $5 за 10 печатных плат, первый заказ для новых клиентов БЕСПЛАТЕН

Сборка печатных плат от $30 + БЕСПЛАТНАЯ доставка по всему миру + трафарет

Онлайн просмотровщик Gerber-файлов от PCBWay + Услуги 3D печати
Не в сети
 Заголовок сообщения: Re: Покритикуйте реализацию MODBUS в следующем коде
СообщениеДобавлено: Вс май 26, 2019 16:26:34 
Это не хвост, это антенна
Аватар пользователя

Карма: -16
Рейтинг сообщений: -136
Зарегистрирован: Чт фев 19, 2015 12:41:04
Сообщений: 1406
Рейтинг сообщения: 0
Программа для хоста была не та перзагрузите.

Вложение:
ModBus.zip [43.4 KiB]
Скачиваний: 241

_________________
"Every profession is a conspiracy against the uninitiated" (B. Shaw)
"A textbook can be defined as a book unsuitable for reading" (B. Shaw)
Tautology is humor in "this" place (Vigo Carpathian)


Вернуться наверх
 
Организация питания на основе надежных литиевых аккумуляторов EVE и микросхем азиатского производства

Качественное и безопасное устройство, работающее от аккумулятора, должно учитывать его физические и химические свойства, профили заряда и разряда, их изменение во времени и под влиянием различных условий, таких как температура и ток нагрузки. Мы расскажем о литий-ионных аккумуляторных батареях EVE и нескольких решениях от различных китайских компаний, рекомендуемых для разработок приложений с использованием этих АКБ. Представленные в статье китайские аналоги помогут заменить продукцию западных брендов с оптимизацией цены без потери качества.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Покритикуйте реализацию MODBUS в следующем коде
СообщениеДобавлено: Вт ноя 12, 2019 05:57:31 
Друг Кота
Аватар пользователя

Карма: 23
Рейтинг сообщений: 283
Зарегистрирован: Пт мар 09, 2007 15:01:52
Сообщений: 3040
Откуда: Биробиджан
Рейтинг сообщения: 1
Медали: 1
Получил миской по аватаре (1)
astrahard, твоя программа при запуске требует кучу библиотек. В частности RTL60.BPL, vcl60.bpl, CPortLibCB5.bpl, возможно есть ещё, но третий файл я не нашёл для дальнейших попыток запуска программы.
Вот статья где написано как отучить программу от bpl файлов: http://www.cyberforum.ru/cpp-builder/thread15180.html


Вернуться наверх
 
Новый аккумулятор EVE серии PLM для GSM-трекеров, работающих в жёстких условиях (до -40°С)

Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре. Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.

Подробнее>>
Не в сети
 Заголовок сообщения: Re: Покритикуйте реализацию MODBUS в следующем коде
СообщениеДобавлено: Ср ноя 20, 2019 14:14:15 
Это не хвост, это антенна
Аватар пользователя

Карма: -16
Рейтинг сообщений: -136
Зарегистрирован: Чт фев 19, 2015 12:41:04
Сообщений: 1406
Рейтинг сообщения: 0
Спасибо, поленился исправлю попозже. Просто комп на котором все в гараже. Этот исходник помимо ModBus реализует цифровой ШИМ контроллер для компьютерного БП на замену TL494. Код мой. Если кому интересна тема полностью цифрового управления инвертором можно продолжить.

Добавлено after 22 minutes 18 seconds:
Обратите внимание, что код выполнен полностью на прерываниях. В окончание функции Main() есть только маленький цикл реализующий Idle процесс, как во "Взрослых операционных системах" Осциллографом можно посмотреть насколько загружен процессор. Код выдает ШИМ сигнал для управления компьютерным БП заместо TL494, реализует ПИД регулятор и, параллельно может 100 опросов в секунду по протоколу ModBus на скорости 38400 и это не влияет на ШИМ и ПИД процессы, этот код также принимает уставки от хоста (ПК настольный) на изменение напряжения БП и снимает осциллограммы, и это все - этот маленький код. Кварц несколько нестандартный, но, я думаю, и на 16 МГц UART и ModBus будут работоспособны. На мой скромный взгляд этот код само совершенство....

Добавлено after 12 minutes 56 seconds:
P.S. Если бы я писал операционную систему... Такой маленький код, выполняет столько функций в режиме реального времени... и ничто друг другу не мешается, а процессор загружен лишь на треть. А какое мастерское использование аппаратуры процессора, не, я положительно собой горжусь!

Добавлено after 29 minutes 30 seconds:
Если кто захочет испытать на практике, то добавлю, что первый вход АЦП подключается к +5В каналу компьютерного БП (обратная связь) через резистивный делитель на 3 а конденсатор 10 нанофарад параллельно входу АЦП (антиалисинг фильтр).

_________________
"Every profession is a conspiracy against the uninitiated" (B. Shaw)
"A textbook can be defined as a book unsuitable for reading" (B. Shaw)
Tautology is humor in "this" place (Vigo Carpathian)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Покритикуйте реализацию MODBUS в следующем коде
СообщениеДобавлено: Чт ноя 21, 2019 08:18:29 
Это не хвост, это антенна
Аватар пользователя

Карма: -16
Рейтинг сообщений: -136
Зарегистрирован: Чт фев 19, 2015 12:41:04
Сообщений: 1406
Рейтинг сообщения: 0
Исправлены некоторые комментарии и добавлены новые. Код не менялся никак.
Вложение:
Project1.rar [6.51 KiB]
Скачиваний: 241


Добавлено after 1 hour 2 minutes 9 seconds:
astrahard, твоя программа при запуске требует кучу библиотек. В частности RTL60.BPL, vcl60.bpl, CPortLibCB5.bpl, возможно есть ещё, но третий файл я не нашёл для дальнейших попыток запуска программы.
Вот статья где написано как отучить программу от bpl файлов: http://www.cyberforum.ru/cpp-builder/thread15180.html

Принес комп домой. Но Чего-то не срабатывает такой подход. - закладка linker: убрать галочку Use dinamyc RTL это я сделал и думал достаточно. А этот пункт - закладка packages: убрать галочку Build with runtimes packages вызывает ошибку компиляции. Дополнительный компонент СОМ порт говорит не найден, да и Build with runtimes packages вроде говорит о том чтобы включать packages. Чего-то здесь заморочено, я думал только линкеру надо указание дать.

_________________
"Every profession is a conspiracy against the uninitiated" (B. Shaw)
"A textbook can be defined as a book unsuitable for reading" (B. Shaw)
Tautology is humor in "this" place (Vigo Carpathian)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Покритикуйте реализацию MODBUS в следующем коде
СообщениеДобавлено: Чт ноя 21, 2019 09:18:04 
Друг Кота
Аватар пользователя

Карма: 23
Рейтинг сообщений: 283
Зарегистрирован: Пт мар 09, 2007 15:01:52
Сообщений: 3040
Откуда: Биробиджан
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Могу предположить что у компонента для последовательного порта не хватает файлов. Вот из-за таких приколов я принципиально не пишу на borland и net


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Покритикуйте реализацию MODBUS в следующем коде
СообщениеДобавлено: Чт ноя 21, 2019 09:44:13 
Это не хвост, это антенна
Аватар пользователя

Карма: -16
Рейтинг сообщений: -136
Зарегистрирован: Чт фев 19, 2015 12:41:04
Сообщений: 1406
Рейтинг сообщения: 0
Кроме своего приложения я управлял Мегой с помощью Модбас тестера функции 3 и 6. Тоже работает, правда он не позволяет опрашивать чаще 10-20 раз в секунду. У меня из своей программы получалось 100 опросов в сек.

Добавлено after 12 minutes 13 seconds:
Получилось нашел я поиском "невидимые" файлы и, скопировал в папку с проектом. Можно было путь дополнительный прописать конечно.
Вложение:
ModBus.rar [245.67 KiB]
Скачиваний: 262


Добавлено after 2 minutes 59 seconds:
Только он залочен на СОМ3 всегда, недостаток, не позволяет выбрать порт. Еще недостаток ввод уставки происходит только когда кликнешь на другое поле ввода я нуб в программировании на ПК. Скорость 56000. Я разобрал устройство частично и не помню скорость. Кроме того у меня стояли инверторы на транзисторах перед подачей на контактные площадки выпаяной TL494. Не помню, исправил-ли в исходнике, вроде исправлял и, скорость порта изменил на 56000. Я пользовался Визардом CodeVision и, там менял полярность ШИМ сигнала.

P.S. И еще, нижняя строка там где копирайт нажимается и открываются дополнительные кнопки управления. Еще интересный факт, прошивал контроллер при подключенном в 220В БП и подключенном ШИМ заместо TL494 больше 100 раз и, ничего не сгорело!!!!

_________________
"Every profession is a conspiracy against the uninitiated" (B. Shaw)
"A textbook can be defined as a book unsuitable for reading" (B. Shaw)
Tautology is humor in "this" place (Vigo Carpathian)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Покритикуйте реализацию MODBUS в следующем коде
СообщениеДобавлено: Пт ноя 22, 2019 04:56:02 
Друг Кота
Аватар пользователя

Карма: 23
Рейтинг сообщений: 283
Зарегистрирован: Пт мар 09, 2007 15:01:52
Сообщений: 3040
Откуда: Биробиджан
Рейтинг сообщения: 1
Медали: 1
Получил миской по аватаре (1)
Вообще с портом можно работать и без компонента, как с текстовым файлом. Но если используешь компонент, то попробуй следующую конструкцию:
Код:

PortName 
:= "COM1";
ComPort1->Port := PortName;
 

PortName - это переменная где хранится выбранный порт.
Port - это название пункта у компонента куда вписываешь название использованного порта. Я не знаю как выглядит у тебя этот параметр, просто предположил.
Ввод данных происходит потому что ты привязался к событию OnSelectили как-то так. Опять же я не вижу кода, а только предполагаю.
Прятать дополнительные настройки, особенно кнопку закрытия порта, за не очевидную кнопку не лучшее решение.
У тебя отсутствуют проверки ввода и выскакивают системные ошибки.

При подключенном к сети источнике лучше не прошивать потому что в этот момент могут вылететь ключи или напряжение на выходе выйти за пределы допустимые для нагрузки.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Покритикуйте реализацию MODBUS в следующем коде
СообщениеДобавлено: Пт ноя 22, 2019 07:33:17 
Это не хвост, это антенна
Аватар пользователя

Карма: -16
Рейтинг сообщений: -136
Зарегистрирован: Чт фев 19, 2015 12:41:04
Сообщений: 1406
Рейтинг сообщения: 0
Спасибо большое за подсказки. А доп. настройки я спрятал в основном из-за пунктов включения и выключения ПИД регулятора. У меня еще осталась проблема, когда на большой нагрузке ПИД регулятор перестает справляться. На малых нагрузках все хорошо. И еще, я снял цифровым запоминающим осциллографом переходные процессы при включении, нагружении и разгрузке и, был приятно удивлен, что они лучше выглядят чем с родной TL494. Здорово и то, что на отключение конденсатора 10НФ в антиалисинг фильтре в делителе на 3 АЦП, который упомянут в исходнике, ПИД регулятор реагирует согласно теории, значит ПИД работает правильно. Планирую продолжить разработку на контроллерах dSPIC33EP64GS505-ISO и TMS320F28027 (TMS320F28016). Хочу доделать трехфазный ШИМ с осциллографированием на предмет сбоев в работе.

Добавлено after 3 minutes 13 seconds:
Вот такую плату разработал и уже спаял https://radiokot.ru/forum/viewtopic.php?f=11&t=139007

Добавлено after 1 hour 38 minutes 56 seconds:
В связи с появлением очень дешевого контроллера stm8s003f3 у меня возникла идея переписать код под него. Можно получить полностью цифровой ШИМ контроллер для БП компьютеров и не только, с сервисом ввода уставок по напряжению, осциллографированием сбоев в работе ШИМ и сбоев сетевого питания и, диагностикой ухудшения характеристик деталей БП (конденсаторов сетевого фильтра, деградация силовых транзисторов и высыхание электролитов выпрямителя) с целью определения его остаточного ресурса. Это как Smart для жестких и твердотельных дисков. Кроме того здорово сократиться к-во деталей обвязки если учесть что stm8s003f3 не нуждается во внешнем кварце.

Добавлено after 6 minutes 18 seconds:
И в самом деле, диагностика состояния батареи аккумуляторов есть, а диагностики состояния электролитов и силовых транзисторов в БП такого еще не было?

_________________
"Every profession is a conspiracy against the uninitiated" (B. Shaw)
"A textbook can be defined as a book unsuitable for reading" (B. Shaw)
Tautology is humor in "this" place (Vigo Carpathian)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Покритикуйте реализацию MODBUS в следующем коде
СообщениеДобавлено: Вс ноя 24, 2019 03:57:03 
Друг Кота
Аватар пользователя

Карма: 23
Рейтинг сообщений: 283
Зарегистрирован: Пт мар 09, 2007 15:01:52
Сообщений: 3040
Откуда: Биробиджан
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
Хочешь мониторить помехи в питании? А контроллеру башню не снесёт при высыхании электролитов? И почему для управления выбран Modbus, а не свой протокол? Ведь он ориентирован для интеграции в разные SCADA системы.


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Покритикуйте реализацию MODBUS в следующем коде
СообщениеДобавлено: Вс ноя 24, 2019 14:40:51 
Это не хвост, это антенна
Аватар пользователя

Карма: -16
Рейтинг сообщений: -136
Зарегистрирован: Чт фев 19, 2015 12:41:04
Сообщений: 1406
Рейтинг сообщения: 0
Поэтому и выбран, что есть OPC сервер для ModBus и SCADA есть лайтовые удобные. Что касается не снесет-ли крышу контроллеру, у него-же есть собственный фильтр, да и потребляет он мало. кроме того я хочу развить проект на.

Выбор или двухядерный Microchip dsPIC33CH128MP508 или Texas Instruments TMS320F28027???? Это в плане ПО для управления трехфазным инвертором с ККМ чтобы было полностью цифровое управление (в том числе ККМ) с минимальной обвязкой деталями. Это я хочу сделать для мощных преобразователей электроэнергии (десятки киловатт, где вопрос цены не стоит так остро), как то 3Ф инвертор с ККМ, выпрямитель Виена с ККМ, векторное управление обобщенным электродвигателем с ККМ, MIG сварка на десятки киловатт без брызг с ККМ. Много лет назад уже начинал. Сейчас здорово продвинулся в понимании топологий и работы мощных инверторов и решил продолжить...

Добавлено after 3 minutes 6 seconds:
P.S. Ну и, главное двинуть идею, чтобы было что реализовывать, вот например моя тема, которую лучше было-бы назвать "Датчик отказа датчика" http://forum.easyelectronics.ru/viewtop ... =9&t=39701

Добавлено after 5 hours 7 minutes 58 seconds:
Просто мне показали однажды как работает OPC-ModBus сервер отдавая данные, например, напрямую в Excel и, мне понравилось. А какой еще путь для сверхбыстрой визуализации можно придумать?

Добавлено after 1 hour 57 minutes 43 seconds:
Да, кстати. Визуализацию полученных от микроконтроллера данных очень удобно делать в Excel. Бесплатный modbus_opc_server_32tags можно найти и скачать, вариантов много, например https://insat.ru/products/?category=1666 как раз для отладки и некоммерческих проектов. Для радиолюбителя то что надо... Как известно, Excel позволяет написать в своей клеточки запрос к OPC серверу. А как это визуализировать поймет каждый пользователь электронной таблицы. Я не пойму, почему радиолюбители этим не пользуются?

P.S. запрос к OPC server в excel https://www.aggsoft.ru/opc-data-logger/ ... -excel.htm

Добавлено after 1 hour 52 seconds:
Класс, мне удалось посрамить Немцев и фирму Ti, кажется, как авторов векторного управления обобщенным электродвигателем. Я упростил выражение для векторного регулирования и, упростил схему силовой части заодно, по моему, до сих пор, считалось, что упростить выражения векторного регулирования обобщенным электродвигателем невозможно. Вот не знаю что и думать, либо я раскрыл тайну Ti (их секретного наблюдателя InstaSPIN-FOC ), либо опередил их?

_________________
"Every profession is a conspiracy against the uninitiated" (B. Shaw)
"A textbook can be defined as a book unsuitable for reading" (B. Shaw)
Tautology is humor in "this" place (Vigo Carpathian)


Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Покритикуйте реализацию MODBUS в следующем коде
СообщениеДобавлено: Пн ноя 25, 2019 14:35:39 
Друг Кота
Аватар пользователя

Карма: 23
Рейтинг сообщений: 283
Зарегистрирован: Пт мар 09, 2007 15:01:52
Сообщений: 3040
Откуда: Биробиджан
Рейтинг сообщения: 0
Медали: 1
Получил миской по аватаре (1)
А ты не думал что сложность их схемы обусловлена не тупым управлением, а управлением с обратной связью, наличием защит и прочей ерундой? Ещё я обратил внимание что ты жёстко задаёшь адрес устройства в коде программы, это делает невозможным работу более одного устройства на шине.
И ещё, использовать контроллер на 40 выводов, как замену микросхеме стоимостью в три раза дешевле не лучшая идея. Попробуй портировать код на ATtiny26L-8PU или STM8S003F3P6 например


Последний раз редактировалось radteh Пн ноя 25, 2019 15:26:44, всего редактировалось 1 раз.

Вернуться наверх
 
Не в сети
 Заголовок сообщения: Re: Покритикуйте реализацию MODBUS в следующем коде
СообщениеДобавлено: Пн ноя 25, 2019 16:49:43 
Это не хвост, это антенна
Аватар пользователя

Карма: -16
Рейтинг сообщений: -136
Зарегистрирован: Чт фев 19, 2015 12:41:04
Сообщений: 1406
Рейтинг сообщения: 0
Я не ту сложность имею ввиду, что вызвана "прочей ерундой" имеется ввиду выражения контура управления. Не я вполне серьезно. Вот рассуждения, которые привели меня к такому выводу. Это моя тема на сайте Электрик.орг http://www.electrik.org/forum/index.php?showtopic=71016 А также ШИМ в звене постоянного тока со своим ФНЧ может нести сразу две функции, генерацию 3-й гармоники для коммутатора и функцию ККМ "в одном флаконе".

P.S. Я как раз собираюсь портировать код на STM8S003F3P6. И исправить недочеты с "жесткой привязкой" это вызвано просто элементарной ленью и, легко уйдет в прошлое в очередном релизе.

Добавлено after 51 minute 35 seconds:
Короче, для тех кто читает тему tp://www.electrik.org/forum/index.php?showtopic=71016 интересное замечание. ШИМ в звене постоянного тока, который питает, в свою очередь, 3-Ф 120 градусный коммутатор. Этот ШИМ может быть "Три в одном" тоесть нести три функции сразу 1. ККМ 2. Векторное регулирование 3. Фильтр ШИМ для того чтобы в двигатель не проникала высокая частота негативно сказывающаяся на изоляции обмоток. Для Этого ШИМ в звене постоянного тока должен выполнять нетривиальную, сложную модуляцию... В эту модуляцию войдет и закон управления, но все же, "уцелом" выражения закона управления и, "наблюдателя" упростятся, а вычисления станут более точными и быстрыми. Короче, вместо того чтобы ШИМить 3-Ф мостом, ну Вы поняли, а то я уже начинаю повторяться.

Добавлено after 1 minute 51 second:
P.S. Приоритет на идею сохраняю за собой, буду делать реализацию и патентовать.

Добавлено after 37 minutes 41 second:
И, в то-же время. Этот единый ШИМ и его закон, получаются очень простым, гораздо проще прежнего "фирменного". Ну я Голова, это-же надо такое придумать!!!!

_________________
"Every profession is a conspiracy against the uninitiated" (B. Shaw)
"A textbook can be defined as a book unsuitable for reading" (B. Shaw)
Tautology is humor in "this" place (Vigo Carpathian)


Вернуться наверх
 
Показать сообщения за:  Сортировать по:  Вернуться наверх
Начать новую тему Ответить на тему  [ Сообщений: 15 ] 

Часовой пояс: UTC + 3 часа


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 20


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
Extended by Karma MOD © 2007—2012 m157y
Extended by Topic Tags MOD © 2012 m157y