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

[分享]ECT的输入捕捉程序(MC9S12DG128B)

[分享]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
欢迎联系,共同探讨.
工程文件http://bbs.chinaecnet.com/uploadImages/ECT.rar
你用的CW是什么版本?
我用的CW 是 V4.5
你的程序经过调试验证过了吗?你自己做中断方式有什么困难呢?
海纳百川  有容乃大
这个程序在我的机器上已经验证通过了
效果很好
因为我也刚接触这个不是很长时间,目前对中断还有很多疑惑
测试的时候需要将PWM5口和PT2相连
你这样作输入不捉不合理的,因为你是采用 While循环的办法等待第二个波形到来把,如果频率比较低,比如几百Hz的波形,这样就影响到其他的处理速度了
你可以用中断,检测到两个上升沿的时候产生一次中断
水泡泡
 我的QQ是:52449804 
 我的网站是: www.dyic.com.cn
 欢迎访问和留言跟我联系
谢谢楼上的提醒
这个只是我做的一个例子
我也正在考虑用中断
由于我刚接触这个芯片,还不是太熟悉
会改进的,努力ing...
中断方式的输入捕捉程序终于搞定了
感谢大家的关注和建议
希望大家继续给我的这个程序指出不足
麻烦楼上的把你用中断写的代码上传参考一下,行吗?
en 版主能不能贴一下呀你的用在中断写的代码呀,万分感谢
大家好
版主能不能贴一下呀你的用在中断写的代码呀,万分感谢!
回复楼上的几位:
最近忙着毕业论文和毕业答辩
等我答辩完后我会把相关的程序文件贴上来的
谢谢大家对我的支持与肯定
这是我写的一个中断方式的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;
}
返回列表