⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart_send.c

📁 基于msp430的软件模拟串口发送程序(在MSP430F147型单片机上成功实现)
💻 C
字号:
/***********************************************
软件模拟msp430串口,发送端
硬件资源:Timer_A,CCR0,UP Mode
时钟选择:MCLK=4.9MHz, ACLK32768Hz
数据发送端口:p3.7
发送数据帧:开始位(1b)+数据位(8b)+ 停止位(1b)
时间:2006.12.7
作者:BackerShu
*************************************************/
#include <msp430x14x.h>

typedef  unsigned char uchar;
typedef  unsigned int  uint;


void InitSys();
void SetClock();
void Delay(int i);
void SetBuff();

uint bitTime=64;//每一位数据时间

uint sendData[8]={0x55,0x55,0x12,0x34,0x56,0x78,0x55,0x55};
uint sendBuff;//发送数据缓冲区,10位
uchar bitCnt=0;//正在发送的数据位标志
uchar i=0;//正在发送的数据的字节号
uchar stopFlag=0;//发送结束标志

void main(void)
{
  InitSys();
  while(1)
  {
    //P1OUT |= BIT4;//红灯亮
    if(i<8)SetBuff();//设置发送缓冲区
    while(!stopFlag);
    stopFlag = 0;//一字节数据发送完成标志清零
   
    if(i==8)//8字节数据发送结束,绿灯亮一次
    {
      /*uint j = 512;
      for(;j>0;j--)
      {
        P1OUT |= BIT5;//绿灯亮
      }
        P1OUT &= ~BIT5;//绿灯灭*/
        P1OUT |= BIT5;//绿灯亮
        //i=0;//i清零,实现循环发送
        CCTL0 &= ~CCIE;//发送完八字节后关中断,复位后重新再发
    }
    
    //_BIS_SR(LPM0_bits + GIE);//不发送数据时,处于低功耗状态
  }
  
}
/*************中断服务程序*****************************/
#pragma  vector=TIMERA0_VECTOR
__interrupt void TA0_ISR(void)
{
   TACTL &= ~TACLR;//TAR清零,保证下一次来中断间隔时间正确
   if(bitCnt<9)//发送数据
   {
    // P3OUT = sendBuff<<1;
     if(sendBuff&0x01) P3OUT |= 0x80;//发送数据1
     else   P3OUT &= 0x7f;//发送数据0
     sendBuff>>=1;
   }
   else
   {
    // TACTL &= ~MC_1;//停止定时器工作,也可以通过关中断来实现
     CCTL0 &= ~CCIE;
     P3OUT |= BIT7;//发送口置高,准备下一位数据的发送
     stopFlag = 1;//一字节数据发送完成标志,在主程序中置位
     i++;//已经发送数据的字节数
    // bitCnt = 0;//数据位标志清零
   }
    bitCnt++;   //数据为标志加1,下次进中断发送下一位
}


/************子函数***********************/
//系统初始化
void InitSys()
{
            WDTCTL = WDTPW+WDTHOLD ;//关闭看门狗
            volatile unsigned int m;
            for (m=0; m<2000; m++)                   // Delay for crystal stabilization
            {
            }
            SetClock();//设置时钟 
                       
            DCOCTL |= DCO0 + DCO1 + DCO2 ;
            BCSCTL1 |= RSEL0 + RSEL1 + RSEL2;//设置DCO为4.9MHz
            
            TACTL = TASSEL_1 + MC_1 + TACLR;//选择Timer_A的时钟为ACLK,UP mode 计数,并清除TAR
            TACCR0 = bitTime;//隔一个数据位的时间进一次中断
            CCTL0 = CCIE;
          //  P1SEL = 0x02;                            // Set P1.1 to TA0,P1.1 是TA0 捕获比较模式的外部输入口  
           // CCTL0 = CM_2 + SCS + CCIS_0 + CAP + CCIE; // falling edge + CCI0A (P1.1)
                                                     // + Capture Mode + Interrupt
            //CCTL0 |=SCS + CCIS_0;   //CCI0A (P1.1)+Compare Mode 
            
            P2DIR = 0x01;                             // P2.0-ACLK
            P2SEL |= 0x01;                            //从P2.0脚输出晶振的波形
            
            
            P3DIR |= BIT7;//P3.7口作为发送数据的出口,初始化为低电平
            P3OUT |= BIT7;//不发送数据时,p3.7保持为高电平
            
            P1DIR = 0x30;    //将p1.4和p1.5置为输出
            P1OUT &= ~0x20;    //绿灯灭
            P1OUT |= BIT4;//红灯亮
            //_EINT();
                   
}

//选择时钟,LF1XT工作在低频状态
void SetClock()
{
     volatile unsigned int j;
      while(IFG1 & OFIFG) //上电后,寄存器IFG1的初值为0x82
      {
         IFG1 &= ~OFIFG;
         for (j=0xff;j>0;j--);
      }

}

//设置发送缓冲区
void SetBuff()
{
  bitCnt = 0;//数据位标志清零
  sendBuff = sendData[i];
  sendBuff <<=1;
  sendBuff |= 0x200;
  
  /*sendBuff = 0x200;//加上开始位和停止位
                   //430的编译器不支持位操作,涉及到位操作的尽量用其他方式代替
  sendData[i]<<=1;//
  sendBuff |= sendData[i];//组成要发送的帧*/
  stopFlag = 0;//清发送结束标志
  TACTL |= MC_1;//UP Mode
  CCTL0 |= CCIE;//开中断,开始比较模式发送数据
  _EINT();
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -