来这里不长收获不少,感谢阿莫,特贡献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; //端口设置: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); //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 接收上位机发来的指令 格式: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向上位机报告状态组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向上位机报告状态组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 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 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/10240x04=1s0x05=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=CANMSG; //取得8个字节的数据
}
}
//------------------------------------------------------
if (num_i & (1<<SIT3))
{
i=3;
CANPAGE = i<<4;
for(num_i = 0; num_i < 8; num_i++)
{
can_data=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;
CANCDMOB = 0x58; //帧发送
CANGIE |=(1<<ENRX);
}
} 主程序中读取中断接收到的CAN数据的程序段,只是介绍下实现方法:
-----------------------------------------------------------------------------
//-------------------读取 主机CAN 数据-------------------
CANGIE &= ~(1<<ENRX); //关CAN接收中断
CANPAGE = 0x00;
CANCDMOB = 0x00;
CANPAGE = 0x30;
CANCDMOB = 0x00;
spd = ((can_data<<8)+ can_data) / 8; //速度指令(单位 0.125)
spd = spd * 5 / 3; //指令频率(单位 50 / 30 @4 poles)
p_trk = (can_data<<8) + can_data; //正转矩
n_trk = (can_data<<8) + can_data; //负转矩
for (i = 0; i < 8; i++) s_sv = can_data; //伺服
CANPAGE = 0x00;
CANCDMOB = 0x98;
CANPAGE = 0x30;
CANCDMOB = 0x98;
CANGIE |= 1<<ENRX; //开CAN接收中断 我顶你!!谢谢,虽然我还没能力看懂! 比我的积分高啊,厉害!我先去饭饭了,一会再来。 收藏啦,以后玩CAN会用到,谢谢。 这么好的帖子要收藏啦,多谢楼主 好帖 多谢了! 程序不错,但好比屠龙之术!
CAN128在国内不太好买,另外
价格在70左右,不如,一片
M16和一片MCP2515方便.
与MOTO的相比,更没有优势.
例如,9S12D64,才不过50左右,
还是16位机. 好呀,终于等到了,这两天公司网停了,真是CAN128的国内第一帖呀,强烈要求斑竹给其加分,以鼓励无私奉献.
谢谢goblin
置顶呀 请问:你用的AVR哪个版本?有ICCAVR7.0吗?有的话麻烦给我传一份。我从网上下载了一个,但不能注册。我的QQ:346604396 good 在这里搜索一下就可以,这里KEY 到IAR412A
支持JTAG MKII的USB口和CAN128,410版本支持的都不很好。要做CAN128最好用412A以上的版本! 过几天到武汉,买本CAN的基础书看一看,CAN128的DATASHEET看了一遍,MOB是什么东西,如何使用,就是看了程序,还是不明白。还有就是那个格式3,0,0,177,239,33是如何和CANIDT对应的。如果楼主能介绍几本CAN的书籍就好了,周立功网站上的好象介绍的不是很全。 在Microchip的网站上有一份数据手册是MCP2515的中文版,你可以下载下来,里面有一些关于CAN协议和总裁的信息,感觉蛮有概括性的。CAN通讯里面感觉做烦人的就是位定时。大多CAN总线控制器基本类似,不管它是大Can的MCU还是独立的CAn控制器。你其实只要搞明白CAN的协议那几个报文、位定时、错误检测,基本上可以算得上是入门了。 郁闷啊,我的还是发送有问题,单步执行就能发出去,写到片子里就不行啊,急!!!!!!! 怎么不是WINAVR GCC编译器 呢?
大家有用 WINAVR GCC的吗? 主程序中读取中断接收到的CAN数据的程序段,只是介绍下实现方法:
-----------------------------------------------------------------------------
//-------------------读取 主机CAN 数据-------------------
CANGIE &= ~(1<<ENRX); //关CAN接收中断
CANPAGE = 0x00;
CANCDMOB = 0x00;
CANPAGE = 0x30;
CANCDMOB = 0x00;
spd = ((can_data<<8)+ can_data) / 8; //速度指令(单位 0.125)
spd = spd * 5 / 3; //指令频率(单位 50 / 30 @4 poles)
p_trk = (can_data<<8) + can_data; //正转矩
n_trk = (can_data<<8) + can_data; //负转矩
for (i = 0; i < 8; i++) s_sv = can_data; //伺服
CANPAGE = 0x00;
CANCDMOB = 0x98;
CANPAGE = 0x30;
CANCDMOB = 0x98;
CANGIE |= 1<<ENRX; //开CAN接收中断
这一段数据是怎么存储的 ,存到 哪个变量里去了,没看明白,麻烦楼主能说清楚点吗? 顶,我虽说看不懂。建议阿莫给楼主加400分。 集成can控制器的一种做法是,把can相关的控制/状态/数据寄存器分成一组,有的芯片称其为Message Object(can128中的mob似乎与此类似),用户代码不能直接访问,mcu中有n组这样的寄存器。然后以另外一组寄存器作为用户程序可以直接访问的can寄存器,程序通过这组寄存器以类似软件上指针的方式访问各个Message Object,每次这组寄存器只能访问同一个Message Object里的各个寄存器,这组类似指针的寄存器也有被称为Message Handler的。
can128有16个mob(好像是,因该没记错),而像arm芯片一般会有32个类似的mob,比如easycan4有4个can控制器,包括3个16buffers、1个32buffers。mob可以根据需要设置为接收mob或发送mob,所以如果要发送并接收can数据,至少需要2个mob,分别负责接收与发送,而实际中由于can接收中断需要时间处理,只有1个接收mob时会出现数据丢失,所以接收mob一般大于2个。 这么好的东东,不顶对不起楼主啊 学习楼主的贡献精神。我初学的,以后多指教! zhichi 正要学习啊,感谢楼主
还有回帖提供信息的各位兄弟 lz你的AT90CAN128多少钱一片? 记号 兄弟能传个完整的项目文件吗? 做个记号 留个记号 好帖谢谢! 要怎样设置才能进入中断呢?怎么我用Simulator仿真不能进入中断呢? 收藏了 谢谢 收藏 楼主在吗?
我也正在研究AT90CAN128的CAN控制器,能否和你交流交流!
我的QQ是:40454681
MSN是:danesh.zhao@hotmail.com
欢迎各位对这块有兴趣的朋友,都来交流交流! mark mark MARK 很奇怪,我就是死活调试不过,郁闷啊,怎么高手都不指导下呢???? 谢谢楼主,好贴子,值得拿来收藏 关于CAN的要学习。。 好贴要顶 3Q 做个记号 mark jihao mark 谢谢,在这里让我这段程序的理解豁然开朗 真是惭愧啊,现在看当初的程序是漏洞百出啊!呵呵呵
目前除了CAN发送还是定时直接发送外,其他如usart、CAN、ADC、eeprom等都已经转入地下中断服务了。呵呵呵
老程序存在有些概念还没彻底摸清的情况,没有错误处理机制,错误过多就会导致进入错误被动模式等。
希望借鉴这个程序的朋友自己可要多分析哦。 虽然看不懂还是顶 感谢支持楼主的热心奉献精神! MARK 还没用到CAN,不过记个号 好帖 顶,我虽说看不懂。 这个程序能实现两个接收中断吗?我试了,只能响应一个中断,请高手指教一下。 mark,谢谢现在正在学习 mark 几号下 是不是和MEGA系列的指令兼容? 学习了。 支持 【10楼】 wenming 老王
-------------------------
AT90CAN128现在国内的零售价是多少?性价比高吗? mark AT90CAN128 用什么编程软件,貌似 ICC不支持啊 mark 好东西啊 顶一个 留个记号,以后用得着 AT90留记号 mark mark,某年某月的某一天,可能会用到的 学习,谢谢 mark mark mark 标记 mark 值得收藏 mark 精神可嘉,等我发展到你那个程度也发些代码出来。 收藏啦,以后玩CAN会用到,谢谢。 也记一下,过两天再来看 程序再多点注释就好了 {:smile:}挺好,比较详细 楼主好淫啊!做个标记。
收藏啦,以后玩CAN会用到
挺好,比较详细 也准备入门can通讯 好老的帖子,过来学习一下,这款片子不错,我们这边军工单位都用上了。 这么好的东东,不顶对不起楼主啊 不错,顶起来 10年整 很好的代码,看起来很舒适 谢谢分享,学习了 收藏备用 完全没有搞明白。呵呵。 本帖最后由 xuekcd 于 2019-3-8 16:24 编辑
谢谢楼主啊!我抄了!
楼主帮了我大忙!谢谢!
程序很好用!
页:
[1]