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

📄 autouart.c

📁 用MSP430(C)写的红外抄表程序,是初学者好代码
💻 C
字号:
#include <msp430x14x.h>

//定义串口操作变量
// 串口 1 的接收标志
char nRev_UART1;			
// 串口 1 的发送缓冲区
char UART1_TX_BUF[60];	
// 串口 1 的接收缓冲区	
char UART1_RX_BUF[60];		
int nTX1_Len;
char nRX1_Len;
char nRX1_Len_temp;
char nTX1_Flag;
char nTime_Flag;
int nSend_TX1;
char GetChar(void);

typedef enum  
{ BAUD115200, BAUD57600,BAUD38400, BAUD19200,
  BAUD14400,  BAUD9600, BAUD4800,  BAUD2400, 
  BAUD1200       
} baudrates;

typedef struct {
  char ubr00;
  char ubr01;
  char umctl0;
  char *desc;
} baudreg;

// 串口寄存器的值 (UBR0_1, UBR1_1, UMCTL_1, Descr)
const baudreg baudregs[] =
{
    0x45, 0x00, 0x00, "115200",    // BAUD115K
    0x8b, 0x00, 0x00, "57600",     // BAUD57600
    0xd0, 0x00, 0x00, "38400",     // BAUD38400
    0xa0, 0x01, 0x00, "19200",     // BAUD19200
    0x2c, 0x02, 0x00, "14400",     // BAUD14400
    0x41, 0x03, 0x00, "9600",      // BAUD9600
    0x83, 0x06, 0x00, "4800",      // BAUD4800
    0x05, 0x0d, 0x00, "2400",      // BAUD2400
    0x0b, 0x1a, 0x00, "1200"       // BAUD1200
};

void SetBaud(int baud);
void Delay_8_33ms(void);
void Init_UART1(void);
void Init_CLK(void);
void Init_TimerA(void);

