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

求PIC18F25K80,USB转CAN的例程,或者有没有这款单片机写的相关

[复制链接]
5353|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
guaxian|  楼主 | 2013-8-5 11:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 guaxian 于 2013-8-6 14:18 编辑

求PIC18F25K80,USB转CAN的例程,或者有没有这款单片机写的相关代码呢,本人菜鸟求指导啊~有个代码在这,看得也是一知半解啊~求高手帮忙再注释下,讲解下,目前硬件还没做好,只是编译通过了~还没试过收发数据啊。。。。。
#include <htc.h>

//振荡器为HS(12M),系统振荡器时钟转换选择禁止,故障保护时钟监视器禁止,不使用扩展指令集,直接使用振荡器高功耗,禁止低功耗稳压器
__CONFIG(1,RETEN_OFF & INTOSCSEL_LOW & SOSCSEL_DIG & XINST_OFF & FOSC_HS1 & PLLCFG_OFF & FCMEN_OFF & IESO_OFF);
//监视定时器WDT禁止watchdog,掉电锁定复位硬件使能欠压复位(仅硬件)电压为2.0V,上电定时器使能
__CONFIG(2,PWRTEN_OFF & BOREN_SBORDIS & BORV_2 & BORPWR_ZPBORMV & WDTEN_OFF & WDTPS_256); //
//CANTX/CANRX引脚在RB2/RB3上,MSSP V3 7位地址掩码模式,MCLR使能
__CONFIG(3,CANMX_PORTB & MSSPMSK_MSK7 & MCLRE_ON); //
//使能RB6、RB7为专用调试器接口,堆栈溢出复位使能,低压编程禁止
__CONFIG(4,STVREN_OFF & BBSIZ_BB2K);
//程序存储区、数据EEPROM,引导区都无代码保护,正式发布时要改成保护状态。
__CONFIG(5,CP0_OFF & CP1_OFF & CP2_OFF & CP3_OFF & CPB_OFF & CPD_OFF);
//程序存储区、数据EEPROM,引导区、配置寄存器都无写保护
__CONFIG(6,WRT0_OFF & WRT1_OFF & WRT2_OFF & WRT3_OFF & WRTC_OFF & WRTB_OFF & WRTD_OFF);
//程序存储区、引导区都无表读保护
__CONFIG(7,EBTR0_OFF & EBTR1_OFF & EBTR2_OFF & EBTR3_OFF & EBTRB_OFF);


/*全局变量定义*/

char CAN_TX_Adress_H;         //CAN高地址标识符,应与接收方标识符相同
char CAN_TX_Adress_L;         //CAN低地址标识符
// 设置接收邮箱0标识符
char CAN_RX_Adress_H;         //CAN高地址标识符
char CAN_RX_Adress_L;         //CAN低地址标识符,应与发送方标识符相同

unsigned char CanRecFlag;          //=1接收到自身的CAN 数据,=0未接收到数据
unsigned char Counter;              //计数器
unsigned char UartFlag;            //串口数据接收标志

unsigned char Uartdata[8];         //接收数据,PC-MCU
unsigned char Senddata[8];         //发送数据,MCU-PC


/*函数声明*/

#define Fosc     12000000   //晶振为12MHZ  
#define BAUDRATE 9600       //波特率为9600(uart串口)

void PicInit(void);   //芯片初始化
void CANInit(void);  //自带CAN口初始化
void interrupt HI_ISR(void);
void interrupt low_priority LOW_ISR(void);
void Delay(unsigned int time);  //延时函数
void UartInt(void);  //串口初始化程序


/*芯片初始化程序*/
void PicInit(void)
{
        PORTA = 0x00;    //清除PORTA完成初始化
        LATA = 0x00;     //清除数据输出锁存
        PORTB = 0x00;
        LATB = 0x00;
        PORTC = 0x00;
        LATC = 0x00;
        ADCON1 = 0x0F;   //关闭模拟通道,使之为数字通道
        UartFlag = 0;    //计数器清0
        CanRecFlag =0;
        Counter = 0;      
}

/*串口初始化程序(与PC通讯)*/

void UartInt(void)
{
        TRISC6 = 0;         //设置UART端口,RC6是数据发送
        TRISC7 = 1;         //RC7是数据接收
        BAUDCON1=0x00;      //8位波特率发生器,SPBRGH值忽略
        SPBRG1 = ((Fosc/BAUDRATE)/64)-1;  //值约为(31)8位,异步,低速 (波特率设置寄存器)
        TXSTA1 = 0b00100010;//异步模式,8位发送,发送使能,低速
        RCSTA1 = 0b10010000;//使能串口,8位接收,使能连续接收
        RCIP = 0;           //EUSATR串口接收设置为低优先级中断
        RCIE = 1;           //允许EUSART接收中断
        TXIE = 0;           //禁止发送中断
        CREN1 = 1;          //允许串口接收数据
        PIR1bits.RCIF = 0;  //串口接收中断标志清零
}

