找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5505|回复: 4
打印 上一主题 下一主题
收起左侧

两个单片机之间的通讯和控制的问题

[复制链接]
跳转到指定楼层
楼主
ID:69634 发表于 2015-3-28 22:22 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
这是STC12C5A60S2单片机连续测得8路模拟量,在本单片机中显示通道号和数值(0-1024),并通过串口输出下个单片机

#include"STC12C5A60S2.h"
#include"intrins.h"
unsigned char code LedChar[]={        0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f };
unsigned char LedBuff[ ]={0xff,0xff,0xff,0xff,0xff        };                                                                          
unsigned int a = 0;
float AD_val = 0;
//------------------------------------------------------------------------------
void AD_init();
void serial_init();
void delay(unsigned int b);
float AD_work(unsigned char channel);
unsigned int AD_get(unsigned char channel);

void main()
{
          TMOD = 0x01;
        TH0 = 0xFC;
        TL0 = 0x67;
        TR0 = 1;
        EA = 1;
        ET0 = 1;

    AD_init();    //A/D转换初始化
    serial_init();   //串口初始化
while(1)
{
        float b;
        unsigned char e, i,j=0;
        for(i=0;i<8;i++) //循环发送P1.0-P1.7的转换数值
        {  b=AD_work(i);
               a=(unsigned int)b ;         
                LedBuff[0] = LedChar[a%10];
                        LedBuff[1] = LedChar[a/10%10];                       
                        LedBuff[2] = LedChar[a/100%10];
                        LedBuff[3] = LedChar[a/1000%10];
                        LedBuff[4] = LedChar[i];

                if(j==0)  { SBUF = i; while(!TI); TI=0;j++;}
                if(j==1)  {  SBUF = a; while(!TI); TI=0;j++;}
                if(j==2)  {  e = a>>8; SBUF = e;while(!TI);TI=0;j=0;}
            delay(2000); //延时约2s
        }
}
}
//------------------------------------------------------------------------------
unsigned int AD_get(unsigned char channel)
{
  ADC_CONTR=0x88|channel;    //开启AD转换1000 1000 即POWER SPEED1 SPEED0 ADC_FLAG   ADC_START CHS2 CHS1 CHS0
  _nop_(); _nop_(); _nop_(); _nop_();//要经过4个CPU时钟的延时,其值才能够保证被设置进ADC_CONTR 寄存器
  while(!(ADC_CONTR&0x10));    //等待转换完成
  ADC_CONTR&=0xe7;      //关闭AD转换,ADC_FLAG位由软件清0
  return(ADC_RES*4+ADC_RESL);   //返回AD转换完成的10位数据(16进制)
}
//------------------------------------------------------------------------------
float AD_work(unsigned char channel)
{
  float AD_val;     //定义处理后的数值AD_val为浮点数
  unsigned char i;
  for(i=0;i<100;i++)
  AD_val+=AD_get(channel); //转换100次求平均值(提高精度)
  AD_val/=100;
  return AD_val;
}
//------------------------------------------------------------------------------
void delay(unsigned int b) //延时约1ms
{
        unsigned int i;
        while (--b!=0)
        for(i=600;i>0;i--);   //1T单片机i=600,若是12T单片机i=125
}

//------------------------------------------------------------------------------
void AD_init()
{
        P1ASF=0xff; //P1口全部作为模拟功能AD使用
        ADC_RES=0;   //清零转换结果寄存器高8位
        ADC_RESL=0; //清零转换结果寄存器低2位
        ADC_CONTR=0x80;//开启AD电源
        delay(2);   //等待1ms,让AD电源稳定
}

          unsigned char j = 0;
           void InterruptTimer0()  interrupt 1                 
{
        TH0 = 0xFC;
        TL0 = 0x67;
        P0 = 0xFF;   
                           if(j == 0)                        {P2=7; j++;   P0=LedBuff[0];}  //数码港显示
                           else if(j == 1)                {P2=6; j++;   P0=LedBuff[1];}
                       else if(j == 2)                {P2=5; j++;   P0=LedBuff[2];}
                       else if(j == 3)                {P2=4; j++;   P0=LedBuff[3];}
                           else if(j == 4)                {P2=0; j=0;   P0=LedBuff[4];}
}
void serial_init()
{
        TMOD=0x20;
        TH1=0xfd;
        TL1=0xfd; //设置9600波特率
        SCON=0x50; //串口方式1,允许接收
        TR1=1;
}

