首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

※学习MC9S12单片机——软件篇※ 不断更新中

asker_dfr@yahoo.com.cn      你也是yahoo的邮箱吧
给自己的告诫
                                    不要做浮躁的人

这是从其他论坛中拷贝过来的,有借鉴意义。
请不要做浮躁的人
1.不要看到别人的回复第一句话就说:给个代码吧!你应该想想为什么。当你自己想
出来再参考别人的提示,你就知道自己和别人思路的差异。
2.初学者请不要看太多太多的书那会误人子弟的,先找本系统的学,很多人用了很久
都是只对部分功能熟悉而已,不系统还是不够的。
3.看帮助,不要因为很难而自己是初学者所以就不看;帮助永远是最好的参考手册,
虽然帮助的文字有时候很难看懂,总觉得不够直观。
4.不要被对象、属性、方法等词汇所迷惑;最根本的是先了解最基础知识。
5.不要放过任何一个看上去很简单的小问题--他们往往并不那么简单,或者可以引伸
出很多知识点;不会举一反三你就永远学不会。
6.知道一点东西,并不能说明你会写脚本,脚本是需要经验积累的。
7.学脚本并不难,JSP、ASP、PHP等等也不过如此--难的是长期坚持实践和不遗余力的博览
群书;
8.看再多的书是学不全脚本的,要多实践
9.把时髦的技术挂在嘴边,还不如把过时的技术记在心里;
10.学习脚本最好的方法之一就是多练习;
11.在任何时刻都不要认为自己手中的书已经足够了;
12.看得懂的书,请仔细看;看不懂的书,请硬着头皮看;
13.别指望看第一遍书就能记住和掌握什么——请看第二遍、第三遍;
14.请把书上的例子亲手到电脑上实践,即使配套光盘中有源文件;
15.把在书中看到的有意义的例子扩充;并将其切实的运用到自己的工作中;
16.不要漏掉书中任何一个练习——请全部做完并记录下思路;
17.当你用脚本到一半却发现自己用的方法很拙劣时,请不要马上停手;请尽快将余
下的部分粗略的完成以保证这个代码的完整性,然后分析自己的错误并重新编写和工
作。
18.别心急,写脚本确实不容易;水平是在不断的实践中完善和发展的;
19.每学到一个脚本难点的时候,尝试着对别人讲解这个知识点并让他理解----你能
讲清楚才说明你真的理解了;
20.记录下在和别人交流时发现的自己忽视或不理解的知识点;
21.保存好你做过的所有的源文件----那是你最好的积累之一;
22.对于网络,还是希望大家能多利用一下,很多问题不是非要到论坛来问的,首先
你要学会自己找答案,比如google、百度都是很好的搜索引擎,你只要输入关键字就
能找到很多相关资料,别老是等待别人给你希望,看的出你平时一定也很懒!
23,到一个论坛,你学会去看以前的帖子,不要什么都不看就发帖子问,也许你的问
题早就有人问过了,你再问,别人已经不想再重复了,做为初学者,谁也不希望自己
的帖子没人回的。
24,虽然不是打击初学者,但是这句话还是要说:论坛论坛,就是大家讨论的地方,
如果你总期望有高手总无偿指点你,除非他是你亲戚!!讨论者,起码是水平相当的
才有讨论的说法,如果水平真差距太远了,连基本操作都需要别人给解答,谁还跟你
讨论呢。

浮躁的人容易问:我到底该学什么;----别问,学就对了;
浮躁的人容易问:Js有钱途吗;----建议你去抢银行;
浮躁的人容易说:我要中文版!我英文不行!----不行?学呀!
浮躁的人分两种:只观望而不学的人;只学而不坚持的人;
浮躁的人永远不是一个高手。

※学习MC9S12单片机——软件篇※ 不断更新中

