查看: 1157|回复: 0

ATmega328 Xplained mini初上手(一)

[复制链接]
  • TA的每日心情
    奋斗
    2022-4-7 16:37
  • 签到天数: 736 天

    连续签到: 1 天

    [LV.9]以坛为家II

    发表于 2014-11-7 09:22:31 | 显示全部楼层 |阅读模式
    分享到:
    感谢爱板网提供一款基于AVR微控制器的Atmel Xplained系列的mini评估板——ATmega328P-XMINI,确实很迷你——尺寸75mm*60mm。
    一、测试准备:1、Atmel studio IDE软件;2、mini-USB线缆;3、Atmel Mega328 Xplained mini Demo板
    二、测试步骤
    1、从ATMEL官网上把Atmel Studio6.2下载下来,注意下载10月份最新更新的版本,否则会出现各种意想不到的BUG,比如IDE总是莫名其妙的弹出去。将安装文件下载到本地进行安装,安装基本上是分为4个步骤:.NET framework 4.0、VS2010、ATMEL的usb驱动和IDE软件。整个过程只需一路NEXT就行,安装前先关掉类似360安全卫士的软件,否则安装过程中总是弹出各种拦截对话框。
    2、安装完成后,打开Atmel studio IDE软件,用mini-USB线缆插上ATmega328P-XMINI,另一端插上电脑的USB接口,电脑会自动识别EDBG接口。EDBG是Atmel特有的板载调试器,不仅省去了外部调试工具,而且生成虚拟串口可以用于与主机通信。

    **********************************************************************************************************************************************************************************
    注意:通过mini-USB线连接电脑的USB接口和ATmega328P-XMINI时,可能会出现mEDBG无法识别的现象。原因可能涉及以下几种:

    • 1、操作系统原因——精简版的GOST系统(尤其是XP的系统),缺少必要的usbser.sys文件;解决办法:从网上下下来解压后将usbser.sys复制到c:\windows\system32\drivers;有些系统可能缺少大量的*.dll文件,建议直接重装系统。(笔者直接重装了!)


    • 2、USB接口原因——某些台式机USB接口年久出现故障,无法识别mEDBG,可多换几个USB接口试试(笔者换了3个才成功!说多了都是泪。。。)


    • 3、手贱upgrade原因——有的人一打开Atmel studio IDE就有提示要升级,手贱点了升级,半天没反应,强行中止了,直接导致板子无法识别。这个时候,打开Atmel studio IDE,选择tools→command prompt,输入指令atfw –t edbg –a “D:\Program Files\Atmel\Atmel Studio 6.2\tools\EDBG\edbg_fw.zip”

    **********************************************************************************************************************************************************************************
    3、上电的同时Atmel studio IDE很快会识别出这块ATmega328P-XMINI,并且会展现出ATmega328P-XMINI评估板的相关信息和帮助文件。

    4、Demo程序
    ATmega328P-XMINI评估板预置了Demo程序,这个程序很有意思,并不是简单的按键点亮LED功能。而是一个morse编解码的程序,可以通过串口程序窗口互动。程序在初始化时会发送ATMEL五个字符的morse码。

    该Demo能把串口输入的字符解码为morse编码来驱动LED亮和灭,同时我们按下评估板的按键动作也可以解码为字符在串口程序显示。这样可以将ATmega328P-XMINI评估板当作一款小型的morse码发报机来用!

    但是一次不能发送过多字符,否则解码过慢显示不全,比如输入eeboard,结果只显示了EEBD

    下面是通过按键发送morse码,程序会解码为字符在串口程序显示,同时LED灯会根据morse码的点横会短亮或长亮。

    附上morse源码程序,这个是历经千辛万苦”翻到的“,具体过程就不详述了。。。
    /** * \file remorse.c * * \brief Morse Code Encoder/Decorder board support package * * Copyright (c) 2011 - 2014 Atmel Corporation. All rights reserved. * * \asf_license_start * * \page License * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, *    this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, *    this list of conditions and the following disclaimer in the documentation *    and/or other materials provided with the distribution. * * 3. The name of Atmel may not be used to endorse or promote products derived *    from this software without specific prior written permission. * * 4. This software may only be redistributed and used in connection with an *    Atmel microcontroller product. * * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * \asf_license_stop * * This version of Remorse is a polling implemenation, and implemented * as only one self contained file. */#define F_CPU                        16000000UL         // Fuse for internal oscillator at 16MHz#include <stddef.h>#include <ctype.h>#include <stdbool.h>#include <stdio.h>#include <string.h>#include <avr/io.h>#include <avr/interrupt.h>#include <util/delay.h>#include <avr/pgmspace.h>/* typedefs  */typedef struct                /* RING - ring buffer */        {        int         p_to_buf;        /* offset from start of buffer where to write next */        int         p_from_buf;        /* offset from start of buffer where to read next */        int         buf_size;        /* size of ring in bytes */        char *        buf;                /* pointer to start of buffer */        } RING;typedef RING *RING_ID;/* defines */#define DOT_TIME_IN_TICKS        (25)        #define DOT_TIME_IN_MS                (DOT_TIME_IN_TICKS * 10.0)        #define LED_ON                                PORTB |=  (1<&ltORTB5)#define LED_OFF                                PORTB &= ~(1<&ltORTB5)#define USART_BAUDRATE                9600#define BAUD_PRESCALE                (((F_CPU / (USART_BAUDRATE * 16UL))) - 1)#define REMORSE_CLK_HZ                (100)                                // the clock basis for polling and sequencing#define        REMORSE_TIMEOUT                (1000)                                // remorse will restart after this many idle ticks#define        REMORSE_RESTART                (400)                                // remorse will restart if button held this long#define MORSE_RX_BUF_SIZE        (32)                                // ring buffer for decoded morse code/* macros */#define min(a,b)                                \   ({ __typeof__ (a) _a = (a);         \      __typeof__ (b) _b = (b);        \     _a < _b ? _a : _b; })/* locals */static char                                        morse_rx_buf[MORSE_RX_BUF_SIZE + 1]; // buffer for morse characters readstatic RING                                 morse_rx_ring;                // morse receive buffer ringstatic RING_ID                                 morse_rx_ring_id;        // morse receive buffer ring idstatic bool                                 user_input = false;        // Instructions print out until first character receivedstatic volatile uint32_t        remorse_tick_cnt;        // incremented on each clock tickstatic volatile uint32_t        remorse_wd_cnt;                // reset to zero after each user input outputstatic volatile bool                remorse_restart;        // set by watchdog to true to restart applicationconst uint8_t morse_ascii_tbl[][2] =        {        // Morse Hex        A        M        Morse Code                Binary                ASCII        Notes                 {6, 0x14},        //        !        !        – · – · – –            010100                33        33        Exclamation mark [!]         {6, 0x2D},        //        "        "        · – · · – ·            101101                34        34        Quotation mark ["]         {8, 0xFF},        //        #        ERR        · · · · · · · ·        11111111        35        ERR        Hash mark [#]         {7, 0x76},        //        $        $        · · · – · · –          1110110                36        36        Dollar sign [$]         {8, 0xFF},        //        %        ERR        · · · · · · · ·        11111111        37        ERR        Percent [%]         {5, 0x17},        //        &        &        · – · · ·              10111                38        38        Ampersand [&], Wait         {6, 0x21},        //        '        '        · – – – – ·            100001                39        39        Apostrophe [']         {5, 0x09},        //        (        (        – · – – ·              01001                40        40        Parenthesis open [(]         {6, 0x12},        //        )        )        – · – – · –            010010                41        41        Parenthesis close [)]         {8, 0xFF},        //        *        ERR        · · · · · · · ·        11111111        42        69        Asterix
  •          {5, 0x15},        //        +        +        · – · – ·              10101                43        43        Plus [+]         {6, 0x0C},        //        ,        ,        – – · · – –            001100                44        44        Comma [,]         {6, 0x1E},        //        -        -        – · · · · –            011110                45        45        Hyphen, Minus [-]         {6, 0x2A},        //        .        .        · – · – · –            101010                46        46        Period [.]         {5, 0x0D},        //        /        /        – · · – ·              01101                47        47        Slash [/], Fraction bar         {5, 0x00},        //        0        0        – – – – –              00000                48        48                 {5, 0x10},        //        1        1        · – – – –              10000                49        49                 {5, 0x18},        //        2        2        · · – – –              11000                50        50                 {5, 0x1C},        //        3        3        · · · – –              11100                51        51                 {5, 0x1E},        //        4        4        · · · · –              11110                52        52                 {5, 0x1F},        //        5        5        · · · · ·              11111                53        53                 {5, 0x0F},        //        6        6        – · · · ·              01111                54        54                 {5, 0x07},        //        7        7        – – · · ·              00111                55        55                 {5, 0x03},        //        8        8        – – – · ·              00011                56        56                 {5, 0x01},        //        9        9        – – – – ·              00001                57        57                 {6, 0x07},        //        :        :        – – – · · ·            000111                58        58        Colon [:]         {6, 0x15},        //        ;        ;        – · – · – ·            010101                59        59        Semicolon [;]         {8, 0xFF},        //        <        ERR        · · · · · · · ·        11111111        60        ERR        Less Than [<]         {5, 0x0E},        //        =        =        – · · · –              01110                61        61        Double dash [=]         {8, 0xFF},        //        >        ERR        · · · · · · · ·        11111111        62        ERR        Greather Than [<]         {6, 0x33},        //        ?        ?        · · – – · ·            110011                63        63        Question mark [?]         {6, 0x25},        //        @        @        · – – · – ·            100101                64        64        At sign [@]         {2, 0x02},        //        A        A        · –                    10                        65        65                 {4, 0x07},        //        B        B        – · · ·                0111                66        66                 {4, 0x05},        //        C        C        – · – ·                0101                67        67                 {3, 0x03},        //        D        D        – · ·                  011                        68        68                 {1, 0x01},        //        E        E        ·                      1                        69        69                 {4, 0x0D},        //        F        F        · · – ·                1101                70        70                 {3, 0x01},        //        G        G        – – ·                  001                        71        71                 {4, 0x0F},        //        H        H        · · · ·                1111                72        72                 {2, 0x03},        //        I        I        · ·                    11                        73        73                 {4, 0x08},        //        J        J        · – – –                1000                74        74                 {3, 0x02},        //        K        K        – · –                  010                        75        75                 {4, 0x0B},        //        L        L        · – · ·                1011                76        76                 {2, 0x00},        //        M        M        – –                    00                        77        77                 {2, 0x01},        //        N        N        – ·                    01                        78        78                 {3, 0x00},        //        O        O        – – –                  000                        79        79                 {4, 0x09},        //        P        P        · – – ·                1001                80        80                 {4, 0x02},        //        Q        Q        – – · –                0010                81        81                 {3, 0x05},        //        R        R        · – ·                  101                        82        82                 {3, 0x07},        //        S        S        · · ·                  111                        83        83                 {1, 0x00},        //        T        T        –                      0                        84        84                 {3, 0x06},        //        U        U        · · –                  110                        85        85                 {4, 0x0E},        //        V        V        · · · –                1110                86        86                 {3, 0x04},        //        W        W        · – –                  100                        87        87                 {4, 0x06},        //        X        X        – · · –                0110                88        88                 {4, 0x04},        //        Y        Y        – · – –                0100                89        89                 {4, 0x03},        //        Z        Z        – – · ·                0011                90        90                 {8, 0xFF},        //        [        ERR        · · · · · · · ·        11111111        91        ERR        Open Bracket [[]         {8, 0xFF},        //        \        ERR        · · · · · · · ·        11111111        92        ERR        Backslash [\]         {8, 0xFF},        //        ]        ERR        · · · · · · · ·        11111111        93        ERR        Close Bracket []]         {8, 0xFF},        //        ^        ERR        · · · · · · · ·        11111111        94        ERR        Circumflex [^]         {6, 0x32}        //        _        _        · · – – · –            110010                95        95        Underscore [_]        };/* forward declarations */static int                bsp_tty_putchar (char c, FILE *stream);static int                bsp_tty_getchar (FILE *stream);static int                bsp_morse_putchar (char c, FILE *stream);static int                bsp_morse_getchar (FILE *stream);static void                remorse_instructions(void);static void         morse_fmtchar (char rc);static void         morse_poll (void);static RING_ID         rng_init (RING *p_ring, int nbytes, char *buffer);static bool         rng_is_empty (RING_ID ring_id);static bool         rng_is_full (RING_ID ring_id);static int                 rng_buf_get (RING_ID rng_id, char *buffer, int maxbytes);static int                 rng_buf_put (RING_ID rng_id, char *buffer, int nbytes);static int                 rng_free_bytes (RING_ID ring_id);static int                 rng_nBytes (RING_ID ring_id);static void         rng_flush (RING_ID ring_id);// Associate the devices with AVR libc FILE streams to enable standard i/o callsstatic FILE        tty_console = FDEV_SETUP_STREAM(bsp_tty_putchar,   bsp_tty_getchar,   _FDEV_SETUP_RW);static FILE        tty_morse        = FDEV_SETUP_STREAM(bsp_morse_putchar, bsp_morse_getchar, _FDEV_SETUP_RW);/** * \brief Entry point for morse code example * */int main (void)        {        char rc;        /* set up the IO pins */        DDRB        |= (1<<DDB5);                                                // PB5 As Output pin        PORTB        |= (1<<DDB5);                                                // PB5 Activate internal pullUp resistor        DDRB        &= ~(1<<DDB7);                                                // PB1 As Input pin        PORTB        |= 1<<DDB7;                                                        // PB1 Activate internal pullUp resistor        LED_OFF;                                                                        // start with the LED off        UCSR0B        = (1 << RXEN0)  | (1 << TXEN0);                // turn on the transmission and reception circuitry        UCSR0C        = (1 << UCSZ00) | (1 << UCSZ01);        // use 8-bit character sizes        UBRR0H        = (BAUD_PRESCALE >> 8);                                // upper 8-bits of baud rate value into high byte of UBRR register        UBRR0L        = BAUD_PRESCALE;                                        // lower 8-bits of baud rate value into low byte of UBRR register        /* set up the system 100Hz timer */    OCR1A        = 20000;                                                        // Set CTC compare value to 10ms @ 8Mhz Clock (Mode 4)    TCCR1B        |= (1 << WGM12);                                        // Configure timer 1 for CTC mode (Mode 4)    TIMSK1        |= (1 << OCIE1A);                                        // Enable interrupt on compare match    TCCR1B        |= (1 << CS11);                                                // set prescaler to 8 and starts the timer        /* initialize ring buffers */        morse_rx_ring_id = rng_init (&morse_rx_ring, MORSE_RX_BUF_SIZE, morse_rx_buf);                /* Enable global interrupts */        sei();     /* attach the serial port to stdio streams */        stdout        = &tty_console;        stdin        = &tty_console;        stderr        = &tty_console;        /* encode/decode the user input to/from morse code */        for (;;)                                                                        // loop forever (timeouts restart here)                {                remorse_instructions ();                                // print out some instructions                remorse_restart = false;                                // reset watchdog                remorse_wd_cnt = 0;                                                // reinitialize watchdog timer                while (!remorse_restart)                                // check watchdog                        {                        rc = getchar ();                                        // non-blocking in this application                        /* process input from serial line */                        if (!ferror(stdin))                                        // was a character available?                                {                                remorse_wd_cnt = 0;                                // reinitialize watchdog timer                                morse_fmtchar (rc);                                // echo the morse code on console                                fputc (rc, &tty_morse);                        // encode the character to morse led                                }                        else                                {                                clearerr (&tty_console);                // no input, clear error                                }                        /* process input from morse decoder */                        rc = fgetc (&tty_morse);                        if (!ferror(&tty_morse))                        // was a morse character available?                                {                                remorse_wd_cnt = 0;                                // reinitialize watchdog timer                                putchar (rc);                                        // print the character to console                                }                        else                                {                                clearerr (&tty_morse);                        // no input, clear error                                }                        }                   }         /* we should never get here */        return (0);        }/** * \brief Push a character out uart transmitter * * Polling version of character write.  We spin here until character * can be placed in transmit register. */static int bsp_tty_putchar(char c, FILE *stream)        {        if (c == '\n')                                                                // handle linefeed - carriage return                bsp_tty_putchar('\r', stream);                while ((UCSR0A & (1 << UDRE0)) == 0)                 {                // Do nothing until UDR is ready for more data to be written to it                };        UDR0 = c;                                                                        // transmit character        return (0);                                                                        // transmit success        }/** * \brief Fetch a character from uart receiver * * Polling version of a character read.  We spin here until receive * buffer has something to read. */static int bsp_tty_getchar(FILE *stream)        {        if ((UCSR0A & (1 << RXC0)) == 0)                 return (_FDEV_ERR);                                                // No character available, so we return error        user_input = true;                                                        // Record the fact that we have received input        return (UDR0);                                                                // Return the received character        }/** * \brief Flash out morse code for character on led * * Polling version of character write.  We spin here until character * can be placed in transmit register. */static int bsp_morse_putchar(char c, FILE *stream)        {        int index = toupper(c) - '!';        if (c == ' ')                {                // Delay between words is seven units                LED_OFF;                                                                // LED OFF between words                _delay_ms (7 * DOT_TIME_IN_MS);                }        else if ((index >= 0) && (index < (sizeof (morse_ascii_tbl) / 2)))                {                unsigned int mask = (0x1 << (morse_ascii_tbl[index][0] - 1));                while (mask != 0)                        {                        if (morse_ascii_tbl[index][1] & mask)                                {                                // DIT                                LED_ON;                                                        // Start DIT LED on                                _delay_ms (DOT_TIME_IN_MS);                // DIT length is one unit                                }                        else                                {                                // DASH                                LED_ON;                                                        // Start DASH LED on                                _delay_ms (3 * DOT_TIME_IN_MS);        // DASH length is three units                                }                                                LED_OFF;                                                        // DIT or DASH is finished                        // Delay between parts of same letter is one unit                        _delay_ms (DOT_TIME_IN_MS);                        mask = mask >> 1;                        }                // Delay between letters is three units (two more)                _delay_ms (2 * DOT_TIME_IN_MS);                }        return (0);                                                                        // transmit success        }/** * \brief Decode morse code input from button * * If we have any decoded morse code we return it or _FDEV_ERR if none. */static int bsp_morse_getchar(FILE *stream)        {        char morse_char;        if (rng_buf_get (morse_rx_ring_id, &morse_char, 1) == 1)                return (morse_char);                                        // return next character                return (_FDEV_ERR);                                                        // No character available, so we return error        }/** * \brief Print out character as ASCII morse code (. and -) */static void morse_fmtchar (char rc)        {        int index = toupper(rc) - '!';        if ((index >= 0) && (index < (sizeof (morse_ascii_tbl) / 2)))                {                unsigned int mask = (0x1 << (morse_ascii_tbl[index][0] - 1));                while (mask != 0)                        {                        printf_P (PSTR(" %c"), (morse_ascii_tbl[index][1] & mask) ? '.' : '-');                        mask = mask >> 1;                        }                printf_P (PSTR(" [%c]"), toupper(rc));                }        else                {                /* handle non-printable characters */                if (rc == '\r')                        printf_P (PSTR(" . - . - [<CR>]\n-> "));                }        }/** * \brief Parse morse code pattern into ASCII character * * \param[in]        pattern        morse code pattern to match * \param[in]        len                morse code patter length * \return                                the ASCII character that matches the mores code patter */static char morse_parse (uint8_t pattern, int len)        {        int index;        for (index = 0; index < (sizeof (morse_ascii_tbl) / 2); index ++)                {                if ((morse_ascii_tbl[index][0] == len) && (morse_ascii_tbl[index][1] == pattern))                        return (index + '!');                }        /* pattern not found! */        return ('*');                                        // return asterix as error indicator (not a morse character)        }/** * \brief Print out remorse instructions */static void remorse_instructions (void)        {        if (!user_input)                {                printf_P (PSTR("\n"));                printf_P (PSTR("Morse Encoder/Decoder\n"));                printf_P (PSTR("Copyright (c) 2011 - 2014 Atmel Corporation. All rights reserved.\n"));                printf_P (PSTR("\n"));                printf_P (PSTR("Characters received from the serial port will be be echoed back in morse code.\n"));                printf_P (PSTR("Morse code tapped into button will be converted to ASCII.\n"));                printf_P (PSTR("\n"));                printf_P (PSTR("(ie)"));                morse_fmtchar ('A'); fputc ('A', &tty_morse);                morse_fmtchar ('T'); fputc ('T', &tty_morse);                morse_fmtchar ('M'); fputc ('M', &tty_morse);                morse_fmtchar ('E'); fputc ('E', &tty_morse);                morse_fmtchar ('L'); fputc ('L', &tty_morse);                }        printf_P (PSTR("\n-> "));                                        // prompt for serial input        }/** * Interrupt Service Routines *//** * \brief Remorse clock interrupt routine * * This routine is called at interrupt level on each clock interrupt. */ISR(TIMER1_COMPA_vect)    {        ++remorse_tick_cnt;                                                        // always advance remorse tick count        if (++remorse_wd_cnt > REMORSE_TIMEOUT)                // fire watchdog on timeout                remorse_restart = true;    morse_poll ();                                                                // poll for morse input    }/** * \brief Poll button for debounced conversion to Morse code */static void morse_poll (void)        {        static uint8_t        morse_code                = 0;                // built up morse code input        static uint8_t        morse_code_len        = 0;                // morse code length        static uint8_t        button_hist                = 0;                // 8 sample button history        static bool                button_down                = false;        // current state of button        static uint32_t        tick_down                = 0;                // tick when button released        static uint32_t        tick_up                        = 0;                // tick when button pressed        static uint32_t        duration                = 0;                // ticks with button down        static uint32_t        space                        = 0;                // ticks with button up        /* shift in the current state of the button */        button_hist = (button_hist<<1) | !(PINB & (1<&ltB7)) | 0xf0;                if (button_hist == 0xff)                                        // all samples are button down                {                LED_ON;                                                                        // light the LED for user feedback                user_input = true;                                                // we have interaction                if (!button_down)                                                // are we changing state?                        {                        button_down = true;                                        // set debounced button state                        tick_down        = remorse_tick_cnt;                // timestamp the button press                        }                duration = remorse_tick_cnt - tick_down;                if (duration > REMORSE_RESTART)                        // restart!                        {                        morse_code_len        = 0;                                // erase current code                        morse_code                = 0;                                // erase last code                        rng_flush (morse_rx_ring_id);                // flush the morse input ring                        user_input                = false;                        // start from begining                        remorse_restart = true;                                // RESTART REMORSE                        }                }        else if (button_hist == 0xf0)                                // all samples are button up                {                if (button_down)                                                // are we changing state?                        {                        LED_OFF;                                                        // turn off LED between morse keys                        button_down = false;                                // set debounced button state                        tick_up                = remorse_tick_cnt;                // timestamp button release                        /* emit the right code based on click duration */                        duration = tick_up - tick_down;                                if (duration <= (2 * DOT_TIME_IN_TICKS))                // dot                                {                                morse_code = (morse_code << 1) | 1;                                morse_code_len++;                                rng_buf_put (morse_rx_ring_id, " .", 2);                                }                        else if (duration <= (5 * DOT_TIME_IN_TICKS))        // dash                                {                                morse_code = (morse_code << 1) | 0;                                morse_code_len++;                                rng_buf_put (morse_rx_ring_id, " -", 2);                                }                        }                }        /* return now if there has been no input or button is currently down */        if ((!user_input) || (button_down))                return;        /* now process spaces between button presses as follows         *     - one dot time between code (NOP)         *     - three dot time between letters (flush the letter)         *     - seven dot time between words (flush space chracter)         */        space = remorse_tick_cnt - tick_up;        if (space == (4 * DOT_TIME_IN_TICKS))                // this will only happen once                {                char morse_char = morse_parse (morse_code, morse_code_len);                // letter seperator                rng_buf_put (morse_rx_ring_id, " [", 2);                rng_buf_put (morse_rx_ring_id, &morse_char, 1);                rng_buf_put (morse_rx_ring_id, "]", 1);                morse_code_len        = 0;                                        // get ready for next letter                morse_code                = 0;                                        // erase last code                }        else if (space == (10 * DOT_TIME_IN_TICKS))        // this will only happen once                {                // word separator                rng_buf_put (morse_rx_ring_id, " [ ]", 4);                }        }/** * Ring Utility Functions *//** * \brief initialize an empty ring buffer * * This routine initializes a ring buffer of size "nbytes". The * buffer must be one byte larger than nBytes since the algorithm * always leaves at least one empty byte in the buffer. * * \param[in]        p_ring        pointer to a RING struct * \param[in]        nbytes        number of bytes in ring buffer * \param[in]        buffer        pointer to RING buffer of size nBytes + 1 * \return                                ID of the ring buffer, or NULL if init fails */RING_ID rng_init (RING * p_ring, int nbytes, char *buffer)        {        RING_ID ring_id = p_ring;                /* RING_ID is simply a pointer to RING */        /* bump number of bytes requested because ring buffer algorithm         * always leaves at least one empty byte in buffer */        ring_id->buf_size        = nbytes + 1;        ring_id->buf                = buffer;        rng_flush (ring_id);        return (ring_id);        }/** * \brief make a ring buffer empty * * This routine initializes a specified ring buffer to be empty. * Any data currently in the buffer will be lost. * * \param[in] ring_id        ring buffer to initialize */void rng_flush (RING_ID ring_id)        {        ring_id->p_to_buf        = 0;        ring_id->p_from_buf = 0;        }/** * \brief - get characters from a ring buffer * * This routine copies bytes from the ring buffer <rng_id> into <buffer>. * It copies as many bytes as are available in the ring, up to <maxbytes>. * The bytes copied will be removed from the ring. * * param[in] ring_id        ring buffer to get data from * param[in] buffer                pointer to buffer to receive data * param[in] maxbytes        maximum number of bytes to get * \return                                The number of bytes actually received from the ring buffer; *                                                 it may be zero if the ring buffer is empty at the time of the call. */int rng_buf_get (RING_ID rng_id, char *buffer, int maxbytes)        {        int bytesgot = 0;        int p_to_buf = rng_id->p_to_buf;        int bytes2;        int p_rng_tmp = 0;        if (p_to_buf >= rng_id->p_from_buf)                {                /* p_to_buf has not wrapped around */                bytesgot = min (maxbytes, p_to_buf - rng_id->p_from_buf);                memcpy (buffer, &rng_id->buf [rng_id->p_from_buf], bytesgot);                rng_id->p_from_buf += bytesgot;                }        else                {                /* p_to_buf has wrapped around.  Grab chars up to the end of the                 * buffer, then wrap around if we need to. */                bytesgot = min (maxbytes, rng_id->buf_size - rng_id->p_from_buf);                memcpy (buffer, &rng_id->buf [rng_id->p_from_buf], bytesgot);                p_rng_tmp = rng_id->p_from_buf + bytesgot;                /* If p_from_buf is equal to buf_size, we've read the entire buffer,                 * and need to wrap now.  If bytesgot < maxbytes, copy some more chars                 * in now. */                if (p_rng_tmp == rng_id->buf_size)                        {                        bytes2 = min (maxbytes - bytesgot, p_to_buf);                        memcpy (buffer + bytesgot, rng_id->buf, bytes2);                        rng_id->p_from_buf = bytes2;                        bytesgot += bytes2;                        }                else                        rng_id->p_from_buf = p_rng_tmp;                }        return (bytesgot);        }/** * \brief - put bytes into a ring buffer * * This routine puts bytes from <buffer> into ring buffer <ring_id>. The * specified number of bytes will be put into the ring, up to the number of * bytes available in the ring. * * * \param[in] rng_id        ring buffer to put data into * \param[in] buffer        buffer to get data from * \param[in] nbytes        number of bytes to try to put * \return                                The number of bytes actually put into the ring buffer; *                                                 it may be less than number requested, even zero, *                                                if there is insufficient room in the ring buffer at the time of the call. */int rng_buf_put (RING_ID rng_id, char *buffer, int nbytes)        {        int bytesput = 0;        int p_from_buf = rng_id->p_from_buf;        int bytes2;        int p_rng_tmp = 0;        if (p_from_buf > rng_id->p_to_buf)                {                /* p_from_buf is ahead of p_to_buf.         We can fill up to two bytes                 * before it */                bytesput = min (nbytes, p_from_buf - rng_id->p_to_buf - 1);                memcpy (&rng_id->buf [rng_id->p_to_buf], buffer, bytesput);                rng_id->p_to_buf += bytesput;                }        else if (p_from_buf == 0)                {                /* p_from_buf is at the beginning of the buffer.        We can fill till                 * the next-to-last element */                bytesput = min (nbytes, rng_id->buf_size - rng_id->p_to_buf - 1);                memcpy (&rng_id->buf [rng_id->p_to_buf], buffer, bytesput);                rng_id->p_to_buf += bytesput;                }        else                {                /* p_from_buf has wrapped around, and its not 0, so we can fill                 * at least to the end of the ring buffer.        Do so, then see if                 * we need to wrap and put more at the beginning of the buffer. */                bytesput = min (nbytes, rng_id->buf_size - rng_id->p_to_buf);                memcpy (&rng_id->buf [rng_id->p_to_buf], buffer, bytesput);                p_rng_tmp = rng_id->p_to_buf + bytesput;                if (p_rng_tmp == rng_id->buf_size)                        {                        /* We need to wrap, and perhaps put some more chars */                        bytes2 = min (nbytes - bytesput, p_from_buf - 1);                        memcpy (rng_id->buf, buffer + bytesput, bytes2);                        rng_id->p_to_buf = bytes2;                        bytesput += bytes2;                        }                else                        rng_id->p_to_buf = p_rng_tmp;                }        return (bytesput);        }/** * \brief - test if a ring buffer is empty * * This routine determines if a specified ring buffer is empty. * * \param[in] rng_id        ring buffer to test * \return                                TRUE if empty, FALSE if not. */bool rng_is_empty (RING_ID ring_id)        {        return (ring_id->p_to_buf == ring_id->p_from_buf);        }/** * \brief - test if a ring buffer is full (no more room) * * This routine determines if a specified ring buffer is completely full. * * \param[in] rng_id        ring buffer to test * \return                                TRUE if full, FALSE if not. */bool rng_is_full (RING_ID ring_id)        {        int n = ring_id->p_to_buf - ring_id->p_from_buf + 1;        return ((n == 0) || (n == ring_id->buf_size));        }/** * \brief - determine the number of free bytes in a ring buffer * * This routine determines the number of bytes currently unused in a specified * ring buffer. * * \param[in] rng_id        ring buffer to examine * \return                                The number of unused bytes in the ring buffer. */int rng_free_bytes (RING_ID ring_id)        {        int n = ring_id->p_from_buf - ring_id->p_to_buf - 1;        if (n < 0)                n += ring_id->buf_size;        return (n);        }/** * * rng_nBytes - determine the number of bytes in a ring buffer * * This routine determines the number of bytes currently in a specified * ring buffer. * * \param[in] rng_id        ring buffer to be enumerated * \return                                The number of bytes filled in the ring buffer. */int rng_nBytes (RING_ID ring_id)        {        int n = ring_id->p_to_buf - ring_id->p_from_buf;        if (n < 0)                n += ring_id->buf_size;        return (n);        }/** * \brief - put a byte ahead in a ring buffer without moving ring pointers * * This routine writes a byte into the ring, but does not move the ring buffer * pointers. Thus the byte will not yet be available to rng_buf_get() calls. * The byte is written <offset> bytes ahead of the next input location in the * ring. Thus, an offset of 0 puts the byte in the same position as would * RNG_ELEM_PUT would put a byte, except that the input pointer is not updated. * * Bytes written ahead in the ring buffer with this routine can be made available * all at once by subsequently moving the ring buffer pointers with the routine * rng_move_ahead(). * * Before calling nng_put_ahead(), the caller must verify that at least * <offset> + 1 bytes are available in the ring buffer. * * \param[in] ring_id        ring buffer to put byte in * \param[in] byte                byte to be put in ring * \param[in] offset        offset beyond next input byte where to put byte */void rng_put_ahead (RING_ID ring_id, char byte, int offset)        {        int n = ring_id->p_to_buf + offset;        if (n >= ring_id->buf_size)                n -= ring_id->buf_size;        *(ring_id->buf + n) = byte;        }/** * \brief - advance a ring pointer by <n> bytes * * This routine advances the ring buffer input pointer by <n> bytes. This makes * <n> bytes available in the ring buffer, after having been written ahead in * the ring buffer with rng_put_ahead(). * * \param[in] ring_id        ring buffer to be advanced * \param[in] n                        number of bytes ahead to move input pointer */void rng_move_ahead (RING_ID ring_id, int n)        {        n += ring_id->p_to_buf;        if (n >= ring_id->buf_size)                n -= ring_id->buf_size;        ring_id->p_to_buf = n;        }有精力的同学可以找我要完整代码,这个只是remorse.c文件。
  • 回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    手机版|小黑屋|与非网

    GMT+8, 2024-4-24 10:22 , Processed in 0.126371 second(s), 18 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.