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

📄 at90can128程序.txt

📁 at90can128初始化源程序
💻 TXT
字号:
AT90CAN128全部代码工作程序
第一个是CAN128的初始化程序: 


-------------------------------------------------------------------------------------- 
//-----------------------------------------------------------------------------| 
// 初始化 :MCU 时钟,端口方向 ,USART1 波特率 ,CAN控制器 ,看门狗 ,TCC1   | 
// CAN控制器 0# ,4# 信箱中断接收 ,1#、2#、3# 信箱发送数据           | 
// 定时器 TCC1 做CAN数据一秒内达到判断,1秒内无数据报警            | 
//-----------------------------------------------------------------------------| 

void mcu_init(void) 
{ 
//----------------watch dog init --------------- 
WDTCR = (1<<WDCE) | (1<<WDE);                         //2行看门狗初始化 
WDTCR = 0x0f;                                 //0x1c=0.25s  0x1d=0.5s 
__watchdog_reset();                              //喂狗 

//-------------------CLK INITIAL----------------- 
CLKPR = 128; 
CLKPR = 0; 
//-------------------prot init------------------- 
DDRC = 0xff;                                 //端口设置C设置为推挽1输出 
PORTC = 0xfe; 
DDRA = 0x00;                                 //端口设置A设置为输入 

//---------------- 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);                            //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; 

//--------------can_MOB INITIAL------------------- 
//MOB0=RX[CMD]  接收上位机发来的指令    格式:3,0,0,177,239,33 
CANPAGE = 0x00;                               //MOB0,自动增量,初值为0 
CANSTMOB = 0; 
CANCDMOB = 0x18;                               //can2B,DLC=8 
CANIDT4 = 0x08;                                // 00001 0xx 
CANIDT3 = 0x79;                                // 01111 001       33 
CANIDT2 = 0x8f;                                // 10001 111       239 
CANIDT1 = 0x65;                                // 01100 101       177 

CANIDM4 = 0xfc;                               //               11111 100 
CANIDM3 = 0xff;                               //               11111 111 
CANIDM2 = 0xff;                               //               11111 111 
CANIDM1 = 0x07;                               //CANIDM4-1数据校验屏蔽寄存器 00000 111 

//MOB1=TX[STA1] 向上位机报告状态组1     6,0,0,178,239,33 
CANPAGE = 0x10; 
CANSTMOB = (1<<TXOK); 
CANCDMOB = 0x18; 
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; 
CANSTMOB = (1<<TXOK); 
CANCDMOB = 0x18; 
CANIDT4 = 0x08;                                // 00001 000 
CANIDT3 = 0x79;                                // 01111 001       33 
CANIDT2 = 0x9f;                                // 10011 111       239 
CANIDT1 = 0xc5;                                // 11000 101       179 

//MOB3=RX[2#servo]              7,0,0,100,101,100 
CANPAGE = 0x30;                               //MOB3,自动增量,初值为0 
CANSTMOB = 0; 
CANCDMOB = 0x18;                               //can2B,DLC=8 
CANIDT4 = 0x20;                                // 00100 000 
CANIDT3 = 0x2b;                                // 00101 011      100 
CANIDT2 = 0x23;                                // 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; 
CANSTMOB = (1<<TXOK); 
CANCDMOB = 0x18; 
CANIDT4 = 0x20;                                // 00100 000 
CANIDT3 = 0x23;                                // 00100 011      101 
CANIDT2 = 0x2b;                                // 00101 011      100 
CANIDT1 = 0xe3;                                // 11100 011      100 

CANGIE |= ((1<<ENIT) + (1<<ENRX));                      //开全局中断 和 接收中断 
CANIE2 |= 0x09;                                //开MOB3 & MOB0信箱接收中断(接收邮箱) 
CANPAGE = 0x00; 
CANCDMOB |= 0x80;                               //MOB0接收使能 
CANPAGE = 0x30; 
CANCDMOB |= 0x80;                               //MOB3接收使能 
CANGCON |= 0x02;                               //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;                                 //开全局中断 
} 
第二个中断接收程序, 一秒无接收信号报警标志中断程序: 


------------------------------------------------------------------------------- 
//定时器1秒(约)中断函数,用于监视上位机指令到达是否正确。 
#pragma vector = TIMER1_OVF_vect 
__interrupt void TIMER1_OVF(void) 
{ 
M_err_flg = 1;              //报告:上位机CAN通信异常 
} 


//----------------------------------------------------------------------------- 


//中断函数   接收CAN数据帧 并 存入数据单元组 
//********************************************************** 
#pragma vector=CANIT_vect 
__interrupt void CAN_INTERRUPT(void) 
{ 
uchar i = 1, num_i; 
CANGIE &= ~(1<<ENRX);         //关接收中断**** 
num_i = CANSIT2; 


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

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


}
CAN发送子程序: 

//CAN数据帧发送 

void MOB_send (uchar n) 
{ 
CANGIE &= ~(1<<ENRX); 
uint 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]; 

CANCDMOB = 0x58;                //帧发送 
CANGIE |=(1<<ENRX); 
} 
}
主程序中读取中断接收到的CAN数据的程序段,只是介绍下实现方法: 

----------------------------------------------------------------------------- 
//-------------------读取 主机CAN 数据------------------- 
  CANGIE &= ~(1<<ENRX);         //关CAN接收中断 
  CANPAGE = 0x00; 
  CANCDMOB = 0x00; 
  CANPAGE = 0x30; 
  CANCDMOB = 0x00; 


spd = ((can_data[0][0]<<8) + can_data[0][1]) / 8;   //速度指令(单位 0.125) 
spd = spd * 5 / 3;            //指令频率(单位 50 / 30 @4 poles) 
p_trk = (can_data[0][2]<<8) + can_data[0][3];          //正转矩 
n_trk = (can_data[0][4]<<8) + can_data[0][5];           //负转矩 
for (i = 0; i < 8; i++) s_sv = can_data[3];        //伺服 

  CANPAGE = 0x00; 
  CANCDMOB = 0x98; 
  CANPAGE = 0x30; 
  CANCDMOB = 0x98; 
  CANGIE |= 1<<ENRX;                   //开CAN接收中断





⌨️ 快捷键说明

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