智能车制作
标题: 谁能够写个基于16位飞思卡尔单片机的超声波测距程序给我 [打印本页]
作者: 火海凡人 时间: 2011-7-27 18:49
标题: 谁能够写个基于16位飞思卡尔单片机的超声波测距程序给我
作者: 转角踩到屎 时间: 2011-7-31 16:00
将模组的Trig接A1口,Echo接T7口,GND与单片机的GND共地,新建工程时选择带浮点型的
#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
float Distance;
unsigned int n, shicha,cn0,cn1 ;
//-----时钟初始化程序--------//
void PLL_Init(void) //PLLCLK=2*OSCCLK*(SYNR+1)/(REFDV+1)
{ //锁相环时钟=2*16*(2+1)/(1+1)=48MHz
REFDV=1; //总线时钟=48/2=24MHz
SYNR=2;
while(!(CRGFLG&0x08));
CLKSEL=0x80;
}
/*IO口初始化*/
void IO_Init(void)
{
DDRA=0x02; // A1输出
}
void DELAY(unsigned int loop_times) //延时10us程序
{
unsigned int loop_i,loop_j;
for(loop_i=0;loop_i<loop_times;loop_i++)
{for(loop_j=0;loop_j<38;loop_j++)
;
}
}
//===============PIT模块初始化==================//
void Pit_Init(void)
{
PITCFLMT_PITE = 1; //使能PIT模块
PITCE = 0X00; //通道0,1 PIT模块禁止
PITINTE = 0x03; //通道0,1中断使能
PITMUX = 0x00; //16位定时通道0使用0号8位微计数器,16位定时器1使用1号微计数器
PITMTLD0 =120-1; //8位定时器初值设定。120分频,在24MHzBusClock下,为0.2MHz。即5us.
PITLD0 =4000-1; //16位定时器初值设定,即定时20ms
PITCE = 0X01; //通道0,1 PIT模块使能
}
//==============触发信号发生程序==========//
void Chufa(void)
{
PORTA_PA1=1;//PA1输出高电平
DELAY(1); //延时10us
PORTA_PA1=0;//PA1输出低电平
}
#pragma CODE_SEG __NEAR_SEG NON_BANKED
interrupt 66 void PIT0(void)
{
PITTF_PTF0 = 1;
Chufa();
}
void ECT0_Init(void)
{
TSCR2=0x06; //禁止溢出中断,分频系数64 周期 2.67us
TIOS=0x00; //PT7为输入捕捉
TCTL3=0xc0; //输入捕捉7上升沿和下降沿均有效
TIE_C7I=1; //通道7输入捕捉中断允许
TSCR1=0x80; //使能定时器
}
void interrupt 15 Timer0_Onput(void)
{
TFLG1_C7F=1;
if(!(n%2)==0)
{
cn0=TCNT;
}
else if(n%2==0)
{
cn1=TCNT;
if(cn1>cn0)
{
shicha=cn1-cn0;
}
else if(cn1<cn0)
{
shicha=cn1+65535-cn0;
Distance=shicha*2.67*0.017; //单位cm
}
}
}
//=======================主函数================================//
void main(void)
{
PLL_Init(); //设置锁相环
Pit_Init();
IO_Init();
ECT0_Init();
EnableInterrupts;
for(;;)
{
}
}
作者: njhgrmk 时间: 2011-9-25 12:54
n值没有修改
作者: OPQ_XYQ 时间: 2012-3-24 17:11
#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
#include <math.h>
#include "lcd5110.h"
//-----------------PIT定时中断参量--------------------------------------------------
#define PITTIME1 100;
#define PITTIME2 180;
int loop_i=0;
int loop_j=0;
//-------------------中断服务变量------------
//--------------pk
int test_start=0;
int test_over=1;
int start_flage=0;
unsigned int time_m_o=0;
unsigned int time_start=0 ;
unsigned int time_over=0;
float time_rising=0;
float distance=0;
//----------------
/****************************准确延时*****************************/
//---------------------------1us准确延时__64M-----------------------------
void Delay1us(int c)
{
int cnt0;
for(cnt0=0;cnt0<2*c;cnt0++)
{
_asm NOP; _asm NOP;_asm NOP;
_asm NOP; _asm NOP;_asm NOP;_asm NOP;
_asm NOP; _asm NOP;_asm NOP;_asm NOP;
_asm NOP; _asm NOP;_asm NOP;_asm NOP;
_asm NOP; _asm NOP;_asm NOP;
}
}
//---------------------------1ms准确延时__64M-------------------------
void Delay1ms(int c)
{
int cnt;
int cnt1;
for(cnt=0;cnt<2*c;cnt++)
{
for(cnt1=0;cnt1<1000;cnt1++)
{
_asm NOP; _asm NOP;_asm NOP;_asm NOP;
_asm NOP; _asm NOP;_asm NOP;_asm NOP;
_asm NOP; _asm NOP;_asm NOP;_asm NOP;
_asm NOP; _asm NOP;_asm NOP;_asm NOP;
_asm NOP; _asm NOP;_asm NOP;_asm NOP;
}
}
}
/**************总线时钟设置函数***************************/
void SetBusCLK_64M(void)
{
CLKSEL=0x00;
PLLCTL_PLLON=1; //turn on PLL
SYNR =0xc0 | 0x07; //80M
REFDV=0x80 | 0x01;
POSTDIV=0x00; //pllclock=2*16*(1+SYNR)/(1+REFDV)=xxMHz;
while(CRGFLG_LOCK!=1);//Wait Till VCO Run Stable
CLKSEL_PLLSEL=0x01;//PLLCLK Enabled,Bus Clock=PLLCLK/2=24M
}
/**************PWM初始化函数******************************/
void PWM_Init(void)
{
//时钟设置
PWMPRCLK = 0X44; //CLKA,CLKB 16分频:=4MHz
// PWMSCLA = 0x20; //对clock SA 进行2*PWMSCLA分频;pwm clock=clockA/64=171kHz;
PWMSCLB = 0XC8; //200 //clk SB=clk B/(2*pwmsclb)=10kHz
PWMCLK = 0xc0;//0x80; //67口时钟源CLOCK SB 23口时钟源CLOCK B
//45口时钟源CLOCK A 01口时钟源CLOCK A
PWMCTL = 0x80; //1000 0000 :76级联控制!54、32?、1不级联
PWMCAE=0x00; // 居中对齐允许寄存器 0左对齐,1 居中
PWMPOL=0xff; /// 1 周期开始 高电平 0 周期开始低电平
//通道周期寄存器
PWMPER3=100; ///10ms //if 左对齐 PWMxPeriod=Channel_Clockperiod*PwmPerx
PWMDTY3=0; //else PWMxPeriod=Channel_Clockperiod*PwmPerx*2
PWMPER5=100; // 10ms 80000/8000=10ms
PWMDTY5=0;
PWMPER67=200; //50HZ
// PWMDTY67=duoji_mid;
PWME =0xeb; //1110 1011:通道2、4被禁止输出作为通用IO口用
}
/**************I/O初始化函数******************************/
void PORT_ini (void)
{
DDRP_DDRP2=1; //数据方向寄存器为1:A口为输出;
DDRP_DDRP4=1; //数据方向寄存器为1:A口为输出;
DDRA=0XFF; //数据方向寄存器为1:A口为输出;
PORTA=0XAA; //A口1010 1010:
// DDRB=0XFF; //B口同上A口;
// PORTB=0X55; //A口0101 0101:
//---液晶--------B口-------------------
DDRA_DDRA0=1; //数据方向寄存器1为输出,写数据
//设置H口0位的中断
DDRH_DDRH0=0; //H口0位:开关量输入 读数据!
PERH_PERH0=1; //H口0位:允许上拉或下拉器件
//H口初始化为高电平还是低电平???____应该为低电平!!!
PPSH_PPSH0=0; //H口0位:1上升沿触发中断 0下降沿
PIEH_PIEH0=1; //H口0位:中断允许 中断标志位 PIFH_PIFH0
}
/**************PIT定时中断函数******************************/
void PIT_init(void)//定时中断初始化函数 5MS定时中断设置
{
PITCFLMT_PITE=0; //定时中断通道0关
PITCE_PCE0=1;//定时器通道0使能
PITMUX_PMUX0=0;
PITMTLD0=PITTIME1-1;//8位定时器初值设定,11分频,在88MHzBusClock下,为8MHz。
PITLD0=PITTIME2-1;//16位定时器初值设定。8分频 1MHz
PITINTE_PINTE0=1;//定时器中断通道0中断使能
PITCFLMT_PITE=1;//定时器通道0使能
}
/**************ECT初始化函数***********************************/
static void ECT_ini(void)
{
TIOS_IOS7=0;//:通道选择寄存器0:相应通道为输入捕捉;1:相应通道为输出比较;
TIOS_IOS0=0; //T0输入捕捉
TIOS_IOS1=0; //T1输入捕捉
TSCR1_TEN=1;//定时器系统控制寄存器1:定时器使能
TSCR1_PRNT=1;//定时器系统控制寄存器1:精确定时器,PTPSR寄存器有效,对主定时器计数器频率进行设置 5.5M??????
PTPSR=0X07;//8分频
TCTL1_OM7=0;
TCTL1_OL7=0;//OC7 没有输出动作!
OC7M_OC7M7=0;//不把OC7D中的数据传送到定时器的数据端口;
TCTL4=0X04;//0000 0100 :脉冲累加器T1仅在上升沿捕捉
TIE=0X02;//0000 0010禁止中断; 0允许中断
TSCR2_TOI=1; //定时器溢出中断允许
}
//------------给触发电平
void SET_PULSE (void)
{
if (start_flage == 0) //30us的触发电平 高于10us
{
PORTA_PA0=0;
Delay1us(30);
PORTA_PA0=1;
Delay1us(30);
PORTA_PA0=0;
start_flage=1;
test_start=1;
test_over=0;
}
}
//------------给触发电平结束
void check_up (void)
{
if ((start_flage==1)&&(PTH_PTH0==1)) // 检测到上升沿,记录当前时间
{
time_start=0;
time_m_o=0;
TCNT=0X0000;
start_flage=2; // cap riseing edge
}
}
////////////中断服务函数
#pragma CODE_SEG __NEAR_SEG NON_BANKED
//----------------------------------------------
void interrupt 25 h_irupt (void) //H口下降沿发生中断
{
if (start_flage == 2)
{
time_over=TCNT;
time_rising=((time_over-time_start)+time_m_o*65535)/80;
time_m_o=0;
start_flage=0;
distance=(time_rising*340)/2000; //公式
test_start=0;
test_over=1;
}
PIFH_PIFH0=1;
}
//--------------------------------------------------------
void interrupt 16 Irupt_t1 (void) //计时器中断溢出
{
if ((start_flage==2)&&(test_start==1))
{
time_m_o++;
}
TFLG2_TOF=1;
}
//-------------------/
void interrupt 66 Irupt_pit0 (void) //通道0 2ms
{
if(loop_i>100) //测量周期大100ms
{
SET_PULSE();
loop_i=0;
}
PITTF_PTF0=1; //PIT溢出标志寄存器, 清除中断标志位
}
//------------------------------------------------------
/////////////中断服务程序结束///////////////
void main(void)
{
SetBusCLK_64M();
PWM_Init();
PORT_ini();
ECT_ini();
PIT_init;
EnableInterrupts;
LCD_init();
LCD_clear();
for(;;)
{
if(test_start==1)
check_up();
}
}
作者: 卧听南窗雨 时间: 2012-4-15 00:33
OPQ_XYQ 发表于 2012-3-24 17:11 
#include /* common defines and macros */
#include "derivative.h" /* derivative-speci ...
太棒了!!!!
作者: OPQ_XYQ 时间: 2012-4-15 08:07
这次把附件加上[attach]22863[/attach]
作者: OPQ_XYQ 时间: 2012-4-15 08:08
卧听南窗雨 发表于 2012-4-15 00:33 
太棒了!!!!
[attach]22864[/attach]
作者: 475246126 时间: 2012-10-31 13:56
OPQ_XYQ 发表于 2012-3-24 17:11 
#include /* common defines and macros */
#include "derivative.h" /* derivative-speci ...
八位的s08AC16可以用这个程序吗?
作者: yangshenle 时间: 2012-11-2 09:37
好
作者: 1347519017 时间: 2013-4-5 11:09
#include <hidef.h> /* common defines and macros */
#include <MC9S12XS128.h> /* derivative information */
#pragma LINK_INFO DERIVATIVE"mc9s12xs128"
/*可以通过更改TIMER的值来实现不同时间的定时,
定时长为TIMER *10us*/
#define TIMER 1
#define TRING PORTA_PA0 //控制端
#define ECHO PORTA_PA1 //接收端
ulong time = 0;
/* n * 10us延时*/
void Delay_Us(ulong n)
{
time = n;
while (time);
}
/*IO口初始化*/
void IO_Init(void)
{
DDRA = 0x01; //A0输出,A1输入
}
/*PIT初始化,实现10US定时*/
void PIT_Init(void)
{
PITCFLMT_PITE = 0; //定时中断通道0关
PITCE_PCE0 = 1; //定时器通道0使能
PITMTLD0 = 160 - 1; //8位定时器初值设定,160分频
PITLD0 = TIMER - 1; //16位定时器初值设定,TIMER*10us
PITINTE_PINTE0 = 1; //定时器中断通道0中断使能
PITCFLMT_PITE = 1; //定时器通道0使能
}
void main(void)
{
ulong t;
double dis;
IO_Init(); //IO初始化
PIT_Init(); //PIT初始化
EnableInterrupts; //开中断
/*等待200us使超声波模块初始化完毕*/
Delay_Us(20);
while (1)
{
/*给控制端一个超过10US的高电平,然后置低*/
TRING = 1;
Delay_Us(2);
TRING = 0;
/*等待接收端产生高电平并计时*/
while (!ECHO);
time = 0xff;
while (ECHO);
t = 0xff - time; //计时
dis = 1.7 * t; //计算距离
//延时10MS,这个的原因大家看时序图,不同的硬件不同
Delay_Us(1000); }
}
/*PIT定时中断*/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
void interrupt 66 PIT0(void)
{
PITTF_PTF0 = 1; //清中断标志位
--time;
}
作者: 1347519017 时间: 2013-4-9 16:43
#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
#include <math.h>
//-----------------PIT定时中断参量--------------------------------------------------
#define PITTIME1 250;
#define PITTIME2 250;
int loop_i=0;
//int loop_j=0;
//-------------------中断服务变量------------
//--------------pk
int test_start=0;
int test_over=1;
int start_flage=0;
unsigned int time_m_o=0;
unsigned int time_start=0 ;
unsigned int time_over=0;
float time_rising=0;
int distance=0;
int k;
int duty;
//----------------
/****************************准确延时*****************************/
//---------------------------1us准确延时__64M-----------------------------
void Delay1us(int c)
{
intcnt0;
for(cnt0=0;cnt0<2*c;cnt0++)
{
_asm NOP; _asm NOP;_asm NOP;
_asm NOP; _asm NOP;_asm NOP;_asm NOP;
_asm NOP; _asm NOP;_asm NOP;_asm NOP;
_asm NOP; _asm NOP;_asm NOP;_asm NOP;
_asm NOP; _asm NOP;_asm NOP;
}
}
//---------------------------1ms准确延时__64M-------------------------
void Delay1ms(int c)
{
int cnt;
int cnt1;
for(cnt=0;cnt<2*c;cnt++)
{
for(cnt1=0;cnt1<1000;cnt1++)
{
_asm NOP; _asm NOP;_asm NOP;_asm NOP;
_asm NOP; _asm NOP;_asm NOP;_asm NOP;
_asm NOP; _asm NOP;_asm NOP;_asm NOP;
_asm NOP; _asm NOP;_asm NOP;_asm NOP;
_asm NOP; _asm NOP;_asm NOP;_asm NOP;
}
}
}
/**************总线时钟设置函数***************************/
void SetBusCLK_64M(void)
{
CLKSEL=0x00;
PLLCTL_PLLON=1; //turn on PLL
SYNR =0xc0 | 0x07; //80M
REFDV=0x80 | 0x01;
POSTDIV=0x00; //pllclock=2*16*(1+SYNR)/(1+REFDV)=xxMHz;
while(CRGFLG_LOCK!=1);//Wait Till VCO Run Stable
CLKSEL_PLLSEL=0x01;//PLLCLK Enabled,Bus Clock=PLLCLK/2=24M
}
/**************I/O初始化函数******************************/
void PORT_ini (void)
{
DDRP_DDRP2=1; //数据方向寄存器为1:p2口为输出;
DDRP_DDRP4=1; //数据方向寄存器为1:p4口为输出;
//---发射口--------A口-------------------
DDRA_DDRA0=1; //数据方向寄存器1为输出,写数据
PORTA_PA0=0;
//设置H口0位的中断
DDRH_DDRH0=0; //H口0位:开关量输入 读数据!
PERH_PERH0=0; //H口0位:允许上拉或下拉器件
//H口初始化为低电平
PPSH_PPSH0=0; //H口0位:1上升沿触发中断 0下降沿
PIEH_PIEH0=1; //H口0位:中断允许 中断标志位 PIFH_PIFH0
}
/*******************************************************************
定时中断模块
********************************************************************/
static void PIT_ini(void) //1ms定时中断
{
PITCFLMT_PITE=0; //PIT控制寄存器及强制载入微定时器寄存器
//禁止PIT
PITMUX_PMUX0=0; //PIT定时器复合寄存器:选择8位的基时钟base0
PITMUX_PMUX3=1; // 选择8位的基时钟base1
//------溢出周期计算:time-out period = (PITMTLD +1) * (PITLD + 1) / fBUS.
PITMTLD0=0xc7; //PIT微定时器装载寄存器:8位, 0xc7——199;0x85——6399
PITLD0=0x36f; //PIT定时器装载寄存器:16位0xffff; 0x36f——879
//T0通道定时周期T0 period=200*880/88M=2ms;
PITMTLD1=0X85; //0X85——133;C8——200+1
PITLD3=0XFFFF; // FFFF——65535
//T0通道定时周期T3period=134*65536/88M=99.79ms;
PITCE_PCE0=0; // PIT通道使能寄存器 : 通道0使能
PITCE_PCE3=1; //通道3使能
PITINTE_PINTE0=0; //PIT中断使能寄存器:
PITINTE_PINTE3=1; //通道3中断使能
PITCFLMT_PITE=1; //PIT使能
}
/**************ECT初始化函数***********************************/
static void ECT_ini(void)
{
TIOS_IOS7=0; //:通道选择寄存器0:相应通道为输入捕捉;1:相应通道为输出比较;
TIOS_IOS0=0; //T0输入捕捉
TIOS_IOS1=0; //T1输入捕捉
TSCR1_TEN=1; //定时器系统控制寄存器1:定时器使能
TSCR1_PRNT=1;//定时器系统控制寄存器1:精确定时器,PTPSR寄存器有效,对主定时器计数器频率进行设置 5.5M
PTPSR=0X07; //8分频
TCTL1_OM7=0;
TCTL1_OL7=0; //OC7 没有输出动作!
OC7M_OC7M7=0; //不把OC7D中的数据传送到定时器的数据端口;
TCTL3=0X80; //1000 0000 :脉冲累加器T1仅在上升沿捕捉
TIE=0X80; //1000 0000禁止中断; 0允许中断
TSCR2_TOI=1; //定时器溢出中断允许
}
//------------给触发电平
void SET_PULSE (void)
{
if (start_flage==0) //30us的触发电平 高于10us
{
PORTA_PA0=0;
Delay1us(30);
PORTA_PA0=1;
Delay1us(300);
PORTA_PA0=0;
start_flage=1;
test_start=1;
test_over=0;
}
}
//------------给触发电平结束
void check_up (void)
{
if ((start_flage==1)&&(PTH_PTH0==1)) // 检测到上升沿,记录当前时间
{
time_start=0;
time_m_o=0;
TCNT=0X0000;
start_flage=2; // cap riseingedge
}
}
////////////中断服务函数
#pragma CODE_SEG __NEAR_SEG NON_BANKED
//----------------------------------------------
void interrupt 25 h_irupt (void) //H口下降沿发生中断
{
if (start_flage == 2)
{
time_over=TCNT;
time_rising=((time_over-time_start)+time_m_o*65535)/80; //计算出来为ms
time_m_o=0;
start_flage=0;
distance=(time_rising*340)/20; //公式 计算出来为cm
TCNT=0x0000;
test_start=0;
test_over=1;
}
PIFH_PIFH0=1;
}
//--------------------------------------------------------
void interrupt 16 Irupt_t1 (void) //计时器中断溢出
{
if ((start_flage==2)&&(test_start==1))
{
time_m_o++;
}
TFLG2_TOF=1; //定时器溢出标志位,写1清0
}
//***************************************************************/
void interrupt 69 Irupt_pit3(void) //通道3 100ms中断,检测周期
{
SET_PULSE();
//test_start=1;
PITTF_PTF3=1;
//清除中断标志位
}
#pragma CODE_SEG DEFAULT
//中断结束
//------------------------------------------------------
/////////////中断服务程序结束///////////////
/*PWM初始化程序*/
void PWM1_init()
{
PWME_PWME2=0x00; // Disable PWM 禁止
PWMPRCLK=0x33; // 0011 0011A=B=24M/8=3M 时钟预分频寄存器设置
PWMSCLA=150; //SA=A/2/150=10k 时钟设置
PWMSCLB=15; // SB=B/2/15=100k 时钟设置
PWMCLK_PCLK2=1; //PWM3-----SB 时钟源的选择
PWMPOL_PPOL2=1; // Duty=HighTime 极性设置
PWMCAE_CAE2=0; //Left-aligned 对齐方式设置
PWMCTL=0x00; // noconcatenation 控制寄存器设置
PWMPER2=100; // Frequency=SB/100=1K 周期寄存器设置
PWMDTY2=0; // Duty cycle =duty 占空比寄存器设置
PWME_PWME2=1; // Enable PWM 使能
}
voidmotor_forward() //控制电机
{
PWME_PWME4=0;
PWME_PWME2=1;
DDRP_DDRP2=1;
PTP_PTP2=0;
k=distance/5;
duty=k-1;
PWMDTY2=duty;
}
void main(void)
{
DisableInterrupts;
SetBusCLK_64M();
PORT_ini();
ECT_ini();
PIT_ini();
EnableInterrupts;
SET_PULSE();
for(;;)
{
if(test_start==1)
{
check_up();
}
if(time_m_o>=300)
{
duty=100;
}
if ((test_start==1)&&(test_over==1) )
{
SET_PULSE();
}
PWM1_init();
motor_forward();
}
}
作者: 一刀. 时间: 2013-4-20 10:20
OPQ_XYQ 发表于 2012-3-24 17:11 
#include /* common defines and macros */
#include "derivative.h" /* derivative-speci ...
这个用的是DG128吧?
作者: zhouji0509 时间: 2013-4-26 22:12
njhgrmk 发表于 2011-9-25 12:54 
n值没有修改
n怎么改呀!??急急急!!
作者: 【风】 时间: 2013-8-14 15:51
1347519017 发表于 2013-4-5 11:09 
#include /* common defines and macros */ #include /* derivative information */ #pra ...
非常感谢,很好用
作者: 【风】 时间: 2013-8-14 16:00
1347519017 发表于 2013-4-5 11:09 
#include /* common defines and macros */ #include /* derivative information */ #pra ...
你的程序很好用,有一个问题,请问下面打问号的什么意思,谢谢
while (!ECHO);
time = 0xff; ?
while (ECHO);
t = 0xff - time; //计时 ?
补充内容 (2013-8-14 19:20):
距离换成m就不准了
补充内容 (2013-8-14 19:20):
cm
作者: ℡单身旅行 时间: 2013-8-18 15:41
楼上给的例子不行啊
作者: dongwei185 时间: 2013-9-2 15:20
1347519017 发表于 2013-4-5 11:09 
#include /* common defines and macros */ #include /* derivative information */ #pra ...
有点浪费资源了,10us都要进一次中断。。。
作者: 天若ㄝ寒 时间: 2014-1-21 12:09
H口和T1口都借到ECHO上吗?
作者: 走走甜甜 时间: 2015-7-18 18:19
n值怎么修改?
这是啥东西
欢迎光临 智能车制作 (http://www.znczz.com/) |
Powered by Discuz! X3.2 |