Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: AT91sam7x256->UART1->теряет данные
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
D1ma
Здравствуйте уважаемые.

Надо организовать передачу по UART .
Написал код на прием. Послал с компа к ат91сам7с256 пакет 1,2,3,4,5,6,7,8,176,207 – 10 байт. Но приходит в среднем 5 байт через 1,2.
Не знаю где глюк. Помогите, целый день пробился бестолку smile3046.gif
код ниже . IAR
CODE
void AIC_ConfigureIT(
unsigned int source,
unsigned int mode,
void (*handler)(void))
{
// Disable the interrupt first
AT91C_BASE_AIC->AIC_IDCR = 1 << source;

// Configure mode and handler
AT91C_BASE_AIC->AIC_SMR[source] = mode;
AT91C_BASE_AIC->AIC_SVR[source] = (unsigned int) handler;

// Clear interrupt
AT91C_BASE_AIC->AIC_ICCR = 1 << source;
}
//------------------------------------------------------------------------------
/// Enables interrupts coming from the given (unique) source (AT91C_ID_xxx).
/// \param source Interrupt source to enable.
//------------------------------------------------------------------------------
void AIC_EnableIT(unsigned int source)
{
AT91C_BASE_AIC->AIC_IECR = 1 << source;
}
//------------------------------------------------------------------------------
/// Interrupt handler for USART1.
//------------------------------------------------------------------------------
int count=0;
#define SIZEBUF 10
unsigned char pBuffer[SIZEBUF];
void ISR_Usart1(void)
{

unsigned int status;
// Read USART status
status = AT91C_BASE_US1->US_CSR;
// Receive buffer is full
if ((status & AT91C_US_ENDRX) == AT91C_US_ENDRX)
{
if ((AT91C_BASE_US1->US_RCR == 0) && (AT91C_BASE_US1->US_RNCR == 0))
{
AT91C_BASE_US1->US_RPR = (unsigned int) pBuffer;
AT91C_BASE_US1->US_RCR = SIZEBUF;
AT91C_BASE_US1->US_PTCR = AT91C_PDC_RXTEN;
}
}
}

void InitModBus()
{

AT91C_BASE_US1->US_CR = AT91C_US_RSTRX | // Reset Receiver
AT91C_US_RSTTX | // Reset Transmitterp
AT91C_US_RXDIS | // Receiver Disable
AT91C_US_TXDIS; // Transmitter Disable

AT91C_BASE_PDC_US1->PDC_PTCR = AT91C_PDC_RXTDIS |AT91C_PDC_TXTDIS; //PDC off
//clear buf
AT91C_BASE_US1->US_TCR = 0;
AT91C_BASE_US1->US_RCR = 0;
AT91C_BASE_US1->US_TNCR = 0;
AT91C_BASE_US1->US_RNCR = 0;

//timeout off
AT91C_BASE_US1->US_TTGR = 0;
AT91C_BASE_US1->US_RTOR = 0;
//PIOA - init
AT91C_BASE_PIOA->PIO_PER=(1<<24);//всегда прием
AT91C_BASE_PIOA->PIO_OER=(1<<24);
AT91C_BASE_PIOA->PIO_CODR=(1<<24);

AT91C_BASE_PIOA->PIO_PDR=(1<<21)|(1<<22);//|(1<<24);
AT91C_BASE_PIOA->PIO_ASR=(1<<21)|(1<<22);//|(1<<24);
AT91C_BASE_PIOA->PIO_BSR=0;
//uart MCK on
AT91C_BASE_PMC->PMC_PCER=(1<<AT91C_ID_US1);
//set uart1
AT91C_BASE_US1->US_MR= AT91C_US_USMODE_NORMAL |//AT91C_US_USMODE_RS485 |
AT91C_US_CLKS_CLOCK |
AT91C_US_CHRL_8_BITS |
AT91C_US_NBSTOP_1_BIT |
AT91C_US_CHMODE_NORMAL ;
AT91C_BASE_US1->US_BRGR=BOARD_MCK/(16*9600);


//set buf rx
AT91C_BASE_US1->US_RPR = (unsigned int) pBuffer;
AT91C_BASE_US1->US_RCR = SIZEBUF;
//buf on rx tx
AT91C_BASE_US1->US_PTCR = AT91C_PDC_RXTEN|AT91C_PDC_TXTEN;

// intr for null count buf rx
AT91C_BASE_US1->US_IER=AT91C_US_ENDRX;

// intr uart1 on
AIC_ConfigureIT(AT91C_ID_US1, 0, ISR_Usart1);
AIC_EnableIT(AT91C_ID_US1);
//eneble tx & rx
AT91C_BASE_US1->US_CR=AT91C_US_RXEN|AT91C_US_TXEN;


};


Да байты приходят правельные, тоесть параметр юарта норм. (жаль не все cranky.gif )
D1ma
нашол грабли smile.gif
Код
AT91C_BASE_US1->US_MR=  AT91C_US_USMODE_NORMAL  |//AT91C_US_USMODE_RS485   |
                            AT91C_US_CLKS_CLOCK     |
                            AT91C_US_CHRL_8_BITS    |
                            AT91C_US_NBSTOP_1_BIT   |
                            AT91C_US_CHMODE_NORMAL;

это значит проверка на парность
из даташит
Цитата
PAR Parity Type
0 0 0 Even parity
0 0 1 Odd parity
0 1 0 Parity forced to 0 (Space)
0 1 1 Parity forced to 1 (Mark)
1 0 x No parity
1 1 x Multidrop mode

а яслал бес проверки. дописал
Код
AT91C_BASE_US1->US_MR=  AT91C_US_USMODE_NORMAL  |//AT91C_US_USMODE_RS485   |
                            AT91C_US_CLKS_CLOCK     |
                            AT91C_US_CHRL_8_BITS    |
                            AT91C_US_NBSTOP_1_BIT   |
                            AT91C_US_CHMODE_NORMAL|
                            (1<<11);                                         ;

и все отлично принемает cool.gif
fantex
Вот пример исходника класса для работы с СОМ-портом. Пользуйтесь, если хотите.

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()
{


}

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.