430单片机的串口和定时器模拟串口的问题、、

2019-07-15 20:28发布

430的串口和定时器模拟的串口为什么只能用一个啊? (程序附在下面,大侠帮忙看一下)
#include "msp430x15x.h"
#include  <math.h>
#include  <stdio.h>
#include "BoardConfig.h"
#include "UART.h"
#include "12864.h"


#define  LED_H   P2OUT |= BIT7
#define  LED_L   P2OUT &=~BIT7


#define uchar unsigned char
#define uint  unsigned int


#define  TBIT1    2;      //TBIT为1位时间
#define  TBIT_5   1;      //TBIT_5为半位时间
#define  TXD      0x0002
#define  RXD      0x0004
#define  TEN      0x0001   //发送允许位


uchar GBIT=0x00;    //通用位区
uint  TR_COUNT;     //发收计数器
uint  T_DATA;     //发送缓冲器
uint  R_DATA;     //接收缓冲器




void delay_t(uint t)
{
    uint i;
    for(i=0;i<t;i++);
}
void delay_N(uchar i)
{
   uchar t;
   for(t=0;t<i;t++)
     delay_t(50000);
}
/**********选择系统主时钟为8MHz********/
void clock_init()
{
     unsigned int i;
    BCSCTL1 &= ~XT2OFF;                  // 打开XT2高频晶体振荡器
    do
    {
        IFG1 &= ~OFIFG;                 //清除晶振失败标志
        for (i = 0xFF; i > 0; i--);     // 等待8MHz晶体起振
    }
    while ((IFG1 & OFIFG));             // 晶振失效标志仍然存在?
    BCSCTL2 |= SELM_2+SELS;                  //主时钟选择高频晶振
}


/**********定时器A模拟串口初始化**************/
void timerA_UART_init()
{
      P1DIR |= BIT0;
      P1OUT &=~BIT0;   //设DE485=0;-接收允许
      
      P1DIR |= TXD;   //P1.1设位输出—TXD
      P1SEL |= TXD;  //P1.1设为使用外围模块
        
      P2DIR &=~RXD;  //P2.2设为输入—RXD
      P2SEL |= RXD;    //P2.2设为使用外围模块
      
      CCTL0 |= OUT;    //CCR0的OUT设1(OUT定义为0x0004)
      TACTL |= TASSEL0 + MC0;  //设定时器为连续模式,同时启动计时
      _EINT();       //开启总中断允许
}






/**********发送一个字节函数*************/
void  TXD_Byte(uchar byte)
{
      T_DATA = byte;   
      CCR0   = TAR;                //将TAR时间存入CCR0,确定第一位的长度
      CCR0   = CCR0 + TBIT1;      //将每1位时间周期加入CCR0
      T_DATA = T_DATA<<1;        //将字节数据向左移一位,构造最低位为起始位
      T_DATA = T_DATA|0x0200;   //将字节的第10位设为1,以作停止位使用
      TR_COUNT = 10;           //发送计数器
      
      CCTL0  = OUTMOD0 + CCIE;     //重新设置CCTL0(CCIS1-0=00)
                                  //捕获/比较模块输出模式1,允许模块中断
      while(CCIE & CCTL0);       //等待CCIE是否为0?为真,则表示发送完数据
}


/**********接收数据函数**************/
void RXD_data(void)
{
    TR_COUNT = 8;   //接收数据位的位数
    //设置比较捕获控制寄存器0的设置
    //比较捕获为输出模式+比较捕获模块为中断允许+下降沿捕获+设置为捕获模式
     //+选择CCI0B为捕获源+同步捕获
    CCTL0 = OUTMOD0 + CCIE + CM1 + CAP + CCIS0 + SCS;
}


void IO_init()
{
  P2DIR |= BIT7;
  P2OUT |= BIT7;
}


void Test()
{
  if(R_DATA == 0x89 || R_DATA == 0xC9 || R_DATA == 0x91 || R_DATA == 0xD1||
     R_DATA == 0x99 || R_DATA == 0xD9 || R_DATA == 0xA1 || R_DATA == 0xE0)
  {
    LED_L;
  }
else if(R_DATA == 0x88 || R_DATA == 0xC8 || R_DATA == 0x90 || R_DATA == 0xD0||
        R_DATA == 0x98 || R_DATA == 0xD8 || R_DATA == 0xA0 || R_DATA == 0xC0)
  {
    LED_H;
  }
}
/****************发送单个数据函数************************/
void Send_data(uchar da)
{
     //while (!(IFG1 & UTXIFG0));             //等待以前的字符发送完毕
        TXBUF0=da;
        //while (!(IFG1 & UTXIFG0));            
        delay_t(100);         //延时数据发送(大约延时2s)
      
}


// 发送温度数据
void Send_Temp(unsigned char *ZJ)
{
     uint i;
       while(!(IFG1 & UTXIFG0));
       for(i=0;i<2;i++)
       {
         TXBUF0=ZJ;
         while(!(IFG1 & UTXIFG0));
       }
       delay_t(100);            //延时控制发送一个字节
  
}


// 发送烟雾数据
void Send_Smoke(unsigned char *ZJ)
{
     uint i;
       while(!(IFG1 & UTXIFG0));
       for(i=0;i<2;i++)
       {
         TXBUF0=ZJ;
         while(!(IFG1 & UTXIFG0));
       }
       delay_t(100);            //延时控制发送一个字节
  
}


/****************接收数据函数***********************/
void Receive_data()
{
      uchar RX_buf;
      uchar RX[2];
     uint ptr[3], aa[2];
     uint count1, count2;
     uchar TT[2], SS[2];
     
          RX_buf=U0RXBUF;    //接收缓存器
          while(!(IFG1&UTXIFG0));
          delay_t(500);
            RX[0]=RX[1];
            RX[1]=RX_buf;   
                  
   if(RX[0]=='T')
      {
        count1=(uint)RX[1];
        if(count1 <= 80)
        {
          Send_data('T');
        ptr[0]=count1/10;
        ptr[1]=count1%10;
        
        TT[0] = ptr[0]+48;
        TT[1] = ptr[1]+48;
        Send_Temp(TT);


        write_cmd(0x95);
        write_dat(0x30+ ptr[0]);
        write_dat(0x30+ptr[1]);
        }
      }
    else if(RX[0]=='S')
      {  
        count2=(uint)RX[1];
        if(count2 <= 80)
        {
        Send_data('S');
        aa[0]=count2/10;
        aa[1]=count2%10;
      
        SS[0] = aa[0]+48;
        SS[1] = aa[1]+48;
        Send_Smoke(SS);
        
        write_cmd(0x85);
        write_dat(0x30+aa[0]);
        write_dat(0x30+aa[1]);
        }
      }
}
void display_12864()
{
  uchar i;
    write_cmd(0x80);                    //设定首次显示位置
   for(i=0;table1!='';i++)
   write_dat(table1);   
       write_cmd(0x90);                    //设定首次显示位置
   for(i=0;table2!='';i++)
   write_dat(table2);
       write_cmd(0x88);                    //设定首次显示位置
   for(i=0;table3!='';i++)
   write_dat(table3);
}




void main()
{


      BoardConfig(0xba);
      WDTCTL = WDTPW + WDTHOLD;
            clock_init();
      IO_init();
      lcd_init();             //初始化12864液晶
      UART_init();            //串口初始化
      TimerA_UART_init();    //定时器模拟串口初始化
      display_12864();
    while(1)
    {   
      Receive_data();
       RXD_data();
        //LPM3;
       TXD_Byte(R_DATA);
      Test();
    }
}


#pragma vector= TIMERA0_VECTOR
__interrupt void cc10int(void)
{
    CCR0 = CCR0 + TBIT1;  //重装下一位时间(当前时间+1位时间)
    if(CCIS0 & CCTL0)     //是处于接收中还是发送中?
    {
      if(CCTL0 & CAP)     //是捕获模式还是比较模式?
      {
        CCTL0 &=~CAP;     //是-开始捕获,将捕获功能改为比较功能
        CCR0   = CCR0 + TBIT_5; //开始捕获位再加半位时间
      }
      else
      {
        R_DATA = R_DATA>>1;    //处于比较功能,将前面的那位向低位移
        if(CCTL0 & SCCI)      //捕获/比较输入信号SCCI位是1还是0?
          R_DATA|=0x80;       //SCCI位是1,将第8位置1,否则第8位为0
        TR_COUNT--;           //计数器减1
        if(TR_COUNT == 0)     //是否接收完8位?
        {
          CCTL0 &= ~CCIE;     //是-接受完,捕获/比较停止中断允许
              LPM3_EXIT;        //退出低功耗模块
        }
      }
    }
                  //接收结束            
    /****************************/
    else                  //开始发送程序
    {
      if(TR_COUNT == 0)
        CCTL0 &= ~CCIE;   //关捕获/比较中断,发送接收
      else
      {
        if(T_DATA & 0x0001)  //状态寄存器C位是1,还是0?
          CCTL0 &= ~OUTMOD2;   //状态寄存器C位为1,发送1。
        else
          CCTL0 |=  OUTMOD2;  //状态寄存器C位为0,发送0。
        T_DATA = T_DATA>>1;   //将字节数据向右移一位
        --TR_COUNT;           //位计数器减1
      }
    }

}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
4条回答
愤怒的企鹅
1楼-- · 2019-07-16 00:43
 精彩回答 2  元偷偷看……
z00
2楼-- · 2019-07-16 04:28
看了一下你的程序 只有模拟的串口中断 并没有使用到430的串口中断
z00
3楼-- · 2019-07-16 07:02
可以看一下这篇文章

基​于​M​S​P​4​3​0​的​模​拟​串​口​通​讯​程​序​T​i​m​e​r​_​A​_​U​S​A​R​T

基于MSP430的模拟串口通讯程序Timer_A_USART.pdf (169.23 KB, 下载次数: 518)
lcc1
4楼-- · 2019-07-16 10:02
好好学习天天向上

一周热门 更多>