查看: 852|回复: 0
打印 上一主题 下一主题

AT90CAN128的CAN收发程序

[复制链接]
跳转到指定楼层
沙发
发表于 2016-6-14 18:51:23 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近研究这块芯片,也找了点资料,现在整理完的程序如下,和大家分享。

can.h
******************************************************************************/

#ifndef __can_h__
#define __can_h__

struct MOb
{
        unsigned long id;
        unsigned char data [8];
};

void can_init (void);
void can_tx (struct MOb msg);
void can_rx (struct MOb msg);

#endif

****************************************************************************************************************

#include <avr/io.h>
#include "can.h"

/****************************************************************/
/* CAN initialization                                                */
/****************************************************************/
void can_init (void)
{
        //reset CAN interface
        CANGCON |= (1<<SWRES);
        
        //reset all MObs
        for (unsigned char i=0; i<15; i++)
        {
                CANPAGE = (i<<4);        //select MOb
                CANCDMOB = 0;                //disable MOb
                CANSTMOB = 0;                //clear status
                CANIDT1 = 0;                //clear ID
                CANIDT2 = 0;
                CANIDT3 = 0;
                CANIDT4 = 0;
                CANIDM1 = 0;                //clear mask
                CANIDM2 = 0;
                CANIDM3 = 0;
                CANIDM4 = 0;
                for (unsigned char j=0; j<8; j++)
                        CANMSG = 0;        //clear data
        }

        // set CAN -> baudrate        
        // bit timing -> datasheet 264 (check table)
        // 250Kbps 16MHz cpu-clk
        CANBT1 = 0x0E;for
        CANBT2 = 0x04;
        CANBT3 = 0x13;
        
        // clear CAN interrupt registers
        CANGIE = 0;                        // none interrupts
        CANIE1 = 0;                        // none interrupts on MObs
        CANIE2 = 0;
        CANSIT1 = 0;                        
        CANSIT2 = 0;

        //start CAN interface
        CANGCON = (1<<ENASTB);

        //wait until module ready        
        while (!(CANGSTA & (1<<ENFG)));
}

/****************************************************************/
/* CAN transmission via mailbox 1 (polling)                        */
/****************************************************************/
void can_tx (struct MOb msg)
{        
        //enable MOb1, auto increment index, start with index = 0
        CANPAGE = (1<<4);
        
        //set IDE bit, length = 8
        CANCDMOB = (1<<IDE) | (8<<DLC0);
        
        //write 29 Bit identifier
        msg.id <<= 3;
        CANIDT4 = (unsigned char) (msg.id&0xF8);
        CANIDT3 = (unsigned char) (msg.id>>8);
        CANIDT2 = (unsigned char) (msg.id>>16);
        CANIDT1 = (unsigned char) (msg.id>>24);
        
        //put data in mailbox
        for (unsigned char i=0; i<8; i++)
                CANMSG = msg.data ;
        
        //enable transmission
        CANCDMOB |= (1<<CONMOB0);

        //wait until complete
        while (!(CANSTMOB & (1<<TXOK)));

        //reset flag
        CANSTMOB &= ~(1<<TXOK);
}


/****************************************************************/
/* CAN reception evia mailbox 0 (polling)                        */
/****************************************************************/
void can_rx (struct MOb msg)
{
        
        CANHPMOB=0;
        
        //select MOb0
        CANPAGE = 0x00;        //select MOb0

        //clear MOb flags
        CANSTMOB = 0;

        // select ID which can be receive
        CANIDT4 = (uint8_t) (msg.id << 3);
        CANIDT3 = (uint8_t) (msg.id >> 5);
        CANIDT2 = (uint8_t) (msg.id >> 13);
        CANIDT1 = (uint8_t) (msg.id >> 21);

        // set mask in order to receive only the message with the ID
        CANIDM4 = 248;
        CANIDM3 = 255;
        CANIDM2 = 255;
        CANIDM1 = 255;
        // enable extended ID
        CANIDM4 |= (1<<IDEMSK);

        // enable reception and
        CANCDMOB=(1<<CONMOB1) | (1<<IDE);

        // wait until reception is complete
        while(!(CANSTMOB&(1<<RXOK)));
        
        // reset flag
        CANSTMOB &= ~(1<<RXOK);
        
        // get data
        for (unsigned char i=0; i<(CANCDMOB&0xf); i++)
                msg.data = CANMSG;

        //get identifier which has to be the same like ID
        msg.id = 0;
        msg.id |= ((unsigned long) CANIDT1<<24);
        msg.id |= ((unsigned long) CANIDT2<<16);
        msg.id |= ((unsigned long) CANIDT3<<8);
        msg.id |= (CANIDT4&0xF8);
        msg.id >>= 3;
}

**************************************************************************************************************************

#include <avr/io.h>
#include <stdlib.h>
#include "usart0.h"
#include "can.h"

// message to receive
struct MOb msg={0x1,{0,0,0,0,0,0,0,0}};

// toggle the LED on the Crumb-Board
#define toggleLED() (DDRB^=(1<<7))

int main(){
        // init usart on 19200 8N1 at 16 MHz cpu clock
        usart0_init(51);
        // greet the world
        usart0_transmit_string("Hello World\n");
        // init the can interface
        can_init();

        while(1){
                // send can message
                can_rx(msg);

                toggleLED();
        }
}
***************************************************************************************
usart0.c


#include <avr/io.h>
#include "usart0.h"

/* Initialize UART */
void usart0_init( unsigned int baudrate )
{
        /* Set the baud rate */
        UBRR0H = (unsigned char) (baudrate>>8);                  
        UBRR0L = (unsigned char) baudrate;
        
        /* Enable UART receiver and transmitter */
        UCSR0B = ( ( 1 << RXEN0 ) | ( 1 << TXEN0 ) );
        
        /* Set frame format: 8N1 */
        UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
}


/* Read and write functions */
unsigned char usart0_receive( void )
{
        /* Wait for incomming data */
        while ( !(UCSR0A & (1<<RXC0)) );                                       
        /* Return the data */
        return UDR0;
}

void usart0_transmit( unsigned char data )
{
        /* Wait for empty transmit buffer */
        while ( !(UCSR0A & (1<<UDRE0)) );                                         
        /* Start transmittion */
        UDR0 = data;                                 
}

void usart0_transmit_string(char* p){
        while (*p)
                usart0_transmit(*p++);
}

*******************************************************************************************************************
usart0.h

#ifndef __usart0_h__
#define __usart0_h__

void usart0_init( unsigned int baudrate );
unsigned char usart0_receive( void );
void usart0_transmit( unsigned char data );
void usart0_transmit_string(char* p);

#endif

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入因仑

本版积分规则

快速回复 返回顶部 返回列表