ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Среда
17 июля
299482 Топик полностью
Bill (15.01.2012 23:02, просмотров: 187) ответил mazur на Прочитал это сообщение ->, и с того времени вот эти слова не давали мне покоя:
Пример того, как я делал простенький автомат. Но так, опять же, он написан на Си. Собственно говоря, задача состояла в следующем: необходимо было организовать обмен сообщениями между двумя устройствами по UART. Ниже дано описания пакетов // // *** UART constant definitions // // Flag bit definitions // #define MESSAGE_BIT (1<<0) // The new message is received #define REPLY_BIT (1<<1) // The reply request flag /* Data packet definitions */ // // Constant definitions // #define REQUEST_HDR '?' // Request header symbol #define REPLY_HDR '!' // Reply header symbol #define BRDCAST_HDR '*' // Broadcast packet header #define NO_KEYS 0xFF; // No key is pressed code // // Packet structure typedefs // typedef struct { // Packet to send char Header; // Header byte unsigned Info; // Console number or LED array state } SEND_PACK; typedef struct { // Reply packet char Header; // Header byte char Console; // Console number char KeyNumber; // Key pressed humber } REPLY_PACK; Для передачи и приема пакетов по прерываниям был определен простенький автомат. Его реализация приведена ниже/* UART service routines File: uart.c 24-Jan-03 BK Initial edit 25-Jan-03 BK Last update */ #include "console.h" #define FCK 6000000L // Overide crystal frequency default value #include "uart.h" // // Current UART state definitions // #define INIT_STATE 0 // UART initial state #define MSB_STATE 1 // 1st information byte reception state #define LSB_STATE 2 // 2nd information byte reception state #define CONSOLE_STATE 1 // Sending a console number state #define KEY_STATE 2 // Sending the number of the pressed key state // // Variables // SEND_PACK SendPacket; // Send packet REPLY_PACK RplyPacket; // Reply packet /* Static variables */ volatile char UARTflags; // Various UART flags, can be changed in UART ISRs volatile char UARTstate; // Current UART state while reading a mixer message // or sending a reply to the mixer // // ** InitUART -- the routine initiates the UART module // void InitUART(void) { // // Init UART related in/out ports // UART_CTRL &= ~DIR_BIT; // Receiver enable UART_CTRL_DDR |= DIR_BIT; // // // Init UART hadware // UBRR = UBRR_VALUE; // Set the Baud Rate register UCR = RXEN_BIT | RXCIE_BIT | TXEN_BIT; // Set UART Control Register bits UARTflags = 0; // Clear flags UARTstate = INIT_STATE; // Set UART in intial state } // // ** SendReply -- the function initiates reply sending // void SendReply(void) { UARTflags |= REPLY_BIT; // Set the flag UARTstate = INIT_STATE; // Set UART to the initial state UCR |= UDRIE_BIT; // Enable transmitter interrupts } // // **** UART interrupt handlers *** // // UART transmitter handlers // #pragma vector = UART_UDRE_vect __interrupt void TX_Int(void) // **** UDRE interrupt handler { switch (UARTstate) // Process the current transmission state { case INIT_STATE: // Transmit the reply header UDR = RplyPacket.Header; // Transmitt the byte UARTstate = MSB_STATE; // The next will be info MSB return; case CONSOLE_STATE: // Transmit the console number UDR = RplyPacket.Console; // Transmit the byte UARTstate = LSB_STATE; // The next will be info LSB return; case KEY_STATE: // Transmit the pressed key number (the last byte in packet) UDR = RplyPacket.KeyNumber; // Transmit the byte UARTstate = INIT_STATE; // Return to the initial state UCR |= TXCIE_BIT; // Enable TXC interrupts return; } } #pragma vector = UART_TX_vect __interrupt void TXC_Int(void) // **** TXC interrupt handler { UCR &= ~TXCIE_BIT; // Disable TXC interrupts UARTflags &= ~REPLY_BIT; // Reset the event flag UART_CTRL &= ~DIR_BIT; // Set RS-485 driver in reception mode } // // UART reciever handler // #pragma vector = UART_RX_vect __interrupt void RX_Int(void) { char _ch; _ch = UDR; // Get the just received byte switch (UARTstate) // Process the current state { case INIT_STATE: // Initial state if (_ch==REQUEST_HDR || _ch==BRDCAST_HDR) // Message header is received { SendPacket.Header = _ch; // Fill the message header field, UARTstate = MSB_STATE; // Wait for the MSB info byte } return; // Interrupt exit case MSB_STATE: // 1st info byte is received SendPacket.Info = ((unsigned)_ch << 8); // Fill the MSB info field UARTstate = LSB_STATE; // Wait for the LSB info byte return; // Interrupt exit case LSB_STATE: // 2nd info byte is received SendPacket.Info |= _ch; // Concatenate LSB byte UARTflags |= MESSAGE_BIT; // The new message is received default: UARTstate = INIT_STATE; // Wait for a new messge return; } } Вопросы есть?