void InterruptUART() interrupt 4
{   }


下面是90c516单片机,接受上单片机发来的数据和通道号,在1602液晶显示

#include<reg52.h>
#define uchar unsigned char
#define uint  unsigned int
sbit lcden=P0^5;
sbit lcdrw=P0^6;
sbit lcdrs=P0^7;
sbit jidianqi=P0^0;
uchar a,b, tab ;
uint tab1 ;

void delay(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
        for(y=110;y>0;y--);
}
void write_com(uchar com)
{
        lcdrs=0;
        P2=com;
        delay(5);
        lcden=1;
        delay(5);
        lcden=0;
}

void write_data(uchar date)
{
        lcdrs=1;
        P2=date;
        delay(5);
        lcden=1;
        delay(5);
        lcden=0;
}
void init()
{

        lcden=0;
        write_com(0x38);
        write_com(0x0e);
        write_com(0x06);
        write_com(0x01);
        write_com(0x80+0x03);
}
    /* 串口配置函数,baud-通信波特率 */
void ConfigUART(unsigned int baud)
{
    SCON  = 0x50;  //配置串口为模式1
    TMOD &= 0x0F;  //清零T1的控制位
    TMOD |= 0x20;  //配置T1为模式2
    TH1 = 256 - (11059200/12/32)/baud;  //计算T1重载值
    TL1 = TH1;     //初值等于重载值
    ET1 = 0;       //禁止T1中断
    ES  = 1;       //使能串口中断
    TR1 = 1;       //启动T1
}

void UartRead(  )
{
          uchar j=0;
          if(j==0)  {   while(!RI);  tab=SBUF; RI=0; j++;}
          if(j==1)  {   while(!RI);  a=SBUF; RI=0;   j++;}
          if(j==2)  {   while(!RI);  b=SBUF;  RI=0;  j=0;}

          tab1=(b<<8)|((unsigned int)a);
}

void InterruptUART() interrupt 4
{
       if (RI)  //接收到新字节
    {
        RI = 0;  //清零接收中断标志位
               
    }
    if (TI)  //字节发送完毕
    {
        TI = 0;   //清零发送中断标志位
    }
}

uchar qian,bai,shi,ge;        //声明两个变量用来分解data1

void main()
{
        lcdrw=0;
        init();
        ConfigUART(9600);       
       
        while(1)

{

        UartRead( ) ;
        delay(20);
        write_com(0x80+0x03);
        write_data(tab+0x30);
        delay(20);

    qian= tab1/1000;
    bai=  tab1%1000/100;
    shi=  tab1%100/10;        //将十位分离出来
    ge=   tab1%10;        //将个位分离出来
    write_com(0x80+0x41);//要写的地方,这里是第二行
    write_data(qian+0x30);
        delay(20);
    write_data(bai+0x30);
    delay(20);
    write_data(shi+0x30);//调用1602字库,0x30+shi表示0-9数字,写完后地址自动加一指针。
        delay(20);
    write_data(ge+0x30);
        delay(20);
        if(tab==0) {
                    if(tab1>500) {jidianqi=0;}
                                else         {jidianqi=1;}
                   }
  }               
}


问题是,控制继电器太慢,循环一周后继电器动作,现在要他tab1大于500数值(比仿50度温度),立刻继电器动作,通道号和数值循环不变,请问各位老师该如何做?



























分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:69634 发表于 2015-4-1 19:10 | 只看该作者
为什么没有人回答,这道题怎么难吗?
回复

使用道具 举报

板凳
ID:69634 发表于 2015-4-5 22:37 | 只看该作者
没有人回答,我自己改进了一下,效果不很理想。有时1602液晶显示跑掉,通道号不变,继电器反应快了

这是STC12C5A60S2单片机的

