请教,三片430单片机做485主从式通讯,一片为主机通过按键逐个显示从机的温湿度数据,可是一直显示乱码,求解。

2019-07-15 16:10发布

/*主机程序*/
#include <msp430x14x.h>
#include  "Cry12864HZ.c"
#include  "Cry12864HZ.h"
#define keyin    (P5IN & 0x0f)
#define DRE_out     P3DIR |= BIT3     //连接485芯片的DE,RE端口的IO设置为输出状态
#define DE          P3OUT |= BIT3     //设置485芯片处于发送状态
#define RE          P3OUT &= ~BIT3    //设置485芯片处于接收状态

void Init_uat0(void);
void delay(void);//收发都需要
char receive(void); //接受函数
void rade_init();
void display();
//unsigned char DATA[6]={"------"};
unsigned char RR=0;
unsigned char TT=0;
uchar R_shi,R_ge,T_shi,T_ge,T_xs1,T_xs2,R_xs1,R_xs2;
uchar num,flag,keyval;
uint r[7];
uchar string[]={"温湿测试系统"};
uchar string1[]={"温湿测试从1"};
uchar string2[]={"温湿测试从2"};
uchar str_t[]={"温  度:"};
uchar str_r[]={"湿  度:"};
uchar str_suit[]={"适宜度:"};
uchar str1[]={"适  宜"};
uchar str2[]={"不适宜"};
unsigned char sendBytes[16]={"ABCDEF0123456789"};
/*****************子函数********************/
void delay(void)
{
  unsigned int i=1800;
  while(i--);
}
void delay_1ms(uint z)
{
   uint i,j;
   for(i=z;i>0;i--)  
        for(j=80;j>0;j--);
}

void keycantrol()
{
  uchar s;
  if(keyin != 0x0f)       //键值有改变
  {
    delay_1ms(10);            //延时消抖
    if(keyin != 0x0f)   //再次检测按键状态
    {   
      s=keyin;

      while(keyin != 0x0f);   //等待按键被放开
      switch(s)    //转换键值   
      {
      case 0x0e:
                  keyval = 0x01;break;
      case 0x0d:
                  keyval = 0x02;break;
      case 0x0b:
                  keyval = 0x03;break;
      case 0x07:
                  keyval = 0x04;break;
      default:
        break;
      }
      delay_1ms(1);delay_1ms(1);delay_1ms(1);delay_1ms(1);
    }
  }
}

void display()
{
  if(keyval==0x01)
  {
    Disp_HZ(0x81,string1,6);
  }
  if(keyval==0x02)
  {
    Disp_HZ(0x81,string2,6);
  }
  Write_Cmd(0x94);
  delay_1ms(10);
  Write_Data(T_shi);
  Write_Data(T_ge);
  delay_1ms(10);
  Write_Data('.');
  Write_Data(T_xs1);
  Write_Data(T_xs2);
  Write_Data(' ');
  Write_Data(str_t[4]);
  Write_Data(str_t[5]);
  Write_Cmd(0x8C);
  delay_1ms(10);
  Write_Data(R_shi);
  Write_Data(R_ge);
  delay_1ms(10);
  Write_Data('.');
  Write_Data(R_xs1);
  Write_Data(' ');
  Write_Data('%');
  Write_Data('R');
  Write_Data('H');
  if(r[0]>10 && r[0]<33 && r[2]>30 && r[2]<80)
    Disp_HZ(0x98+4,str1,3);
  else
    Disp_HZ(0x98+4,str2,3);
}

void main(void)
{

  unsigned int i;
  WDTCTL=WDTPW+WDTHOLD;             //停止看门狗
  BCSCTL1 &= ~XT2OFF;                       // XT2on

  do
  {
  IFG1 &= ~OFIFG;                           // Clear OSCFault flag
  for (i = 0xFF; i > 0; i--);               // time for flag to set
  }
  while ((IFG1 & OFIFG));                   // OSCFault flag still set?

  BCSCTL2 |= SELM_2 + SELS;                 // MCLK = SMCLK = XT2 (safe)

  DRE_out;
  RE;//收允许


  P5DIR = 0xf0;               //设置P5.0~P5.3为输入状态  
  Init_uat0();
  Ini_Lcd();                  //初始化液晶
  Disp_HZ(0x81,string,6);
  Disp_HZ(0x90,str_t,4);
  Disp_HZ(0x88,str_r,4);
  Disp_HZ(0x98,str_suit,4);
  _EINT(); //中断

  while(1)
  {
    keycantrol();
    display();
  }  

}

