📄 main.c
字号:
/*
//*************************************************************************
//
// 串口输入输出控制器
//
// COPYRIGHT (c) 2005 BY 11
// -- ALL RIGHTS RESERVED --
//
// File Name: main.c
// Created: 2005.7.4
// Modified: 2005.7.5
// Revision: 1.0
//
//*************************************************************************
// 芯片类型 AT89S51
//*************************************************************************
*/
#include <at89x52.h>
#include <INTRINS.H>
void InitCom(void);
void ComOutChar(unsigned char OutData);
void PackCheck(void);
void SendErrMsg(void);
void SendCRCMsg(void);
void SendTeMsg(void);
void SendNSMsg(void);
void RunPack(void);
void CheckID(void);
void SendPack(void);
void Write(void);
void Read(void);
static unsigned char Pack[9]; //数据包数组
static unsigned char PN = 0; //接收指针
static unsigned char TN = 0; //超时标识
static unsigned char SN = 0;
unsigned char code SNID[] = {"SN0001"}; //固件的序列号
void main(void)
{
unsigned int a;
InitCom();
do
{
for (a=0; a<30000; a++)
P3_6 = 1;
for (a=0; a<30000; a++) //指示灯闪动
P3_6 = 0;
}
while(1);
}
//串口初始化 晶振为11.0592M 方式1 波特率57600
void InitCom(void)
{
SCON = 0x50; //串口方式1,允许接收
TMOD = 0x21; //定时器1定时方式2,定时0为模式1,16位模式
TCON = 0x40; //设定时器1开始计数
TH1 = 255; //设波特率为57600
TL1 = 255;
PCON = 0x80; //波特率加倍控制,SMOD位
RI = 0; //清收发标志
TI = 0;
TR1 = 1; //启动定时器
EA = 1; //开总中断
ES = 1; //开串口中断
}
//向串口输出一个字符(非中断方式)
void ComOutChar(unsigned char OutData)
{
SBUF = OutData; //输出字符
while(!TI); //空语句判断字符是否发完
TI = 0; //清TI
}
//串口接收中断
void ComInINT(void) interrupt 4
{
if (RI) //判断是不是收完字符
{
ET0 = 0; //开定时中断
TR0 = 0;
TN = 0; //接收超时变量清零
RI = 0; //RI清零
Pack[PN] = SBUF; //存数据
PN++; //指针加1
if (PN == 9)
{
PN = 0; //指针清零 一帧数据收完后
PackCheck(); //调用数据包检查
}
else
{
TH0 = 0x70; //设定时值,收到数据时设定时值
TL0 = 0x43;
ET0 = 1; //定时器中断0开
TR0 = 1; //启动定时器 定时器用于在一帧数据接收时如有丢包则返回错误信息12个0xEE
}
}
}
//定时器中断用于处理丢包
void Timer0(void) interrupt 1
{
if (TN>2) // 帧中的两字符间隔tn*40ms则为出错
{
ET0 = 0;
TR0 = 0; //关定时中断
SendTeMsg(); //发送超时错误信息
PN = 0; //pack指针清零
TN = 0;
}
else
TN++;
}
//信息包校验
void PackCheck(void)
{
unsigned char CRCL = 0, CRCH = 0; //CRC高低字节暂存
unsigned char TempCyc;
for (TempCyc=0; TempCyc<7; TempCyc++)
{
CRCL = CRCL + Pack[TempCyc]; //把信息包中的前十个相加
if (CY) //当CRCL大于0xFF时,CY为1
CRCH++; //CY为1时CRCH加1
}
if ((CRCL == Pack[8]) && (CRCH == Pack[7]))
RunPack(); //校验正确时执行包
else
SendCRCMsg(); //CRC校验不对时,这个包将不执行,并向PC发送CRC错误信息
}
//发送SN错误信息
void SendErrMsg(void)
{
ComOutChar(0x0A);
}
//发送命令完成
void SendOKMsg(void)
{
ComOutChar(0x0B);
}
//发送CRC错误
void SendCRCMsg(void)
{
ComOutChar(0x0C);
}
//发送超时错误
void SendTeMsg(void)
{
ComOutChar(0x0D);
}
//发送命令不支持错误
void SendNSMsg(void)
{
ComOutChar(0x0E);
}
//运行信息包
void RunPack(void)
{
switch(Pack[0])
{
case 1: CheckID(); break;
case 2: Write(); break;
case 3: Read(); break;
default: SendNSMsg(); //命令不支持
}
}
//校验序列号
void CheckID(void)
{
unsigned char TempCyc;
for (TempCyc=1; TempCyc<7; TempCyc++)
{
if (SNID[TempCyc-1]!=Pack[TempCyc])
{
TempCyc=7; //如有一个不对时跳出循环
SN = 0;
}
else
{
SN = 1;
}
}
if (SN)
SendOKMsg(); //返回OK
else
SendErrMsg(); //发送SN错误信息
}
//发送信息包
void SendPack(void)
{
unsigned char CRCL = 0, CRCH = 0; //CRC高低字节暂存
unsigned char TempCyc;
for (TempCyc=0; TempCyc<7; TempCyc++)
{
CRCL = CRCL + Pack[TempCyc]; //把信息包中的前十个相加
if (CY) //当CRCL大于0xFF时,CY为1
CRCH++; //CY为1时CRCH加1
}
Pack[7] = CRCH;
Pack[8] = CRCL; //计算要发送的信息包CRC
for (TempCyc=0; TempCyc<9; TempCyc++)
ComOutChar(Pack[TempCyc]); //发送错误信息包
}
//写命令的信息包处理
void Write(void)
{
if (SN)
{
switch(Pack[1]) //0为P0,1为P1,2为P2,3为关闭所有
{
case 0:
P0 = Pack[2];
SendOKMsg();
break;
case 1:
P1 = Pack[2];
SendOKMsg();
break;
case 2:
P2 = Pack[2];
SendOKMsg();
break;
case 3:
P0 = 0xFF;
P1 = 0xFF;
P2 = 0xFF;
SendOKMsg();
break;
case 4:
P0 = 0x00;
P1 = 0x00;
P2 = 0x00;
SendOKMsg();
break;
default: SendNSMsg();
}
}
else
{
SendErrMsg();
}
}
//跟据相应的芯片类型去读芯片
void Read(void)
{
if (SN)
{
switch(Pack[1]) //0为P0,1为P1,2为P2,3为返回全部
{
case 0:
Pack[1] = P0;
Pack[2] = 0;
Pack[3] = 0;
SendPack();
break;
case 1:
Pack[1] = 0;
Pack[2] = P1;
Pack[3] = 0;
SendPack();
break;
case 2:
Pack[1] = 0;
Pack[2] = 0;
Pack[3] = P2;
SendPack();
break;
case 3:
Pack[1] = P0;
Pack[2] = P1;
Pack[3] = P2;
SendPack();
break;
default: SendNSMsg();
}
}
else
{
SendErrMsg();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -