打印

求串口接收函数

[复制链接]
916|23
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
lizye|  楼主 | 2017-8-5 19:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
沙发
yszong| | 2017-8-5 19:42 | 只看该作者
这里有msp430f149串口函数该怎样修改.
/***********************************宏定义*********************************/
#define UxCTL   U0CTL
#define UxRCTL  U0RCTL
#define UxTCTL  U0TCTL

#define UxBR0   U0BR0
#define UxBR1   U0BR1
#define UxMCTL  U0MCTL

#define UxRXBUF U0RXBUF
#define UxTXBUF U0TXBUF

#define UxME    U0ME
#define UxIE    U0IE
#define UxIFG   U0IFG

#define UTXEx   UTXE0
#define URXEx   URXE0

#define URXIEx  URXIE0
#define UTXIEx  UTXIE0

#define UARTxTX_VECTOR  UART0TX_VECTOR
#define UARTxRX_VECTOR  UART0RX_VECTOR

#define UARTON  P3SEL |= 0X30          // P3.4,5 = USART0 TXD/RXD
/**************************************************************************/

char TxFlag=1;
char RxFlag=0;


/****************************************************************************
* 名    称:abs
* 功    能:求绝对值
* 入口参数:i:整数
* 出口参数:int 求得的绝对值
****************************************************************************/
int abs(int i)
{
    return (i>=0?i-i));
}

/***************************************************************************
* 名    称:SetBaudRateRegisters
* 功    能:根据时钟 波特率设置对应寄存器
* 入口参数:
*           clk:        所选时钟频率(如:32768)
*           baud:       波特率      (300~115200)
* 出口参数:无
* 范    例: SetBaudRateRegisters(32768,9600)//用时钟频率32768产生9600的波特率
****************************************************************************/
void SetBaudRateRegisters(long clk,long baud)
{
    int n = clk / baud;     //整数波特率
    char mSum = 0;          //Σmi
    int txEr0;              //对应位为0时错误率
    int txEr1;              //对应位为1时错误率
    char i = 0;             //循环计数

    UxBR1 = n >> 8;         //高8位
    UxBR0 = n & 0xff;       //低8位
    UxMCTL = 0;

    //循环 比较错误率大小 设置UxMCTL
    for(;i < 8;i++)
    {
        txEr0 = 100 * baud * ((i + 1) * n + mSum) / clk - 100 * (i + 1);
        txEr1 = 100 * baud * ((i + 1) * n + mSum + 1) / clk - 100 * (i + 1);
        if(abs(txEr1) < abs(txEr0))
        {
            mSum++;
            UxMCTL |= (1<<i);
        }
    }
}

/****************************************************************************
* 名    称:UartInit()
* 功    能:初始化串口。设置波特率等
* 入口参数:
*           baud:       波特率      (300~115200)
            parity:     奇偶校验位  ('n'=无校验  'p'=偶校验  'o'=奇校验)
            datsBits:   数据位位数  (7或8)
            stopBits:   停止位位数  (1或2)
* 出口参数:返回值为1时表初化成功,为0表示参数有错误
* 范    例: UartInit(9600,'n',8,1) //设成9600bps,无校验,8位数据,1位停止位
            UartInit(2400,'p',7,2) //设成2400bps,偶校验,7位数据,2位停止位
****************************************************************************/
char UartInit(long baud,char parity,char dataBits,char stopBits)
{
    long int brclk;                 //波特率发生器时钟频率

    UxCTL |= SWRST;                 //初始

    //时钟源设置
    UxTCTL &=~ (SSEL0+SSEL1);       //清除之前的时钟设置
    if(baud<=9600)                  //
    {
      UxTCTL |= SSEL0;              //ACLK,降低功耗
      brclk = 32768;                //波特率发生器时钟频率=ACLK(32768)
    }
    else
    {
      UxTCTL |= SSEL1;              //SMCLK,保证速度
      brclk = 1000000;              //波特率发生器时钟频率=SMCLK(1MHz)
    }

    //------------------------设置波特率-------------------------   
    if(baud < 300||baud > 115200)   //波特率超出范围
    {
        return 0;
    }
    SetBaudRateRegisters(brclk,baud);         //设置波特率寄存器

    //------------------------设置校验位-------------------------  
    switch(parity)
    {
        case 'n':case'N': UxCTL &=~ PENA;               break;  //无校验
        case 'p':case'P': UxCTL |= PENA + PEV;          break;  //偶校验
        case 'o':case'O': UxCTL |= PENA; UxCTL &=~ PEV; break;  //奇校验  
        default :         return(0);                            //参数错误
    }

    //------------------------设置数据位-------------------------   
    switch(dataBits)
    {
        case 7:case'7': UxCTL &=~ CHAR; break;      //7位数据
        case 8:case'8': UxCTL |= CHAR;  break;      //8位数据
        default :       return(0);                  //参数错误
    }
    //------------------------设置停止位-------------------------   
    switch(stopBits)
    {
        case 1:case'1': UxCTL &= ~SPB;  break;      //1位停止位
        case 2:case'2': UxCTL |= SPB;   break;      //2位停止位
        default :       return(0);                  //参数错误
    }

    UARTON;                     //端口使能
    UxME |= UTXEx + URXEx;      //发送 接收使能

    UCTL0 &= ~SWRST;            // Initialize USART state machine

    UxIE |= URXIEx + UTXIEx;    // Enable USART0 RX interrupt

    return(1);                  //设置成功
}

/****************************************************************************
* 名    称:UartLpm
* 功    能:串口收/发等待过程中,将时钟系统的部分时钟该关掉,休眠省电
* 入口参数:无
* 出口参数:无
* 说    明: 若与其他外设的时钟冲突,可注释掉该函数,但会增加功耗。
****************************************************************************/
void UartLpm()
{
    if(UxTCTL&SSEL0) LPM3;  //若以ACLK 作时钟,进入LPM3休眠(仅打开ACLK)
    else             LPM0;  //若以SMCLK作时钟,进入LPM0休眠(不关闭SMCLK)
}

/****************************************************************************
* 名    称:UartWriteChar
* 功    能:向串口写一个字节数据
* 入口参数:c:  待发送的一字节数据
* 出口参数:无
* 说    明: 在等待发送完毕的过程中,CPU会休眠
****************************************************************************/
void UartWriteChar(char c)
{
    while (TxFlag==0) UartLpm();  // 等待上一字节发完,并休眠
    TxFlag=0;                     //
    UxTXBUF=c;
}

/****************************************************************************
* 名    称:UartReadChar
* 功    能:从串口读取1字节数据
* 入口参数:无  
* 出口参数:收到的一字节数据
* 说    明: 如果串口没有数据,会一直等待。等待过程中,CPU会休眠
****************************************************************************/
char UartReadChar()
{
    while (RxFlag==0) UartLpm(); // 收到一字节?
    RxFlag=0;
    return(UxRXBUF);
}

/****************************************************************************
* 名    称:UartWriteStr
* 功    能:向串口写一个字符串
* 入口参数:s:要写入的字符串  
* 出口参数:无
* 说    明: 如果没有到 NULL 继续写入字符
****************************************************************************/
void UartWriteStr(char *s)
{
    while(*s)
    {
        UartWriteChar(*s++);
    }
}

/****************************************************************************
* 名    称:UartRx
* 功    能:串口接收中断,每接收到1字节会发生一次中断
****************************************************************************/
#pragma vector=UARTxRX_VECTOR
__interrupt void UartRx()
{
    RxFlag=1;
    __low_power_mode_off_on_exit();
}

/****************************************************************************
* 名    称:UartTx
* 功    能:串口发送中断,每发完1字节会发生一次中断
****************************************************************************/
#pragma vector=UARTxTX_VECTOR
__interrupt void UartTx ()
{
    TxFlag=1;
    __low_power_mode_off_on_exit();
}

使用特权

评论回复
板凳
dengdc| | 2017-8-5 19:44 | 只看该作者

下面这个例子好长

使用特权

评论回复
地板
lizye|  楼主 | 2017-8-5 19:45 | 只看该作者
问错地方了,结贴吧~~~

使用特权

评论回复
5
heweibig| | 2017-8-5 19:46 | 只看该作者
这个例子有点长啊
不过还是很有用
再贴代码的时候换成有格式的就好了

使用特权

评论回复
6
lizye|  楼主 | 2017-8-5 19:48 | 只看该作者
嗯,我再好好缕一缕吧,有了好消息及时通知大家,结贴喽

使用特权

