这个超声波测距是利用定时器中的输入捕获为主要技术手段设计而成
测距模块:
超声波测距的型号是HC_SR04,这个超声波模块有一个控制端trig,和一个测距口echo。只要给trig一个超过20us的高电平,那么echo就会产生高电平,直到超声波回到超声波模块中,整个程序的难点在于怎么计数高电平时间,而输入捕获可以捕获echo口的高电平时间,正好做到这一点。其实用通用定时器简单的计数功能也可以做到这一点,准备下一步采用这一方法写一个程序。
显示模块:
显示距离可以直接调用mdk中usart.c文件中的printf,可以直接打印距离。
设置最小距离
这是这个超声波测距中的另一难点,我们是直接使用串口向单片机传数据,但是串口只能传字符串,这个时候我们就需要利用ASCII码将一个个字符转换成数字。串口是一位一位传数据的,会将数据存在一个缓冲数组(USART_RX_BUF【】)中,并且在传数据的过程中我们会得到这个数据的长度len。利用这个式子将接收到的字符串转化成数字:
for(i=0;i
s1+=(USART_RX_BUF[len-1-i]-48)*table1[i];
}
int table1[]={1,10,100,1000};
0的ASCII码是48,根据这个可以求得其他数据的ASCII码。
报警模块
当测得的距离小于串口设置的阀值,串口显示error,LED灯闪烁。
接下来是我的程序:
这是超声波模块利用到的GPIO口的初始化和输入捕获的初始化
#include "timer.h"
#include "led.h"
#include "usart.h"
#include "delay.h"
//¶¨Ê±Æ÷5ͨµÀ1ÊäÈ벶»ñÅäÖÃ
//arr£º×Ô¶¯ÖØ×°Öµ(TIM2,TIM5ÊÇ32λµÄ!!)
//psc£ºÊ±ÖÓÔ¤·ÖƵÊý
void TIM5_CH1_Cap_Init(u32 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;
TIM_ICInitTypeDef TIM5_ICInitStructure;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE); //TIM5ʱÖÓʹÄÜ
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //ʹÄÜPORTAʱÖÓ
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //GPIOA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//¸´Óù¦ÄÜ
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //ËÙ¶È100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //ÍÆÍ츴ÓÃÊä³ö
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //ÏÂÀ
GPIO_Init(GPIOA,&GPIO_InitStructure); //³õʼ»¯PA0
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //GPIOA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//¸´Óù¦ÄÜ
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; //ËÙ¶È100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //ÍÆÍ츴ÓÃÊä³ö
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //ÏÂÀ
GPIO_Init(GPIOA,&GPIO_InitStructure); //³õʼ»¯PA0
GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM5); //PA0¸´ÓÃλ¶¨Ê±Æ÷5
TIM_TimeBaseStructure.TIM_Prescaler=psc; //¶¨Ê±Æ÷·ÖƵ
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //ÏòÉϼÆÊýģʽ
TIM_TimeBaseStructure.TIM_Period=arr; //×Ô¶¯ÖØ×°ÔØÖµ
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM5,&TIM_TimeBaseStructure);
//³õʼ»¯TIM5ÊäÈ벶»ñ²ÎÊý
TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 Ñ¡ÔñÊäÈë¶Ë IC1Ó³Éäµ½TI1ÉÏ
TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //ÉÏÉýÑز¶»ñ
TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //Ó³Éäµ½TI1ÉÏ
TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //ÅäÖÃÊäÈë·ÖƵ,²»·ÖƵ
TIM5_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 ÅäÖÃÊäÈëÂ˲¨Æ÷ ²»Â˲¨
TIM_ICInit(TIM5, &TIM5_ICInitStructure);
TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);//ÔÊÐí¸üÐÂÖÐ¶Ï ,ÔÊÐíCC1IE²¶»ñÖжÏ
TIM_Cmd(TIM5,ENABLE ); //ʹÄܶ¨Ê±Æ÷5
NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//ÇÀÕ¼ÓÅÏȼ¶3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =0; //×ÓÓÅÏȼ¶3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨµÀʹÄÜ
NVIC_Init(&NVIC_InitStructure); //¸ù¾ÝÖ¸¶¨µÄ²ÎÊý³õʼ»¯VIC¼Ä´æÆ÷¡¢
}
//²¶»ñ״̬
//[7]:0,ûÓгɹ¦µÄ²¶»ñ;1,³É¹¦²¶»ñµ½Ò»´Î.
//[6]:0,»¹Ã»²¶»ñµ½µÍµçƽ;1,ÒѾ²¶»ñµ½µÍµçƽÁË.
//[5:0]:²¶»ñµÍµçƽºóÒç³öµÄ´ÎÊý(¶ÔÓÚ32λ¶¨Ê±Æ÷À´Ëµ,1us¼ÆÊýÆ÷¼Ó1,Òç³öʱ¼ä:4294Ãë)
u8 TIM5CH1_CAPTURE_STA=0; //ÊäÈ벶»ñ״̬
u32 TIM5CH1_CAPTURE_VAL; //ÊäÈ벶»ñÖµ(TIM2/TIM5ÊÇ32λ)
//¶¨Ê±Æ÷5ÖжϷþÎñ³ÌÐò
void TIM5_IRQHandler(void)
{
if((TIM5CH1_CAPTURE_STA&0X80)==0)//»¹Î´³É¹¦²¶»ñ
{
if(TIM_GetITStatus(TIM5, TIM_IT_Update) != RESET)//Òç³ö
{
if(TIM5CH1_CAPTURE_STA&0X40)//ÒѾ²¶»ñµ½¸ßµçƽÁË
{
if((TIM5CH1_CAPTURE_STA&0X3F)==0X3F)//¸ßµçƽ̫³¤ÁË
{
TIM5CH1_CAPTURE_STA|=0X80; //±ê¼Ç³É¹¦²¶»ñÁËÒ»´Î
TIM5CH1_CAPTURE_VAL=0XFFFFFFFF;
}else TIM5CH1_CAPTURE_STA++;
}
}
if(TIM_GetITStatus(TIM5, TIM_IT_CC1) != RESET)//²¶»ñ1·¢Éú²¶»ñʼþ
{
if(TIM5CH1_CAPTURE_STA&0X40) //²¶»ñµ½Ò»¸öϽµÑØ
{
TIM5CH1_CAPTURE_STA|=0X80; //±ê¼Ç³É¹¦²¶»ñµ½Ò»´Î¸ßµçƽÂö¿í
TIM5CH1_CAPTURE_VAL=TIM_GetCapture1(TIM5);//»ñÈ¡µ±Ç°µÄ²¶»ñÖµ.
TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Rising); //CC1P=0 ÉèÖÃΪÉÏÉýÑز¶»ñ
}else //»¹Î´¿ªÊ¼,µÚÒ»´Î²¶»ñÉÏÉýÑØ
{
TIM5CH1_CAPTURE_STA=0; //Çå¿Õ
TIM5CH1_CAPTURE_VAL=0;
TIM5CH1_CAPTURE_STA|=0X40; //±ê¼Ç²¶»ñµ½ÁËÉÏÉýÑØ
TIM_Cmd(TIM5,DISABLE ); //¹Ø±Õ¶¨Ê±Æ÷5
TIM_SetCounter(TIM5,0);
TIM_OC1PolarityConfig(TIM5,TIM_ICPolarity_Falling); //CC1P=1 ÉèÖÃΪϽµÑز¶»ñ
TIM_Cmd(TIM5,ENABLE ); //ʹÄܶ¨Ê±Æ÷5
}
}
}
TIM_ClearITPendingBit(TIM5, TIM_IT_CC1|TIM_IT_Update); //Çå³ýÖжϱê־λ
}
这是主函数:
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "beep.h"
extern u8 TIM5CH1_CAPTURE_STA; //ÊäÈ벶»ñ״̬
extern u32 TIM5CH1_CAPTURE_VAL; //ÊäÈ벶»ñÖµ
long long temp=0;//²â¾àʱ¼ä
long long S=0,s1=0,t=0,Sm=0;//¾àÀë
int table1[]={1,10,100,1000};
//¿ªÆô³¬Éù²¨Ä£¿é
void count()
{
trig=1;
delay_ms(20);
trig=0;
}
//½ÓÊÕÊý¾Ý
float js()
{
u8 i;
u8 len;
if(USART_RX_STA&0x8000)//Èç¹û½ÓÊÕµ½Êý¾Ý
{
len=USART_RX_STA&0x3fff;//µÃµ½´Ë´Î½ÓÊÕµ½µÄÊý¾Ý³¤¶È
for(i=0;i
在此加上我的主程序:
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "beep.h"
#include "bmp.h"
#include "oled.h"
extern u8 TIM5CH1_CAPTURE_STA; //ÊäÈ벶»ñ״̬
extern u32 TIM5CH1_CAPTURE_VAL; //ÊäÈ벶»ñÖµ
long long temp=0;//²â¾àʱ¼ä
long long S=0,s1=0,t=0,Sm=0;//¾àÀë
int table1[]={1,10,100,1000};
//¿ªÆô³¬Éù²¨Ä£¿é
void count()
{
trig=1;
delay_ms(20);
trig=0;
}
//½ÓÊÕÊý¾Ý
float js()
{
u8 i;
u8 len;
if(USART_RX_STA&0x8000)//Èç¹û½ÓÊÕµ½Êý¾Ý
{
len=USART_RX_STA&0x3fff;//µÃµ½´Ë´Î½ÓÊÕµ½µÄÊý¾Ý³¤¶È
for(i=0;it)
{
OLED_ShowCHinese(0,0,0);//?
OLED_ShowCHinese(18,0,1);//?
OLED_ShowCHinese(36,0,2);//?
OLED_ShowCHinese(54,0,3);//?
OLED_ShowCHinese(72,0,4);//?
OLED_ShowCHinese(90,0,5);//?
OLED_ShowCHinese(108,0,6);//?
OLED_ShowCHinese(20,3,7);//?
OLED_ShowCHinese(38,3,8);//?
OLED_ShowString(60,3,": ");
OLED_ShowNum(72,3,t,6,16);//??ASCII?????
OLED_ShowString(0,6,"Distance: ");
OLED_ShowNum(72,6,Sm,6,16);//??ASCII?????
delay_ms(2);
}
else
{
OLED_Clear();
OLED_ShowCHinese(0,0,0);//?
OLED_ShowCHinese(18,0,1);//?
OLED_ShowCHinese(36,0,2);//?
OLED_ShowCHinese(54,0,3);//?
OLED_ShowCHinese(72,0,4);//?
OLED_ShowCHinese(90,0,5);//?
OLED_ShowCHinese(108,0,6);//?
OLED_ShowCHinese(20,3,7);//?
OLED_ShowCHinese(38,3,8);//?
OLED_ShowString(60,3,": ");
OLED_ShowNum(72,3,t,6,16);//??ASCII?????
OLED_ShowString(48,6,"error!!!");
}
}
//Ö÷º¯Êý
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//ÉèÖÃϵͳÖжÏÓÅÏȼ¶·Ö×é2
delay_init(168); //³õʼ»¯ÑÓʱº¯Êý
uart_init(9600);//³õʼ»¯´®¿Ú²¨ÌØÂÊΪ115200
LED_Init();
OLED_Init(); //???OLED
OLED_Clear();
LED0=0;
TIM5_CH1_Cap_Init(0XFFFFFFFF,84-1); //ÒÔ1MhzµÄƵÂʼÆÊý
while(1)
{
count();//¿ªÆô³¬Éù²¨Ä£¿é
jisuan();//¼ÆËã¾àÀë
delay_ms(20);
js();//½ÓÊÕ´®¿ÚÉèÖõÄ×îС¾àÀë
display();
LED0=!LED0;//ÅжϺ¯ÊýÕý³£½øÐÐ
delay_ms(2);
}
}