?? 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 + -