Jump to content

    

spoluer

Участник
  • Content Count

    29
  • Joined

  • Last visited

Community Reputation

0 Обычный

About spoluer

  • Rank
    Участник
  1. Может быть чем-то поможет) В своем проекте на STM32F217 для хранения лог событий системы и настроек использовали внешнюю flash-память. По ходу возникла проблема: если при записи данных во внешнюю флеш дернуть питание, то данные все слетят. Соответственно для решения придумали такую вещь: У данного контроллера есть энергонезависимая память Backup SRAM, в которой организовали очередь записи во внешнюю флеш. Таким образом, если нужно было что-то записать во внешнюю флеш, данные сначала записывались в Backup SRAM на контроллере. Затем если внешняя флеш была готова к записи, считывали из очереди данные и писали во внешнюю флеш. После окончания записи, считывали вновь записанные данные из внешней флеш и сравнивали с данными, которые хранятся в Backup SRAM. Если данные не совпадали, то снова пытались записать их во внешнюю флеш. Если же данные совпадали, то сдвигали очередь в Backup SRAM влево, удаляя при этом первый элемент. Таким образом проблему решили, при сбросе питания данные во флеш не терялись, и при восстановлении нормальной работы могли быть заново записаны из Backup SRAM.
  2. RS485-USART

    Что-то лыжи совсем не едут... Я данный вами код немного подправил. Вышло вот такое: static inline void uart_rx_isr(uint16_t status) { static const uint32_t ERR_MASK = USART_SR_ORE | USART_SR_NE | USART_SR_FE | USART_SR_PE; // overrun, nois or frame errors uint8_t data = USART2->DR; // read data first if ((status & ERR_MASK)==0) // if no errors { // fifo_put_byte(&uart->fifo.rx, data); } } //============================================================================= static inline void uart_tx_isr(void) { // if (!fifo_get_byte(&uart->fifo.tx, (uint8_t*)&uart->sfr->DR)) // { // uart_set_tx_int(uart, 0); // tx_int off // } } void USART2_IRQHandler(void) { uint16_t status = USART2->SR; if (status & USART_SR_RXNE) // if RX data_reg isn't empty (auto-clr by reading data_reg) { uart_rx_isr(status); } else if (status & USART_SR_TXE) // if TX data_reg is empty (auto-clr by writing data_reg) { uart_tx_isr(); } } И в итоге все также. Я тут на своем прежнем коде один раз поймал состояние, когда RXNE=1 в breakpoint, но так и не понял, что на это повлияло. В общем, пока копаю дальше...
  3. RS485-USART

    to demiurg_spb 1. Это понятно, что достаточно одного вывода. Но сделали так, как сделали. 2. Действительно, я ошибся. Сейчас посмотрел, выходит, что там будет высокий импеданс. Но проблемы это не решает. to KnightIgor Действительно, ситуация такая получается, что в какой-то момент времени флаг RXNE устанавливается, срабатывает прерывание по нему, а затем он сбрасывается. И в breakpoint я попадаю в тот момент, когда RXNE уже сброшен. Breakpoint установлен в самом начале обработчика прерывания. __DSB() поставил в конец ISR. Не помогло. Так же при пересылке >1 байт происходит установка флага ORE. Т.е. можно сделать вывод, что данные из регистра DR не считаны и RXNE сбрасывается по какой-то другой причине.
  4. RS485-USART

    1. Да управляю. Выводы PA1 и PA4. 2. В логической "1".
  5. RS485-USART

    RX и TX выводы подключены к выводам RO и DI микросхемы драйвер приема/передачи RS485 MAX3486.
  6. RS485-USART

    void USART2_IRQHandler(void) { if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) { RxBuffer[RxCounter++] = (USART_ReceiveData(USART2) & 0x7F); if(RxCounter == NbrOfDataToRead) { USART_ITConfig(USART2, USART_IT_RXNE, DISABLE); } } } Вот собственно функция обработки прерывания по RXNE. При отладке вот эта строка if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) всегда FALSE, т.е. бит RXNE = 0. Вот где считывается DR?
  7. RS485-USART

    Пытаюсь переслать байт от компьютера на STM32F103RET6 по следующей схеме: ПК<->RS232<->RS485<->USART В качестве IDE использую IAR 6.21. Переходник RS232-RS485 работает корректно. На плате используется драйвер приема/передачи RS485 MAX3486, который работает также корректно. При приеме байта от ПК, программа залетает в прерывание, в нем[прерывании] видно, что установлены флаги RXNE=0, а IDLE=1. При том, что буфер данных DR содержит принятый байт. Разрешено только прерывание по приему данных RXNIE=1, а прерывание по состоянию IDLE не разрешено IDLEIE=0. Если запретить прерывание по приему данных RXNIE=0, то программа не улетает в прерывание, но флаг IDLE-состояния устанавливается IDLE=1. В общем, ощущение как-будто программа уходит в прерывание по непустому буферу приема, но при этом флаг RXNE сбрасывается в 0. На осциллограмме сигнала на выводе PA3 (USART2 RX) видно, что передаются нужные данные, что подтверждает тот факт, что в буфере данных находятся принятые данные. Подскажите, друзья, пожалуйста. Правильно ли я понимаю, что флаг RXNE должен сбрасываться в 0 только когда данные прочитаны из буфера данных DR? И что это за IDLE-frame? Откуда он берется и почему устанавливается флаг IDLE=1 Вот собственно код. #include "stm32f10x_conf.h" #include "stm32f10x.h" void SetupUSART(void); void InitNVIC(void); USART_InitTypeDef USART_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; extern uint16_t tmp,rx,tx_end; int main() { InitNVIC(); SetupUSART(); while(1) { } return 0; } void InitNVIC(void) { NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void SetupUSART(void) { RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); /* Configure USART2 Rx (PA3) as input floating */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure USART2 Tx (PA2) as alternate function push-pull */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); USART_InitStructure.USART_BaudRate = 9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b; USART_InitStructure.USART_StopBits = USART_StopBits_1; USART_InitStructure.USART_Parity = USART_Parity_No ; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_Init(USART2, &USART_InitStructure); USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); // USART_ITConfig(USART2, USART_IT_IDLE, ENABLE); // USART_ITConfig(USART1, USART_IT_TXE, ENABLE); /* Configure PA1 as rs485 tx select */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); /* Configure PA4 as rs485 rx select */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_ResetBits(GPIOA, GPIO_Pin_4); GPIO_ResetBits(GPIOA, GPIO_Pin_1); // GPIO_SetBits(GPIOA, GPIO_Pin_4); // GPIO_SetBits(GPIOA, GPIO_Pin_1); // USART_SendData(USART2, 0x02); USART_Cmd(USART2, ENABLE); }
  8. ADPCM

    Имеется два CC430F6137. На одном из них с помощью таблицы синуса и шим генерируется синусоида, затем она подается на АЦП 8 бит, данные с АЦП кодируются с помощью IMA ADPCM и посылаются по радиоканалу. На втором данные принимаются, декодируются и поступаются на ШИМ, с помощью которого получаем синусоиду. В прикрепленных файлах исходники и картинка, поясняющая вышесказанное. На приемнике используется двойная буферизация, т.е. таймер поочередно читает данные из двух массивов, а декодированные данные записываются в тот массив, который в данный момент не используется таймером. Проблема заключается в следующем, в момент переключения буферов на получаемой синусоиде происходят скачки. Если на передатчике отключить АЦП и кодировать и передавать уже готовую таблицу синуса, то эти скачки исчезают и синусоида получается идеальной. Как можно решить данную загвоздку? Sinus.zip
  9. ADPCM

    Пытаюсь сделать сжатие звука на CC430F6137 посредством IMA ADPCM кодека. Кодирую 8-битные сэмплы в 4 бита. Но что-то я совсем запутался с этим ADPCM(( Пытаюсь разобраться с простейшей программой. Есть таблица выборок синусоиды. Кодирую ее ADPCM, затем декодирую и смотрю что получилось. Как я понимаю на выходе должна получиться таблица с идентичными значениями. Но в массиве на выходе все значения равны 0х8000. В чем может быть дело? Ниже привожу код программы, а в прикрепленных файлах ADPCM. #include "adpcm.h" #include "cc430f6137.h" #define buf_len 16 signed int buf[buf_len] = { 0x80,0xB0,0xDA,0xF6,0xFF,0xF6,0xDA,0xB1,0x80,0x4F,0x25,0x09,0x00,0x09,0x25, 0x4E }; unsigned long count_sample = buf_len; unsigned char encoded_buf[8]; unsigned long size_in; signed int decoded_buf[16]; void main(void) { // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; while(1) { size_in = encode_adpcm(buf,count_sample,encoded_buf,0,0); count_sample = decode_adpcm(encoded_buf,size_in,decoded_buf,0,0); // for(int idx=0;idx<count_sample;idx++) // TA1CCR1 = decoded_buf[idx]; } } adpcm.zip
  10. Контакты замыкал у переходника USB-RS232, на терминале эхо видно. USB хост на ноуте жив. Можно поподробней про проверку согласования уровней по RS232 платы и преобразователя?
  11. Стоит задача снимать с микроконтроллера данные на компьютер. Данные передаются микроконтроллером по UART через RS232. При подключении, непосредственно к COM-порту, все работает на ура. Т.к. у ноутбука выведены только USB-порты, пришлось дополнить все это еще и переходником RS232-USB U-350 фирмы ST-LAB. Вот тут и начинается проблема. Данные через переходник передаются совершенно не те, что должны. Приходит на компьютер какая-то ересь. В чем может быть проблема? И что с этим сделать?
  12. Работа близка к завершению. Последний результат. Подправил подсчет пакетов, оформление ланных в один пакет для передачи по UART, саму передачу по UART. Когда запускаю ниже следующий код, передатчик перестает принимать ответы. Когда убираю функцию оформления пакета для передачи по UART PacketMake(), то передатчик начинает принимать ответы. В чем может быть проблема? /* ___________________________Include_libraries_______________________________*/ #include "RF_Toggle_LED_Demo.h" /*_______________________________Define's_____________________________________*/ #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 /*______________________________Variables_____________________________________*/ 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 int Ack = 0; unsigned int Total = 0; unsigned char transmitting = 0; unsigned char Time = 0; unsigned char receiving = 0; unsigned char cAck[4]={0}; unsigned char cTotal[4]={0}; unsigned char id1[1]={1}; unsigned char id2[1]={2}; unsigned int PacketLen = 10; unsigned char Packet[10]; /*________________________________Main_Function_______________________________*/ 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) { TA1CTL = TASSEL_1 + MC_2 + TACLR + TAIE; // SMCLK, contmode, clear TAR __bis_SR_register( LPM3_bits + GIE ); __no_operation(); if (Time) // Timer count set->transmit { P3OUT |= BIT6; // Pulse LED during Transmit Time = 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; } while (transmitting); ReceiveOn(); //Perevod v rezhim priema dlya polucheniya otveta receiving = 1; _BIS_SR(LPM0_bits); PacketMake(); InitUART(); } } /*_______________________________Functions____________________________________*/ //****************************************************************************** // @fn PacketMake // @brief Oformlenie paketa dannyh, dlya peredachi po UART // @param none // @return none // ***************************************************************************** void PacketMake(void) { IntToChar (Ack, cAck); IntToChar (Total, cTotal); unsigned int idx; unsigned int idx1; for (idx=0; idx<1; idx++) { Packet[idx]=id1[idx]; } for (idx=1, idx1=0; idx<5; idx++, idx1++) { Packet[idx]=cAck[idx1]; } for (idx=5, idx1=0; idx<6; idx++, idx1++) { Packet[idx]=id2[idx1]; } for (idx=6, idx1=0; idx<10; idx++, idx1++) { Packet[idx]=cTotal[idx1]; } } //****************************************************************************** // @fn IntToChar // @brief Preobrazovanie kolichestva paketov v massiv // @param unsigned int num Chislo tipa INT // @param unsigned char *Arr Massiv dannyh Char // @return none // ***************************************************************************** void IntToChar (unsigned int num, unsigned char *Arr) { unsigned int count = 0; unsigned int q=num; while (q!=0) { q/=10; count++; } do { Arr[count-1]=(num%10); num/=10; count--; } while (num!=0); } //****************************************************************************** // @fn Init UART // @brief Initialization UART // @param none // @return none // ***************************************************************************** void InitUART(void) { PMAPPWD = 0x02D52; // Get write-access to port mapping regs P3MAP0 = PM_UCA0RXD; // Map UCA0RXD output to P2.6 P3MAP1 = PM_UCA0TXD; // Map UCA0TXD output to P2.7 PMAPPWD = 0; // Lock port mapping registers P3DIR |= BIT1; // Set P2.7 as TX output P3SEL |= BIT0 + BIT1; // Select P2.6 & P2.7 to UART function UCA0CTL1 |= UCSWRST; // **Put state machine in reset** UCA0CTL1 |= UCSSEL_2; // SMCLK UCA0CTL1 |= UC7BIT; UCA0BR0 = 6; // 1MHz 9600 (see User's Guide) UCA0BR1 = 0; // 1MHz 9600 UCA0MCTL = UCBRS_0 + UCBRF_13 + UCOS16; // Modln UCBRSx=0, UCBRFx=0, // over sampling UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** UCA0IE |= UCRXIE+UCTXIE; // Enable USCI_A0 RX interrupt } //****************************************************************************** // @fn InitButtonLeds // @brief Initialization button and LEDs // @param none // @return none // ***************************************************************************** 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; } //****************************************************************************** // @fn InitRadio // @brief Initialization Radio // @param none // @return none // ***************************************************************************** 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); } //****************************************************************************** // @fn Transmit // @brief Transmit the packet of data // @param unsigned char *buffer Ukazatel na dannye // @param unsined char length Razmer dannyh // @return none // ***************************************************************************** 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 } //****************************************************************************** // @fn ReceiveOn // @brief Vklyuchenie rezhima priema // @param none // @return none // ***************************************************************************** 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 ); } //****************************************************************************** // @fn ReceiveOff // @brief Vyklyuchenie rezhima priema // @param none // @return none // ***************************************************************************** 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 ); } /*__________________________Obrabotchiki_preryvanie___________________________*/ //****************************************************************************** //@name Obrabocthik preryvaniy po UART //@brief Pri pustom TX bufere peredaet dannye v nego //****************************************************************************** #pragma vector=USCI_A0_VECTOR __interrupt void USCI_A0_ISR(void) { switch(__even_in_range(UCA0IV,4)) { case 0:break; // Vector 0 - no interrupt case 2: // Vector 2 - RXIFG break; case 4: for(int i=0;i<PacketLen;i++) { UCA0TXBUF = Packet[i]; while (UCA0STAT & UCBUSY); } UCA0IE ^= UCTXIE; break; // Vector 4 - TXIFG default: break; } } //****************************************************************************** //@name Timer_A3 Interrupt Vector (TAIV) handler //@brief Pri perepolnenii ustanavlivaetsya flag Time //****************************************************************************** #pragma vector=TIMER1_A1_VECTOR __interrupt void TIMER1_A1_ISR(void) { switch(__even_in_range(TA1IV,14)) { case 0: break; // No interrupt case 2: break; // CCR1 not used case 4: break; // CCR2 not used case 6: break; // reserved case 8: break; // reserved case 10: break; // reserved case 12: break; // reserved case 14: Time = 1; // overflow __bic_SR_register_on_exit(LPM3_bits); break; default: break; } } //****************************************************************************** //@name Radio Core Interrupt Vector handler //@brief //****************************************************************************** #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++; //Kolichestvo podtverzhdeniy } } 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++; //Obschee kolichestvo peredannyh paketov } 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); } Проблема решена путем добавления "_BIS_SR(LPM0_bits);" перед "PacketMake();". Код приведенный выше подправил.
  13. Вобщем вот, что получилось у меня практически в итоге. #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 int TransmitPacket(char *pData, int nDataSize); void IntToChar (int num, char *Arr); 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 Time = 0; unsigned char receiving = 0; char cAck[4]={0}; char cTotal[4]={0}; char id1[1]={1}; char id2[1]={2}; char Packet[10]; int PacketLen = 10; 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) { TA1CTL = TASSEL_1 + MC_2 + TACLR + TAIE; // SMCLK, contmode, clear TAR __bis_SR_register( LPM3_bits + GIE ); __no_operation(); if (Time) // Timer count set->transmit { P3OUT |= BIT6; // Pulse LED during Transmit Time = 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; } while (transmitting); ReceiveOn(); //ïåðåâîä â ðåæèì ïðèåìà, äëÿ ïîëó÷åíèÿ îòâåòà receiving = 1; /*_________Îôîðìëåíèå ïàêåòà äëÿ ïåðåäà÷è ïî UART___________*/ IntToChar (Ack, cAck); IntToChar (Total, cTotal); int idx; for (idx=0; idx<1; idx++) { Packet[idx]=id1[idx]; } for (idx=1; idx<5; idx++) { Packet[idx]=cAck[idx]; } for (idx=5; idx<6; idx++) { Packet[idx]=id2[idx]; } for (idx=6; idx<10; idx++) { Packet[idx]=cTotal[idx]; //ñîñòàâ ïàêåòà: |ID1|êîëè÷åñòâî ïðèíÿòûõ ïàêåòîâ ïî ðàäèî(4 byte)|ID2|êîëè÷åñòâî ïåðåäàííûõ ïàêåòîâ ïî ðàäèî(4 byte)| } PMAPPWD = 0x02D52; // Get write-access to port mapping regs P2MAP6 = PM_UCA0RXD; // Map UCA0RXD output to P2.6 P2MAP7 = PM_UCA0TXD; // Map UCA0TXD output to P2.7 PMAPPWD = 0; // Lock port mapping registers P2DIR |= BIT7; // Set P2.7 as TX output P2SEL |= BIT6 + BIT7; // Select P2.6 & P2.7 to UART function UCA0CTL1 |= UCSWRST; // **Put state machine in reset** UCA0CTL1 |= UCSSEL_2; // SMCLK UCA0CTL1 |= UC7BIT; UCA0BR0 = 6; // 1MHz 9600 (see User's Guide) UCA0BR1 = 0; // 1MHz 9600 UCA0MCTL = UCBRS_0 + UCBRF_13 + UCOS16; // Modln UCBRSx=0, UCBRFx=0, // over sampling UCA0CTL1 &= ~UCSWRST; // **Initialize USCI state machine** UCA0IE |= UCRXIE; // Enable USCI_A0 RX interrupt TransmitPacket(Packet,PacketLen); //ïåðåäà÷à ïàêåòà } } int TransmitPacket(char *pData, int nDataSize) { UCA0IE |= UCTXIE; //ðàçðåøèòü ïðåðûâàíèÿ ïî ïðèåìó char *pTmpData = pData; //Ïåðåìåííàÿ äëÿ õðàíåíèÿ î÷åðåäíîãî áàéòà äàííûõ (äëÿ óñêîðåíèÿ îïåðàöèè äîñòóïà ê äàííûì ìàññèâà) int nCount; for (nCount=0; nCount<nDataSize; nCount++) //öèêë ïåðåäà÷è äàííûõ { //while (!(UCA0IFG & UCTXIFG)); UCA0TXBUF = *pTmpData++; while (!(UCA0STAT & UCBUSY)); } UCA0IE ^= UCTXIE; //ïåðåäà÷à çàâåðøåíà, ïðåêðàòèòü âûçîâ îáðàáîò÷èêà ïðåðûâàíèé return 0; } void IntToChar (int num, char *Arr) //ïðåîáðàçîâàíèå Int â Char { int count = 0; int q=num; while (q!=0) { q/=10; count++; } do { Arr[count-1]=num%10+48; num/=10; count--; } while (num!=0); } 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); } /*_______Îáðàáîò÷èê ïðåðûâàíèé ïî UART_________*/ #pragma vector=USCI_A0_VECTOR __interrupt void USCI_A0_ISR(void) { switch(__even_in_range(UCA0IV,4)) { case 0:break; // Vector 0 - no interrupt case 2: // Vector 2 - RXIFG break; case 4: __bic_SR_register( GIE ); break; // Vector 4 - TXIFG default: break; } } // Timer_A3 Interrupt Vector (TAIV) handler #pragma vector=TIMER1_A1_VECTOR __interrupt void TIMER1_A1_ISR(void) { switch(__even_in_range(TA1IV,14)) { case 0: break; // No interrupt case 2: break; // CCR1 not used case 4: break; // CCR2 not used case 6: break; // reserved case 8: break; // reserved case 10: break; // reserved case 12: break; // reserved case 14: Time = 1; // overflow __bic_SR_register_on_exit(LPM3_bits); break; default: 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); } Хотелось бы услышать дельные советы, где я мог ошибиться. В частности меня интересует, правильно ли я реализовал подсчет переданных и принятых пакетов? У меня по этому поводу большие сомнения. Так же вполне возможно не совсем правильно организовал работу UART. Прошу взглянуть свежим, профессиональным взглядом.
  14. Всем привет! Стоит задача провести тест на качество передачи информации. Железо: две платы EM430F6137RF900. Т.к. SmartRF не поддерживает данный вид теста для CC430, нужно написать код. Пробую это делать на основе "C430x613x RF examples". Пакеты данных непрерывно передаются на принимающее устройство. После каждого принятого пакета приемник шлет ответ. PER=((Total-Ack)/Total)*100% где Total - общее количество пакетов, переданных передатчиком; Ack - подтверждение, пришедшее от приемника. Total-Ack - количество потерянных пакетов. Затем данные будут выводится через RS232 на ноутбук. Но это позже. Для начала, хотелось бы завести сам тест. Может кто-нибудь уже занимался этим? Хотелось бы увидеть примеры кода в IAR. Через некоторое время выложу свои попытки реализации. Код для передатчика: #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); } Вот код для приемника: #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); } По идее, при нажатии кнопки на передатчике, на нем зажигается LED2, когда пакет передан, LED2 потухает. На приемнике переключается LED1 при приеме пакета. Затем применик передает ответный пакет и при этом на нем загорается LED2. А на передатчике при приеме ответа загорается LED1. При дебаге все работает как часы. Когда нормально их запускаю, то при нажатии кнопки на передатчике, на приемнике загораются оба светодиода и ничего не происходит. В чем может быть проблема?
  15. Плата питается от external power, т.е. от батареек. Разъем JTAG 14-PIN, в первом посте указаны номера пинов, как описано в прикрепленном файле по MSP430 на стр. 23. Джамперы скомутированы на SBW. А JP2 на external power. В ИАРе настроен debugger техасский на SBW подключенный через USB.