打印

单片机的控制程序

[复制链接]
2159|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
zhbwgh|  楼主 | 2007-5-29 15:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
#include "W78E354.H"
#define COUNT 4  //定义接收缓冲区的大小//
#define uchar unsigned char
/*数据采集部分管脚定义*/
sbit RO=P2^0;//格雷码输入//
sbit RED=P2^1;//允许格雷码输入,低电平有效//
sbit DE=P2^2;//时钟输出允许,高电平有效//
sbit CLOCK=P2^3;//时钟输出//
/*串口输出部分管脚定义*/
sbit RE_DE=P1^4;//485控制引脚//
sbit Key_3=P0^4;
sbit Key_4=P0^5;
sbit ALARM=P0^3;
/*7219管脚定义*/
sbit LOAD = P0^2; //MAX7219    Load-Data Input:  
sbit DIN  = P0^0; //MAX7219    Serial-Data Input:     
sbit CLK  = P0^1; //MAX7219   Serial-Clock Input: 
uchar bstop=0;/*结束泵工作的标志*/
uchar fstop=0;/*结束阀工作的标志*/
uchar key=0;
uchar key1=0;/*7219寄存器的标志设置*/
uchar idata displ[COUNT]={3,6,8};/*定义发送缓冲区*/
void COM_inter(void);/*声明函数变量*/
void manage_key1(void);
void manage_key2(void);
void Timer_ini(void);
void judge_key(void);
void collect(void);
main()

  CLOCK=1;
  RED=0;/*接收器允许*/
  DE=1;/*发送器允许*/
  Key_3=0;/*泵,阀初始化*/
  Key_4=0;
  RE_DE=0;/*485准备接收*/
  Timer_ini();
  while(1)
  { 
    collect();
    judge_key();
  }
}

void Timer_ini(void) //定时器的初始化//
{
  TMOD=0x20;/*定时器0工作于方式2,定时器1工作于方式2, 0010 0010*/   
  TH1=0xb7;//实现数据传输率9600//
  TL1=0xb7;
  SCON=0x50;//选择串口工作方式1,打开接收允许//
  PCON=0x00;//波特率倍增设置//
  TR1=1;//启动定时器T1//
  ES=1;EA=1;//允许串口中断//
}

//--------------------------------------------------------
//函数名称:COM_send();串口发送函数
//函数功能:把数据缓冲区的4位数据发送出去
//--------------------------------------------------------
void COM_send(void)
{
  uchar point;
  for(point=0;point<COUNT;point++) //连续发送4位数据,将数据发送到缓冲口//
  {  
     SBUF=displ[point];//发送数据//
       while(TI!=1);
     TI=0;
  }
  ES=1;
}
//-----------------------------------------------
//函数名称:manage_key3()
//函数功能:按键3处理子程序
//-----------------------------------------------
void manage_key3(void)
{
 bstop++;
 if(bstop<=1)
 { 
   Key_3=1;/*使外部泵开始工作*/
 }
 else
 {
  Key_3=0;/*结束泵工作*/
  bstop=0;/*标注清零*/
 } 


}
//-----------------------------------------------
//函数名称:manage_key4()
//函数功能:按键4处理子程序
//-----------------------------------------------
void manage_key4(void)
{
 fstop++;/**/
 if(fstop<=1)
 {
  Key_4=1;/*使外部阀开始工作*/
 }
 else
 {
  Key_4=0;/*结束外部阀开始工作*/
  fstop=0;/*标注清零*/
 }
}

//--------------------------------------------------------
//函数名称:com_interrup()串口接收中断处理函数
//函数功能:接收包括起始位0xFE,地址位和终止位0xEF在内的10bit数据到数据缓冲区
//         ,地址不匹配,则接收到的是无效数字,不写到接收缓冲区
//--------------------------------------------------------
void COM_inter(void) interrupt 4 using 1//串口处理函数//

  uchar a;/*串口标志*/
  RI=0;
  RE_DE=0;
  a=SBUF;
  switch(a)
  {
    case 0x01:ES=0;RI=0;manage_key1();ES=1;break;
    case 0x02:ES=0;RI=0;manage_key2();ES=1;break;
    case 0x03:ES=0;RI=0;manage_key3();ES=1;break;/*调用函数实现泵的控制*/
    case 0x04:ES=0;RI=0;manage_key4();ES=1;break;/*调用函数实现阀的控制*/
    default:RE_DE=1;RI=0;TI=0; ES=0;COM_send();break;/*使485处于发送状态,发送数据*/
  }
}
/******************************************
发送一个字节的子程序:
上升沿发送数据,
MSB first
******************************************/
void Write_Max7219_byte(unsigned char temp)
{
    unsigned char i;
    for (i=0; i<8; i++)     
    { 
        CLK = 0;
        DIN = (bit)(temp&0x80);      
        temp <<=1;  
        CLK = 1;
    }
}
/**********************************************************
向寄存器中写入一个数据
先写地址,后写数据
load 上升沿锁存数据
**********************************************************/
void Write_Max7219(unsigned char address,unsigned char dat)

    LOAD = 0;
    Write_Max7219_byte(address); 
    Write_Max7219_byte(dat);
    LOAD = 1;                 
}
//-----------------------------------------------
//函数名称:manage_key1()
//函数功能:按键1处理子程序
//-----------------------------------------------
void manage_key1(void)
{  
  key1++;/*进行寄存器的标志设置*/
  key++;
  switch(key1)
  {
  case 1:Write_Max7219(1,     0x80);break;//选择最低位寄存器,准备进行调节//
  case 2:Write_Max7219(2,     0);break;//选择次低位寄存器,进行调节//
  case 3:Write_Max7219(3,     0);break;//选择次中间寄存器,进行调节//
  case 4:Write_Max7219(4,     0);break;//选择最高位寄存器,进行调节//
  default:key1=0;break;
  }
}
//-----------------------------------------------
//函数名称:manage_key2()
//函数功能:按键2处理子程序,对显示的数据进行增1调节
//-----------------------------------------------
void manage_key2(void)
{
  switch(key)
  {
     case 1:{displ[0]++;Write_Max7219(1,(displ[0]|0x80));if((displ[0]|0x80)==0x8A)displ[0]=(0|0x80);}break;//依次对显示进行增量调节
     case 2:{displ[1]++;Write_Max7219(2,displ[1]);if(displ[1]==10)displ[1]=0;}break;
     case 3:{displ[2]++;Write_Max7219(3,displ[2]);if(displ[2]==10)displ[2]=0;}break;
     case 4:{displ[3]++;Write_Max7219(4,displ[3]);if(displ[3]==10)displ[3]=0;key=0;}break;
     default:key=0;break;
  }
}
/*延时子程序,延时时间为(16×N+24微秒)*/
void delay(unsigned int N)
{
  int i;
  for(i=0;i<N;i++);
}
//----键值判断--------------------------

