Стоит задача провести тест на качество передачи информации. Железо: две платы EM430F6137RF900. Т.к. SmartRF не поддерживает данный вид теста для CC430, нужно написать код. Пробую это делать на основе "C430x613x RF examples". Пакеты данных непрерывно передаются на принимающее устройство. После каждого принятого пакета приемник шлет ответ.
PER=((Total-Ack)/Total)*100%
где Total - общее количество пакетов, переданных передатчиком;
Ack - подтверждение, пришедшее от приемника.
Total-Ack - количество потерянных пакетов.
Затем данные будут выводится через RS232 на ноутбук. Но это позже. Для начала, хотелось бы завести сам тест.
Может кто-нибудь уже занимался этим? Хотелось бы увидеть примеры кода в IAR. Через некоторое время выложу свои попытки реализации.
Код для передатчика:
[c]#include "RF_Toggle_LED_Demo.h"
#define PACKET_LEN (0x05) // PACKET_LEN <= 61
#define RSSI_IDX (PACKET_LEN) // Index of appended RSSI
#define CRC_LQI_IDX (PACKET_LEN+1) // Index of appended LQI, checksum
#define CRC_OK (BIT7) // CRC_OK bit
#define PATABLE_VAL (0x51) // 0 dBm output
extern RF_SETTINGS rfSettings;
unsigned char packetReceived;
unsigned char packetTransmit;
unsigned char RxBuffer[PACKET_LEN+2];
unsigned char RxBufferLength = 0;
const unsigned char TxBuffer[PACKET_LEN]= {0xAA, 0xBB, 0xCC, 0xDD, 0xEE};
unsigned char buttonPressed = 1;
unsigned int i = 0;
unsigned int Ack = 0;
unsigned int Total = 0;
unsigned char transmitting = 0;
unsigned char receiving = 0;
void main( void )
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
// Increase PMMCOREV level to 2 for proper radio operation
SetVCore(2);
ResetRadioCore();
InitRadio();
InitButtonLeds();
ReceiveOn();
receiving = 1;
while (1)
{
__bis_SR_register( LPM3_bits + GIE );
__no_operation();
if (buttonPressed) // Process a button press->transmit
{
P3OUT |= BIT6; // Pulse LED during Transmit
buttonPressed = 0;
P1IFG = 0;
ReceiveOff();
receiving = 0;
Transmit( (unsigned char*)TxBuffer, sizeof TxBuffer);
transmitting = 1;
P1IE |= BIT7; // Re-enable button press
}
else if(!transmitting)
{
ReceiveOn();
receiving = 1;
}
// Strobe( RF_SIDLE ); //перевод в режим ожидания
while (transmitting);
ReceiveOn(); //перевод в режим приема, для получения ответа
receiving = 1;
}
}
void InitButtonLeds(void)
{
// Set up the button as interruptible
P1DIR &= ~BIT7;
P1REN |= BIT7;
P1IES &= BIT7;
P1IFG = 0;
P1OUT |= BIT7;
P1IE |= BIT7;
// Initialize Port J
PJOUT = 0x00;
PJDIR = 0xFF;
// Set up LEDs
P1OUT &= ~BIT0;
P1DIR |= BIT0;
P3OUT &= ~BIT6;
P3DIR |= BIT6;
}
void InitRadio(void)
{
// Set the High-Power Mode Request Enable bit so LPM3 can be entered
// with active radio enabled
PMMCTL0_H = 0xA5;
PMMCTL0_L |= PMMHPMRE_L;
PMMCTL0_H = 0x00;
WriteRfSettings(&rfSettings);
WriteSinglePATable(PATABLE_VAL);
}
#pragma vector=PORT1_VECTOR
__interrupt void PORT1_ISR(void)
{
switch(__even_in_range(P1IV, 16))
{
case 0: break;
case 2: break; // P1.0 IFG
case 4: break; // P1.1 IFG
case 6: break; // P1.2 IFG
case 8: break; // P1.3 IFG
case 10: break; // P1.4 IFG
case 12: break; // P1.5 IFG
case 14: break; // P1.6 IFG
case 16: // P1.7 IFG
P1IE = 0; // Debounce by disabling buttons
buttonPressed = 1;
__bic_SR_register_on_exit(LPM3_bits); // Exit active
break;
}
}
void Transmit(unsigned char *buffer, unsigned char length)
{
RF1AIES |= BIT9;
RF1AIFG &= ~BIT9; // Clear pending interrupts
RF1AIE |= BIT9; // Enable TX end-of-packet interrupt
WriteBurstReg(RF_TXFIFOWR, buffer, length);
Strobe( RF_STX ); // Strobe STX
}
void ReceiveOn(void)
{
RF1AIES |= BIT9; // Falling edge of RFIFG9
RF1AIFG &= ~BIT9; // Clear a pending interrupt
RF1AIE |= BIT9; // Enable the interrupt
// Radio is in IDLE following a TX, so strobe SRX to enter Receive Mode
Strobe( RF_SRX );
}
void ReceiveOff(void)
{
RF1AIE &= ~BIT9; // Disable RX interrupts
RF1AIFG &= ~BIT9; // Clear pending IFG
// It is possible that ReceiveOff is called while radio is receiving a packet.
// Therefore, it is necessary to flush the RX FIFO after issuing IDLE strobe
// such that the RXFIFO is empty prior to receiving a packet.
Strobe( RF_SIDLE );
Strobe( RF_SFRX );
}
#pragma vector=CC1101_VECTOR
__interrupt void CC1101_ISR(void)
{
switch(__even_in_range(RF1AIV,32)) // Prioritizing Radio Core Interrupt
{
case 0: break; // No RF core interrupt pending
case 2: break; // RFIFG0
case 4: break; // RFIFG1
case 6: break; // RFIFG2
case 8: break; // RFIFG3
case 10: break; // RFIFG4
case 12: break; // RFIFG5
case 14: break; // RFIFG6
case 16: break; // RFIFG7
case 18: break; // RFIFG8
case 20: // RFIFG9
if(receiving) // RX end of packet
{
// Read the length byte from the FIFO
RxBufferLength = ReadSingleReg( RXBYTES );
ReadBurstReg(RF_RXFIFORD, RxBuffer, RxBufferLength);
// Stop here to see contents of RxBuffer
__no_operation();
// Check the CRC results
if(RxBuffer[CRC_LQI_IDX] & CRC_OK)
{
P1OUT ^= BIT0; // Toggle LED1
Ack++; //Количество подтверждений
}
}
else if(transmitting) // TX end of packet
{
RF1AIE &= ~BIT9; // Disable TX end-of-packet interrupt
P3OUT &= ~BIT6; // Turn off LED after Transmit
transmitting = 0;
Total++; //общее кол-во переданных пакетов
}
else while(1); // trap
break;
case 22: break; // RFIFG10
case 24: break; // RFIFG11
case 26: break; // RFIFG12
case 28: break; // RFIFG13
case 30: break; // RFIFG14
case 32: break; // RFIFG15
}
__bic_SR_register_on_exit(LPM3_bits);
}
[/c]
Вот код для приемника:
[c]
#include "RF_Toggle_LED_Demo.h"
#define PACKET_LEN (0x05) // PACKET_LEN <= 61
#define RSSI_IDX (PACKET_LEN) // Index of appended RSSI
#define CRC_LQI_IDX (PACKET_LEN+1) // Index of appended LQI, checksum
#define CRC_OK (BIT7) // CRC_OK bit
#define PATABLE_VAL (0x51) // 0 dBm output
extern RF_SETTINGS rfSettings;
unsigned char packetReceived;
unsigned char packetTransmit;
unsigned char RxBuffer[PACKET_LEN+2];
unsigned char RxBufferLength = 0;
const unsigned char TxBuffer[PACKET_LEN]= {0xAA, 0xBB, 0xCC, 0xDD, 0xEE};
unsigned char buttonPressed = 1;
unsigned int i = 0;
unsigned char CRC = 0;
unsigned char transmitting = 0;
unsigned char receiving = 0;
void main( void )
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
// Increase PMMCOREV level to 2 for proper radio operation
SetVCore(2);
ResetRadioCore();
InitRadio();
InitButtonLeds();
ReceiveOn();
receiving = 1;
while (1)
{
__bis_SR_register( LPM3_bits + GIE );
__no_operation();
// if (CRC) // Если пакет принят и CRC совпадает запускаем передачу ответа
while (CRC)
{
P3OUT |= BIT6; // Pulse LED during Transmit
ReceiveOff();
receiving = 0;
Transmit( (unsigned char*)TxBuffer, sizeof TxBuffer);
transmitting = 1;
}
// else if(!transmitting)
// {
ReceiveOn();
receiving = 1;
//}
}
}
void InitButtonLeds(void)
{
// Set up the button as interruptible
P1DIR &= ~BIT7;
P1REN |= BIT7;
P1IES &= BIT7;
P1IFG = 0;
P1OUT |= BIT7;
P1IE |= BIT7;
// Initialize Port J
PJOUT = 0x00;
PJDIR = 0xFF;
// Set up LEDs
P1OUT &= ~BIT0;
P1DIR |= BIT0;
P3OUT &= ~BIT6;
P3DIR |= BIT6;
}
void InitRadio(void)
{
// Set the High-Power Mode Request Enable bit so LPM3 can be entered
// with active radio enabled
PMMCTL0_H = 0xA5;
PMMCTL0_L |= PMMHPMRE_L;
PMMCTL0_H = 0x00;
WriteRfSettings(&rfSettings);
WriteSinglePATable(PATABLE_VAL);
}
#pragma vector=PORT1_VECTOR
__interrupt void PORT1_ISR(void)
{
switch(__even_in_range(P1IV, 16))
{
case 0: break;
case 2: break; // P1.0 IFG
case 4: break; // P1.1 IFG
case 6: break; // P1.2 IFG
case 8: break; // P1.3 IFG
case 10: break; // P1.4 IFG
case 12: break; // P1.5 IFG
case 14: break; // P1.6 IFG
case 16: // P1.7 IFG
P1IE = 0; // Debounce by disabling buttons
buttonPressed = 1;
__bic_SR_register_on_exit(LPM3_bits); // Exit active
break;
}
}
void Transmit(unsigned char *buffer, unsigned char length)
{
RF1AIES |= BIT9;
RF1AIFG &= ~BIT9; // Clear pending interrupts
RF1AIE |= BIT9; // Enable TX end-of-packet interrupt
WriteBurstReg(RF_TXFIFOWR, buffer, length);
Strobe( RF_STX ); // Strobe STX
}
void ReceiveOn(void)
{
RF1AIES |= BIT9; // Falling edge of RFIFG9
RF1AIFG &= ~BIT9; // Clear a pending interrupt
RF1AIE |= BIT9; // Enable the interrupt
// Radio is in IDLE following a TX, so strobe SRX to enter Receive Mode
Strobe( RF_SRX );
}
void ReceiveOff(void)
{
RF1AIE &= ~BIT9; // Disable RX interrupts
RF1AIFG &= ~BIT9; // Clear pending IFG
// It is possible that ReceiveOff is called while radio is receiving a packet.
// Therefore, it is necessary to flush the RX FIFO after issuing IDLE strobe
// such that the RXFIFO is empty prior to receiving a packet.
Strobe( RF_SIDLE );
Strobe( RF_SFRX );
}
#pragma vector=CC1101_VECTOR
__interrupt void CC1101_ISR(void)
{
switch(__even_in_range(RF1AIV,32)) // Prioritizing Radio Core Interrupt
{
case 0: break; // No RF core interrupt pending
case 2: break; // RFIFG0
case 4: break; // RFIFG1
case 6: break; // RFIFG2
case 8: break; // RFIFG3
case 10: break; // RFIFG4
case 12: break; // RFIFG5
case 14: break; // RFIFG6
case 16: break; // RFIFG7
case 18: break; // RFIFG8
case 20: // RFIFG9
if(receiving) // RX end of packet
{
// Read the length byte from the FIFO
RxBufferLength = ReadSingleReg( RXBYTES );
ReadBurstReg(RF_RXFIFORD, RxBuffer, RxBufferLength);
// Stop here to see contents of RxBuffer
__no_operation();
// Check the CRC results
if(RxBuffer[CRC_LQI_IDX] & CRC_OK)
{P1OUT ^= BIT0; CRC = 1;} // Toggle LED1
}
else if(transmitting) // TX end of packet
{
RF1AIE &= ~BIT9; // Disable TX end-of-packet interrupt
P3OUT &= ~BIT6; // Turn off LED after Transmit
transmitting = 0;
}
else while(1); // trap
break;
case 22: break; // RFIFG10
case 24: break; // RFIFG11
case 26: break; // RFIFG12
case 28: break; // RFIFG13
case 30: break; // RFIFG14
case 32: break; // RFIFG15
}
__bic_SR_register_on_exit(LPM3_bits);
}
[/c]
По идее, при нажатии кнопки на передатчике, на нем зажигается LED2, когда пакет передан, LED2 потухает. На приемнике переключается LED1 при приеме пакета. Затем применик передает ответный пакет и при этом на нем загорается LED2. А на передатчике при приеме ответа загорается LED1. При дебаге все работает как часы. Когда нормально их запускаю, то при нажатии кнопки на передатчике, на приемнике загораются оба светодиода и ничего не происходит. В чем может быть проблема?
-
- Бегло. 1)смотреть синхронизацию transmiting receiving 2)кнопка как правило имеет дребезг - его обработки я не увидел. - Xитpый Kитaeц(06.05.2011 10:17)
- Что-то я про дребезг кнопки не слышал... Можно поподробней? - spoluer(06.05.2011 10:39)
- А погуглить? - Vladimir Ljaschko(06.05.2011 11:20)
- Как можно его программно обработать? - spoluer(06.05.2011 12:04)
- Редкая незамутненность. Из "чистых" программистов, штоль? - Vladimir Ljaschko(06.05.2011 12:27, ссылка)
- Сравнить текущее состояние кнопочного бита порта с предыдущим (взятым миллисекунд 10..20 назад), и считать нажатием только при совпадении этих двух состояний - MBedder(06.05.2011 12:16)
- Вобщем вот, что получилось у меня практически в итоге. spoluer(10440 знак., 12.05.2011 06:20 - 06:28)
- Если используете прерывания, так и передавайте байты в прерывании и сигнализируйте об окончании передачи фоновой задаче. Обработка UART у Вас - смесь бульдога с носорогом, которая работать не будет. - Xитpый Kитaeц(12.05.2011 09:59)
- Кстати да) Передачу подправил. Так же подправил оформление пакета. Теперь оно работает как надо. Вот код: spoluer(12696 знак., 12.05.2011 12:17)
- А какой смысл в __bic_SR_register( GIE ) в обработчике прерывания? - Vit(12.05.2011 12:59)
- Действительно, никакого смысла) Спасибо за подсказку! - spoluer(12.05.2011 13:03)
- А какой смысл в __bic_SR_register( GIE ) в обработчике прерывания? - Vit(12.05.2011 12:59)
- Кстати да) Передачу подправил. Так же подправил оформление пакета. Теперь оно работает как надо. Вот код: spoluer(12696 знак., 12.05.2011 12:17)
- И где тут обработка кнопок? Если хотите спросить про радио, перенесите это сообщение в раздел беспроводной связи. - Vladimir Ljaschko(12.05.2011 09:34)
- Если используете прерывания, так и передавайте байты в прерывании и сигнализируйте об окончании передачи фоновой задаче. Обработка UART у Вас - смесь бульдога с носорогом, которая работать не будет. - Xитpый Kитaeц(12.05.2011 09:59)
- Вобщем вот, что получилось у меня практически в итоге. spoluer(10440 знак., 12.05.2011 06:20 - 06:28)
- Как можно его программно обработать? - spoluer(06.05.2011 12:04)
- А погуглить? - Vladimir Ljaschko(06.05.2011 11:20)
- Что-то я про дребезг кнопки не слышал... Можно поподробней? - spoluer(06.05.2011 10:39)
- Бегло. 1)смотреть синхронизацию transmiting receiving 2)кнопка как правило имеет дребезг - его обработки я не увидел. - Xитpый Kитaeц(06.05.2011 10:17)