#include"STC12C5A60S2.h" //头文件在STC公司主页上下载
#include"intrins.h"
unsigned char code LedChar[]={        0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f        };
unsigned char LedBuff[ ]={        0x3f, 0x3f,  0x3f, 0x3f        , 0x3f        };                                                                          
unsigned int g,  a = 0, n=0 ;
unsigned char d , m=0;
float AD_val = 0;
//------------------------------------------------------------------------------
void AD_init();
void serial_init();
void delay(unsigned int b);
float AD_work(unsigned char channel);
unsigned int AD_get(unsigned char channel);
void display(unsigned int g );
//------------------------------------------------------------------------------
void main()
{
        unsigned char j, e=0 ;
        float   b;
        unsigned int Led[]={ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff };
          TMOD = 0x01;
        TH0 = 0xFC;
        TL0 = 0x67;
        TR0 = 1;
        EA = 1;
        ET0 = 1;
AD_init();    //A/D转换初始化
serial_init();   //串口初始化
while(1)
{
  for(d =0;d <8;d++) //循环发送P1.0-P1.7的转换数值
   {            b=AD_work(d );
                    a=(unsigned int)b ;       
                                Led[d]        = a;
                            if(j==0)  { SBUF = d; while(!TI); TI=0; j++;}
                        if(j==1)  { SBUF = a; while(!TI); TI=0; j++;}
                        if(j==2)  { e = a>>8; SBUF = e;   while(!TI); TI=0; j=0; n++;}
                                  
                                if(n>=640) { n=0;  m=0; }
                       switch(m=n/80)
                                 {
                                        case 0:                                                
                                                g=        Led[0] ;                                                                        
                        display( g  ) ;
break;
                                        case 1:                                                                                         
                                                g=        Led[1] ;                                                                        
                                                display( g ) ;
break;
                                        case 2:                                                                                         
                                                g=        Led[2] ;                                                                        
                                                display( g ) ;                 
break;
                                        case 3:                                                                                         
                                                g=        Led[3] ;                                                                        
                                                display( g  ) ;
break;
                                        case 4:                                                                                         
                                                g=        Led[4] ;                                                                        
                        display( g ) ;
break;
                                        case 5:                                                                                         
                                                g=        Led[5] ;                                                                        
                        display( g  ) ;
break;
                                        case 6:                                                                                         
                                                g=        Led[6] ;                                                                        
                        display( g  );
break;
                                        case 7:
                                                 g=        Led[7] ;                                                                                
                        display( g  ) ;
break;
}
      }      
              }
}

void display(unsigned int g  )
{
        LedBuff[0] = LedChar[g%10];
        LedBuff[1] = LedChar[g/10%10];                       
        LedBuff[2] = LedChar[g/100%10];
        LedBuff[3] = LedChar[g/1000%10];
        LedBuff[4] = LedChar[m];
}
//------------------------------------------------------------------------------
unsigned int AD_get(unsigned char channel)
{
ADC_CONTR=0x88|channel;    //开启AD转换1000 1000 即POWER SPEED1 SPEED0 ADC_FLAG   ADC_START CHS2 CHS1 CHS0
_nop_(); _nop_(); _nop_(); _nop_();//要经过4个CPU时钟的延时,其值才能够保证被设置进ADC_CONTR 寄存器
while(!(ADC_CONTR&0x10));    //等待转换完成
ADC_CONTR&=0xe7;      //关闭AD转换,ADC_FLAG位由软件清0
return(ADC_RES*4+ADC_RESL);   //返回AD转换完成的10位数据(16进制)
}
//------------------------------------------------------------------------------
float AD_work(unsigned char channel)
{
float AD_val;     //定义处理后的数值AD_val为浮点数
unsigned char i;
for(i=0;i<50;i++)
AD_val+=AD_get(channel); //转换100次求平均值(提高精度)
AD_val/=50;
//AD_val=(AD_val*5)/1024; //AD的参考电压是单片机上的5v,所以乘5即为实际电压值
return AD_val;
}
//------------------------------------------------------------------------------
void delay(unsigned int b) //延时约1ms
{
unsigned int i;
while (--b!=0)
for(i=600;i>0;i--);   //1T单片机i=600,若是12T单片机i=125
}

//------------------------------------------------------------------------------
void AD_init()
{
P1ASF=0xff; //P1口全部作为模拟功能AD使用
ADC_RES=0;   //清零转换结果寄存器高8位
ADC_RESL=0; //清零转换结果寄存器低2位
ADC_CONTR=0x80;//开启AD电源
delay(2);   //等待1ms,让AD电源稳定
}

unsigned char j = 0 ;
void InterruptTimer0()  interrupt 1                 
{
        TH0 = 0xFC;
        TL0 = 0x67;
        P0 = 0xFF;

                           if(j == 0)
                        {P2=7; j++; P0=LedBuff[0];}
                        else if(j == 1)
                        {P2=6; j++;   P0=LedBuff[1];}
                         else if(j == 2)
                        {P2=5; j++;  P0=LedBuff[2];}
                        else if(j == 3)
                        {P2=4; j++; P0=LedBuff[3];}
                                 else if(j == 4)
                        {P2=0; j=0; P0=LedBuff[4];}
}
void serial_init()
{
TMOD=0x20;
TH1=0xfd;
TL1=0xfd; //设置9600波特率
SCON=0x50; //串口方式1,允许接收
TR1=1;
}
void InterruptUART() interrupt 4        {}



