/*自带CAN口初始化*/

void CANInit(void)
{
        TRISB2 = 0;                      //设置CANRX-RB3输入
        TRISB3 = 1;                      //设置CANTX-RB2输出
        CANCON = 0x80;                   //请求配置方式(0x00请求进入正常模式)
        while((CANSTAT&0x80)==0);        //等待进入配置模式(若=0x40进入自测模式)   
        // 设置CAN波特率125kbps,在Fosc=12MHz时,Tbit=8us,假设BRP=05h
        // 则Tq=[2*(1+BRP)]/Fosc=2*(1+5)/(12MHz)=1us
        // normal bit rate=8Tq,SJW=00,Sync_Seg=1Tq,Prog_Seg=1Tq
        // Phase_Seg1=3Tq,Phase_Seg2=3Tq
        // 位时间=(1+1+3+3)=8Tq
        // 总线过滤器用于唤醒
        BRGCON1 = 0x05;        // SJW同步跳转宽度SJW=00(1Tq),BRP=05h波特率预分频比为5
        BRGCON2 = 0x90;        // 配置相位缓冲段1 Phase_Seg1为3Tq,传播时间为1 Prog _SegTq
        BRGCON3 = 0x42;        // 配置相位缓冲段2为3Tq,使用CAN总线线路滤波器来唤醒
       
        //设置发送邮箱0标识符 :00110011111=0x019F
        CAN_TX_Adress_H=0x33;         //CAN高地址标识符,应与接收方标识符相同
        CAN_TX_Adress_L=0xe0;         //CAN低地址标识符
        CAN_TX_Adress_L=CAN_TX_Adress_L&0xe0;

        // 设置接收邮箱0标识符 :10011001010=0x04CA
        CAN_RX_Adress_H=0x99;         //CAN高地址标识符
        CAN_RX_Adress_L=0x55;         //CAN低地址标识符,应与发送方标识符相同
        CAN_RX_Adress_L=CAN_RX_Adress_L&0xe0;
       
        //设置发送邮箱0标识符号和发送的数据
        TXB0CON = 0x03;                   //设置TXB0 发送最高优先级3
        TXB0SIDH = CAN_TX_Adress_H;       //
        TXB0SIDL = CAN_TX_Adress_L&0xe0;  //
        TXB0DLC = 0x08;                   //设置数据缓冲区长度为8个字节
        TXB0D0 = 0x01;                    //第2个字节 // 第一个字节用来区分是发送到那个can口的标记     
        TXB0D1 = 0x02;                    //第3个字节      
        TXB0D2 = 0x03;                    //第4个字节      
        TXB0D3 = 0x04;                    //第5个字节      
        TXB0D4 = 0x05;                    //第6个字节      
        TXB0D5 = 0x06;                    //第7个字节      
        TXB0D6 = 0x07;                    //第8个字节      
        TXB0D7 = 0x08;                    //第9个字节  

        //设置接收邮箱0的标识符和初始化数据
        RXB0SIDH = CAN_RX_Adress_H;                  //
        RXB0SIDL = CAN_RX_Adress_L&0xe0;             //
        RXB0CON = 0x20; //仅接收带有标准标示符的有效报文
        RXB0DLC = 0X08; //设置接收缓冲器0的数据区长度
        RXB0D0 = 0X00;  //初始化接收缓冲器0的数据区数据
        RXB0D1 = 0X00;
        RXB0D2 = 0X00;
        RXB0D3 = 0X00;
        RXB0D4 = 0X00;
        RXB0D5 = 0X00;
        RXB0D6 = 0X00;
        RXB0D7 = 0X00;

        //*******初始化接收滤波器0和接收屏蔽*****************/
        RXF0SIDH=CAN_RX_Adress_H;
        RXF0SIDL=CAN_RX_Adress_L&0xe0;//高3位为标识符低3位,低5位是配置 */
        RXM0SIDH=0Xff;
        RXM0SIDL=0Xe0;                //11个1表示接收11位标识符进行滤波,标识符不同不接收

        //初始化CAN模块的I/O控制寄存器,当“隐性”时,CANTX引脚驱动到高阻状态,禁止CAN捕捉
        CIOCON = 0x00;
        CANCON = 0x00;                    //请求正常方式
        while((CANSTAT&0x80) != 0);       //等待进入正常模式

        //初始化CAN的中断,PIR3为CAN的外围中断标志寄存器
        PIR5bits.RXB0IF = 0;              //CAN接收缓冲器0中断标志位清零
        PIE5bits.RXB0IE = 1;              //使能CAN接收缓冲器0的接收中断
        IPR5bits.RXB0IP = 1;              //接收缓冲器0的接收中断为高优先级
        NOP();
       
}

/*中断函数*/

