⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cantest.c

📁 AVR系列单片机
💻 C
字号:
#include <avr/io.h>
#include <avr/delay.h>
#include <avr/interrupt.h>
//-----------------------------------------------------------------------------|
// 初始化 :MCU 时钟,端口方向 ,USART1 波特率 ,CAN控制器 ,看门狗 ,TCC1     |
// CAN控制器 0# ,4# 信箱中断接收 ,1#、2#、3# 信箱发送数据                     |
// 定时器 TCC1 做CAN数据一秒内达到判断,1秒内无数据报警                        |
//-----------------------------------------------------------------------------|
unsigned char can_data[4][8]=
							{
								1,2,3,4,5,6,7,8,
								11,12,13,14,15,16,17,18,
							};



void mcu_init(void)
{
unsigned int i=0; 
//-------------------prot init-------------------
 	 //DDRC  = 0xff;                                                                 //端口设置:PC设置为推挽1输出
 	// PORTC = 0xfe;
 	 DDRA  = 0x00;                                                                 //端口设置:PA设置为输入

//---------------- MCU interrupt ----------------
 	 SREG = 0x00;                                                                  //关全局中断; 0x80开全局中断

//-----------------usart 1 INITIAL---------------
  	UBRR1 =25;                                                                    //USART1 波特率设置9600 X 16M-"103",
                                                                                //38400bpsX16M=25;
 	 UCSR1B=(1<<RXEN1)|(1<<TXEN1)|(1<<RXCIE1);                                     //使能接收 & 使能发送 & 使能接收中断
 	 UCSR1C=(1<<UCSZ10)|(1<<UCSZ11);                                               //0x06 8位数据,1位停止位,无校验 */

//----------------CAN_REG INITIAL----------------
 	 CANGCON |= (1<<SWRES); 
	  for(i=0;i<=50000;i++){}       
	     for(i=0;i<=50000;i++){}     
		   for(i=0;i<=50000;i++){}     
		     for(i=0;i<=50000;i++){}     
			   for(i=0;i<=50000;i++){}     
			     for(i=0;i<=50000;i++){}     
				                                               //CAN控制器软复位
 	 CANBT1 = 0X06;    
	       
	                                                      //设置波特率分频因子16MHz,16TQ,250k,=4=3+1,3
 	 CANBT2 = 0x0c;                                                                //同步段为1“0x0n”传播段=7=6+1
	CANBT3 = 0x37;    
	                                                            //相位缓冲PH2=4=3+1,PH1=4=3+1
 	// CANTCON = 0xff;
	CANTCON = 0B00000010;

//--------------can_MOB INITIAL-------------------
//MOB0=RX[CMD]    接收上位机发来的指令       //格式:3,0,0,177,239,33
 	 CANPAGE  = 0x00;                                                              //MOB0,自动增量,初值为0
 	 CANSTMOB = 0;
 	 CANCDMOB = 0x08;    //2.0b  0x10    8个byte     
    /*                                          //can2B,DLC=8
 	 CANIDT4 = 0x08;                                                               // 00001 0xx
 	 CANIDT3 = 0x79;                                                               // 01111 001              33
 	 CANIDT2 = 0x8f;                                                               // 10001 111             239
 	 CANIDT1 = 0x65; 
	 */ 
	//  CANIDT4 = 0x20+0B00001000;                                                               // 00100 000
 //CANIDT4 = 0x20;   
 // CANIDT3 = 0x23;                                                               // 00100 011           101
  CANIDT2 = 0x2b;                                                               // 00101 011           100
  CANIDT1 = 0xdd;                                                               // 01100 101             177

 //	 CANIDM4  =0xff;                                                              //                             11111 100
 //	 CANIDM3  =0xff;                                                              //                             11111 111
 	 CANIDM2  = 0x00;                                                              //                             11111 111
 	 CANIDM1  = 0x00;  




//MOB1=TX[STA1]  向上位机报告状态组1          6,0,0,178,239,33
  	CANPAGE = 0x10;
 CANSTMOB = (1<<TXOK);
 	// CANCDMOB = 0;
 CANCDMOB = 0x08;   
 	CANIDT4 = 0x08;                                                               // 00001 000
  	CANIDT3 = 0x79;                                                               // 01111 001              33
  	CANIDT2 = 0x97;                                                               // 10010 111             239
 	CANIDT1 = 0xc5; 

	                                                           // 11000 101             178

//MOB2=TX[STA2]  向上位机报告状态组2          6,0,0,179,239,33
 	 CANPAGE = 0x20;
  	CANCDMOB = 0;
	 	 CANSTMOB = (1<<TXOK);
 	 CANCDMOB = 0x08;
 	 CANIDT4 = 0x08;                                                               // 00001 000
 	 CANIDT3 = 0x79;                                                               // 01111 001              33
 	 CANIDT2 = 0x9f;                                                               // 10011 111             239
 	 CANIDT1 = 0xc5;                                                               // 11000 101             179
 CANCDMOB = 0x08; 
//MOB3=RX[2#servo]                            7,0,0,100,101,100
  CANPAGE  = 0x30;                                                              //MOB3,自动增量,初值为0
  CANSTMOB = 0;
  CANCDMOB = 0x08; 
                                                               //can2B,DLC=8
  CANIDT4 = 0x20;                                                               // 00100 000
  CANIDT3 = 0x2b;                                                               // 00101 011           100
  CANIDT2 = 0x22;                                                               // 00100 011           101
  CANIDT1 = 0xe3;                                                               // 11100 011           100
  CANIDM4  = 0xfc;                                                              //                             11111 100
  CANIDM3  = 0xff;                                                              //                             11111 111
  CANIDM2  = 0xff;                                                              //                             11111 111
  CANIDM1  = 0x07;                                                              //CANIDM4-1数据校验屏蔽寄存器  00000   111

//MOB4=TX[2#servo]                            7,0,0,101,100,100
  CANPAGE = 0x40;
  CANCDMOB = 0;
	 	 CANSTMOB = (1<<TXOK);
  CANCDMOB = 0x08;
  CANIDT4 = 0x20;                                                               // 00100 000
  CANIDT3 = 0x23;                                                               // 00100 011           101
  CANIDT2 = 0x2b;                                                               // 00101 011           100
  CANIDT1 = 0xe3;                                                               // 11100 011           100
 CANCDMOB = 0x08; 


CANGIE |= ((1<<ENIT) + (1<<ENRX)); //开全局中断 和 接收中断
  CANIE2 |= 0x09;    //开MOB3 & MOB0信箱接收中断(接收邮箱)
  CANPAGE  = 0x00;
  CANCDMOB |= 0x80;    //MOB0接收使能
  CANPAGE  = 0x30;
  CANCDMOB |= 0x80; //MOB3接收使能
  CANGCON |= 0x02;   //enable //CAN控制器启动

/*
  CANGIE |= ((1<<ENIT) + (1<<ENRX));   
                    //开全局中断 和 接收中断
  CANIE2 |= 0x09;                                                               //开MOB3 & MOB0信箱接收中断(接收邮箱)
  CANPAGE  = 0x00;
  CANCDMOB |= 0x80;                                                             //MOB0接收使能
  CANPAGE  = 0x30;

  CANCDMOB |= 0x80;   
                                                            //MOB3接收使能
  CANGCON |= 0x02;         //enable                                                    //CAN控制器启动

*/
/*
//-------------TCC1定时器初始化-----------------
  TCCR1A = 0x00;                                                                //设置工作模式和分频因子
  TCCR1B = 0x04;                                                                // T=CLK/1024  0x04=1s  0x05=4s
  TCCR1C = 0x00;
  TIMSK1 = 0x01;                                                                // 允许溢出中断
  TCNT1 = 0x0000;                                                               //初始化计数器值,在程序中更改相应数值可以更改中断时间
*/
//-------------------ADC初始化------------------
  ADCSRA = 0x8c;                                                                //使能ADC单元,单次,允许中断,16分频(1MHzADC时钟)
  ADMUX = 0x40;                                                                 //AVcc参考电源,右对齐,未指定输入源

 // __watchdog_reset();                                                           //喂狗

  SREG = 0x80;                                                                  //开全局中断
}


