luoyiming1984 发表于 2012-9-11 00:10:48

发一个RL-ARM的UART例程,采用队列缓冲,动态分配内存。

本帖最后由 luoyiming1984 于 2012-9-11 00:22 编辑

采用LPC2142芯片,有点老了,keil4最新版。
UART采用了16字节FIFO和队列buffer的方式,UartRead支持接收超时。
两个任务,因为保密的需要,我把FLASH,LCM,无线通信的驱动全部扣了(不要扁我,人不为己天诛地灭)。
一个任务是接收Uart数据,一个是把收到的发出来。
每个任务的堆栈分配,我用的动态分配,这样在删除任务时,可以把内存也删除掉。




winfisher 发表于 2012-9-11 00:27:42

那能看到啥?

luoyiming1984 发表于 2012-9-11 09:32:12

没有人看吗??

myhonour 发表于 2012-9-21 12:15:42


MARK一下~~·

roguebear2012 发表于 2012-9-21 21:23:08

能整个stm32上的串口的?

luoyiming1984 发表于 2012-9-22 11:45:27

roguebear2012 发表于 2012-9-21 21:23 static/image/common/back.gif
能整个stm32上的串口的?

已经做好了,连续收发鸭梨不大

roguebear2012 发表于 2012-9-22 13:10:29

luoyiming1984 发表于 2012-9-22 11:45 static/image/common/back.gif
已经做好了,连续收发鸭梨不大

我来贴个。keil测试通过,感觉效率不太高啊。

兄台把你的整上来……



/*----------------------------------------------------------------------------
* Name:    Usart.c
* Purpose: USART usage for STM32
* Version: V1.00
*----------------------------------------------------------------------------
* This file is part of the uVision/ARM development tools.
* This software may only be used under the terms of a valid, current,
* end user licence from KEIL for a compatible version of KEIL software
* development tools. Nothing else gives you the right to use this software.
*
* Copyright (c) 2005-2007 Keil Software. All rights reserved.
*----------------------------------------------------------------------------*/




#include <stm32f10x_conf.h>   



/* 注意: 打开 RXNE          TXE 中断*/
#define USARTx                        USART1
#define USARTx_IRQHandler        USART1_IRQHandler

/*----------------------------------------------------------------------------
Notes:
The length of the receive and transmit buffers must be a power of 2.
Each buffer has a next_in and a next_out index.
If next_in = next_out, the buffer is empty.
(next_in - next_out) % buffer_size = the number of characters in the buffer.
*----------------------------------------------------------------------------*/
#define TBUF_SIZE   256             /*** Must be a power of 2 (2,4,8,16,32,64,128,256,512,...) ***/
#define RBUF_SIZE   256      /*** Must be a power of 2 (2,4,8,16,32,64,128,256,512,...) ***/

/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
#if TBUF_SIZE < 2
#error TBUF_SIZE is too small.It must be larger than 1.
#elif ((TBUF_SIZE & (TBUF_SIZE-1)) != 0)
#error TBUF_SIZE must be a power of 2.
#endif

#if RBUF_SIZE < 2
#error RBUF_SIZE is too small.It must be larger than 1.
#elif ((RBUF_SIZE & (RBUF_SIZE-1)) != 0)
#error RBUF_SIZE must be a power of 2.
#endif

/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
struct buf_st {
unsigned int in;                              // Next In Index
unsigned int out;                               // Next Out Index
char buf ;                           // Buffer

};

static struct buf_st rbuf = { 0, 0, 0};
#define SIO_RBUFLEN ((unsigned short)(rbuf.in - rbuf.out))

static struct buf_st tbuf = { 0, 0, 0};
#define SIO_TBUFLEN ((unsigned short)(tbuf.in - tbuf.out))

static unsigned int tx_restart = 1;               // NZ if TX restart is required

/*----------------------------------------------------------------------------
USARTx_IRQHandler
Handles USARTx global interrupt request.
*----------------------------------------------------------------------------*/
void USARTx_IRQHandler (void) {
volatile unsigned int IIR;
struct buf_st *p;

    IIR = USARTx->SR;
    if (IIR & USART_FLAG_RXNE) {                  // read interrupt
      USARTx->SR &= ~USART_FLAG_RXNE;                // clear interrupt

      p = &rbuf;

      if (((p->in - p->out) & ~(RBUF_SIZE-1)) == 0) {
      p->buf = (USARTx->DR & 0x1FF);
      p->in++;
      }
    }

    if (IIR & USART_FLAG_TXE) {
      USARTx->SR &= ~USART_FLAG_TXE;                // clear interrupt

      p = &tbuf;

      if (p->in != p->out) {
      USARTx->DR = (p->buf & 0x1FF);
      p->out++;
      tx_restart = 0;
      }
      else {
      tx_restart = 1;
                USARTx->CR1 &= ~USART_FLAG_TXE;                      // disable TX interrupt if nothing to send

      }
    }
}



/*------------------------------------------------------------------------------
SenChar
transmit a character
*------------------------------------------------------------------------------*/
int SendChar (int c) {
struct buf_st *p = &tbuf;

                                                // If the buffer is full, return an error value
if (SIO_TBUFLEN >= TBUF_SIZE)
    return (-1);
                                                
p->buf = c;         // Add data to the transmit buffer.
p->in++;

if (tx_restart) {                               // If transmit interrupt is disabled, enable it
    tx_restart = 0;
        USARTx->CR1 |= USART_FLAG_TXE;                        // enable TX interrupt
}

return (0);
}

/*------------------------------------------------------------------------------
GetKey
receive a character
*------------------------------------------------------------------------------*/
int GetKey (void) {
struct buf_st *p = &rbuf;

if (SIO_RBUFLEN == 0)
    return (-1);

return (p->buf [(p->out++) & (RBUF_SIZE - 1)]);
}


/*------------------------------------------------------------------------------
buffer_Init
initialize the buffers
*------------------------------------------------------------------------------*/
void buffer_Init (void) {

          tbuf.in = 0;                                    // Clear com buffer indexes
        tbuf.out = 0;
        tx_restart = 1;

        rbuf.in = 0;
        rbuf.out = 0;
}









#if 0

/*----------------------------------------------------------------------------
Demo function
*----------------------------------------------------------------------------*/
int main (void) {

        buffer_Init();                                  // init RX / TX buffers

        stm32_Init ();                                  // STM32 setup

        printf ("\r\n\r\nInterrupt driven Serial I/O Example\r\n\r\n");

        while (1) {                                     // Loop forever
            printf ("Press a key. ");
   
            printf ("You pressed '%c'.\r\n\r\n", getchar () );

        } // end while
} // end main
#endif

azhuweichang 发表于 2012-9-23 23:13:50

借鉴下,学习啦
页: [1]
查看完整版本: 发一个RL-ARM的UART例程,采用队列缓冲,动态分配内存。