打印

PIC18F2423单片机RS485通信

[复制链接]
1191|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
北航吴彦祖|  楼主 | 2017-12-28 21:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 北航吴彦祖 于 2017-12-28 22:19 编辑

求问。
PIC18F2423单片机,使用RS485通信,编译环境MPLAB IDEV8.91。
在通信时,串口接收信号正确,将接收的数据帧从RCREG寄存器中读取出来,赋值给别的变量,数据就产生了变化,变化很固定,请问这是什么原因?已查明不是电路的问题。第一次发帖,求大神回复!
#include<pic18.h>                          //包含单片机内部资源预定义
#include<pic18f4523.h>
#include <stdio.h>
#include "main.h"
#include "sci.h"


//函数区========================================================================
void main()
{
GIE=0;      //禁止中断
io_init();                  //初始化
timer_init();
sci_init();
sys_init();    //处理中断等
adc_init();
GIE=1;      //开中断
PEIE=1;
while(1)
{
if (**1ms)
{
  **1ms=0;
  
}
if (**_ADtime)
    {
  AD_go();    //启动一次AD转换
  **_ADtime=0;
}
if(tx**)
{
  tx**=0;  
  Sci2Tx();
}
ms_delay(2);
}                    //等待接收中断  
}
/*========================================================================
========================================================================*/
void io_init(void)
{
PORTA=0b00101111; //RA0、RA1、RA2、RA3、RA5输入
TRISA=0b00101111;
PORTB=0b00001110; //RB1、RB2、RB3输入
TRISB=0b00001110;  
TRISC=0b00000000;
// PORTC&=0b11101111;
}
//=========SCI串口函数==========================================================
void sci_init(void)
{
SPBRG=103;   //16MHz-9600
                     //波特率计算公式
              //1.同步方式:波特率=Fosc/[4(X+1)]
             //2.异步方式:BRGH=0:波特率=Fosc/[64(x+1)]
      // BRGH=1:波特率=Fosc/[16(x+1)]
BAUDCON&=~(1<<3); //BRG16=0
TRISC|=(1<<7);  //RC7置1设置为输入
TRISC&=~(1<<6);  //RC6置0设置为输出
EnRS485Receive2();
TXSTA=0x24;//异步,高速(BRGH=1),8位
RCSTA=0x90;  //使能UART
RCIF=0;
TXIF=0;   //清除UART2中断标志
IPR1|=(1<<4)|(1<<5); //usart1高优先级
RCIE=1;    //使能收中断
TXIE=0;    //禁止发送中断
orderRxSci1=0;
tx**=0;
}
//=========AD函数==========================================================
void adc_init(void)
{
    ADCON1=0x00;        //参考电压VDD VSS;
ADCON0=0x01;  //选择通道0(bit6:2),使能ADC
ADCON2=0xB5;  //右对齐,16Tad,Foc/16(Tad=1us)
ADIF=0;    //清除AD转换标志
ADIE=1;    //AD中断允许
}
//AD改变通道channel:0~7
void AD_ch_change(void)
{
const uchar AD_ch_set[]={
  0b00000001,0b00000101,0b00001001,0b00001101,0b00010001,0b00100001,0b00100101,0b00101001};
ADchannel++;
ADchannel%=8;
ADCON0=AD_ch_set[ADchannel];
}
void AD_deal(void)
{
if(AD_data[ADchannel]<5) //AD采样处理,防止溢出
{
  AD_data[ADchannel]=0;
}
if(AD_data[ADchannel]>4095)
{
  AD_data[ADchannel]=4095;
}
if(ADchannel<=7)    //八个通道数据存在AD[]里
{
   AD[ADchannel]=((AD_vol*AD_data[ADchannel]))/AD_acc;
}
}
//=========系统==========================================================
void sys_init(void)
{
SWDTEN=0;   //关看门狗
IPEN=1;    //中断优先级,置1使能
INTCON=0xF0;  //允许高低中断、TIM0中断、INT0中断
INTCON2=0x00;  //下降沿触发
INTCON3=0xC8;  //允许INT1中断,外部中断高优先级
PIE1=0x60;   //允许中断:AD,RC
PIR1=0;
}
//=========定时器函数==========================================================
void timer_init(void)
{
T0CON=0x45;   //8位定时器,16M晶振64分频,需要计数250次
TMR0IF=0;   //标志位清0
TMR0IE=1;   //允许溢出中断
TMR0IP=0;   //TIM0中断 低优先级
TMR0=0x05;   //定时常数5 =1ms
TMR0ON=1;   //使能TIM0
}
//***********************************
void us_delay(uchar us)  //延时函数
{         
  uchar i, j;
  for(i=0;i<16;i++)
  {
for(j=0;j<us;j++)
{;}
  }      
}
void ms_delay(uchar ms)  //延时函数
{  
  uint i;      
  uchar j;
   for(i=0;i<16000;i++)
  {
for(j=0;j<ms;j++)
{;}
  }      
}
void interrupt HI_ISR()
{
if(INT0IF)     //INT0外部中断
{
INT0IF=0;
       //**添加代码
}
if(INT1IF)     //INT1外部中断
{
INT1IF=0;
       //**添加代码
}
if(RCIF)       //如果是串口接收中断的话,则进入中断处理
{
RCIF=0;
Sci2Rx();
}
}  
//***********************************
void interrupt low_priority LOW_ISR()
{
if(ADIF)     //判断是否是AD转换中断
{   
ADIF=0;     //清0
AD_data[ADchannel]=(ADRESH<<8|ADRESL);
AD_deal();
AD_ch_change();
}
if(TMR0IE)
{          //确认是定时器0中断
   if(TMR0IF)
  {
**1ms=1;
    ms_temp++;
    TMR0IF=0;
    TMR0=0x05;              //1ms定时常数
    if(ms_temp==AD_time) //定时到
    {
  **_ADtime=1;
  ms_temp=1;
     }
  }
}
}


