这里转载的是别人现成的代码,进行了实际的编译和下载运行,罗列了实际运行中出现的问题,主要是证明代码的可靠性。
1、新建工程、选择好器件、选择编译环境,我当时选择的是C:Program Files (x86)Microchipmplabc18v3.47文件夹下的C18编译器。实际操作时,我当时误选了_mplink.exe,实际上选择的应该是mplink.exe文件。编译时出现错误,重新选择后,错误消除。
2、文件如下
源文件
main.c
#pragma config XINST = OFF // CONFIG1L
#pragma config FOSC = INTIO2, FCMEN = OFF, IESO = OFF ,PLLCFG = OFF // CONFIG1H
#pragma config BOREN = OFF, BORV = 0 // CONFIG2L
#pragma config WDTEN = OFF // CONFIG2H
/** I N C L U D E S **************************************************/
#include "main.h"
unsigned char CAN_RecFLAG=0;
unsigned char Flag50ms = 0;
// AD采样的数据变量
unsigned int VoltageEdlc[5];
unsigned int VoltageBat;
unsigned int Current1;
unsigned int Current2;
unsigned int Temperature1;
unsigned int Temperature2;
void InterruptHandler(void);
#pragma code high_vector=0x08
void high_interrupt (void)
{
_asm GOTO InterruptHandler _endasm
}
#pragma code
#pragma code low_vector=0x18
void low_interrupt (void)
{
_asm GOTO InterruptHandler _endasm
}
#pragma code
#pragma interruptlow InterruptHandler
#pragma interrupt InterruptHandler
void InterruptHandler(void)
{
static unsigned char Tick = 0;
static unsigned char ChannelNo = 0;
// 定时器0
if(INTCONbits.TMR0IF&&INTCONbits.TMR0IE) // timer0 = 10ms
{
INTCONbits.TMR0IF = 0;
TMR0H = 0x63;
TMR0L = 0xBF;
Tick++;
if(Tick ==200)
{
Flag50ms = 1; // 5s发送CAN消息到ECU
Tick = 0;
LATCbits.LATC5 = ~LATCbits.LATC5;
}
}
// CAN接收数据
if(PIR5bits.RXB0IF==1)
{
CAN_RecFLAG=1;
PIR5bits.RXB0IF=0; // 清接收中断标志
RXB0CONbits.RXFUL=0; // 清除标志,接收新报文
}
}
#pragma code
void main(void)
{
unsigned int EDLC_temp[4];
INTCON=0x00;
InitInterOSC();
InitPORT();
InitCan();
Timer0_Init();
// INTCON=0xc0; //使能中断 1100 0000
INTCONbits.GIE=1;
INTCONbits.PEIE=1;
// INTCONbits.GIEL=1;
// TXB0CONbits.TXREQ = 0;
while(1)
{
if(CAN_RecFLAG==1)
{
CAN_RecFLAG = 0;
TXB0D0=1; /* 写发送缓冲器数据区数据初值 */
TXB0D1=2;
TXB0D2=3;
TXB0D3=4;
TXB0D4=5;
TXB0D5=6;
TXB0D6=7;
TXB0D7=8;
TXB0CONbits.TXERR = 0;
TXB0CONbits.TXREQ=1; //请求发送,TXREQ=1
// while(TXB0CONbits.TXREQ){;}
while(!PIR5bits.TXB0IF){;}
Delay10KTCYx(1000);
Delay10KTCYx(1000);
}
}
}
SysInit.c
#include "main.h"
#include "p18f45k80.h"
void InitInterOSC(void)
{
// Set the internal oscillator to 64MHz
OSCCONbits.IRCF = 7; // 16 M
OSCTUNEbits.PLLEN = 0;
}
void InitPORT(void)
{
/*
RE2 RE1 RE0 RA5 RA3 RA2 RA1 RA0
AN7 AN6 AN5 AN4 AN3 AN2 AN1 AN0 : ANCON0
Current2 Current1 BatV C5 C4 C3 C2 C1
RB0 RB4 RB1
X X X X X AN10 AN9 AN8 : ANCON1
temp2 temp1
*/
ANCON0 = 0xff;
ANCON1 = 0x03; // 模拟/数字口选择
TRISA = 0b00101111; // RA方向寄存器
TRISB = 0b11111010; // RB方向寄存器
TRISC = 0b00000000; // RC方向寄存器
TRISD = 0b10010000; // RD方向寄存器
TRISE = 0b00001111; // RE方向寄存器
LATCbits.LATC1 = 0; // disable buck
LATCbits.LATC2 = 0; // disable boost
LATCbits.LATC4 = 1; // enable Aux power
}
// 使用16位定时器,使用内部时钟16Mhz,周期是4/16M = 0.25uS, TMR0H=TMR0L=0.定时时间2^16 = 65535/4uS=16.383mS
void Timer0_Init(void)
{
// RCONbits.IPEN=1; //打开中断高低优先级
INTCONbits.TMR0IE = 1; // 允许定时器0溢出中断
INTCONbits.TMR0IF = 0; // 清除中断标志
// INTCON2bits.TMR0IP = 0; // 设置定时器0中断为低优先级
T0CON = 0b00001000; // 定时器0设定为16位定时器,内部时钟触发,不使用分频器
// T0CON = 0b00000001; // 定时器0设定为16位定时器,内部时钟触发,使用分频器,1:4分频比
TMR0H = 0x63; // clear timer - always write upper byte first
TMR0L = 0xBF; // timer = 10ms
// INTCONbits.GIE=1;
// INTCONbits.PEIE=1;
// INTCONbits.GIEL=1;
T0CONbits.TMR0ON=1;
}
// need to set to 500kbps,standard frame
void InitCan(void)
{
TRISB=(TRISB|0x08)&0xFB; //设置CANRX/RB3为输入,CANTX/RB2为输出
CANCON = 0x80;
while(CANSTAT&0x80==0){;}
// 500Kbps@16M
BRGCON1 = 0x00; //0000 0100
BRGCON2 = 0xb8; //1011 1010
BRGCON3 = 0x05; //0000 0101
CIOCON=0X00;
ECANCON=0x00;
//设置发送邮箱0标识符号和发送的数据
TXB0CON=0x03; // TXB0发送优先级为最高优先级,TXPRI=11
TXB0SIDH=0b01010001; // 设置发送缓冲器0为标准标识符,ID = 0x28F
TXB0SIDL=0b11100000;
// TXB0SIDH=0x00; // 设置发送缓冲器0为标准标识符,ID = 0x28F
// TXB0SIDL=0x00;
TXB0DLC=0x08; // 设置数据长度为8个字节
TXB0D0=0X10; /* 写发送缓冲器数据区数据初值 */
TXB0D1=0X11;
TXB0D2=0X12;
TXB0D3=0X13;
TXB0D4=0X14;
TXB0D5=0X15;
TXB0D6=0X16;
TXB0D7=0X17;
//设置接收邮箱0的标识符和初始化数据
RXB0SIDH=0Xff; // 设置接收缓冲器0的标识符 ID = 0x26D
RXB0SIDL=0Xe0;
RXB0CON=0X20; // 仅仅接收标准标识符,FILHIT0=0表示RXB0采用filter0
RXB0DLC=0X08; // 设置接收缓冲器0的数据区长度
//初始化接收滤波器0,Id = 0x26D = 0b 010 0110 1101
RXF0SIDH=0b01001101;
RXF0SIDL=0b10100000;
//初始化接收屏蔽器0,所有11位都比较滤波
RXM0SIDH=0Xff;
RXM0SIDL=0Xe0;
//所有ID 都进来
// RXM0SIDH=0X00;
// RXM0SIDL=0X00;
Nop();
//使CAN进入某种工作模式
CANCON=0x00; //=0X40,进入自测试模式;=0x00,正常操作模式
while(CANSTAT&0XE0!=0){;}
//while(CANSTAT&0X40==0){;}
//初始化CAN的中断
PIR5=0X00; //清所有中断标志
PIE5=0X01; //使能接收缓冲器0的接收中断
// IPR5=0X01; //接收缓冲器0的接收中断为最高优先级
}
头文件
main.H
#ifndef _MAIN_H_
#define _MAIN_H_
#include
#include
#include "SysInit.h"
extern unsigned int VoltageEdlc[5];
extern unsigned int VoltageBat;
extern unsigned int Current1;
extern unsigned int Current2;
extern unsigned int Temperature1;
extern unsigned int Temperature2;
#endif
p18f45k80.h
/*-------------------------------------------------------------------------
* MPLAB-Cxx PIC18F45K80 processor header
*
* (c) Copyright 1999-2011 Microchip Technology, All rights reserved
*-------------------------------------------------------------------------*/
#ifndef __18F45K80_H
#define __18F45K80_H
extern volatile far unsigned char RXERRCNT;
extern volatile far union {
struct {
unsigned REC:8;
};
struct {
unsigned REC0:1;
unsigned REC1:1;
unsigned REC2:1;
unsigned REC3:1;
unsigned REC4:1;
unsigned REC5:1;
unsigned REC6:1;
unsigned REC7:1;
};
} RXERRCNTbits;
extern vola
『本文转载自网络,版权归原作者所有,如有侵权请联系删除』