📄 main.c
字号:
//#include "msp430x41x.h"//"msp430xE42x.h"
#define uchar unsigned char
#define uint unsigned int
#include "msp430xE42x.h"
#include "LCD.h"
#define ENABLE BIT0
#define UTXD BIT4
#define URXD BIT5
#define Num 64
uchar ss[10]={char_0,char_1,char_2,char_3,char_4,char_5,char_6,char_7,char_8,char_9};
uint r0 = 0,s0 = 0,rr0 = 0,aa = 0;
uchar RXFLG = 0,TXFLG = 0,CS = 0x00,SS = 0x00,ACC,CY = 1,Command_Status1 = 0x00;
uchar r_buf[Num],s_buf[Num],a[Num];
/*******************************************************************************
Rec_Judge()
接受数据的判断函数 判断是否符合645协议 并验证效验码
*******************************************************************************/
uchar Rec_Judge(uchar *s)
{
uchar i,j,k;
if((*s != 0x68) && (*(s+7) != 0x68))
return 0;
else
{
for(i=1;i<7;i++)
{
if(*(s+i) > 0x99)
return 0;
}
}
if(*(s+9) > (Num-12))
return 0;
for(k=0;k<(*(s+9)+10);k++)
{
CS += *(s+k);
}
for(j=0;j<*(s+9);j++)
{
*(s+10+j) -= 0x33;
}
if(CS != *(s+(*(s+9)+10)))
return 0;
if(*(s+(*(s+9)+11)) != 0x16)
return 0;
else
return 1;
}
/*******************************************************************************
Send_Set()
数据发送的准备函数 把所发送的数据存到s_buf[N]数组中,完成后关节后关闭接受中断,
打开发送中断
*******************************************************************************/
void Send_Set(uchar *s)
{
uint ii,jj,kk;
for(ii=0;ii<4;ii++) //前导字节
{
s_buf[ii] = 0xFE;
aa += 1;
}
for(jj=0;jj<10;jj++) //帧起始符到数据长度
{
s_buf[4+jj] = *(s+jj);
aa += 1;
SS += s_buf[4+jj];
}
for(kk=0;kk<*(s+9);kk++) // 数据域的处理和准备
{
s_buf[14+kk] = (*(s+10+kk) + 0x33);
aa += 1;
SS += s_buf[14+kk];
}
aa ++;
s_buf[(14+s_buf[13])] = SS; //效验码的计算结果
aa ++;
s_buf[(15+s_buf[13])] = 0x16; //帧结束符
P2OUT |= ENABLE;
P2OUT |= URXD;
IE1 &= ~URXIE0; //关接受中断
IE1 |= UTXIE0; //开发送中断
CY = 1;
}
/*******************************************************************************
delay()
延时函数
*******************************************************************************/
void delay(uint n)
{
while(n -->0);
}
/*******************************************************************************
Serial_Address()
通讯地址判断函数
*******************************************************************************/
uchar Serial_Address(uchar *s1)
{
uchar i,a[6];
for(i=0;i<=5;i++)
{
if((*(s_buf+i)) != 0x99) //不是广播地址
break;
if(i==5)
return(0x01);
}
for(i=0;i<=5;i++)
{
if((*(s1+i)) != a[i])
return(0x00); //地址不相同
}
return(0x02);
}
/*******************************************************************************
Serial_Password()
通讯密码判断函数
*******************************************************************************/
char Serial_Password(uchar *s1)
{
uchar i,a[4];
for(i=0;i<=3;i++)
{
if((*(s1+i)) != a[i])
return 0;
}
return 1;
}
/*******************************************************************************
Serial_Command_Run()
通讯执行函数
*******************************************************************************/
char Serial_Command_Run(uchar *s)
{
switch(Serial_Address(s)) //判断地址是否正确
{
case 0x02: //广播地址999999999999H
break;
case 0x01:
switch(*(s_buf+6)) //正常地址
{
case 0x0f: //进行密码修改
if(~Serial_Password(s+8))
return 0;
delay(5);
(*(s+6)) |= 0x80;
(*(s+7)) = 0x04;
Send_Set(s); //*存取新密码
break;
case 0x02:
break;
case 0x04:
break;
default:
break;
}
break;
case 0x00:
return 0;
}
return 1;
}
/*******************************************************************************
Serial_Command()
通讯主函数
*******************************************************************************/
void Serial_Command()
{
if(RXFLG) // 准备发送数据
{
RXFLG = 0;
TXFLG = Rec_Judge(r_buf);
if(TXFLG)
{
TXFLG = 0;
CS = 0x00;
Command_Status1 |= 0x04;
if(CY == 1)
{
Send_Set(r_buf);
}
}
}
if(Command_Status1 & 0x04) //通讯事件发送
{
if(~Serial_Command_Run(s_buf)) //帧执行
{
Command_Status1 &= 0xfb; //帧错误,恢复信道功
return;
}
Command_Status1 &= 0xfb; //清除通讯处理事件
}
}
/*******************************************************************************
Init_USART0()
串口初始化函数
*******************************************************************************/
void Init_USART0(void)
{
U0CTL |= (SWRST + PENA + PEV + CHAR); //选择偶校验,8位传送
U0TCTL |= SSEL0; //选择ACLK
ME1 |= (URXE0 + UTXE0); //使能UART0的URXD和UTXD
P2SEL |= URXD + UTXD +ENABLE; //设置P2.5为URXD,P2.4为UTXD,P2.0为使能端
P2DIR |= UTXD + ENABLE; //UTXD和ENABLE置输出
U0BR0 = 0x1B; //波特率1200bps
U0BR1 = 0x00;
U0MCTL = 0x03;
TXBUF0 = 0x00;
U0CTL &= ~SWRST;
P2OUT &= ~ENABLE;
IE1 |= URXIE0; //打开UART0的RX中断
return;
}
/*******************************************************************************
main()
主函数
*******************************************************************************/
void main(void)
{
uchar i;
WDTCTL = WDTPW + WDTHOLD; //关看门狗
_DINT(); //关总中断
BTCTL = BTHOLD + BTFRFQ1;
LCDCTL = LCDON + LCD4MUX + LCDSG0_3;
U0IFG &= ~URXIFG0; //复位操作
U0IFG &= ~UTXIFG0;
U0CTL = 0X00;
U0TCTL = 0X00;
for(i = 0;i < 12;i ++)
{
LCDMEM[i] = 0x00;
}
Init_USART0();
_EINT(); //开总中断
while(1)
{
Serial_Command();
}
}
/*******************************************************************************
usart0_rx()
接受中断函数
*******************************************************************************/
uchar Lead_Flag = 0; //前导字节接受标志
uchar Begin_Flag = 0;//开始接收数据帧的标志
#pragma vector=UART0RX_VECTOR
__interrupt void usart0_rx(void)
{
IFG1 &= ~URXIFG0;
if(RXBUF0 == 0xfe)
{
Lead_Flag ++;
}
if((RXBUF0 != 0xfe) && (Lead_Flag > 3))
{
Begin_Flag = 1;
}
if(Begin_Flag)
{
r_buf[r0 ++] = RXBUF0;
if(r0 >= 10)
{
ACC = r_buf[9];
r_buf[9+rr0] = RXBUF0;
rr0 ++;
if(rr0>(ACC+2))
{
r0 = 0;
rr0 = 0;
ACC = 0;
RXFLG = 1;
Lead_Flag = 0;
Begin_Flag = 0;
}
}
}
}
/*******************************************************************************
usart_tx()
发送中断函数
*******************************************************************************/
#pragma vector=UART0TX_VECTOR
__interrupt void usart0_tx(void)
{
IFG1 &= ~UTXIFG0; //清零
TXBUF0 = s_buf[s0++]; //发送数据到缓冲寄存器
if(s0 >= aa) //发送接受的标志
{
s0 = 0;
aa = 0;
SS = 0;
P2OUT &= ~ENABLE; //恢复485使能端置低
IE1 &= ~UTXIE0; //关闭发送中断
IE1 |= URXIE0; //打开接受中断
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -