使用状态机控制数据

时间:2014-06-11 18:48:11

标签: state-machine atmega

我正在连续从一台Atmega644P向另一台Atmega644P发送一些数据。前三个字节是SYN(0x16),DLE(0x10)和STX(0x02)。在接收部分,我创建了一个状态机来控制我是否正确接收这些字节。

当它处于DLE_1_s状态时,它直接进入" else"声明,虽然数据是0x10。为什么会这样?

我正在使用Peter Fleury的uart图书馆。

这是我想要实现的图表: enter image description here

代码:

int main(void)
{
    DDRD = 0b11111010;  //  PORTD input/output.
    DDRC = 0xFF;

    uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );

    sei();

    unsigned int rec_char;
    char buffer[7];

    while(1)
    {
        rec_char=uart_getc();

        switch(state)
        {
            case SYN_s:
                {                   
                    if ((unsigned char) rec_char == 0x16) // SYN
                    {
                        state=DLE_1_s;
                    }
                    else
                    {
                        state=SYN_s;
                    }
                }
            break;

            case DLE_1_s:
                {
                    if ((unsigned char) rec_char == 0x10) // DLE
                    {
                        state=STX_s;
                    }
                    else if ((unsigned char) rec_char == 0x16) // SYN
                    {
                        state=DLE_1_s;
                    }
                    else
                    {
                        state=SYN_s;
                    }
                }
            break;

            case STX_s:
                {
                    if ((unsigned char) rec_char == 0x02) // STX
                    {
                        state=TARGET_NO_1_s;
                    }
                    else if ((unsigned char) rec_char == 0x16) // SYN
                    {
                        state=DLE_1_s;
                    }
                    else
                    {
                        state=SYN_s;
                    }
                }
            break;

1 个答案:

答案 0 :(得分:0)

#include <stdio.h>

#define FAKE 1
#if FAKE
unsigned DDRD, DDRC;
#define  UART_BAUD_RATE 123
#define  F_CPU 0
#define UART_BAUD_SELECT(a,b) (((a)<<8)+((b)&0xff))
#define UART_NO_DATA 1

#define SYN 0x16
#define DLE 0x10
#define STX 0x02

extern void uart_init(unsigned);
extern void sei(void);
extern void maybe_sleep(void);
extern unsigned uart_getc(void);
#endif

int main(void)
{
    DDRD = 0b11111010;  //  PORTD input/output.
    DDRC = 0xFF;

    uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );

    sei();

    unsigned int rec_char;
    int state;

    for(state=0; ; ) {
        unsigned int hi,lo;

        rec_char = uart_getc();
        hi = rec_char >> 8;
        lo = rec_char & 0xff;

        switch (hi) { /** handle errors from uart here */
        case 0: break;
        case UART_NO_DATA: /* no receive data available */
                maybe_sleep();
                continue;
        default:
            fprintf(stderr, "Hi=%x Lo=%x\n", hi, lo);
            /* some cleanup here ... */
            state =0;
            continue;
            }

        switch(state) {
        case 0:
            if (lo == SYN) { state = 1 ; break;}
            break;
        case 1:
            if (lo == DLE) { state = 2; break; }
            if (lo == SYN) { break; }
            state= 0;
            break;
        case 2:
            if (lo == STX) { state = 3; break; }
            if (lo == SYN ) { state = 1; break; }
            state = 0;
            break;
        case 3:
           /* handle payload here ... */
           break;
           }
    }
    return 0;
}