回复

使用道具 举报

地板
ID:69634 发表于 2015-4-5 22:42 | 只看该作者
这是90c516单片机的程序,接受上单片机STC12C5A60S2发来的数据和通道号,在1602液晶显示,在单片机STC12C5A60S2显示是正确的,在1602液晶显示数据明显离谱

#include<reg52.h>
#define uchar unsigned char
#define uint  unsigned int
sbit lcden=P0^5;
sbit lcdrw=P0^6;
sbit lcdrs=P0^7;
sbit jidianqi=P0^0;
uchar a,b, tab,cnt=0 ;
uint tab1, num=0  ;
uint shuzu[]={ 0xff,0xffff,0x0fff,0x0800,0xff,0xff,0xff,0xff };

void delay(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)
        for(y=110;y>0;y--);
}
void write_com(uchar com)
{
        lcdrs=0;
        P2=com;
        delay(5);
        lcden=1;
        delay(5);
        lcden=0;
}

void write_data(uchar date)
{
        lcdrs=1;
        P2=date;
        delay(5);
        lcden=1;
        delay(5);
        lcden=0;
}
void init()
{
        lcden=0;
        write_com(0x38);
        write_com(0x0e);
        write_com(0x06);
        write_com(0x01);
        write_com(0x80+0x03);
}
    /* 串口配置函数,baud-通信波特率 */
void ConfigUART(unsigned int baud)
{
    SCON  = 0x50;  //配置串口为模式1
    TMOD &= 0x0F;  //清零T1的控制位
    TMOD |= 0x20;  //配置T1为模式2
    TH1 = 256 - (11059200/12/32)/baud;  //计算T1重载值
    TL1 = TH1;     //初值等于重载值
    ET1 = 0;       //禁止T1中断
    ES  = 1;       //使能串口中断
    TR1 = 1;       //启动T1
}

void UartRead(  )
{
          uchar j=0;
          if(j==0)  {   while(!RI);  tab=SBUF; RI=0; j++;}
          if(j==1)  {   while(!RI);  a=SBUF; RI=0;   j++;}
          if(j==2)  {   while(!RI);  b=SBUF;  RI=0;  j=0;}
          tab1=(b<<8)|((unsigned int)a);
          shuzu[tab]        = tab1;
}

void InterruptUART() interrupt 4 { }
void Display( )       
{       
        uchar  qian,bai,shi,ge ;        //声明变量用来分解tab1       
    delay(20);
        write_com(0x80+0x03);
        write_data(cnt+0x30);
        delay(20);

    qian= shuzu[cnt]/1000;
    bai=  shuzu[cnt]%1000/100;
    shi=  shuzu[cnt]%100/10;        //将十位分离出来
    ge=   shuzu[cnt]%10;        //将个位分离出来
    write_com(0x80+0x41);//要写的地方,这里是第二行
    write_data(qian+0x30);
        delay(20);
    write_data(bai+0x30);
    delay(20);
    write_data(shi+0x30);//调用1602字库,0x30+shi表示0-9数字,写完后地址自动加一指针。
        delay(20);
    write_data(ge+0x30);
        delay(20);
}
void InterruptTimer0()  interrupt 1                 
{
        TH0 = 0xFC;
        TL0 = 0x67;
        num++;
        if(num==1000) {num=0; Display( ); cnt++; }
        if(cnt>7)     {cnt=0;}
}
void main()
{
        TMOD = 0x01;
        TH0 = 0xFC;
        TL0 = 0x67;
        TR0 = 1;
        EA = 1;
        ET0 = 1;
        lcdrw=0;
        init();
        ConfigUART(9600);               
        while(1)
{
        UartRead( ) ;
        if(tab==1){
        if(shuzu[1]>500) {jidianqi=0;}
        else             {jidianqi=1;}       
                  }     
}               
}

回复

使用道具 举报

5#
ID:69634 发表于 2015-4-5 22:44 | 只看该作者
各位老师能指点一二,在下感激不尽。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表