Board logo

标题: [分享]ECT的输入捕捉程序(MC9S12DG128B) [打印本页]

作者: fyhl_moto    时间: 2007-5-18 10:30     标题: [分享]ECT的输入捕捉程序(MC9S12DG128B)

本程序利用芯片自身的PWM功能产生一个方波
然后对此波形作为ECT输入进行输入捕捉
计算的结果通过串行口输出到PC机察看(使用串口调试助手)

程序代码如下(不知道怎样才能上传工程文件,所以只好贴出main.c文件):
PS:哪位高手能把这个程序改成中断的方式吗?小弟在此等候.

#include /* common defines and macros */
#include /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12dg128b"
#include
#include
#include

//函数声明
void timer_init(void); //计数器初始化
void measure_wave(void); //波形测量函数
void period_freq(void); //周期、频率
void SCI_Init(void);
void SCI0Output_char(unsigned char ch);
void PWMIni(void);

//全局变量声明
unsigned long int rising_1;
unsigned long int rising_2;

void main(void) {
/* put your own code here */
// EnableInterrupts;
SCI_Init();
PWMIni();
DDRB=0xff;
PORTB=0xe7;
timer_init();
measure_wave();
period_freq();

for(;;) {} /* wait forever */
/* please make sure that you never leave this function */
}


void timer_init(void){
TIE=0x00; //禁止中断
TSCR2=0x02; //时钟=M Clock/4=2MHz
TIOS=0x00; //ch2设置为输入捕捉
TSCR1=0x80; //启用定时器
TCTL4=0x10; //捕捉上升沿
TFLG1=0xFF; //写1清除标志,其实是让寄存器中的值变成0

}


void measure_wave(){
while((TFLG1 & 0x04)==0)//等待C2F标志产生
{
;
}
rising_1=TCNT;
TFLG1=0x04; //写1清除C2F标志

while((TFLG1 & 0x04)==0)//等待C2F标志产生
{
;
}
rising_2=TCNT;
TFLG1=0x04; //写1清除C2F标志
}

