Вот пример исходника класса для работы с СОМ-портом. Пользуйтесь, если хотите.
CODE
#include "types.h"
#include "at91sam7se.h"
class ComPort
{
public:
struct ReadBuffer
{
bool recieved;
word len;
word maxLen;
void* data;
};
struct WriteBuffer
{
bool transmited;
word len;
void* data;
};
protected:
enum STATUS485 { WRITEING = 0, WAIT_READ = 1, READING = 2, READ_END = 3 };
union CUSART { void *vp; HW::S_DBGU *DU; HW::S_USART *SU; };
struct ComBase
{
bool used;
const CUSART HU;
ComPort** const objCom;
const dword mask485;
};
static ComBase _bases[3];
bool _connected;
byte _status485;
byte _portNum;
word _prevDmaCounter;
word _BaudRateRegister;
dword _ModeRegister;
dword _mask485;
dword _preReadTimeout;
dword _postReadTimeout;
dword _startTransmitTime;
dword _startReceiveTime;
HW::S_USART *_SU;
ReadBuffer *_pReadBuffer;
WriteBuffer *_pWriteBuffer;
word BoudToPresc(dword speed);
void EnableTransmit(void* src, word count);
void DisableTransmit();
void EnableReceive(void* dst, word count);
void DisableReceive();
static bool _InitCom(byte i, ComPort* cp);
static bool _DeinitCom(byte i, ComPort* cp);
static ComPort *_objCom1;
static ComPort *_objCom2;
static ComPort *_objCom3;
void _IntHandler();
public:
ComPort() : _connected(false), _status485(READ_END) {}
bool Connect(byte port, dword speed, byte parity);
bool Disconnect();
bool Update();
bool Read(ComPort::ReadBuffer *readBuffer, dword preTimeout, dword postTimeout);
bool Write(ComPort::WriteBuffer *writeBuffer);
static __irq void _IntHandlerCom1();
static __irq void _IntHandlerCom2();
static __irq void _IntHandlerCom3();
};
CODE
#include <stdio.h>
//#include <conio.h>
#include "ComPort.h"
#include "hardware.h"
#include "at91sam7se.h"
#include "IntHandlers.h"
#ifdef _DEBUG_
// static const bool _debug = true;
#else
// static const bool _debug = false;
#endif
extern dword millisecondsCount;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ComPort::ComBase ComPort::_bases[3] = {
{false, HW::DBGU, &ComPort::_objCom1, 0 },
{false, HW::USART0, &ComPort::_objCom2, 1<<7 },
{false, HW::USART1, &ComPort::_objCom3, 1<<24 }
};
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
bool ComPort::Connect(byte port, dword speed, byte parity)
{
port -= 1;
if (_connected || port > 2 || _bases[port].used)
{
return false;
};
_portNum = port;
ComBase &cb = _bases[port];
_SU = cb.HU.SU;
_mask485 = cb.mask485;
_BaudRateRegister = BoudToPresc(speed);
_ModeRegister = 0xC0;
switch (parity)
{
case 0: // нет четности
_ModeRegister |= 0x800;
break;
case 1:
_ModeRegister |= 0x200;
break;
case 2:
_ModeRegister |= 0x000;
break;
};
_SU->CR = 3;
_SU->MR = _ModeRegister;
_SU->BRGR = _BaudRateRegister;
cb.objCom[0] = this;
_status485 = READ_END;
return _connected = cb.used = true;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
bool ComPort::Disconnect()
{
if (!_connected) return false;
DisableReceive();
DisableTransmit();
_status485 = READ_END;
_connected = _bases[_portNum].used = false;
return true;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
word ComPort::BoudToPresc(dword speed)
{
if (speed == 0) return 0;
word presc;
presc = (word)((MCK*0.0625) / speed + 0.5);
return presc;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void ComPort::EnableTransmit(void* src, word count)
{
_SU->CR = 0xA0; // Disable transmit and receive
HW::PIOA->SODR = _mask485;
_SU->PDC.TPR = src;
_SU->PDC.TCR = count;
_SU->PDC.PTCR = 0x100;
_startTransmitTime = HW::RTT->VR;
_SU->CR = 0x40;
_status485 = WRITEING;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void ComPort::DisableTransmit()
{
_SU->CR = 0x80;
_SU->PDC.PTCR = 0x200;
HW::PIOA->CODR = _mask485;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void ComPort::EnableReceive(void* dst, word count)
{
_SU->CR = 0xA0; // Disable transmit and receive
HW::PIOA->CODR = _mask485;
_SU->PDC.RPR = dst;
_SU->PDC.RCR = count;
_SU->PDC.PTCR = 1;
_startReceiveTime = HW::RTT->VR;
_SU->CR = 0x10;
_status485 = WAIT_READ;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void ComPort::DisableReceive()
{
_SU->CR = 0x20;
_SU->PDC.PTCR = 2;
HW::PIOA->CODR = _mask485;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
bool ComPort::Update()
{
// static word p = 0;
dword stamp;
// DataCRC CRC;
bool r = true;
if (!_connected)
{
_status485 = READ_END;
};
stamp = HW::RTT->VR;
// 0000 0110 0011 1000
if (_SU->CSR & 0x60)
{
DisableTransmit();
DisableReceive();
_status485 = READ_END;
};
switch (_status485)
{
case WRITEING:
if (_SU->CSR& 0x210)
{
_pWriteBuffer->transmited = true;
_status485 = READ_END;
DisableTransmit();
DisableReceive();
r = false;
};
break;
case WAIT_READ:
if ((_prevDmaCounter-_SU->PDC.RCR) == 0)
{
if ((stamp - _startReceiveTime) >= _preReadTimeout)
{
DisableReceive();
_pReadBuffer->len = _pReadBuffer->maxLen - _prevDmaCounter;
_pReadBuffer->recieved = _pReadBuffer->len > 0;
_status485 = READ_END;
r = false;
};
}
else
{
_prevDmaCounter = _SU->PDC.RCR;
_startReceiveTime = stamp;
_status485 = READING;
};
break;
case READING:
if ((_prevDmaCounter-_SU->PDC.RCR) == 0)
{
if ((stamp - _startReceiveTime) >= _postReadTimeout)
{
DisableReceive();
_pReadBuffer->len = _pReadBuffer->maxLen - _prevDmaCounter;
_pReadBuffer->recieved = _pReadBuffer->len > 0;
_status485 = READ_END;
r = false;
};
}
else
{
_prevDmaCounter = _SU->PDC.RCR;
_startReceiveTime = stamp;
};
break;
case READ_END:
r = false;
break;
};
return r;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
bool ComPort::Read(ComPort::ReadBuffer *readBuffer, dword preTimeout, dword postTimeout)
{
if (_status485 != READ_END || readBuffer == 0)
{
// cputs("ComPort::Read falure\n\r");
return false;
};
_preReadTimeout = preTimeout;
_postReadTimeout = postTimeout;
_pReadBuffer = readBuffer;
_pReadBuffer->recieved = false;
_pReadBuffer->len = 0;
_prevDmaCounter = _pReadBuffer->maxLen;
EnableReceive(_pReadBuffer->data, _pReadBuffer->maxLen);
// cputs("ComPort::Read start\n\r");
return true;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
bool ComPort::Write(ComPort::WriteBuffer *writeBuffer)
{
if (_status485 != READ_END || writeBuffer == 0)
{
return false;
};
_pWriteBuffer = writeBuffer;
_pWriteBuffer->transmited = false;
EnableTransmit(_pWriteBuffer->data, _pWriteBuffer->len);
return true;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
void ComPort::_IntHandler()
{
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Причина редактирования: Нарушение п.3.4 Правил форума.