完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
最近由于需要做项目使用超声波测距模块,在网上和论坛上面找了很多的例程进行参考,也采用了好几种实现的方法,例如使用定时器捕获来进行时间的测量,还有通过外部中断的方式来读出定时器的值,下面是采用第二中方法,下面附上程序吧。由于是测试阶段程序,格式相对较乱,请大神轻喷。
下面附上程序,当然程序改好后,自然奉送大家源代码啦 /******************************************************************************************************************/ 说明:在程序的调试阶段发现了问题,就是定时器的周期会比实际多出大概3万个周期,我也感到很困惑,我感觉程序完全没有问题,自己的东西总是自我感觉良好。。 然后为了避免一些波动的影响,就在上面加上了中值滤波,然并卵,现在偷眼昏花希望大家帮忙找出错误 不甚感激 /*******************************************************************************************************************/ #include #include "basicfunctions.h" #include "oled.h" #define uchar unsigned char #define uint unsigned int #define ulong unsigned long #define N1 11 ulong dis; uchar jieshou_flag=0; int dis1; unsigned char count; unsigned char count_flag; unsigned char timea_overf_flag; int value_buf[11]; int Mid_Num_Filter() { // int value_buf[N]; char i,j,temp; for (j=0;j for (i=0;i if ( value_buf[i]>value_buf[i+1] ) { temp = value_buf[i]; value_buf[i] = value_buf[i+1]; value_buf[i+1] = temp; } } } return value_buf[(N-1)/2]; } /**************************** 函数名称:In_Clk() 功 能:初始化时钟 参 数:无 返 回 值:无 *****************************/ void In_Clk() { uchar i; BCSCTL1&=~XT2OFF; do { IFG1&=~OFIFG; for(i=100;i>0;i--) _NOP(); }while(IFG1&OFIFG); BCSCTL2|=SELM1+SELS; } /**************************** 函数名称:TimerA_Init() 功 能:定时器A初始化 参 数:无 返 回 值:无 *****************************/ void TimerA_Init() { TACTL|=TASSEL_2+ID_1+MC_0; //先设置时钟,430里面很多模块都是相互独立的,所有基本都要设置时钟 TACCR0=65535; //这里就是直接然定时器溢出了 } /**************************** 函数名称:Port_Init() 功 能:IO口初始化 参 数:无 返 回 值:无 *****************************/ void Portsoud_Init() { P1DIR|=BIT0; //P10为输出IO P1DIR&=~BIT1; //P11为输入IO P1IE|=BIT1;//使能中断 //使用中断使能来进行下降沿的判断 P1IES&=~BIT1;//上升沿,这个地方是值得注意的地方 } /**************************** 函数名称:main( void ) 功 能:主函数 参 数:无 返 回 值:无 *****************************/ void main( void ) { // Stop watchdog timer to prevent time out reset WDTCTL = WDTPW + WDTHOLD; //关闭看门狗 In_Clk(); //初始化时钟 //Write_Word_5110(0,0,0); //Write_Word_5110(12,0,1);//距离 //Write_Num_5110(24,0,11);//冒号 这样有时候看起程序来感觉还不如精简指令更加清晰直观 TimerA_Init(); //初始化定时器A,其实很多的时候感觉是没有必要写一些库函数 Portsoud_Init(); //初始化IO这里采用的是TA 输入P10 OUTPUT P11 /* Port_init(); LCD_init(); LCD_clear(); */ LCD_Init(); //oled 初始化 LCD_Fill(0xff); //屏全亮 LCD_CLS(); //初始化OLED LCD_P8x16Str(0,2,"Dis:"); LCD_P8x16Str(0,4,"Thing:"); jieshou_flag=1; //很多程序都有标志位,在我的程序中我还是用的比较少的 _EINT(); //打开总中断开关 while(1) { if(jieshou_flag==1)//已经完成高脉冲测量 { //LCD_clear(); //display(dis);//显示 // dis1=(int)dis; // LCD_DISP_VALUE(30, 2, TAR-30000); if(count_flag==1) { dis1=Mid_Num_Filter(); LCD_DISP_VALUE(30, 2, dis1); } if(timea_overf_flag==1) LCD_DISP_VALUE(0, 6, 1); else LCD_DISP_VALUE(0, 6, 0); delay_ms(100); P1OUT|=BIT0; //输出高电平 delay_us(20); // P1OUT&=~BIT0;//启动脉冲 jieshou_flag=0; } delay_ms(10); } } /*************************** IO口终端函数 用来处理超声波测距 *****************************/ #pragma vector=PORT1_VECTOR __interrupt void TimerA_Clock() { if((P1IN&BIT1)==BIT1)//如果是高,则开始计时 { TACTL|=MC_1+TACLR; P1IES|=BIT1;//设置为下降沿 } else { TACTL|=MC_0;//如果为低,则则停止计时 P1IES&=~BIT1;//并设置为上升沿 if(timea_overf_flag==1) dis=((ulong)(TAR+65536)/100)*17;//计算出高电平时间 else dis=((ulong)TAR/100)*17;//计算出高电平时间 jieshou_flag=1; value_buf[count]=TAR-30000; count++; if(count>9) { count=0; count_flag=1; } else { count_flag=0; } } P1IFG&=~BIT1; } #pragma vector=TIMERA1_VECTOR __interrupt void TimeA_out() { switch (TAIV) { case 0x0a: timea_overf_flag=1; break; default : timea_overf_flag=0; break; } } |
|
相关推荐 |
|
只有小组成员才能发言,加入小组>>
3046个成员聚集在这个小组
加入小组2952 浏览 1 评论
MSP430FR5994 使用库函数 定时器触发AD问题请教
3650 浏览 2 评论
请问怎么把下面51单片机的代码改成msp430 g2 pocket的代码,还有改下时间变成30秒
2354 浏览 1 评论
4822 浏览 1 评论
2583 浏览 1 评论
1349浏览 3评论
MSP430FR5994 使用库函数 定时器触发AD问题请教
3650浏览 2评论
2952浏览 1评论
1542浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-13 09:08 , Processed in 1.667441 second(s), Total 81, Slave 63 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号