打印
[PIC®/AVR®/dsPIC®产品]

PIC18f25K80程序一直重启

[复制链接]
2712|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
kevinwangwang|  楼主 | 2013-12-23 20:25 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
做了个CAN总线的取件放错装置,开机的时候LED灯闪一次灭,调试程序的过程中发现LED一直闪烁找不到原因,烦请高手们帮忙分析分析 附上代码

#include <pic18f25k80.h>
#define uchar unsigned char
#define uint  unsigned int
#define LED PORTBbits.RB4
void init();//初始化函数
void caninit();//CAN初始化
void cansend();//发送函数
void interrupt canrec();//can总线接收中断函数
void delay(uint time);//延时函数
void run();//上位机操作码判断函数
uchar addr;//地址
uchar sidh;//发送标识符高位
uchar sidl;//发送标识符低位
uchar sidh1;//接收标识符高位
uchar sidl1;//接收标识符低位
uchar opcode;//操作码
uchar fucode;//功能码
uchar takenum;//取件数量
uchar opnum;//操作数量
uchar stcation;//指示状态
#pragma config INTOSCSEL=LOW//休眠期间LF-INTOSC处于低功耗模式
#pragma config SOSCSEL=DIG //数字模式使能RC0,RC1端口功能
#pragma config XINST=OFF  //不使用扩展指令集
#pragma config RETEN=OFF  //禁止超低功耗稳压器
#pragma config IESO=OFF    // 禁止双速启动
#pragma config FOSC=HS1   //振荡器4-16MHZ
#pragma config FCMEN=OFF //禁止故障保护时钟
#pragma config PLLCFG=OFF  //直接试用晶振
#pragma config BOREN=OFF   //关闭欠压复位
#pragma config BORPWR=LOW  //低功耗级别
#pragma config BORV=3    //欠压复位电压1.8V
#pragma config PWRTEN=OFF //禁止上电延时复位
#pragma config WDTPS=256   //WDT后分频比为1:256约为1.024S
#pragma config WDTEN=OFF   //关闭看门狗
#pragma config CANMX=PORTB  //CAN TX RX为RB2 RB3
#pragma config MSSPMSK=MSK7  //7位地址掩码
#pragma config MCLRE=ON      // 使能MCLR复位引脚,禁止RE3IO功能
#pragma config STVREN=OFF     //堆栈下溢、满不会导致复位
#pragma config BBSIZ=BB2K   //引导区为2K
#pragma config CP0=OFF      //代码保护关闭
#pragma config CP1=OFF
#pragma config CP2=OFF
#pragma config CP3=OFF
#pragma config CPD=OFF
#pragma config CPB=OFF
#pragma config WRT0=OFF    //不写保护
#pragma config WRT1=OFF
#pragma config WRT2=OFF
#pragma config WRT3=OFF
#pragma config WRTB=OFF
#pragma config WRTC=OFF
#pragma config WRTD=OFF
#pragma config EBTR0=OFF
#pragma config EBTR1=OFF
#pragma config EBTR2=OFF
#pragma config EBTR3=OFF   //允许表读
#pragma config EBTRB=OFF
void main()
{
        INTCON=0x00;//关中断
        init();//初始化
        caninit();//CAN初始化
        INTCON=0XC0;//开中断
    while(1)
{
    if(PORTBbits.RB0==0)//发送数据判断
    {
      delay(10);
      if(PORTBbits.RB0==0)//消抖
      {
                while(PORTBbits.RB0==1);//检测开关是否释放
                LED=1;//如果释放LED灯闪烁2次
                delay(50);
                LED=0;
                delay(50);
                LED=1;
                delay(50);
                LED=0;
                delay(50);
        stcation=0;//更新指示状态
        opnum=opnum++;//操作数量加1
        if(opnum>takenum)
         {
          fucode=0x06;//如果取件错误,设置错误码
         }
        cansend();//CAN总线发送数据
      }
     }
     run();//上位机命令判断
}
        
}
void init()
{   
        TRISC=0xff;//设置RC口为输入
    TRISB=0x09;//设置RB0为输入,CANTX为输出,CANRX为输入,RB4为输出
        //INTCON2bits.nRBPU=1;//开RB上拉
        LED=1;//开机LED闪烁1次
        delay(50);
        LED=0;
        delay(50);
    addr=PORTC;//读取取件器设置地址值
        sidh=(addr>>3)&0x20;//CAN发送高位标识符
        sidl=(addr<<5)&0x00;//CAN发送低位标识符
        sidh1=(addr>>3)&0x00;//can接收高位标识符
        sidl1=(addr<<5)&0x00;//can接收低位标识符
        opcode=1;//初始化操作码
    fucode=1;//初始化功能码
    takenum=0;//初始化取件数量
    opnum=0;//初始化操作数量
    stcation=0;//初始化指示状态
}
void caninit()
{
    CANCON=0x80;//请求进入CAN配置模式
    while(CANSTAT&0x80==0);//等待进入CAN配置模式
    BRGCON1=0X01;//设置SJW和BRP,SJW=1TQ,BRP=01H
    BRGCON2=0X90;//设置Phase_Seg1=3TQ和Prog _Seg=1TQ
    BRGCON3=0X42;//设置Phase_Seg2=3TQ
    TXB0CON=0X03;//设置发送优先级为最高
    TXB0SIDH=sidh;//高位标识符
    TXB0SIDL=sidl;//低位标识符
    TXB0DLC=0x05;//设置数据长度为5字节
        RXB0SIDH=sidh1;//接收缓冲区0高位标识符
    RXB0SIDL=sidl1;//接收缓冲区0低位标识符
    RXB0CON=0X20;//接收标准标识符
    RXB0DLC=0X05;//设置接收缓冲区0数据长度为5字节
        RXF0SIDH=sidh1;//过滤器
    RXF0SIDL=sidl1;//过滤器
        RXM0SIDH=0XFF;//屏蔽与过滤器标识符不同的数据
    RXM0SIDL=0XFF;//屏蔽与过滤器标识符不同的数据
    RXB1SIDH=0X00;//接收广播
    RXB1SIDL=0X00;//接收广播
    RXB1CON=0X22;//接收标准标识符和过滤器为RXF2
    RXB0DLC=0X05;//设置接收缓冲区1数据长度为5字节
        RXF2SIDH=0X00;//过滤器
        RXF2SIDL=0X00;//过滤器
        RXM1SIDH=0XFF;//接收与过滤器2相同标识符的数据
        RXM1SIDL=0XFF;//接收与过滤器2相同标识符的数据
    CIOCON=0x31;//CAN IO初始化 使用振荡器作为时钟
    CANCON=0X00;//正常工作模式
    while(CANSTAT&0XE0!=0);//检测CAN总线是否正常工作
    PIR5=0X00;//清所有CAN中断
    PIE5=0X0c;//开CAN接收中断
    IPR5=0X0c;//CAN接收中断最高优先级
}
void interrupt canrec()//CAN总线接收中断函数
{
    if((PIR5bits.RXB0IF==1)&&(opcode!=0x06))//缓冲区0接收中断
  {
        PIR5bits.RXB0IF=0;//清中断标志位
        RXB0CONbits.RXFUL=0;//打开接收缓冲器0接收数据
        while(RXB0CONbits.RXFUL==0);
        opcode=RXB0D0;//接收操作码
        fucode=RXB0D1;//接收功能码
        takenum=RXB0D2;//取件数量

  }
        if((PIR5bits.RXB1IF==1)&&(opcode!=0x06))//CAN总线缓冲区1接收中断
  {
        PIR5bits.RXB1IF=0;//清中断标志位
        RXB1CONbits.RXFUL=0;//打开接收缓冲区1接收数据
        while(RXB1CONbits.RXFUL==1);//等待接收完成
        opcode=RXB1D0;//接收操作码
        fucode=RXB1D1;//接收功能码
        takenum=RXB1D2;//接收取件数量
  }
   if((PIR5bits.RXB1IF==1)&&(opcode==6)) //误码率测试
  {
    PIR5bits.RXB1IF=0;//清中断标志位
        RXB1CONbits.RXFUL=0;//打开接收缓冲区1接收数据
        while(RXB1CONbits.RXFUL==1);//等待接收完成
        TXB0D0=RXB1D0;
        TXB0D1=RXB1D1;
        TXB0D2=RXB1D2;
        TXB0D3=RXB1D3;
        TXB0D4=RXB1D4;
        cansend();
  }
        if((PIR5bits.RXB0IF==1)&&(opcode==6))  //误码率测试
  {
    PIR5bits.RXB0IF=0;//清中断标志位
        RXB0CONbits.RXFUL=0;//打开接收缓冲区0接收数据
        while(RXB0CONbits.RXFUL==1);//等待接收完成
        TXB0D0=RXB0D0;
        TXB0D1=RXB0D1;
        TXB0D2=RXB0D2;
        TXB0D3=RXB0D3;
        TXB0D4=RXB0D4;
        cansend();
  }
}
void cansend()//CAN发送数据函数
{

        if(opcode!=0x06)
   {
    TXB0D0=opcode;//写发送缓冲区
    TXB0D1=fucode;//写发送缓冲区
    TXB0D2=takenum;//写发送缓冲区
    TXB0D3=opnum;//写发送缓冲区
    TXB0D4=stcation;//写发送缓冲区
    TXB0CONbits.TXREQ=1;//开始发送
    while(PIR5bits.TXB0IF);//检测是否发送完毕
        TXB0CONbits.TXREQ=0;//禁止发送
   }
   if(opcode==0x06)
   {
    TXB0CONbits.TXREQ=1;//开始发送
    while(PIR5bits.TXB0IF);//检测是否发送完毕
        TXB0CONbits.TXREQ=0;//禁止发送
   }
}
void  run()//上位机命令判断函数
{
    switch(opcode)//操作码判断
  {
    case 0:
    {
          cansend();//状态查询
          opcode=1;
      break;
    }
    case 1:
    {
      if(fucode==0)//复位
       {
                LED=0;
                opcode=1;
        fucode=1;
        takenum=0;
        opnum=0;
        stcation=0;
       }
       if(fucode==1)//取件
        {
         if(takenum!=0)
         {
         LED=1;
         fucode=1;
         stcation=1;
         }
         if(takenum==0)
         {
          LED=0;
         }
        }
        break;
    }
    case 2://进入测试流程
     {
        stcation=0x02;
                LED=1;
        delay(50);
                LED=0;
        delay(50);
                LED=1;
        delay(50);
                LED=0;
        delay(50);
                LED=1;
        delay(50);
                LED=0;
        delay(50);
                LED=1;
        delay(50);
                LED=0;
        delay(50);
                LED=1;
        delay(50);
        LED=0;
        opcode=0;
        stcation=0;
      break;
    }
     case 3://设置取件指示灯
      {
        if(fucode==0x03)
        {
         LED=0;
         stcation=0;
        }
        if(fucode==0x04)
        {
         LED=1;
         stcation=1;
        }
        if(fucode==0x05)
        {
         do
         {
                  LED=1;
          delay(50);
          LED=0;
          delay(50);
          stcation=0x03;
         }
         while((fucode!=0x05)||(opcode!=0x03));
         stcation=0;
        }
        break;
      }
     case 5://重启
     {
       WDTCON=1;//开狗
       while(1);//等待看门狗重启程序
     }
  }
}
void delay(uint time)//延时函数
   {
     uint a,b;
     for(a=time;a>0;a--)
     for(b=110;b>0;b--);
   }
     
            
      
         
   
   
   
   

沙发
yklstudent| | 2013-12-23 20:38 | 只看该作者
这程序看的真头疼 简直没法看
自己慢慢调试好了 屏蔽你的开狗部分 看还复位

使用特权

评论回复
板凳
kevinwangwang|  楼主 | 2013-12-23 22:29 | 只看该作者
yklstudent 发表于 2013-12-23 20:38
这程序看的真头疼 简直没法看
自己慢慢调试好了 屏蔽你的开狗部分 看还复位  ...

:(:(本来就没开狗,开始的时候。后面开狗,但是开始是走不到开狗的那里。

使用特权

评论回复
地板
yklstudent| | 2013-12-24 08:26 | 只看该作者
kevinwangwang 发表于 2013-12-23 22:29
本来就没开狗,开始的时候。后面开狗,但是开始是走不到开狗的那里。 ...

走没走到 自己慢慢调试吧

使用特权

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

本版积分规则

1

主题

2

帖子

0

粉丝