void interrupt HI_ISR(void)
{
        if(PIR5bits.RXB0IF ==1 )
        {
                CanRecFlag = 1;                        //自带can接收到CAN数据
                PIR5bits.RXB0IF = 0;        //清接收中断标志
                RXB0CONbits.RXFUL = 0;        //打开接收缓冲器,使可以接收新信息
        }

}

void interrupt low_priority LOW_ISR(void)
{
  if((PIE1bits.RCIE == 1)&&(PIR1bits.RCIF == 1))  //判断是不是串口中断 ,RCIF=1 接收缓冲区RCREG1已满
  {
     Uartdata[Counter]=RCREG;
     Counter++;
     if(Counter>7)                     //8位有效数据
     {
       Counter=0;
       UartFlag=1;                    //有串行数据接收
     }
  }
}


/*延时函数*/

void Delay(unsigned int time)
{
        unsigned int i;
        for(i=0;i<time;i++)
        {;}
}

/*串口接收转发到Can函数*/

void Com2Can(void)
{
        TXB0CON=TXB0CON&0xf7;    //bit3:TXREQ=0, 关请求发送
        UartFlag=0;             //清标志
        TXB0D0=Uartdata[0];      //CAN发送数据更新(用串口接收来的数据)
        TXB0D1=Uartdata[1];
        TXB0D2=Uartdata[2];
        TXB0D3=Uartdata[3];
        TXB0D4=Uartdata[4];
        TXB0D5=Uartdata[5];
        TXB0D6=Uartdata[6];
        TXB0D7=Uartdata[7];
        TXB0CON=TXB0CON|0x08;                  //请求发送,TXB0CONbits.TXREQ=1
        while(TXB0CONbits.TXREQ);        //等待发送完毕
//        Delay(10000);
}

/*Can接收转发到串口函数*/

void Can2Com(void)      //接收数据返回PC机
{
        unsigned char i;
        Senddata[0]=RXB0D0;
        Senddata[1]=RXB0D1;
        Senddata[2]=RXB0D2;
        Senddata[3]=RXB0D3;
        Senddata[4]=RXB0D4;
        Senddata[5]=RXB0D5;
        Senddata[6]=RXB0D6;
        Senddata[7]=RXB0D7;
        RCEN=0;              //接收禁止
        TXEN1=1;              //使能串口发送
        for(i=0;i<8;i++)       //串口数据发送
        {
                TXREG = Senddata;
                while(TXSTA1bits.TRMT == 0);
//                Delay(100);
        }
        TXEN1=0;              //禁止数据发送
        RCEN=1;              //接收使能
}

/*Main函数*/

void main(void)
{
        INTCON = 0x00;  //禁止所有中断
        PicInit();      //芯片状态初始化
        CANInit();      //芯片自带can口初始化
        UartInt();      //串口初始化
        IPEN = 1;       //使能中断优先级
        INTCON |= 0xC0; //开放所有高低优先级中断
        TXB0CONbits.TXREQ = 0;      //禁止CAN发送  
        while(1)
        {
                //串口接收到数据转发
                if(UartFlag)          //接收到串口数据
                {
                        UartFlag=0;
                        Com2Can();
                }
                //CAN 接收到数据转发
                if(CanRecFlag)         //接收到CAN总线数据
                {
                        CanRecFlag=0;
                        Can2Com();
                }

        }

}





沙发
guaxian|  楼主 | 2013-8-5 11:48 | 只看该作者
求高手看看程序有没有写错····

使用特权

评论回复
板凳
guaxian|  楼主 | 2013-8-5 15:24 | 只看该作者
:(一个人也木有·····

使用特权

评论回复
地板
xzy520xr| | 2013-8-12 15:21 | 只看该作者
CAN 应该是没问题的,都有官网的例程

使用特权

评论回复
5
tianyazhix| | 2013-8-13 10:57 | 只看该作者
PIC18 CAN以前调试过,

使用特权

评论回复
6
18986119377| | 2013-11-17 22:41 | 只看该作者
你的头文件自己写到的吗?

使用特权

评论回复
7
18986119377| | 2013-11-17 22:43 | 只看该作者
怎么在mplab中建一个25k80工程文件不能编译呢

使用特权

评论回复
8
yewuyi| | 2013-11-18 11:40 | 只看该作者
1、这个代码肯定不是你自己写的。
2、肯定没人帮你看完这段代码。

使用特权

评论回复
9
Rain_King| | 2013-11-18 13:41 | 只看该作者
代码是没有人帮你看的.............你只能进一步简化成理论的问题

使用特权

评论回复
10
taogaowei| | 2017-1-3 10:48 | 只看该作者
好长的代码,可是硬件原理图有吗?

使用特权

评论回复
11
血刀老祖| | 2017-1-5 09:32 | 只看该作者
请问,官网的例程在哪里找?谢谢

使用特权

评论回复
12
wonderwonder| | 2017-1-17 22:23 | 只看该作者
应该没问题

使用特权

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

本版积分规则

2

主题

6

帖子

0

粉丝