以前已经发了一些帖子,都得到了很好的回复,所以我借此宝地,来开展关于MCS12DP256芯片(为主)和相关的学习与讨论。希望得到版主和众位的帮助,在这里主要贴在软件学习实践过程中遇到的问题,相信,不断学习、不断思考,总会有所收获,你说呢? 先来解剖一只麻雀吧,上次请教关于指针的问题,其实是属于俺对于基本概念的不清,造成读程序有困难,现把这只麻雀贴置如下: /* LEDS.C example file for Motorola MC9S12DP256 Evaluation Board */ #include /* port B definitions */ #define PORTB (*((volatile unsigned char*)(0x0001))) #define DDRB (*((volatile unsigned char*)(0x0003))) /* Timer TCNT definitions */ #define TSCR1 (*((volatile unsigned char*)(0x0046))) #define TSCR2 (*((volatile unsigned char*)(0x004D))) #define TFLG2 (*((volatile unsigned char*)(0x004F))) #define TCNT (*((volatile unsigned short*)(0x0044))) int counter; void TimerOverflow(void) { /* This function waits for th timer overflow. Then it changes the LEDs bargraph display */ while (TCNT != 0x0000); while (TCNT == 0x0000); counter++; if (counter == 1) PORTB = 0x7f; /* LEDs' lightshow */ if (counter == 2) PORTB = 0xbf; if (counter == 3) PORTB = 0xdf; if (counter == 4) PORTB = 0xef; if (counter == 5) PORTB = 0xf7; if (counter == 6) PORTB = 0xfb; if (counter == 7) PORTB = 0xfd; if (counter == 8) PORTB = 0xfe; if (counter == 9) PORTB = 0xAA; if (counter == 10) PORTB = 0x55; if (counter == 11) PORTB = 0xAA; if (counter == 12) PORTB = 0x55; } void main(void) { TSCR1 = 0x80; /* enable timer TCNT */ TSCR2 = 0x03; /* TCNT prescaler setup */ counter = 0; DDRB=0xff; /* PTB as output */ PORTB=0xff; /* LEDs off */ for (;;) { TimerOverflow(); if (counter >= 12) { counter = 0; if (TSCR2 == 0x03) TSCR2 = 0x07; else TSCR2 = 0x03; /* TCNT prescaler switch */ } } }
“//”外的注释是我一边看程序 ,一边对照寄存器map写的,有不对处,希望大家多多指出,很多地方写的就是“不明白”,要像大家请教的。

有几个特别不明白的地方:
1。这里我决得是从CAN0——>CAN4,其中下面那一大串
CAN4TXFG1=0x01;      //发送区域写数据(??)
CAN4TXFG2=0x00;
CAN4TXFG4=0x41;
CAN4TXFG5=0x42;
CAN4TXFG6=0x43;
CAN4TXFG7=0x44;
CAN4TXFG8=0x45;
CAN4TXFG9=0x46;
CAN4TXFGA=0x47;
CAN4TXFGB=0x48;
CAN4TXFGC=0x49;

是给发送区域写数据(是吗?),目的是要传至can0接受的地方,在寄存器定义中,用的是
#define CAN0RXFG0   (*((volatile unsigned char*)(0x0160)))
……
#define CAN0TXFG0   (*((volatile unsigned char*)(0x0170)))   
……
在初始化和主程序里,是如何进行处理接受那一部分的呢?有发送的,接受的在哪里呢?有的话,哪个(些)语句起到了这样的作用呢?很不明白。

