/***********************************************
软件模拟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();
}