中国自动化学会专家咨询工作委员会指定宣传媒体
免费注册 登录 广告服务 | 客服中心
您现在所在的是:

单片机论坛

抖音 德嘉 泓格论坛 FLIR红外热像论坛
工控论坛首页 单片机论坛 → 浏览主题: 初学C写的串口通讯有问题请教
发表新帖 回复该主题
回帖:2个,阅读:528 [上一页] [1] [下一页]
* 帖子主题:

初学C写的串口通讯有问题请教

分享到
1000
sunsoncheng
文章数:109
年度积分:50
历史总积分:1000
注册时间:2010/5/25
发站内信
发表于: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回原
}
  }
}
 }

1000
sunsoncheng
文章数:109
年度积分:50
历史总积分:1000
注册时间:2010/5/25
发站内信
发表于:2012/12/8 11:57:30
#1楼
看到网上有一些接收多个数的程序,抄来后,发现,要是有人(机器出问题了)变成发了与原来约定不同的位数时

就会出错

所以想有一个时间处理,限定了每两个响应的时间,从而可以确定是否是同一批次来的第一个
646
tim4146
文章数:9
年度积分:50
历史总积分:646
注册时间:2013/1/22
发站内信
发表于:2013/1/25 20:55:38
#2楼
楼主,程序有点长,我没细看,只想提醒一下,用的串口线最好买好一点的,普通的容易出问题。
工控学堂推荐视频:

关于我们 | 联系我们 | 广告服务 | 本站动态 | 友情链接 | 法律声明 | 非法和不良信息举报

工控网客服热线:0755-86369299
版权所有 工控网 Copyright©2024 Gkong.com, All Rights Reserved

62.4004