评论回复
7
jimmhu| | 2017-8-5 22:19 | 只看该作者
8
lihuami| | 2017-8-5 22:19 | 只看该作者
官网没有这个代码吗

使用特权

评论回复
9
uptown| | 2017-8-5 22:20 | 只看该作者
void set_rs485_dir(char tx_rx)
{ //1---发送,0接收

  if (tx_rx==1)
  {
    P9OUT|=(BIT6+BIT7);
  }
  else
  {
    P9OUT&=~(BIT6+BIT7);
  }
  P9DIR|=(BIT6+BIT7);
}

void delay(char num)
{
  while(num--);
}

int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

  //串口2 初始化
  P9SEL|= BIT4+BIT5;      //对于P5 6,7为模块功能
  P9DIR|=BIT4;
  P9DIR&=~BIT5;
  UCA2CTL1 |= UCSWRST;                      // **Put state machine in reset**
  UCA2CTL1 |= UCSSEL_2;                     // SMCLK
  UCA2BR0 = 109;                             
  UCA2BR1 = 0;                             
  UCA2MCTL |= UCBRS_1 + UCBRF_0;            // Modulation UCBRSx=1, UCBRFx=0
  UCA2CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  UCA2IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt
  
  __enable_interrupt();//容易忽略
  
     set_rs485_dir(1);//发送
     delay(3000);
     while (!(UCA2IFG&UCTXIFG));             // USCI_A2 TX buffer ready?
     UCA2TXBUF = 0x55;                  // TX -> RXed character
     delay(3000);
     set_rs485_dir(0);//接收
     delay(3000);
     while(1)
     {
       delay(2000);
     }
}

#pragma vector=USCI_A2_VECTOR
__interrupt void USCI_A2_ISR(void)
{
  switch(__even_in_range(UCA2IV,4))
    {
       case 0:break;                             // Vector 0 - no interrupt
       case 2:                                   // Vector 2 - RXIFG
       set_rs485_dir(1);//发送
       delay(30);
       while (!(UCA2IFG&UCTXIFG));               // USCI_A0 TX buffer ready?
       UCA2TXBUF = UCA2RXBUF;                    // TX -> RXed character
       set_rs485_dir(0);//接收
       delay(30);
       break;
       case 4:break;                             // Vector 4 - TXIFG
       default: break;
    }
}

使用特权

评论回复
10
cehuafan| | 2017-8-5 22:21 | 只看该作者
给你发个中断配置的。

使用特权

评论回复
11
usysm| | 2017-8-5 22:21 | 只看该作者
CCS上面有430各种型号的例程

使用特权

评论回复
12
typeof| | 2017-8-5 22:22 | 只看该作者
13
yujielun| | 2017-8-5 22:23 | 只看该作者
14
htmlme| | 2017-8-5 22:24 | 只看该作者
这个根据其他的程序修改。

使用特权

评论回复
15
jimmhu| | 2017-8-5 22:24 | 只看该作者
16
lihuami| | 2017-8-5 22:24 | 只看该作者
现在的串口模块有很多可以参考。

使用特权

评论回复
17
xiaoyaozt| | 2017-8-5 22:24 | 只看该作者
TI都提供相关代码的

使用特权

评论回复
18
uptown| | 2017-8-5 22:25 | 只看该作者
串口接收配置需要注意的是开启总中断( __enable_interrupt(); )

使用特权

评论回复
19
cehuafan| | 2017-8-5 22:25 | 只看该作者
  P3SEL |= 0x30;                            // P3.4,5 = USART0 TXD/RXD
      ME1 |= UTXE0 + URXE0;                     // Enable USART0 TXD/RXD
      UCTL0 |= CHAR;                            // 8-bit character
      UTCTL0 |= SSEL0;                          // UCLK = ACLK
      UBR00 = 0x0D;                             // 32k/2400 - 13.65
      UBR10 = 0x00;                             //
      UMCTL0 = 0x6B;                            // Modulation
      UCTL0 &= ~SWRST;                          // Initialize USART state machine
      IE1 |= URXIE0;                            // Enable USART0 RX interrupt
      
      _EINT();

使用特权

评论回复
20
usysm| | 2017-8-5 22:25 | 只看该作者
现在一个controlsuit工具。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

852

主题

9757

帖子

2

粉丝