Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4534575
  • 博文数量: 252
  • 博客积分: 5347
  • 博客等级: 大校
  • 技术积分: 13838
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-30 10:13
文章分类
文章存档

2022年(12)

2017年(11)

2016年(7)

2015年(14)

2014年(20)

2012年(9)

2011年(20)

2010年(153)

2009年(6)

分类: 嵌入式

2010-11-24 10:56:31

   本程序可以使用中断的方式,也可以实现轮询的方式,实现数据的串口接收。CC2430的UART和PC机的串口连接,当在PC端的串口调试助手中发送数据时,并且最后以‘#’接受字符串时,表明这个字符串结束,字符串同时返回串口调试助手的接受区,并在LCD屏幕中显示。其中,在程序中没有实现的函数定义都在"hal.h"文件中。
 

void main(void)
{
  P1SEL = 0x00;
  P1DIR = 0x0f;
  char c = 0;
  UINT8 i;
  char s[]="UART<-->LCD";
  char s1[]="57600 8-N-1";
  int count = 0;
  initUART();

  LCD_write_english_string(0,0,s);
  LCD_write_english_string(0,1,s1);
 
  memset(buffer.text,' ',BUFFER_SIZE);
  
 buffer.pointer = 0;
 lcdUpdate(&buffer.text[0],&buffer.text[16]);

 printf((char *)"\n\nType text\n");
 printf((char*)"ENTER to readback text to hyperterminal\n");
   printf((char*)"BACKSPACE to delete last written character\n");
   printf((char*)"ESC to quit\n");

    while(1)
    {
    //c = uartGetKey();

      temp = uartGetKey();
   asm("NOP");
   if(temp!=0)
   {
     switch(temp)
    {
    case ENTER:
     //if(temp == ENTER)

     {
        for(i=0;i<BUFFER_SIZE;i++)
        {
         printf((char *)"%c",buffer.text[i]);
       }
       printf((char *)"\n");
    lcdUpdate(&buffer.text[0],&buffer.text[14]);
    memset(buffer.text,' ',BUFFER_SIZE);
    buffer.pointer = 0;
    break;
     }
    case BACK_SPACE:
    
          if(buffer.pointer>0)
          {
            buffer.pointer--;
          buffer.text[buffer.pointer]=' ';
          }
    break;
    case ESC:
      break;
    default:
      if(buffer.pointer < BUFFER_SIZE)
    // else
      {
        buffer.text[buffer.pointer] = temp;
        buffer.pointer++;
      }
    break;
    }     
    //lcdUpdate(&buffer.text[0],&buffer.text[16]);

   }
   temp = 0;
      /* if( temp != 0)
        {
                if((temp!='#'))
                { //’#‘被定义为结束字符
                                               //最多能接收30个字符
              buffer.text[buffer.pointer]=temp;
             buffer.pointer++;
              
                }
                else
                {
                  RTflag = 3; //进入发送状态
                  lcdUpdate(&buffer.text[0],&buffer.text[16]);
                   for(i=0;i                      {
                            printf((char *)"%c",buffer.text[i]);
                       }
                  printf((char *)"\n");
                }
               
              temp = 0;
            }*/

    }
}

#define UART_ENABLE_RECEIVE 0x40

char uartGetKey(void)
{
  char c;
  BYTE status;
  
  status = U0CSR;
  U0CSR |= UART_ENABLE_RECEIVE;
  
  while(!URX0IF);
  c = U0DBUF;
  URX0IF = FALSE;
  U0CSR = status;
  return c;
}

/*#pragma vector = URX0_VECTOR
__interrupt void UART0_ISR(void)
{
  URX0IF = 0; //清中断标示
  temp = U0DBUF;
}*/

其运行结果如下图:


// The macros in this section simplify UART operation.
// BAUD_E和BAUD_M共同决定了波特率,参见波特率计算公式 
// BAUD_E=Baud rate exponent value 指数值 BAUD_E[4:0]在U0/1GCR寄存器中
// BAUD_M=Baud rate mantissa value 尾数值 BAUD_M[7:0]在U0/1BAUD寄存器中

#define BAUD_E(baud, clkDivPow) ( \
    (baud==2400) ? 6 +clkDivPow : \
    (baud==4800) ? 7 +clkDivPow : \
    (baud==9600) ? 8 +clkDivPow : \
    (baud==14400) ? 8 +clkDivPow : \
    (baud==19200) ? 9 +clkDivPow : \
    (baud==28800) ? 9 +clkDivPow : \
    (baud==38400) ? 10 +clkDivPow : \
    (baud==57600) ? 10 +clkDivPow : \
    (baud==76800) ? 11 +clkDivPow : \
    (baud==115200) ? 11 +clkDivPow : \
    (baud==153600) ? 12 +clkDivPow : \
    (baud==230400) ? 12 +clkDivPow : \
    (baud==307200) ? 13 +clkDivPow : \
    0 )


#define BAUD_M(baud) ( \
    (baud==2400) ? 59 : \
    (baud==4800) ? 59 : \
    (baud==9600) ? 59 : \
    (baud==14400) ? 216 : \
    (baud==19200) ? 59 : \
    (baud==28800) ? 216 : \
    (baud==38400) ? 59 : \
    (baud==57600) ? 216 : \
    (baud==76800) ? 59 : \
    (baud==115200) ? 216 : \
    (baud==153600) ? 59 : \
    (baud==230400) ? 216 : \
    (baud==307200) ? 59 : \
  0)

// Macro for setting up a UART transfer channel. The macro sets the appropriate

// pins for peripheral operation, sets the baudrate, and the desired options of

// the selected uart. _uart_ indicates which uart to configure and must be

// either 0 or 1. _baudRate_ must be one of 2400, 4800, 9600, 14400, 19200,

// 28800, 38400, 57600, 76800, 115200, 153600, 230400 or 307200. Possible

// options are defined below.

//

// Example usage:

//

// UART_SETUP(0,115200,HIGH_STOP);

//

// This configures uart 0 for contact with "hyperTerminal", setting:

// Baudrate: 115200

// Data bits: 8

// Parity: None

// Stop bits: 1

// Flow control: None

//

#define UART_SETUP(uart, baudRate, options) \
   do { \
      if ((options) & FLOW_CONTROL_ENABLE){ \
         if((uart) == 0){ /* USART0 */\
            if(PERCFG & 0x01){ /* if U0CFG=1,chose location 2 Alt 2 */\
               P1SEL |= 0x3C; \ //选择RX TX
            } else { /* Alt 1 */\
               P0SEL |= 0x3C; \
            } \
         } \
         else { /* USART1 */\
            if(PERCFG & 0x02){ /* Alt 2 */\
               P1SEL |= 0xF0; \
            } else { /* Alt 1 */\
               P0SEL |= 0x3C; \
            } \
         } \
      } \
      else{ /* Flow Ctrl Dis*/\
         if((uart) == 0){ /* USART0 */\
            if(PERCFG & 0x01){ /* Alt 2 */\
               P1SEL |= 0x30; \
            } else { /* Alt 1 */\
               P0SEL |= 0x0C; \
            } \
         } \
         else { /* USART1 */\
            if(PERCFG & 0x02){ /* Alt 2 */\
               P1SEL |= 0xC0; \
            } else { /* Alt 1 */\
               P0SEL |= 0x30; \
            } \
         } \
      } \
                                                 \
      U##uart##GCR = BAUD_E((baudRate), CLKSPD); \

      ////设置波特率指数值  //U##uart##GCR:普通控制寄存器
      U##uart##BAUD = BAUD_M(baudRate); \
     //设置波特率尾数值,U##uart##BAUD:波特率控制寄存器                                  \
      U##uart##CSR |= 0x80; \//USART设为UART模式  
     /chose UART stop bit level and set FLUSH bit                                     \
      U##uart##UCR |= ((options) | 0x80); \
    //U##uart##UCR :UART控制寄存器                                       \
      if((options) & TRANSFER_MSB_FIRST){ \//options=0x02:High stop bit
         U##uart##GCR |= 0x20; \
      } \
   } while(0)
// Options for UART_SETUP macro

#define FLOW_CONTROL_ENABLE 0x40
#define FLOW_CONTROL_DISABLE 0x00
#define EVEN_PARITY 0x20
#define ODD_PARITY 0x00
#define NINE_BIT_TRANSFER 0x10
#define EIGHT_BIT_TRANSFER 0x00
#define PARITY_ENABLE 0x08
#define PARITY_DISABLE 0x00
#define TWO_STOP_BITS 0x04
#define ONE_STOP_BITS 0x00
#define HIGH_STOP 0x02
#define LOW_STOP 0x00
#define HIGH_START 0x01
#define TRANSFER_MSB_FIRST 0x80
#define TRANSFER_MSB_LAST 0x00


// Example usage:

// if(UART0_PARERR())

// ...

#define UART_PARERR(num) (U##num##CSR & 0x08)
#define UART0_PARERR() UART_PARERR(0)
#define UART1_PARERR() UART_PARERR(1)

// Example usage:

// if(UART1_FRAMEERR())

// ...

#define UART_FRAMEERR(num) (U ##num## CSR & 0x10)
#define UART0_FRAMEERR() UART_FRAMEERR(0)
#define UART1_FRAMEERR() UART_FRAMEERR(1)


// Example usage:

// char ch = 'A';

// UART1_SEND(ch);

// ...

// UART1_RECEIVE(ch);

#define UART_SEND(num, x) U##num##DBUF = x
#define UART0_SEND(x) UART_SEND(0, x)
#define UART1_SEND(x) UART_SEND(1, x)

#define UART_RECEIVE(num, x) x = U##num##DBUF
#define UART0_RECEIVE(x) UART_RECEIVE(0, x)
#define UART1_RECEIVE(x) UART_RECEIVE(1, x)

    从中我们可以看到,用到了大量的宏定义,例如U##num##DBUF其中的“##”表示,替代传递过来的参数。也可以看出,程序中封装的很好,我们调用函数时很方便,还有就是他把很多程序集成了,其实是两个串口,就只用了一个程序代替,编写程序很多好的习惯,以及怎么样编写健壮,通用的程序,在这里体现得也很明显,很值得借鉴。
阅读(4213) | 评论(1) | 转发(6) |
给主人留下些什么吧!~~

chinaunix网友2010-11-30 17:31:49

兄弟你的qq多少,看似你很专业啊!我刚大二,求帮助