//CAN数据帧发送

void MOB_send (unsigned char n)
{
	CANGIE &= ~(1<<ENRX);
	unsigned int i;

	CANPAGE = (n<<4); //MOB_n, auto increment, index 0
	if (CANSTMOB & (1<<TXOK))
	{
		// CANCDMOB= 0x18;
		CANSTMOB &= ~(1<<TXOK);
		for(i = 0; i < 8; i++) CANMSG = can_data[n][i];

		CANCDMOB = 0x58; //帧发送
		CANGIE |=(1<<ENRX);
	}
}


int main(void)
{
unsigned int pp=0;
mcu_init();
//MOB_send(1);

//MOB_send(4);
	while(1)
	{
		pp = 60000;
		while(pp){pp--;}
	pp = 60000;
		while(pp){pp--;}
			pp = 60000;
		while(pp){pp--;}
			pp = 60000;
		while(pp){pp--;}
	//MOB_send(4);


	}

}



//-----------------------------------------------------------------------------
//中断函数 接收CAN数据帧 并 存入数据单元组
//**********************************************************
SIGNAL(SIG_CAN_INTERRUPT1)
{
volatile	unsigned char i = 1, num_i,jj;
	CANGIE &= ~(1<<ENRX); //关接收中断****
	num_i = CANSIT2;


//-----------------------------------------------------
	if (num_i & (1<<SIT0))
	{

		i=0;
		TCNT1 = 0x0000; //重启定时监视器
		CANPAGE = i<<4;
		for(jj = 0; jj < 8; jj++)
		{
			can_data[i][jj]=CANMSG; //取得8个字节的数据
		}
			TCNT1 = 0x0000; //重启定时监视器
	}
//------------------------------------------------------
	if (num_i & (1<<SIT3))
	{
		i=3;
			CANPAGE = i<<4;
		for(jj = 0; jj < 8; jj++)
		{
			can_data[i][num_i]=CANMSG; //取得8个字节的数据
		}
			TCNT1 = 0x0000; //重启定时监视器
	}
//------------------------------------------------------
	CANPAGE = 0x00;
	CANSTMOB &= ~(1<<RXOK); //清中断标志****
	CANCDMOB = 0x98; //接收使能
	CANPAGE = 0x30;
	CANSTMOB &= ~(1<<RXOK); //清中断标志****
	CANCDMOB |= 0x98; //接收使能
	CANGIE |= (1<<ENRX); //开中断
} 



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -