你的位置:电子园STM32学习专区 >> 应用实例>> 详细内容 在线投稿

STM32的LCD驱动及USART驱动

发布: 2009-5-20 16:00 | 作者: hnrain | 查看: 227次


 

*----------------------------------------------------------------------------*/

#include <stm32f10x_lib.h>                        // STM32F10x 库定义
#include <stdio.h>
#include "STM32_Init.h"                           // STM32 初始化

/*----------------------------------------------------------------------------
  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 [RBUF_SIZE];                           // 缓冲区
};

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

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

static unsigned int tx_restart = 1;               // 如果发送重新启动

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

    IIR = USART1->SR;
    if (IIR & USART_FLAG_RXNE) {                  // 如果读中断
      USART1->SR &= ~USART_FLAG_RXNE;           // 则清除中断

      p = &rbuf;

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

    if (IIR & USART_FLAG_TXE) {       //发送中断
      USART1->SR &= ~USART_FLAG_TXE;           // 清中断

      p = &tbuf;

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

      }
    }
}

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

  tbuf.in = 0;                                    //清除缓冲区索引
  tbuf.out = 0;
  tx_restart = 1;

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

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

                                                  //如果缓冲区满了。返回错误
  if (SIO_TBUFLEN >= TBUF_SIZE)
    return (-1);
                                                 
  p->buf [p->in & (TBUF_SIZE - 1)] = c;           //将数据加放发送缓冲氏
  p->in++;

  if (tx_restart) {                               //如果发送中断不能使,则使其能使
    tx_restart = 0;
 USART1->CR1 |= USART_FLAG_TXE;            // 允许发送中断
  }

  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)]);
}


/*----------------------------------------------------------------------------
  MAIN function
 *----------------------------------------------------------------------------*/
int main (void) {
  int  i;
  char c;

  buffer_Init();                                  // init RX / TX buffers
  stm32_Init ();                                  // STM32 setup

  lcdWrStr("KEIL");
  for (i = 0; i < 10000; i++);                 // Wait for initial display
  printf ("\r\n Interrupt driven Serial I/O Example \r\n");

  lcdWrStr("->  ");
  while (1) {                                     // Loop forever
    printf ("Please press a key. ");
    c = getchar ();
    printf ("\r\n");
    printf ("You pressed just now is  '%c'.\r\n\r\n", c);

    lcdWrPos(&c, 3);

  } // end while
} // end main

 

#include <stm32f10x_lib.h>                              // stm32f10x definitions
#include "STM32_Reg.h"                                  // missing bit definitions


unsigned short lcdChar[128] = {
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, //   0..9    unused
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, //  10..19   unused
  0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, //  20..29   unused
  0x0000, 0x0000, 0x0000, 0x2002, 0x0012, 0x0000, 0xAE16, 0x0000, 0x0000, 0x0002, //  30..39   unused          
  0x0000, 0x0000, 0x7662, 0x2602, 0x2000, 0x0600, 0x0000, 0x1040, 0x99D4, 0x08C0, //  40..47   unused, '0', '1'          
  0x8784, 0x8C84, 0x0E90, 0x8E14, 0x8F14, 0x1044, 0x8F94, 0x8E94, 0x0000, 0x0000, //  '2'..'9', 58..59 unused          
  0x4040, 0x8600, 0x1020, 0x2494, 0x0000, 0x0F94, 0x8F10, 0x8114, 0x8F80, 0x8314, //  60..65   unused, 'A'..'E'          
  0x0314, 0x8D14, 0x0F90, 0x2002, 0x4880, 0x4350, 0x8110, 0x09F0, 0x49B0, 0x8994, //  'F'..'O'          
  0x0794, 0xC994, 0x4394, 0x8E14, 0x2006, 0x8990, 0x8990, 0x5990, 0x5060, 0x0160, //  'P'..'Y'         
  0x9044, 0x8114, 0x4020, 0x8884, 0x0000, 0x8000, 0x0010, 0x0F94, 0x8F10, 0x8700, //  'Z', 91..96 unused, 'a'..'c'          
  0x8F80, 0x8314, 0x0314, 0x8D14, 0x0F90, 0x2002, 0x4880, 0x4350, 0x8110, 0x09F0, //  'e'..'m'          
  0x49B0, 0x8F00, 0x0794, 0xC994, 0x0300, 0x8E14, 0x2006, 0x8990, 0x8990, 0x5900, //  'n'..'w'          
  0x5060, 0x0160, 0x9044, 0x0000, 0x2002, 0x0000, 0x0000, 0x0000};                //  'x'..'z', 123..127 unused          

 

unsigned short lcdBuffer[4] = {0, 0, 0, 0};             // LCD representation
unsigned int   lcdState     = 0;                        // write or clear
unsigned int   lcdWrState   = 0;                        // normal or inverted
unsigned int   lcdLine      = 0;                        // line 0..4


/*----------------------------------------------------------------------------
  clear LCD
 *----------------------------------------------------------------------------*/
void lcdClr (void) {
  int lineNr;

  for (lineNr = 0; lineNr < 4; lineNr++) {
    lcdBuffer[lineNr] = 0;
  }

}

/*----------------------------------------------------------------------------
  write a character to LCD position (0..3). Position 0 is left, 3 is right
 *----------------------------------------------------------------------------*/
void lcdWrPos (char* c, int pos) {
  int            lineNr;
  unsigned short cLcd;                                  // character coding for LCD

  cLcd = lcdChar[*c & 0x7F];                            // we only handel character 0..127

  for (lineNr = 0; lineNr < 4; lineNr++) {
    lcdBuffer[lineNr] = (lcdBuffer[lineNr] & ~(0xF<<(4*pos))) | (((cLcd>>(lineNr*4))& 0xF)<<(4*pos));
  }

}

/*----------------------------------------------------------------------------
  write a string to LCD position (0..3). max chars written is 4
 *----------------------------------------------------------------------------*/
void lcdWrStr (char* s) {
  int i;

  for (i = 0; i < 4; i++) {
    lcdWrPos (s+i, i);
  }

}


/*----------------------------------------------------------------------------
  TIM4_IRQHandler
  ticks every 2ms
 *----------------------------------------------------------------------------*/
void TIM4_IRQHandler(void)
{
  if (TIM4->SR & (1<<0)) {                              // UIF set?
//--------------------------------
  GPIOC->CRH &= 0xFFFF0000;
  GPIOC->CRH |= 0x00004444;                             // COM1..4 input floating
  GPIOC->CRH &= ~(0xF<<(4*(3-lcdLine)));
  GPIOC->CRH |=  (0x3<<(4*(3-lcdLine)));                // COMx    ouput push pull 50 MHz

  switch (lcdState){
    case 0:                                             // write state
      switch (lcdWrState) {
        case 0:                                         // write nomal data stat
          GPIOE->ODR  = lcdBuffer[lcdLine];             // write data
          GPIOC->BRR  = (1<<(8+(3-lcdLine)));           // COMx low

          lcdWrState = 1;                               // next state is write inverted data                      
        break;
        case 1:                                         // write inverted data state
          GPIOE->ODR  = ~lcdBuffer[lcdLine];            // write inverted data
          GPIOC->BSRR = (1<<(8+(3-lcdLine)));           // COMx high

          lcdWrState = 0;                               // next state is write normal data
          lcdLine = ((lcdLine+1) == 4) ? 0 : lcdLine+1; // handle next COM
        break;
      } // end switch (lcdWrState)

      lcdState = 1;                                     // next state is clearState
    break;

    case 1:                                             // clear state
      GPIOC->CRH &= 0xFFFF0000;
      GPIOC->CRH |= 0x00003333;                         // COM1..4 ouput push pull 50 MHz

      GPIOE->ODR  =  0x0000;                            // all Segments off
      GPIOC->BRR  = (0xF<<8);                           // all Lines off

      lcdState = 0;                                     // next state is writeState
    break;

  } // end switch (lcdState)
//--------------------------------
    TIM4->SR &= ~(1<<0);                                // clear UIF flag
  }

}

 

软件仿真结果如下:

是不是很爽呢?呵呵。

TAG: LCD USART 驱动
打印 | 收藏此页 | 推荐给好友 | 举报
上一篇 下一篇

评分:0

发表评论
查看全部回复【已有0位网友发表了看法】

CEPARK STM32在线订购

  • 技术咨询:010-64441912
  • 技术热线:13671007554
  • 技术QQ: 174212810
 电子园服务子站:  电子园主站   电子园论坛    电子园社区    电子园商城    电子园百科    开发工具网    项目交易网    在线学习网
 电子园技术子站:  51单片机学习网   USB开发学习网   AVR单片机学习网   CAN总线学习网   PIC学习网   FPGA学习网   ARM学习网   DIY学习网   STM32学习网
 DSP学习网   EDA软件学习网   GPS开发学习网   GUI技术学习网   电源技术网   RF射频技术网   汽车电子技术网   医疗电子技术网   消费电子技术网
 助学开发板资源:  51单片机开发学习板   USB开发学习板   AVR M64单片机开发学习板   AVR M16单片机开发学习板   CAN总线开发学习板