芯片:STM32F103C8T6
模块:HC-SR04
main.c
#include "stm32f10x.h"
#include "OLED.h"
#include "delay.h"
#include "timer3.h"
#include "timer2.h"
#include "gpio.h"
uint16_t S = 0,flag, temp = 0,i=0,sum,agre;
void count(void)
{
temp=TIM_GetCounter(TIM2);
sum += temp;
i++;
if(i==10)
{
i=0;
S = (sum*1.7)/1000;//Ëã³öÀ´µÄÖµÊÇcm
if(S > 700 || flag==1)//Òç³ö
{
OLED_ShowString(2,1,"failed");
}
else
{
OLED_ShowString(2,1," ");
OLED_ShowNum(3,1,S,3);
OLED_ShowNum(4,1,temp,3);
}
sum = 0;
}
}
int main(void)
{
OLED_Init();
GPIO_INIT();
TIM3_Init(5760,1000);//80ms ¶¨Ê±´ò¿ªÄ£¿é
TIM2_Init(65535,72);//¼ÆÊý65535´Î ÓÃÓÚ¼ÆÊý
while(1)
{
while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_9)==RESET);//
TIM_SetCounter(TIM2,0);
TIM_Cmd(TIM2,ENABLE);
while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_9)==SET);
TIM_Cmd(TIM2,DISABLE);
count();
}
}
timer3.c
#include "timer3.h"
#include "delay.h"
void TIM3_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);
TIM_TimeBaseStructure.TIM_Period = arr-1;
TIM_TimeBaseStructure.TIM_Prescaler = psc-1;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;//时钟分频因子
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//计时方式
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseStructure);
TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE);//定时器中断配置
NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
TIM_Cmd(TIM3,ENABLE);
}
void TIM3_IRQHandler(void)//每800ms 启动模块
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update) !=RESET)
{
GPIO_SetBits(GPIOA,GPIO_Pin_8);//产生脉冲
Delay_us(10);
GPIO_ResetBits(GPIOA,GPIO_Pin_8);
TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
}
}
timer2.c
#include "timer2.h"
void TIM2_Init(u16 arr,u16 psc)//TIM3初始化
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);//使能定时时钟
TIM_TimeBaseStructure.TIM_Period = arr-1; //定时器周期
TIM_TimeBaseStructure.TIM_Prescaler = psc-1;// 定时器预分频器系数 除数会自动加一
TIM_TimeBaseStructure.TIM_ClockDivision = 0;//时钟分频因子
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//计时方式
TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStructure);//初始化定时器
TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//定时器中断配置
//中断配置
NVIC_InitStruct.NVIC_IRQChannel = TIM2_IRQn;//Interrupt Request 中断请求
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 2;//响应优先级
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
TIM_Cmd(TIM2,DISABLE);
}
void TIM2_IRQHandler(void)//中断服务函数(中断请求处理函数)
{
uint16_t flag;
if(TIM_GetITStatus(TIM2,TIM_IT_Update) !=RESET)
{
flag=1;
}
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
}
gpio.c
#include "gpio.h"
void GPIO_INIT(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//Êä³ö
GPIO_InitStruct.GPIO_Pin =GPIO_Pin_8;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;//ÊäÈë
GPIO_InitStruct.GPIO_Pin =GPIO_Pin_9;
GPIO_Init(GPIOA,&GPIO_InitStruct);
}
delay.c
#include "stm32f10x.h"
/**
* @brief 微秒级延时
* @param xus 延时时长,范围:0~233015
* @retval 无
*/
void Delay_us(uint32_t xus)
{
SysTick->LOAD = 72 * xus; //设置定时器重装值
SysTick->VAL = 0x00; //清空当前计数值
SysTick->CTRL = 0x00000005; //设置时钟源为HCLK,启动定时器
while(!(SysTick->CTRL & 0x00010000)); //等待计数到0
SysTick->CTRL = 0x00000004; //关闭定时器
}
/**
* @brief 毫秒级延时
* @param xms 延时时长,范围:0~4294967295
* @retval 无
*/
void Delay_ms(uint32_t xms)
{
while(xms--)
{
Delay_us(1000);
}
}
/**
* @brief 秒级延时
* @param xs 延时时长,范围:0~4294967295
* @retval 无
*/
void Delay_s(uint32_t xs)
{
while(xs--)
{
Delay_ms(1000);
}
}
OLED模块相关代码,网上资源较多,可自行搜索。也可通过keil的硬件调试功能查看相关数据。
若有不足,欢迎指出交流。