2。我看到MSCAN模块有中自测模式,这里会不会是用到这个呢?(我决得好像没有,因为没有发现对寄存器CANCTL1中的Loopb做处理。
有不明之处,请教大家。上次见jsbychm 问过关于MOTO芯片的MSCAN通讯问题,那个程序我还看不明白,现在找了一个比较简单的,其中最关键的,就是如何进行can通讯的,还是不明要领:
/* 该例子来自邵老师那本关于S12的书里头的一个can通讯的范例程序,大致意思是将数据利用mscan0传,mscan4接收

#include "printp.h"
#define PORTB    (*((volatile unsigned char*)(0x0001)))   
#define DDRB     (*((volatile unsigned char*)(0x0003)))

#define CAN0CTL0    (*((volatile unsigned char*)(0x0140)))  

相关的寄存器地址定义略


void MSCAN_INITIAL(void)
{
CAN0CTL0|=0x01;            // CAN Control Register   0000,0001-->TNITRQ=1
CAN4CTL0|=0x01;
while(!(CAN0CTL0&0x01))    // CAN0CTL0 为0x01,则往下执行,实为等待CAN0CTL0为0x01
{}
while(!(CAN4CTL0&0x01))
{}
CAN0IDAC=0x20;             // CAN Identifier Acceptance Control   0010,0000
CAN4IDAC=0x20;
CAN0IDAR0=0x01;            //验收寄存器,不太明白
CAN4IDAR0=0x01;
CAN0IDAR1=0x00;
CAN4IDAR1=0x00;
CAN0IDAR2=0x04;
CAN4IDAR2=0x04;
CAN0IDAR3=0x08;
CAN4IDAR3=0x08;
CAN0IDAR4=0x41;
CAN4IDAR4=0x41;
CAN0IDAR5=0x41;
CAN4IDAR5=0x41;
CAN0IDAR6=0x41;
CAN4IDAR6=0x41;
CAN0IDAR7=0x41;
CAN4IDAR7=0x41;

CAN0IDMR0=0xff;            //验收屏蔽寄存器
CAN0IDMR1=0xff;
CAN0IDMR2=0xff;
CAN0IDMR3=0xff;
CAN0IDMR4=0xff;
CAN0IDMR5=0xff;
CAN0IDMR6=0xff;
CAN0IDMR7=0xff;
CAN4IDMR0=0xff;
CAN4IDMR1=0xff;
CAN4IDMR2=0xff;
CAN4IDMR3=0xff;
CAN4IDMR4=0xff;
CAN4IDMR5=0xff;
CAN4IDMR6=0xff;
CAN4IDMR7=0xff;

CAN0BTR0=0x61;             //Bus Timing Register
CAN4BTR0=0x61;
CAN0BTR1=0x13;
CAN4BTR1=0x13;
CAN0CTL1=0x80;
CAN4CTL1=0x80;
CAN0CTL0&=0xfe;
CAN4CTL0&=0xfe;
while(CAN0CTL1&0x01)
{}

while(CAN4CTL1&0x01)
{}

CAN0CTL0=0x08;   
CAN4CTL0=0x08;
CAN0RIER=0x0f;
CAN4RIER=0x0f;

CAN4TBSEL=CAN4TFLG;        //CAN Transmit Buffer Selection=CAN Transmitter Flag Register
CAN4TXFG1=0x01;            //发送区域写数据
CAN4TXFG2=0x00;
CAN4TXFG4=0x41;
CAN4TXFG5=0x42;
CAN4TXFG6=0x43;
CAN4TXFG7=0x44;
CAN4TXFG8=0x45;
CAN4TXFG9=0x46;
CAN4TXFGA=0x47;
CAN4TXFGB=0x48;
CAN4TXFGC=0x49;
CAN4TFLG=CAN4TBSEL;

}
void main(void) {

MSCAN_INITIAL();

while(!(CAN4TFLG&0x01))
{printp("\nCAN4 SEND\n");}

}

void CAN0_RECEIVE(void)
{
asm
{
sei                        //中断屏蔽开
}
printp("CAN0 RECEIVE \n");
asm
{
cli                        //中断屏蔽关
}
asm
{
rti                        //return from interrupt
}

}
void UnimplementedISR(void)
{
   /* Unimplemented ISRs trap.*/
   asm stop;
}





[此贴子已经被作者于2005-3-25 15:00:34编辑过]

应该是等待 CAN0CTL0 末尾是 1

while(!(CAN0CTL0&0x01)) // CAN0CTL0 为0x01,则往下执行,实为等待CAN0CTL0为0x01


应该是等待 CAN0CTL0  末尾是 1。 前面7位是 什么 无所谓。
[em27]
一名专业的嵌入式软件开发工作者
CAN0CTL0是CAN的控制寄存器,其最低位是INTTRQ,位初始化位,当INTTRQ置1,表示MSCAN处于初始化状态。问题是,这个CAN0接受过程我还没看明白


[此贴子已经被作者于2005-3-28 9:31:34编辑过]