void Init_uat0(void)
{
  P3SEL |= 0x30;  //将P3.4,P3.5选做UART1的通信端口TXD/RXD   

  ME1 |= UTXE0 + URXE0;                     // Enable USART0 TXD/RXD
  UCTL0 |= CHAR;                            // 8-bit character
  UTCTL0 |= SSEL1;                          // UCLK = SMCLK
  UBR00 = 0x0;                             // 8Mhz/19200 ~ 417
  UBR10 = 0x03;                             // 7.3728/19200~180H
  UMCTL0 = 0x0;                            // no modulation
  UCTL0 &= ~SWRST;                          // Initialize USART state machine
  IE1 |= URXIE0+ UTXIE0;                            // Enable USART0 RX interrupt

}

#pragma vector = UART0RX_VECTOR
__interrupt void UART0_RXISR(void)
{

    r[RR] = RXBUF0;
    RR++;
    if(RR >= 7)
    {
      R_shi =(0X30+r[0]);
      R_ge =(0X30+r[1]);
      R_xs1=(0X30+r[2]);

    //温度整数部分

      T_shi =(0X30+r[3]);
      T_ge =(0X30+r[4]);
      //温度小数部分
      T_xs1 = (0X30+r[5]);
      T_xs2 = (0X30+r[6]);
      DE;
      RR = 0;
      IFG1 |= UTXIFG0; // 设置中断标志,进入发送中断程序
    }
  // _BIC_SR_IRQ(LPM3_bits);
}
#pragma vector = UART0TX_VECTOR
__interrupt void UART0_TXISR(void)
{

    if(keyval==0x01)
    {
        TXBUF0 = 0x01;    //从机1地址
        delay();
        RE;
    }
    else if(keyval==0x02)
    {
        TXBUF0 = 0x02;    //从机2地址
        delay();
        DE;
    }
    else
    {
        delay();
        RE;

    }
}

/*从机2程序*/
#include <msp430x16x.h>
#define DRE_out     P2DIR |= BIT6     //连接485芯片的DE,RE端口的IO设置为输出状态   
#define DE          P2OUT |= BIT6     //设置485芯片处于发送状态     
#define RE          P2OUT &= ~BIT6    //设置485芯片处于接收状态
//#define DRE_out     P3DIR |= BIT3     //连接485芯片的DE,RE端口的IO设置为输出状态
//#define DE          P3OUT |= BIT3     //设置485芯片处于发送状态
//#define RE          P3OUT &= ~BIT3    //设置485芯片处于接收状态
#define uchar unsigned char
#define uint unsigned int
#define HIGH P3OUT|=BIT1;         //DHT11的DATA
#define LOW P3OUT&=~BIT1;

void Init_uat0(void);
void delay(void);//收发都需要
uchar TH_data,TL_data,RH_data,RL_data,CK_data;
uchar TH_temp,TL_temp,RH_temp,RL_temp,CK_temp;
uchar com_data,untemp,temp;
uchar respond,num;
uchar P[7];
unsigned char RR=0;
unsigned char TT=0;
/*****************子函数********************/
void delay(void)
{
  unsigned int i=1800;
  while(i--);
}
void delay_1ms(uint z)
{
  uint i,j;
  for(i=z;i>0;i--)  
      for(j=80;j>0;j--);
}       

void DelayNus(uint n)//延时1US函数
{
  TACTL|= TASSEL_2+TACLR+ID_3;//定时器A,时钟为SCLK,8分频;   
  TACTL |= MC_1;           //增计数到CCR0
  TACCR0 = n;
  while((TACTL & BIT0)!=0x01);  //等待
  TACTL &= ~MC_1;          //停止计数
  TACTL &= ~BIT0;          //清除中断标志
}
char receive(void) //接受函数
{
  uchar i;
  com_data=0;
  for(i=0;i<=7;i++)   
  {
    respond=2;
    while(!(P3IN&BIT1)&& respond++);              //等待50us的低电平结束
    DelayNus(20);  
    if(P3IN&BIT1)                       //长于30us定义为1
    {
      temp=1;
      respond=2;
      while((P3IN&BIT1)&& respond++);             //结束高电平,即下一位数据的到来
    }
    else
            temp=0;
    com_data<<=1;
    com_data|=temp;
  }
  return(com_data);
}

