标题:
PIC单片机:为什么写的程序光跑飞啊,新手一枚
[打印本页]
作者:
SDDQ
时间:
2022-4-15 12:01
标题:
PIC单片机:为什么写的程序光跑飞啊,新手一枚
程序通电我设置一个灯亮A,进入主函数后,CAN发送成功或者失败对应的灯会亮,但是我只通电不进行任何操作,A灯一直在那里闪,那不就是跑飞了吗?我禁止看门狗了呀!好困惑
#include "p18f458.h"
unsigned int i;
unsigned char j;
int CAN_FLAG; //定义标志寄存器、
//************初始化子程序***********//
void initcan()
{
TRISA=0x20;/*RA5设置为输入,RA0-RA3端口设置为输出(1入,0出)*/
TRISC=0xFF;/*RC0-RC3端口设置为输入,全为输入*/
TRISB=0x08;//把CANRX/RB3设置为输入,CANTX/RB2设置为输出
CANCON=0x80; //请求进入CAN配置模式REQOP=100
while(CANSTAT&0x80==0){;}//等待进入CAN配置模式OPMODE=100,CANSTA&1000 0000,只有第八位为1才不为0,该寄存器只有100配置方式为1,
//所以程序进入其他值时一直在循环空语句等待配置方式进入
//以下为波特率的设定
BRGCON1=0x01;
BRGCON2=0x90;
BRGCON3=0x42;
//设置发送邮箱0标识符号和发送数据
CIOCON=0x00; //CAN输入输出控制寄存器
TXERRCNT=0x00;//初始化发送错误计数寄存器
TXB0CON=0x03;//发送优先级为最高优先级,TXPRI=11
TXB0SIDH=0xFF;//设置“发送"缓冲器0的标准标识符,设置标准标识符高字节寄存器 ,扩展标识符位EID28:EID21
TXB0SIDL=0xE0;//设置标准标识符低字节寄存器,扩展标识符位EID20:EID18
TXB0DLC=0x08;//设置数据长度为8个字节
TXB0D0=0x00;
TXB0D1=0x01;
TXB0D2=0x02;
TXB0D3=0x03;
TXB0D4=0x04;
TXB0D5=0x05;
TXB0D6=0x06;
TXB0D7=0x07;
//设置接收邮箱0的标识符和初始化数据
RXB0SIDH=0xFF;//设置"接收"缓冲器0的标准标识符,扩展标识符位EID28:EID21
RXB0SIDL=0xE0;//扩展标识符位EID20:EID18
RXB0CON=0x20;//仅接收标准标识符有效的信息,bit=0表示RXBO采用过滤器0
RXB0DLC=0x08;//设置数据长度为8个字节
RXB0D0=0x00;
RXB0D1=0x00;
RXB0D2=0x00;
RXB0D3=0x00;
RXB0D4=0x00;
RXB0D5=0x00;
RXB0D6=0x00;
RXB0D7=0x00;
//初始化接收过滤器0和接收屏蔽
RXF0SIDH=0xFF;//设置"接收"过滤器0的标准标识符,扩展标识符"过滤位"EID28:EID21
RXF0SIDL=0xE0;//扩展标识符“过滤位”EID20:EID18
RXM0SIDH=0x00;//设置"接收"屏蔽器0的标准标识符
RXM0SIDL=0x00;
//CAN进入相应的工作模式
CANCON=0x00;//=0x40为进入自测试模式;0x00为进入正常操作模式。
while(CANSTAT&0xE0){;}//等待进入CAN正常模式OPMODE=000,CANSTA&1110 0000,
//只有第6.7.8位为0(000为CAN正常模式)才能不满足括号内条件,
//从而跳出循环,反之则等待。
//初始化CAN中断
PIR3=0x00;//清除所有中断
PIE3=0x01;//使能接收缓冲器0的接收中断
IPR3=0x01;//接收缓冲器0的接收中断为最高优先级。
}
//************接收缓冲器0接收中断服务程序**************
#pragma interrupt can_isr
#pragma code low_ISR=0x18
void low_ISR()
{
_asm
goto can_isr
_endasm
}
#pragma code
void can_isr()
{
if(PIR3bits.RXB0IF==1) CAN_FLAG=1;
PIR3bits.RXB0IF=0;//清除接收中断标志
RXB0CONbits.RXFUL=0;//打开接收缓冲器来接收信息
}
//********延时程序********
void DELAY()
{
for(i=65000;i>1;i--);
{
for(j=650;j>1;j--);
}
}
//********主程序********
void main (void)
{
INTCON=0x00;//禁止所有中断
initcan();//初始化
WDTCON=0;//=1看门狗使能,=0禁止看门狗
INTCON=0xc0;//使能中断
PORTA=0xF4;//点亮第一个LED//
DELAY();
PORTA=0xFF;//关闭LED //
while(1)
{
//*********CAN发送********//
TXB0CONbits.TXREQ=1; //请求发送,TXREQ=1,发送终止位/发送丢失仲裁状态位/发送错误检测状态位都清除
while(PIR3bits.TXB0IF!=1)//等待发送完成,TXB0IF缓冲器0完成中断标志位,只有当该位为1时才完成了信息的发送,可重新装载
{
if(COMSTATbits.TXBO)//发送错误计数大于255则该位为1
{
PORTA=0xF0;/*向PORTA发送数据,点亮两个LED,说明发送失败*/
TXB0CONbits.TXABT=1;//中止发送
TXB0CONbits.TXREQ=0;//TXREQ发送请求位置0,因为发送成功后它自动清零,他没有发送成功,所以要手动清零
TXERRCNT= 0x00;//清除发送错误计数器
break;
}
}
if(PIR3bits.TXB0IF=1)//说明缓冲器0完成了信息的发送//
{
PORTA=0xF4;/*向PORTA发送数据,点亮RA3控制的第一个LED,说明CAN发送成功*/
}
//********CAN接收********//
while(CAN_FLAG==0)//等待接收数据
{
if(COMSTATbits.RXBP)//接收器总线错误过半位=1则为(接收错误计数>127)
{
PORTA=0xF4;//点亮第一个LED//
DELAY();
PORTA=0xFF;//关闭LED //
PORTA=0xF8;//点亮第二个LED //
DELAY();
PORTA=0xFF;//关闭LED //
PORTA=0xF0;//点亮两个LED,说明接收失败 //
TXERRCNT= 0x00;//清除发送错误计数器
break;
}
}
if(PIR3bits.TXB0IF=1)//说明缓冲器0完成了信息的发送//
{
PORTA=0xF8;/*点亮RA3控制的第2个LED,说明CAN接收成功*/
}
CAN_FLAG=0; //清除接收到的标志
TXB0CONbits.TXREQ=0; //禁止发送
TXB0D0=RXB0D0+1;
TXB0D1=RXB0D1+1;
TXB0D2=RXB0D2+1;
TXB0D3=RXB0D3+1;
TXB0D4=RXB0D4+1;
TXB0D5=RXB0D5+1;
TXB0D6=RXB0D6+1;
TXB0D7=RXB0D7+1;
}
}
复制代码
作者:
人工置顶员
时间:
2022-4-16 04:50
顶一下
作者:
Y_G_G
时间:
2022-4-16 15:23
1,在这用PIC单片机的人少
2,会PIC又会CAN的就更少了
作者:
SDDQ
时间:
2022-4-18 16:36
Y_G_G 发表于 2022-4-16 15:23
1,在这用PIC单片机的人少
2,会PIC又会CAN的就更少了
哎呀呀,困扰好久了
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1