Что касается портов ввода вывода их направления и тд.
попытаюсь объяснить.
I,Q-это обычный массив определенны как:
char I[50]
char Q[50]
C переменными данных массивов можно делать булевые операции(I12.5,Q2.3), операции с типом integer (IB2,QW2,ID2), операции с плавающей запятой ID2,QD34.
Главное помнить что integer может иметь размер 1байт(В) 2байта(W) или 4байта(D) а тип данных real 4 байта(D). Первая буква всегда идет идентификатором области памяти(массива).
Теперь о вводе вводе-выводе.
Принято так: программа ПЛК зачитывает данные из реальных каналов ВВОДА в массив I[50] перед обработкой программы пользователя.
Программа ПЛК записывает данные в реальные каналы ВЫВОДА из массива Q[50] после обработкой программы пользователя.
Вывод следующий....функции ввода-вывода пользователь должен написать сам применительно к тому аппаратному обеспечению которое у него есть.
Другими словами....Я ж не знаю какую схему ПЛК вы собрали))))))..и какой порт расширения у вас стоит(SPI, I2C, ППВ).
массив М[50]-массив отданный пользователю для хранения результатов его вычисления.
Например CoDeSys как среда позиционирующая себя под разные ПЛК просто выделяет пустую функцию ввода вывода, которую конечный пользователь должен заполнить сам. Далее пример из ОС CoDeSys
/************************************************** ***************************/
/* IO Access */
/************************************************** ***************************/
void RHIIOInit (void)
{
/* TO-DO: add here code to initialize your hardware */
pfe_enable_pio(5,4);
pfe_enable_pio(9,2);
pfe_enable_pio(10,4);
I2C_select_clock_pin (0);
I2C_select_data_pin (1);
I2C_init();
}
int RHIIOReadInputs (unsigned char *pInputArea,
unsigned int inputAreaSize,
unsigned int moduleOffset,
unsigned int moduleSize,
long moduleHandle,
long taskId)
{
char temp;
char buf[5];
char ret;
// TO-DO: add here code to copy the hardware values into the IEC input area.
RHIInputArea *theInputArea = (RHIInputArea*)pInputArea;
for (temp=0; temp‹6; temp++)
{
ret = I2C_receive_block ( ModuleWork, buf, 3 );
I2C_release();
}
if (ret==0) {theInputArea-›IB0=buf[0]; }
/* avoid compiler warnings */
pInputArea = pInputArea;
inputAreaSize = inputAreaSize;
moduleOffset = moduleOffset;
moduleSize = moduleSize;
moduleHandle = moduleHandle;
taskId = taskId;
return 0;
}
int RHIIOWriteOutputs (unsigned char *pOutputArea,
unsigned int outputAreaSize,
unsigned int moduleOffset,
unsigned int moduleSize,
long moduleHandle,
long taskId)
{
char temp;
char buf[5];
char ret;
/* TO-DO: add here code to copy the IEC output area values to the hardware.
Example:
RHIOutputArea *theOutputArea = (RHIOutputArea *)pOutputArea;
outportb(0x600, theOutputArea-›myByteOutput);
outport (0x602, theOutputArea-›myWordOutput);
*/
RHIOutputArea *theOutputArea = (RHIOutputArea *)pOutputArea;
/* avoid compiler warnings */
pOutputArea = pOutputArea;
outputAreaSize = outputAreaSize;
moduleOffset = moduleOffset;
moduleSize = moduleSize;
moduleHandle = moduleHandle;
taskId = taskId;
return 0;
}
Сообщение от picavr
|
Сообщение от vo1
|
А направления портов обычно "жестко" назначены. И в "процессе" не перенаправляются.
То-есть - нет таких команд ( и не нужно, имхо) в "высшей" системе команд.
Если конечно не химичить с мультиплексированием..
|
Так о задаче направления портов при старте не было сказано, их ведь то же нужно задавать.
А если ногов захочется поболее?... тут мультиплексирование напрашивается.
|
Чтобы небыло больше вопросов я ввиду в программу СИ кода следующие функции:
void IO_Input(void)
{
}
void IO_Output(void)
{
}
void IO_Init(void)
{
А в теле оснофной программы будет их вызов:
//*******OB100********
TMOD = 0x01; // Внутренние таймера 16 разрядные
TR0=1; // Включит таймер 0
ET0=1; // Разрешить прерывание от таймера 0
EA=1; // Резрешить все прерывания
IO_Init(); // Нициализация портов
//********OB1*********
while(1){
IO_Input(); // Чтение входных модулей
//Здесь код пользовательской программы
IO_Output(); // Запись в выходные модули
}}
}