ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
28 ноября
252012
spoluer (06.05.2011 08:51, просмотров: 12459)
Стоит задача провести тест на качество передачи информации. Железо: две платы 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. При дебаге все работает как часы. Когда нормально их запускаю, то при нажатии кнопки на передатчике, на приемнике загораются оба светодиода и ничего не происходит. В чем может быть проблема?