发表于:2012/12/8 8:39:26
#0楼
用C写了个扫描与串口通讯的程序,但单片机收取的数据不全
请教
程序主要部分如下:(怕看晕头了:))
#include<STC12C5A60S2.H>
sbit P12=P2^0; //0 //作为0线的检查 并且是按钮控制的点,数组的输出意义不同了
sbit P00=P0^0; //1线,以下类同
sbit P01=P0^1;
sbit P02=P0^2;
sbit P03=P0^3;
sbit P04=P0^4;
sbit P05=P0^5;
sbit P06=P0^6;
sbit P07=P0^7; //相对于8号线
sbit key1=P2^2; //作为长度控制 按钮点
sbit key2=P2^4; //到了起风的时间或某个指定的位置,低电平时,必须要,就是一个外部再检查.
sbit ctrl1=P2^1; //作为风机继电器控制点,
sbit ctrl2=P2^3; //作为炉门继电器控制点,关门不再另外控制而在外部加延时
sbit ctrl3=P2^5; //变频器电阻开关
sbit ctrl4=P2^7; //变频器电阻开关
unsigned char SentNo; //记录准备发送的数据
unsigned long int CheckNo; //发送信号后已几次了?
unsigned char GetNo1; //记录收到的第一个数
unsigned char GetNo2; //记录收到的第二个数
unsigned char GetNo3; //记录收到的第三个数
unsigned char GetAllNo; //总的收到的数量
unsigned char isok; //检查是否正确
unsigned char iskey2; //key2是否扫描到
unsigned long int longtime; //时间中断次数
unsigned long int nowtime; //时间中断次数
unsigned long int firsttime; //接到第一次收数中断时间
//声明函数
//void initcom(); //串口初始化子程序
void contral(); //控制继电器
void checkdata(); //检查收到的数据是否正常
void otherscan(); //其它扫描
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
void initcom() //串口一的通讯初始化处理
{本部分测试没有问题 }
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
void t0() interrupt 1 // 1:定时中断0
{
longtime++; //记录中断次数加1 '长整形,可以一年不关机了都够用了
}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
//测试时间 89C5211.0592M一个子延时的时长
//经过50X5000次=1955S循环测试, 本子程序为7.82ms
// 长延时
void delay(unsigned int i)
{.....}
// 短延时 按上面的测试 约 78US
void shortdelay(unsigned int i)
{.......}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
void send(unsigned char ch) //串口1发送数据子程序,一个一个字符地发送
{
ES=0; //禁止串口再中断
SBUF=ch; //将数据发送到串口中,等发送
while(!TI); //等待发送完成
TI=0; //发送完成标志
}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
int panduan() //判断各指定管脚电平的子程序
{
SentNo=100;
本部分也测试了没有问题
.......}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
int MyCheckAndSend() //检查是否有信号发送到PC机
{
.......本部分 }
}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
main() //主程序,
{
//T0初始化
P0=0xff;
P2=0xff; //未知何解会低电平,或者讲接通
TH0=0;
TL0=0;
TMOD=0x21; //T0 16位自动重装方式
initcom(); //串口初始化
delay(100); //约3秒 ,只是觉得,未必有意义
CheckNo=100; //初始化处理
while(1) //这里有与没有;的差别很大 有后面的都不再执行,
{
MyCheckAndSend(); //检查是否有必要发送数据到PC机
//扫描是否有其它的脱钩信号 ,有入炉信号时,必须打开炉门及变频吹风
otherscan();
//无此信号才会查通讯口的信号
if(iskey2 ==0)
{
//不能用时间等呀!要不断检查才行的
if(GetAllNo>=3)
{
checkdata(); //检查获取的串口数据
if(isok) //数据正确的话
{contral();} //检查收到的数字正确,则进行控制
}
}
}
}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
void inter() interrupt 4 //0外部中断0 1:定时中断0 2:外部中断1 3:定时中断1
//4:串口中断1 8:串口中断2
{
if(RI) //是一个接收中断
{
ES=0; //关闭中断
//用时间来判断是否为同一次的要收的数
if(GetAllNo==0) //是否已对本次数据进行了记录
{firsttime=longtime;} //记录第一次收到的时间
nowtime=longtime; //记录当前的时间
if (nowtime-firsttime>2) //超过两个周期就不可能是同一批的数据
{ firsttime=longtime;
GetAllNo=0;
}
else
{ if(nowtime<=2){firsttime=longtime;GetAllNo=0;}} //刚转为2周期之内的也一样有效
GetAllNo++; //同一批次的收数次数加一
if(GetAllNo==1)
{GetNo1=SBUF;}
if(GetAllNo==2)
{GetNo2=SBUF;}
if(GetAllNo==3)
{GetNo3=SBUF;}
RI=0; //必须程序清空标志
ES=1; //重开中断
}
}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
void checkdata() //检查收到的数据是否正常
{
isok=0; //预设为不通过
if (GetAllNo==3) //要确定本次收到的是三个数
{
if(GetNo1==0x55) //第一个数必须为此数
{
//if (GetNo3==GetNo1+GetNo2) //符合加和规则
if (GetNo3==0xdd) //符合头尾规则
{ isok=1; //表示收到的数据合理
GetAllNo=0; //收到的个数置0回原
}
}
}
}
请教
程序主要部分如下:(怕看晕头了:))
#include<STC12C5A60S2.H>
sbit P12=P2^0; //0 //作为0线的检查 并且是按钮控制的点,数组的输出意义不同了
sbit P00=P0^0; //1线,以下类同
sbit P01=P0^1;
sbit P02=P0^2;
sbit P03=P0^3;
sbit P04=P0^4;
sbit P05=P0^5;
sbit P06=P0^6;
sbit P07=P0^7; //相对于8号线
sbit key1=P2^2; //作为长度控制 按钮点
sbit key2=P2^4; //到了起风的时间或某个指定的位置,低电平时,必须要,就是一个外部再检查.
sbit ctrl1=P2^1; //作为风机继电器控制点,
sbit ctrl2=P2^3; //作为炉门继电器控制点,关门不再另外控制而在外部加延时
sbit ctrl3=P2^5; //变频器电阻开关
sbit ctrl4=P2^7; //变频器电阻开关
unsigned char SentNo; //记录准备发送的数据
unsigned long int CheckNo; //发送信号后已几次了?
unsigned char GetNo1; //记录收到的第一个数
unsigned char GetNo2; //记录收到的第二个数
unsigned char GetNo3; //记录收到的第三个数
unsigned char GetAllNo; //总的收到的数量
unsigned char isok; //检查是否正确
unsigned char iskey2; //key2是否扫描到
unsigned long int longtime; //时间中断次数
unsigned long int nowtime; //时间中断次数
unsigned long int firsttime; //接到第一次收数中断时间
//声明函数
//void initcom(); //串口初始化子程序
void contral(); //控制继电器
void checkdata(); //检查收到的数据是否正常
void otherscan(); //其它扫描
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
void initcom() //串口一的通讯初始化处理
{本部分测试没有问题 }
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
void t0() interrupt 1 // 1:定时中断0
{
longtime++; //记录中断次数加1 '长整形,可以一年不关机了都够用了
}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
//测试时间 89C5211.0592M一个子延时的时长
//经过50X5000次=1955S循环测试, 本子程序为7.82ms
// 长延时
void delay(unsigned int i)
{.....}
// 短延时 按上面的测试 约 78US
void shortdelay(unsigned int i)
{.......}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
void send(unsigned char ch) //串口1发送数据子程序,一个一个字符地发送
{
ES=0; //禁止串口再中断
SBUF=ch; //将数据发送到串口中,等发送
while(!TI); //等待发送完成
TI=0; //发送完成标志
}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
int panduan() //判断各指定管脚电平的子程序
{
SentNo=100;
本部分也测试了没有问题
.......}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
int MyCheckAndSend() //检查是否有信号发送到PC机
{
.......本部分 }
}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
main() //主程序,
{
//T0初始化
P0=0xff;
P2=0xff; //未知何解会低电平,或者讲接通
TH0=0;
TL0=0;
TMOD=0x21; //T0 16位自动重装方式
initcom(); //串口初始化
delay(100); //约3秒 ,只是觉得,未必有意义
CheckNo=100; //初始化处理
while(1) //这里有与没有;的差别很大 有后面的都不再执行,
{
MyCheckAndSend(); //检查是否有必要发送数据到PC机
//扫描是否有其它的脱钩信号 ,有入炉信号时,必须打开炉门及变频吹风
otherscan();
//无此信号才会查通讯口的信号
if(iskey2 ==0)
{
//不能用时间等呀!要不断检查才行的
if(GetAllNo>=3)
{
checkdata(); //检查获取的串口数据
if(isok) //数据正确的话
{contral();} //检查收到的数字正确,则进行控制
}
}
}
}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
void inter() interrupt 4 //0外部中断0 1:定时中断0 2:外部中断1 3:定时中断1
//4:串口中断1 8:串口中断2
{
if(RI) //是一个接收中断
{
ES=0; //关闭中断
//用时间来判断是否为同一次的要收的数
if(GetAllNo==0) //是否已对本次数据进行了记录
{firsttime=longtime;} //记录第一次收到的时间
nowtime=longtime; //记录当前的时间
if (nowtime-firsttime>2) //超过两个周期就不可能是同一批的数据
{ firsttime=longtime;
GetAllNo=0;
}
else
{ if(nowtime<=2){firsttime=longtime;GetAllNo=0;}} //刚转为2周期之内的也一样有效
GetAllNo++; //同一批次的收数次数加一
if(GetAllNo==1)
{GetNo1=SBUF;}
if(GetAllNo==2)
{GetNo2=SBUF;}
if(GetAllNo==3)
{GetNo3=SBUF;}
RI=0; //必须程序清空标志
ES=1; //重开中断
}
}
/////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////
void checkdata() //检查收到的数据是否正常
{
isok=0; //预设为不通过
if (GetAllNo==3) //要确定本次收到的是三个数
{
if(GetNo1==0x55) //第一个数必须为此数
{
//if (GetNo3==GetNo1+GetNo2) //符合加和规则
if (GetNo3==0xdd) //符合头尾规则
{ isok=1; //表示收到的数据合理
GetAllNo=0; //收到的个数置0回原
}
}
}
}