/*从单片机发单个字节到单片机)*/
void UART_sendchar(uchar dad)
{
  EnRS485Trans2();
  TXREG=dad;
  while(0==TXSTAbits.TRMT);
  EnRS485Receive2();
}  


void Sci2Tx(void)                                         //发送函数
{
uchar i;
  i=0;
qishizifu=0xED;
txBuf[0]=0xEE;    //本机地址
txBuf[1]=0x03;    //功能码
txBuf[2]=0x0F;    //字节数
for(ADchannel=0;ADchannel<1;ADchannel++)
{
  txBuf[(ADchannel+1)*2+1]=(uchar)AD_data[ADchannel];            //低八位传输赋值
  txBuf[(ADchannel+1)*2+2]=(uchar)(AD_data[ADchannel]>>8);       //高低八位传输赋值
}
crc[0]=GenertCrc(txBuf,19)>>8;     //crc码传输
crc[1]=GenertCrc(txBuf,19);
endzifu=0xEF;

UART_sendchar(qishizifu);
UART_sendchar(txBuf[0]);
UART_sendchar(txBuf[1]);
UART_sendchar(txBuf[2]);
UART_sendchar(txBuf[3]);
UART_sendchar(txBuf[4]);
UART_sendchar(crc[0]);  
UART_sendchar(crc[1]);
UART_sendchar(endzifu);

}
   

INT16U GenertCrc(INT8U *str, INT16U num)                //crc码生成函数
{
  INT16U crc=0xFFFF;
  INT16U genertCrc_i=0,genertCrc_j=0;
  INT8U **Crc;
  for (genertCrc_i=0;genertCrc_i<num;genertCrc_i++)
    {
      crc=str[genertCrc_i]^crc;
      for (genertCrc_j=0;genertCrc_j<8;genertCrc_j++)
        {
          **Crc=crc&0x0001;
          crc>>=1;
          if (**Crc)
            {
              crc^=0xA001;
            }
        }
    }
  genertCrc_i=crc;
  crc<<=8;      //调整结果的高8位和低8位
  crc|=(genertCrc_i>>8);
  return(crc);
}


==========================================================================================*/
void Sci2Rx(void)       //RS485接收请求
{
  
  dataRxSci1=RCREG;

  if((0==orderRxSci1)&&(0xED==dataRxSci1Pre))
  {
   rxBufSci1[0]=0xED;
      orderRxSci1=1;    //帧头正确则进入下一状态
  }
  dataRxSci1Pre=dataRxSci1;
  if(orderRxSci1>0)
  {
   rxBufSci1[orderRxSci1]=dataRxSci1; //将接收到的字节赋给数组
      orderRxSci1++;
  }
  
  if(orderRxSci1==10) //判断是否是单片机3发来的请求
  {
   tx**=1;
  }
  if(orderRxSci1==10)
  {
    orderRxSci1=0;
    dataRxSci1Pre=0xFF;
  }
}
沙发
yklstudent| | 2017-12-29 12:15 | 只看该作者
tx**=1;
这是啥意思?

使用特权

评论回复
板凳
Cjy_JDxy| | 2018-1-2 08:55 | 只看该作者
yklstudent 发表于 2017-12-29 12:15
tx**=1;
这是啥意思?

屏蔽了,敏感词汇

使用特权

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

本版积分规则

1

主题

1

帖子

0

粉丝