//---------------------------------------------------
void judge_key(void)
{uchar Key_value=0;
     Key_value=P1&0x0f;
     switch(Key_value)
     {
       case 0x0E:delay(30000);
                 if(Key_value==(P1&0x0f))
                 {
                  manage_key1();break;
                 }
                 else break;
         
       case 0x0D:delay(30000);
                 if(Key_value==(P1&0x0f))
                 {
                  manage_key2();break;
                 }
                 else break;
       case 0x0B:delay(30000);
                 if(Key_value==(P1&0x0f))
                 {
                  manage_key3();break;
                 }
                 else break;
       case 0x07:delay(30000);
                 if(Key_value==(P1&0x0f))
                 {
                  manage_key4();break;
                 }
                 else break;
       default: break;
     }
}
void collect(void)
{
  uchar Gdata[25];
  uchar Bdata[25];
  uchar i,j,k,l=0;
  unsigned long Tran=0;
  for(i=0;i<25;i++)
  {
    CLOCK=0;
    CLOCK=1;
    Gdata=RO;
  }
  i=0;
  Bdata[0]=Gdata[0];/*将首位赋给二进制首位*/
  for(j=1;j<=24;j++)
  {
       if(Gdata[j]==0)/*若格雷码为0,二进制与前一位相同*/
          Bdata[j]=Bdata[j-1];
       else/*若格雷码为1,二进制与前一位相反*/
          {if(l==0)
            {l++;
             if(Bdata[j-1]==1)
                {Bdata[j]=Bdata[j-1]-1;}
             else
                {Bdata[j]=Bdata[j-1]+1;}
             }
           else
            {
             if(Bdata[j-1]==1)
                {Bdata[j]=Bdata[j-1]-1;}
             else
                {Bdata[j]=Bdata[j-1]+1;}
             l=0;}
           }
  }
  for(k=0;k<=20;k++);/*延时*/
  for(i=0;i<25;i++)/*将转换的二进制存入长整形变量*/
  {
     Tran^=Bdata;
     Tran=Tran<<1;
  }
  displ[0]=(Tran/62111);//二进制转换成显示的工程算法,Diaply0显示的是最高位,//
  displ[1]=(Tran%62111)/6211;//此值赋给次高位//
  displ[2]=((Tran%62111)%6211)/621;
  displ[3]=(((Tran%62111)%6211)%621)/62;
  if((displ[0]==9)&&(displ[1]==9))/*出错控制*/
   {ALARM=0;}            
}
程序在单独运行键盘显示时 能用;单独测试串口时 能够给单片机写入数据,上传的数据看不到 我以为是数据格式的问题,但是将两个程序放在一起的时候,就不好用了 请教这是为什么啊 ?多谢大家

相关帖子

沙发
lbx_00| | 2007-5-29 21:10 | 只看该作者

分点

使用特权

评论回复
板凳
lbx_00| | 2007-5-29 21:21 | 只看该作者

逐点调试

你说,下载数据成功了,你看到下载的数据被mcu保存了吗?上传的数据,你先编个小程序试试,上位先不要用你的程序,因为可能有错,先用串口助手,还有,连续发送aah或者55h,用示波器看看波特率。

至于两个程序放在一起不好用,看看有没有冲突的地方,如果你要是有仿真器,就好办一些,要是没有,就要想办法显示主要信息,例如,关键程序是否已经执行了,执行的结果怎么样,认真分析现象,会判断出来的。

你的问题不是大问题,和水平无关,但是要仔细。

写程序不难,调试很重要。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

17

主题

51

帖子

0

粉丝