void period_freq(){
unsigned long int new_rising;
unsigned long int new_falling;
unsigned char peri[9]="Period=";
unsigned char freq[12]="Frequency=";
unsigned char period_buff[8]=" ";
unsigned char int_freq_buff[3]=" ";
unsigned char freq_tenths_buff[4]=" ";

int i;
float frequency;
float period;
unsigned int int_period;
unsigned int int_freq,freq_tenths;
unsigned char chr;

if(rising_2 < rising_1)
{
new_rising=rising_2+0xFFFF;
period=((float)new_rising-(float)rising_1)*0.0000005;
}
else
{
period=((float)rising_2-(float)rising_1)*0.0000005;
}

frequency=1.0/period; //Hz
int_freq=(int)(frequency/1000.0); //KHz
freq_tenths=(int)((frequency-(float)int_freq*1000)/100.0); //0.0KHz
int_period=(int)(1000000*period); //us
_itoa(int_period,period_buff,10);
_itoa(int_freq,int_freq_buff,10);
_itoa(freq_tenths,freq_tenths_buff,10);
////输出周期
for(i=0;i {
chr=peri;
SCI0Output_char(chr);
}
for(i=0;i {
chr=period_buff;
SCI0Output_char(chr);
}
SCI0Output_char('u');
SCI0Output_char('s');
SCI0Output_char('\n');
////输出频率
for(i=0;i {
chr=freq;
SCI0Output_char(chr);
}
for(i=0;i {
chr=int_freq_buff;
SCI0Output_char(chr);
}
SCI0Output_char('.');
for(i=0;i {
chr=freq_tenths_buff;
SCI0Output_char(chr);
}
SCI0Output_char('K');
SCI0Output_char('H');
SCI0Output_char('z');
}
void SCI_Init(void) {
SCI0CR2 = 0x0c; // enable T and R
SCI0BDH = 0x00;
SCI0BDL = 0x34; // sci0 for 9600
// SCI0BDL = 0x68; // sci0 for 4800
}
void SCI0Output_char(unsigned char ch)
{
while(!(SCI0SR1&0x80))
{
}
SCI0DRL = ch;
}
void PWMIni(){
PWME_PWME5=0;
PWMCLK=0x20; //选择PWM5口的时钟源为 SA
PWMPRCLK=0x07; //设置CLOCK A频率为bus clock/128 8000000/128=62500Hz
PWMSCLA=4; //设置再分频寄存器 62500/(4*2)= 7812.5Hz
PWMPOL=0x20;
PWMCAE=0; //对齐方式,左对齐输出
PWMPER5=78; //PWM5输出周期=7812.5/78=100Hz
PWMDTY5=31; //占空比=31/78=40%
DDRP=0xff;
PWME_PWME5=1;
PWMCNT5=0;
}


本人QQ:472113926
E-Mail:fyhl845@163.com
欢迎联系,共同探讨.
作者: fyhl_moto    时间: 2007-5-18 10:35

工程文件http://bbs.chinaecnet.com/uploadImages/ECT.rar
作者: fithkyo0885    时间: 2007-5-18 10:42

你用的CW是什么版本?
作者: fyhl_moto    时间: 2007-5-18 10:46

我用的CW 是 V4.5

作者: strongchen    时间: 2007-5-18 11:17

你的程序经过调试验证过了吗?你自己做中断方式有什么困难呢?
作者: fyhl_moto    时间: 2007-5-18 11:25

这个程序在我的机器上已经验证通过了
效果很好
因为我也刚接触这个不是很长时间,目前对中断还有很多疑惑

作者: fyhl_moto    时间: 2007-5-18 11:29

测试的时候需要将PWM5口和PT2相连
作者: nishui_2000    时间: 2007-5-18 16:28

你这样作输入不捉不合理的,因为你是采用 While循环的办法等待第二个波形到来把,如果频率比较低,比如几百Hz的波形,这样就影响到其他的处理速度了
你可以用中断,检测到两个上升沿的时候产生一次中断
作者: fyhl_moto    时间: 2007-5-18 19:58

谢谢楼上的提醒
这个只是我做的一个例子
我也正在考虑用中断
由于我刚接触这个芯片,还不是太熟悉
会改进的,努力ing...
作者: fyhl_moto    时间: 2007-5-21 21:47

中断方式的输入捕捉程序终于搞定了
感谢大家的关注和建议
希望大家继续给我的这个程序指出不足

作者: skyboy    时间: 2007-5-24 00:23

麻烦楼上的把你用中断写的代码上传参考一下,行吗?
作者: zhaoxyz486    时间: 2007-5-28 14:17

en 版主能不能贴一下呀你的用在中断写的代码呀,万分感谢
作者: eric321    时间: 2007-5-28 15:42

版主能不能贴一下呀你的用在中断写的代码呀,万分感谢!
作者: fyhl_moto    时间: 2007-5-31 21:51

回复楼上的几位:
最近忙着毕业论文和毕业答辩
等我答辩完后我会把相关的程序文件贴上来的
谢谢大家对我的支持与肯定

作者: fyhl_moto    时间: 2007-6-3 18:51

这是我写的一个中断方式的ECT输入捕捉程序
其中有很多串口输出的部分
有兴趣的朋友可以自己把这部分的代码简化下
最好能封装成一个函数再调用

在prm文件最后需要加入VECTOR ADDRESS 0xFFEA measure_wave_intr


/////////////////*************************************************//////
// 中断方式的输入捕捉程序
//程序功能简介:PWM5输出测试用的方波,定时器通道2设为输入捕捉通道,中断方式捕捉PWM5的输出
// 计算其周期和频率,利用串口通信发送到PC机显示
//程序设计:PanLei (感谢ChengMiao的技术支持)
//设计时间:2007年5月21日 晚
/////////////////*********************************************************************//////
#include /* common defines and macros */
#include /* derivative information */
#pragma LINK_INFO DERIVATIVE "mc9s12dg128b"
#include
#include
#include

//函数声明
void timer_init(void); //计数器初始化
void period_freq(void); //周期、频率
void SCI_Init(void);
void SCI0Output_char(unsigned char ch);
void PWMIni(void);

void measure_wave_intr(void); //中断服务程序

//全局变量声明
unsigned long int rising_1;
unsigned long int rising_2;
unsigned int flg=0;

void main(void) {
/* put your own code here */
EnableInterrupts;
SCI_Init();
PWMIni();
DDRB=0xff;
PORTB=0xe7;
timer_init();
/* measure_wave();
period_freq(); */

for(;;) {} /* wait forever */
/* please make sure that you never leave this function */
}


void timer_init(void){
TIE=0x04; //允许C2I中断
TSCR2=0x02; //时钟=M Clock/4=2MHz
TIOS=0x00; //ch2设置为输入捕捉
TSCR1=0x80; //启用定时器
TCTL4=0x10; //捕捉上升沿
TFLG1=0xFF; //写1清除标志,其实是让寄存器中的值变成0

}

//中断服务程序
#pragma CODE_SEG NON_BANKED
#pragma TRAP_PROC
void measure_wave_intr(){
DDRB=0xff;
PORTB=0x00;
if(!flg){
rising_1=TCNT;
TFLG1=0x04; //写1清除C2F标志
flg=1;
}
else{
rising_2=TCNT;
TFLG1=0x04; //写1清除C2F标志
flg=0;
period_freq();
TIE=0x00;
}
}
#pragma CODE_SEG DEFAULT


void period_freq(){
unsigned long int new_rising;
unsigned char peri[9]="Period=";
unsigned char freq[12]="Frequency=";
unsigned char period_buff[8]=" ";
unsigned char int_freq_buff[3]=" ";
unsigned char freq_tenths_buff[4]=" ";
unsigned char author[]="\nDesigned by PanLei on 2007-5-21. Thanks my GF ChengMiao's Help!" ;
int i;
float frequency;
float period;
unsigned int int_period;
unsigned int int_freq,freq_tenths;
unsigned char chr;

if(rising_2 < rising_1)
{
new_rising=rising_2+0xFFFF;
period=((float)new_rising-(float)rising_1)*0.0000005;
}
else
{
period=((float)rising_2-(float)rising_1)*0.0000005;
}

frequency=1.0/period; //Hz
int_freq=(int)(frequency/1000.0); //KHz
freq_tenths=(int)((frequency-(float)int_freq*1000)/100.0); //0.0KHz
int_period=(int)(1000000*period); //us
(void)_itoa(int_period,period_buff,10);
(void)_itoa(int_freq,int_freq_buff,10);
(void)_itoa(freq_tenths,freq_tenths_buff,10);
////输出周期
for(i=0;i {
chr=peri;
SCI0Output_char(chr);
}
for(i=0;i {
chr=period_buff;
SCI0Output_char(chr);
}
SCI0Output_char('u');
SCI0Output_char('s');
SCI0Output_char('\n');
////输出频率
for(i=0;i {
chr=freq;
SCI0Output_char(chr);
}
for(i=0;i {
chr=int_freq_buff;
SCI0Output_char(chr);
}
SCI0Output_char('.');
for(i=0;i {
chr=freq_tenths_buff;
SCI0Output_char(chr);
}
SCI0Output_char('K');
SCI0Output_char('H');
SCI0Output_char('z');
for(i=0;i {
chr=author;
SCI0Output_char(chr);
}
}

void SCI_Init(void) {
SCI0CR2 = 0x0c; // enable T and R
SCI0BDH = 0x00;
SCI0BDL = 0x34; // sci0 for 9600
// SCI0BDL = 0x68; // sci0 for 4800
}
void SCI0Output_char(unsigned char ch)
{
while(!(SCI0SR1&0x80))
{
}
SCI0DRL = ch;
}
void PWMIni(){
PWME_PWME5=0;
PWMCLK=0x20; //选择PWM5口的时钟源为 SA
PWMPRCLK=0x07; //设置CLOCK A频率为bus clock/128 8000000/128=62500Hz
PWMSCLA=4; //设置再分频寄存器 62500/(4*2)= 7812.5Hz
PWMPOL=0x20;
PWMCAE=0; //对齐方式,左对齐输出
PWMPER5=78; //PWM5输出周期=7812.5/78=100Hz
PWMDTY5=31; //占空比=31/78=40%
DDRP=0xff;
PWME_PWME5=1;
PWMCNT5=0;
}
作者: zhaoxyz486    时间: 2007-6-4 08:41

回楼上,,,中断发生的时候 可以直接利用捕捉寄存器和捕捉保持寄存器吧 没有必要再去
TCNT的值吧,大家的意见呢??
作者: sunsetman    时间: 2007-6-12 04:51

能不能给我看下啊 ?
我的邮箱sunsetman@sina.com
我正在写一个输入捕捉的程序,但是有些问题
作者: d9912345    时间: 2007-7-6 21:55

我感觉贴出来的程序有问题啊
比如中断的程序中有下列语句:
for(i=0;i {
chr=peri;
SCI0Output_char(chr);
}
这明显不是一个不完整的语句,但如果把它复制到WORD中就变成了以下语句:
for(i=0;i {
chr=peri;
SCI0Output_char(chr);
}
而且其中的大小写有问题。
这是网站的支持有问题吗?烦请解答,我试中断的程序时出现了编译错误、调试错误,而且很多。


作者: d9912345    时间: 2007-7-6 22:02

看来不行,只有截图让你们看了。

我晕,图片上传不了。大家只有自己试试看了。

这是网站支持有问题,还是我的电脑有问题?

[此贴子已经被作者于2007-7-6 22:02:10编辑过]


作者: d9912345    时间: 2007-7-7 13:09

楼主上传的程序在我的电脑上能编译运行(不过有警告),但是下载到单片机上却不运行。
我自己又引导wizard建一个新的project,但是编译能通过,链接不能通过,链接出现错误,如下所示:
link error:l1822:Symbol _FUFLOAT in file .....main.c.o is undefined
link error:l1822:Symbol _FSUB in file .....main.c.o is undefined
link error:l1822:Symbol _FMUL in file .....main.c.o is undefined
link error:l1822:Symbol _FUFLOAT in file .....main.c.o is undefined
link error:l1822:Symbol _FDIV in file .....main.c.o is undefined
link error:l1822:Symbol _FSTRUNC in file .....main.c.o is undefined
这个问题不能解决。
编译时在itoa那一行出现以下警告:
WARING:C1825:indirection to different types ('unsigned char *'instead of 'signed char *')
WARING:C1420:result of function-call is ignored.

经排查,如果没有用period_freq()这个函数,则编译和链接都能通过。问题应该就在这个函数中。
版主能解决一下吗?(有MCP文件的)

http://bbs.chinaecnet.com/uploadImages/ect2.rar

[此贴子已经被作者于2007-7-7 13:09:59编辑过]


作者: d9912345    时间: 2007-7-7 19:21

版主周末不在吗?没人回答
还好,我自己现在知道怎么回事了,那个函数里面用了浮点数,因此在引导wizard建一个新的project时,要注意选择浮点数,不要一路点选“下一步”。
作者: d9912345    时间: 2007-7-10 22:21

对于楼主的中断程序,有一些问题需要请教版主。在楼主的中断程序中,总线频率是8M,我用串行口通讯,在超级终端中显示的频率为100HZ,但是我用示波器测量PWM5口的波形,却是300HZ,貌似总线频率为24M,如果用锁相环将频率固定为8M,现象不变。另外,我在超级终端中设置的波特率为9600,但是不论在8M总线频率中还是在24M总线频率中,都必须使SCI0BDL = 0x9c才能使单片机通过串行口发送数据到超级终端。请问一下这是怎么回事?

作者: strongchen    时间: 2007-7-11 10:47

你需要检测一下你的总线频率到底是多少。
作者: d9912345    时间: 2007-7-11 13:14

MC9S12DG128B的板子,外部晶振为16MHZ,不用锁相环时总线频率不就是8MHZ吗?这没问题啊
作者: bjg007    时间: 2009-8-7 15:19

也给我传一个吧,bjg0073128@sina.com




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0