今天刚拿到邵老师的书,(已经用9SDG128大半年了)发现邵老师的方法比较适合没多少钱的个人用户。偶用公司买的P&E以及标准版的codewarrior。其实codewarrior帮助里面有很多好的说明。部过邵老师的书也不错(后悔没早拿半年)。不过建议还是要看英文的datesheet,这样对硬件了解多些,可以拿电力出版社的hc12的书比对下。
aressos,你好,我的电力出版社的那本书呢,是用来对照参考手册来看的,二者(68HC12和MC9S12)在相关寄存器上还是有蛮多的不同的,我是才开始看没多久(其实也一个月了),用EVB做点小例子。
这次,在学习CAN通讯方面,想利用S12上提供的MSCAN自测模式来进行通讯。不过,上面发的那一片程序还没消化,关键是不太清楚收发数据是如何处理的,还需要人指点一二
请问上面的代码在书中多少页,我刚拿到书,怎么没看到呀?
没啥说的
我一直MODBUS的总线,所以对CAN的不是很了解。不过刚才稍微看了下CAN4CTL0的定义,INTTRQ有一个功能,就是包括CAN0IDAR0在内的许多寄存器都要在其为1的情况下才可读写。这功能就好像是读写外部数据时先判断总线是否忙碌一样。
我觉的你应该从CAN的数据格式开始学,这样才能很清楚,CAN的收发、数据验证过程。其实我一直觉的所谓硬件实现现场总线,不过是用内部的硬件把数据按照总线的格式进行打包,从而发送出去,接收后在检验、解码。从根本上来说于用软件来处理数据格式,在通过串口发送接收是一样的,(就像软件的I2C总线、MODBUS一样)。只不过它用硬件的方式实现了软件的处理,节省了CPU开销罢了。晚上我再看看CAN的发送,不过不一定能给你一个肯定的答复。比较有过调S12的AD失败了N次的教训。
hehe, 真是好人啊

[建议]

aressos 你的看法有个人獨到之處, 冇錯CAN总线是用硬件的方式实现了一些煩復软件的处理, 节省了CPU开销罢了,但實際上它也有工作是软件不能做到的,例如再同步處理 (hard re-synchronization), 总线仲裁(bus arbitration) 等.

asker_dfr 你的问题是比較花時處理, 原因是你不明白CAN是什麽,首先你要先了解CAN的格式和協議後,才能明白那些記存器的應用o

在S12DP256的記存器
x=0,1,2,3,4   
y=0,1,2,3,4,5,6,7
z=0...0xc

CANxIDARy = Acceptance Register
CANxIDMRy = Mask Register
CANxTFLG = 讀取CANtx 可用緩沖區 (3个其中一个)
CANxTBSEL = 選用CANtx 可用緩沖區
CANxBTR0= Bus Timing (RJW + CAN clock)
CANxBTR1= Bus Timing (Prog+PS1+PS2)
CANxCTL0= CAN module 控制記存器
CANxCTL1= CAN module 控制記存器
CANxTXFGz= 緩沖區


而你的code 不知道在何處抄出來o
1. Filter 的工用就不見,因為所有CANxIDMRy都是$ff.
2. CANxIDAC=0x20  // Eight 8 bit Acceptance Filters
3. Message ID
    CANxIDAR0=01;
    CANxIDAR1=00;
    CANxIDAR2=04;
    CANxIDAR3=08;

看來應是CAN2.0A吧?都應是CAN2.0A 因為Filter 都是8位.但不知道為什麽作者又把CANxIDAR2和CANxIDAR3也有data.真是莫明奇妙! 可否解答?

4. CAN receiver 中斷什麽也沒有,最少也該有中斷設置,如果沒有中斷設置,程式永遠循环在CAN中斷.

[建议]
1. 先看CAN 規格.
2. 了解後再看S12DP256規格
3. 然後才看這段程式
4. 问题可迎刃而解
[em27]
na
呵呵,看完AutoLam也是大大的好人那。我也发现自己的薄弱之处,对于什么是CAN,如何应用,S12中MSCAN寄存器的设置等等,都不是说一知半解的概念,是根本还不明白。还有,receiver什么中断也没有,前天我请教我这边一位高手,他也是一下子看处那个示例程序的问题,还狠批一阵,怎么连CAN是什么都不明天,就来看这方面的东西呢?其中,还说道利用中断服务程序来处理,首先要把程序的一个大致框架搭建起来,任何对于CAN、SCI、PWM等等都是水到渠成的事情了(我思量一下,觉得说得很对)。
只有继续努力啦,硬着头皮看下去,其实,我觉得还是很有意思的。再次谢谢这边的大侠们,我自我感觉,这比我一个月前好多了,至少那个时候我对于该干什么都不是很清晰。
我理解是起延时的作用。让led闪烁起来吧。
返回列表