void Init_UART1(void)
{
	//将寄存器的内容清零
    U1CTL = 0X00;	
	//数据位为8bit
    U1CTL += CHAR;			
    
	//将寄存器的内容清零
    U1TCTL = 0X00;	
	//波特率发生器选择SMCLK
    U1TCTL += SSEL1;			    
	//波特率为115200
    UBR0_1 = 0X45;			
    UBR1_1 = 0X00;
	//调整寄存器
    UMCTL_1 = 0X00;			

	//使能UART1的TXD和RXD
    ME2 |= UTXE1 + URXE1; 
	//使能UART1的RX中断
    IE2 |= URXIE1;	
	//使能UART1的TX中断
    IE2 |= UTXIE1;			
    
	//设置P3.6为UART1的TXD
    P3SEL |= BIT6;	
	//设置P3.7为UART1的RXD
    P3SEL |= BIT7;			    
	//P3.6为输出管脚
    P3DIR |= BIT6;			
    return;
}
void Init_Port(void)
{
    //将所有的管脚在初始化的时候设置为输入方式
    P3DIR = 0;
    //将所有的管脚设置为一般I/O口
    P3SEL = 0;
    return;
}
// 初始定时器模块
void Init_TimerA(void)
{
	// 选择SMCLK,清除TAR
    TACTL = TASSEL1 + TACLR;  
	// 1/8 SMCLK
    TACTL += ID1;
    TACTL += ID0; 
	// CCR0 中断允许
    CCTL0 = CCIE;
	// 时间间隔为 33.8ms
    CCR0 = 33800;
	// 增记数模式
    TACTL |= MC0;			    
}
void Init_CLK(void)
{
    unsigned int i;
	//将寄存器的内容清零
	//XT2震荡器开启
	//LFTX1工作在低频模式
	//ACLK的分频因子为1
    BCSCTL1 = 0X00;	
					
    do 
    {
	IFG1 &= ~OFIFG;                       // 清除OSCFault标志
	for (i = 0x20; i > 0; i--);                
    }
    while ((IFG1 & OFIFG) == OFIFG);      // 如果OSCFault =1   
					
    BCSCTL2 = 0X00;			//将寄存器的内容清零
    BCSCTL2 += SELM1;		//MCLK的时钟源为TX2CLK,分频因子为1
    BCSCTL2 += SELS;		//SMCLK的时钟源为TX2CLK,分频因子为1
}
///////////////////////////////////////
// 处理来自串口 1 的接收中断
interrupt [UART1RX_VECTOR] void UART1_RX_ISR(void)
{
    //接收来自的数据 
    UART1_RX_BUF[nRX1_Len_temp] = RXBUF1;	
    nRX1_Len_temp += 1;        
    if(UART1_RX_BUF[nRX1_Len_temp - 1] == 13)
    {
    	nRX1_Len = nRX1_Len_temp;
    	nRev_UART1 = 1;
    	nRX1_Len_temp = 0;
    }
}
///////////////////////////////////////
// 处理来自串口 1 的发送中断
interrupt [UART1TX_VECTOR] void UART1_TX_ISR(void)
{
    if(nTX1_Len != 0)
    {
		// 表示缓冲区里的数据没有发送完
    	nTX1_Flag = 0;			    	
    	TXBUF1 = UART1_TX_BUF[nSend_TX1];
    	nSend_TX1 += 1;    	
    	if(nSend_TX1 >= nTX1_Len)
    	{
    	    nSend_TX1 = 0;
    	    nTX1_Len = 0;
    	    nTX1_Flag = 1;
    	}
    }
}
// 定时器中断
interrupt [TIMERA0_VECTOR] void TimerA_ISR(void)
{
    nTime_Flag = 1;
	// CCR0 不中断允许
    CCTL0 &= ~CCIE;
}
void SetBaud(int baud)
{
	//停止UART
	U1CTL |= SWRST;
	//禁止中断
	ME2 &= ~(UTXE0 + URXE0); 

	//设置寄存器
	UBR0_1 = baudregs[baud].ubr00;
	UBR1_1 = baudregs[baud].ubr01;
	UMCTL_1 = baudregs[baud].umctl0;
	//使能中断
	ME2 |= UTXE0 + URXE0;
	//UART模块允许
	U1CTL &= ~SWRST;
}
int AutoBaud(void)
{
	baudrates rate;

	//UART复位
	U1CTL |= SWRST;
	//接收出错中断允许位
	URCTL1 = URXEIE; 
	//UART模块允许
	U1CTL &= ~SWRST; 
	//设置速率位115200
	SetBaud(BAUD115200);
	//接收字符
	switch (GetChar()) 
	{
	case 0x0d :
		rate = BAUD115200;
		break;
	case 0xe6 :
		rate = BAUD57600;
		break;
	case 0x1c :
		rate = BAUD38400;
		break;
	case 0xe0 :
		rate = BAUD19200;
		break;
	case 0x80 :
		rate = BAUD14400;
		break;
	case 0x00 :
	{
		// CCR0 中断允许
        CCTL0 = CCIE;
		//延时33.8ms
		while(1)
		{
			if(nTime_Flag == 1)
			{
				nTime_Flag = 0;
				break;
			}
		}
		//设置速率位9600
		SetBaud(BAUD9600);
		//接收字符
		switch (GetChar())  
		{
		case 0x0d : 
			rate = BAUD9600;
			break;
		case 0xe6 :
			rate = BAUD4800;
			break;
		case 0x78 :
			rate = BAUD2400;
			break;
		case 0x80 :
			rate = BAUD1200;
			break;
		default :
			return -1;
		}
		break;
	}
	default :
		return -1;
	}

	// CCR0 中断允许
    CCTL0 = CCIE;
	//延时33.8ms
	while(1)
	{
		if(nTime_Flag == 1)
		{
			nTime_Flag = 0;
			break;
		}
	}
	SetBaud(rate);
	return 0;
}
char GetChar(void)
{
  while (!(IFG2 & URXIFG1));
  return RXBUF1;
}

⌨️ 快捷键说明

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