void rade_init()
{
  P3DIR |= BIT1;    //设置P3.1为输出状态
  LOW;
  DelayNus(24000);    //开始信号
  HIGH;
  DelayNus(20);
  HIGH;
  P3DIR&=~BIT1;    //设置P3.1为输入状态,检测传感器响应
/*  DelayNus(20);     //20US后  P3IN  是否为低电平,不为低电平 说明复位失败,重新开始
  while((P3IN&BIT1)!=0)//如果没有检测到响应信号 继续发送开始信号
  {
      P3DIR |= BIT1;    //设置P3.1为输出状态
      HIGH;
      _NOP();_NOP();_NOP();
      LOW;
      DelayNus(20000);    //开始信号
      HIGH;
      DelayNus(20);
      HIGH;
      P3DIR&=~BIT1;    //设置P3.1为输入状态,检测传感器响应
      DelayNus(20);
  }*/
  if(!(P3IN&BIT1))
  {
    respond=2;
    while(!(P3IN&BIT1)&& respond++);//等待拉高,准备输出数据
    respond=2;
    while((P3IN&BIT1)&& respond++);  //等待低电平,输出数据
                       //下面开始接受数据  
    RH_temp = receive();
    RL_temp = receive();
    TH_temp = receive();
    TL_temp = receive();
    CK_temp = receive();
    P3DIR|=BIT1;
    HIGH;
    untemp=(RH_temp+RL_temp+TH_temp+TL_temp);
    if(untemp==CK_temp)
    {
      RH_data = RH_temp;
      RL_data = RL_temp;
      TH_data = TH_temp;
      TL_data = TL_temp;
      CK_data = CK_temp;
    }
  }
  P[0] = RH_data/10;
  P[1] = RH_data%10;
  P[2]= RL_data/10;

  //温度整数部分

  P[3] = TH_data/10;
  P[4] = TH_data%10;
  //温度小数部分
  P[5] = TL_data/10;
  P[6] = TL_data%10;
}

void main(void)
{

  unsigned int i;
  WDTCTL=WDTPW+WDTHOLD;             //停止看门狗
  BCSCTL1 &= ~XT2OFF;                       // XT2on

  do
  {
  IFG1 &= ~OFIFG;                           // Clear OSCFault flag
  for (i = 0xFF; i > 0; i--);               // Time for flag to set
  }
  while ((IFG1 & OFIFG));                   // OSCFault flag still set?

  BCSCTL2 |= SELM_2 + SELS;                 // MCLK = SMCLK = XT2 (safe)

  DRE_out;
  RE;//收允许


  Init_uat0();

  _EINT(); //中断

  for(;;)
  {
    _NOP();
    rade_init();
    delay_1ms(100);//等待下次采样
    //_BIS_SR(LPM3_bits+GIE); //进入LPM3模式/允许总中断
  }



}

void Init_uat0(void)
{
  P3SEL |= 0x30;  //将P3.4,P3.5选做UART1的通信端口TXD/RXD   

  ME1 |= UTXE0 + URXE0;                     // Enable USART0 TXD/RXD
  UCTL0 |= CHAR;                            // 8-bit character
  UTCTL0 |= SSEL1;                          // UCLK = SMCLK
  UBR00 = 0x0;                             // 8Mhz/19200 ~ 417
  UBR10 = 0x03;                             // 7.3728/19200~180H
  UMCTL0 = 0x0;                            // no modulation
  UCTL0 &= ~SWRST;                          // Initialize USART state machine
  IE1 |= URXIE0+ UTXIE0;                            // Enable USART0 RX interrupt


}

#pragma vector = UART0RX_VECTOR
__interrupt void UART0_RXISR(void)
{

    num = RXBUF0;
    if(num == 0x02)     //从机地址
    {
      DE;
      num = 0;
      IFG1 |= UTXIFG0; // 设置中断标志,进入发送中断程序
    }
}
#pragma vector = UART0TX_VECTOR
__interrupt void UART0_TXISR(void)
{
    if(TT < 7)
    {
        TXBUF0 = P[TT];
        TT++;
    }
    else
    {
        delay();
        TT=0;
        RE;

    }
}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。