|
寄存器写的stm32驱动超声波模块,一直就在检测上升沿电平那里出不来。用的串口获得详细数据,
已解决,模块电压问题,应接5V电压,我接成3.3V,32搞长了,忘记当初做51时是5V供电了。
- //#include "stm32f10x.h"
- #include "led.h"
- #include "sys.h"
- #include "sysclock.h"
- #include "key.h"
- #include "exti.h"
- #include "time.h"
- #include "pwm.h"
- #include "usart.h"<div class="blockcode"><blockquote>#include"hc04.h"
- u8 msHcCount = 0;//ms计数
- void Hr_hc04_Init(void)
- {
- TIM2_Init(1000-1,72-1);//分频系数72,循环1000次1000us
-
- RCC->APB1ENR |= 1<<6; //GPIOE时钟使能
-
- GPIOE->CRL &= 0xfffff00f;//设置位重置 E1、E2
-
- //E1推挽输出
- GPIOE->CRL |= 0x1<<4;
- //E2浮空输入
- GPIOE->CRL |= 0x4<<8;
-
- GPIOE->ODR|=~(1<<1);//E1一开始低电平
- GPIOE->ODR|=~(1<<2);//E2一开始低电平
- }
- static void OpenTimer() //打开定时器
- {
- //清除计数器
- TIM_SetCounter(TIM2,0);
- msHcCount = 0;
- TIM_Cmd(TIM2,ENABLE);//使能定时器
- USARTx_Send_String(USART1,"定时器开启\r\n");
- }
-
- static void CloseTimer() //关闭定时器
- {
- // /*关闭计数器使能*/
- TIM_Cmd(TIM2,DISABLE);
- }
- //获取定时器时间
- u32 GetEchoTimer(void)
- {
- u32 time = 0;
- /*//当回响信号很长是,计数值溢出后重复计数,overCount用中断来保存溢出次数*/
- time = msHcCount*1000;//overCount每++一次,代表overCount毫秒,time微妙
- time += TIM_GetCounter(TIM2);//获取计TIM2数寄存器中的计数值,一边计算回响信号时间
- TIM6->CNT = 0; //将TIM2计数寄存器的计数值清零
- delay_ms(50);
- USARTx_Send_String(USART1,"获取定时器时间:");
- USARTx_Send_number(USART1,time);
- USARTx_Send_String(USART1,"\r\n");
- return time;
-
- }
- /*
- trig_T = 1;//trig拉高信号,发出高电平
- // GPIOE->ODR |= 1<<1;
- if((GPIOE->IDR & 0x0002));//echo等待回响
- {
- USARTx_Send_String(USART1,"trig_T置高位成功\r\n");
- }
- delay_us(20);//持续时间超过10us
- // trig_T = 0;
- GPIOE->ODR |= ~(1<<1);
- USARTx_Send_String(USART1,"开启信号已发出456\n");
- while(!(GPIOE->IDR & 0x0004))//echo等待回响
- {
- i++;
- if(i>=10000)
- {
- USARTx_Send_String(USART1,"回响信号检测失败\n");
- break;
- }
- }
- USARTx_Send_String(USART1,"等待结束,计时中789\r\n");
- delay_ms(50);
-
-
- */
- float Hcsr04GetLength(void )
- {
- /*测5次数据计算一次平均值*/
- float length = 0;
- float t = 0;
- float sum = 0;
- u16 i = 0;
- u16 ttt;
- while(i != 5)
- {
-
- trig_T = 1;//trig拉高信号,发出高电平
- // GPIOE->ODR |= 1<<1;
-
- if((GPIOE->IDR & 0x0002));//echo等待回响
- {
- USARTx_Send_String(USART1,"trig_T置高位成功\r\n");
- }
- delay_us(20);//持续时间超过10us
-
- // trig_T = 0;
- GPIOE->ODR |= ~(1<<1);
- USARTx_Send_String(USART1,"开启信号已发出\r\n");
-
- /*Echo发出信号 等待回响信号*/
- /*输入方波后,模块会自动发射8个40KHz的声波,与此同时回波引脚(echo)端的电平会由0变为1;
- (此时应该启动定时器计时);当超声波返回被模块接收到时,回波引 脚端的电平会由1变为0;
- (此时应该停止定时器计数),定时器记下的这个时间即为
- 超声波由发射到返回的总时长;*/
- // while(echo_R == 0);//echo等待回响
- while(!(GPIOE->IDR & 0x0004))//echo等待回响
- {
- ttt++;
- if(ttt>=50000)
- {
- USARTx_Send_String(USART1,"回响信号检测失败\r\n");
- break;
- }
- }
- USARTx_Send_String(USART1,"等待结束,计时中\r\n");
- /*开启定时器*/
- OpenTimer();
- i = i+1; //每收到一次回响信号+1,收到5次就计算均值
- // while(echo_R == 1);
- while((GPIOE->IDR & 0x0004))//echo等待回响
- {
- ttt++;
- if(ttt>=50000)
- {
- USARTx_Send_String(USART1,"等待回响失败\r\n");
- break;
- }
- }
- /*关闭定时器*/
- CloseTimer();
- /*获取Echo高电平时间时间*/
- t = GetEchoTimer();
- length = (float)t/58;//单位时cm
- sum += length;
- }
- length = sum/5;//五次平均值
-
- return length;
- }
- void TIM2_IRQHandler(void)
- {
- if(TIM2->SR &0X0001)//溢出中断
- {
- msHcCount++;
- TIM2->SR &=~(1<<0);//清除中断标志位
- }
- }
复制代码- #ifndef __hc04_h
- #define __hc04_h
- #include "sys.h"
- #include "stm32f10x.h"
- #include "time.h"
- #include "sysclock.h"
- #include "usart.h"
- #define trig_T PEout(1)
- #define echo_R PEin(2)
- void Hr_hc04_Init(void);
- float Hcsr04GetLength(void );
- #endif
复制代码- #include "time.h"
- //设置 TIMx 计数器寄存器值
- void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter)
- {
- /* Set the Counter Register value */
- TIMx->CNT = Counter;
- }
- //使能或者失能 TIMx 外设
- void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState)
- {
-
- if (NewState != DISABLE)
- {
- /* Enable the TIM Counter */
- TIMx->CR1 |= TIM_CR1_CEN;
- }
- else
- {
- /* Disable the TIM Counter */
- TIMx->CR1 &= (uint16_t)(~((uint16_t)TIM_CR1_CEN));
- }
- }
- //获取计时次数
- uint16_t TIM_GetCounter(TIM_TypeDef* TIMx)
- {
- return TIMx->CNT;
- }
- //自动装载寄存器 (TIMx_ARR)
- //预分频器寄存器 (TIMx_PSC)
- //AHB不分频;APB2不分频;APB1二分频 APB1=72/2 TIM_CLk=72
- void TIM2_Init(u16 arr,u16 psc)
- {
- RCC->APB1ENR|=1<<0; //使能TIM2时钟
-
- TIM2->PSC=psc; //预分频器寄存器
- TIM2->ARR=arr; //自动装载寄存器
-
- TIM2->DIER|=1<<0; //允许更新中断
- TIM2->DIER|=1<<6; //使能触发中断
-
- // TIM2->CR1|=1<<0; //使能计数器 //外部函数TIM_Cmd 实现
-
- NVIC_Init(2,1,TIM2_IRQn,2);
- }
- /*超声波中设置
- void TIM2_IRQHandler(void)
- {
- if(TIM2->SR &0X0001)//溢出中断
- LED1=!LED1;
-
- TIM2->SR &=~(1<<0);//清除中断标志位
- }
- */
复制代码- #ifndef _time_h
- #define _time_h
- #include "exti.h"
- #include "sysclock.h"
- void TIM2_Init(u16 arr,u16 psc);
- //设置 TIMx 计数器寄存器值
- void TIM_SetCounter(TIM_TypeDef* TIMx, uint16_t Counter);
- //使能或者失能 TIMx 外设
- void TIM_Cmd(TIM_TypeDef* TIMx, FunctionalState NewState);
- //获取计时次数
- uint16_t TIM_GetCounter(TIM_TypeDef* TIMx);
- #endif
复制代码
#include "hc04.h"
int main()
{
int temp=0;
System_clock(9);
SysTick_init(72);
uart_init(72,9600);//时钟频率(Mhz) 波特率
LED_Init();
// TIM2_Init(1000-1,72-1);//分频系数72,循环1000次1000us //放在hc04.c里了
Hr_hc04_Init();
delay_ms(50);
while(1)
{
delay_ms(500);
USARTx_Send_String(USART1,"测试距离:123");
delay_ms(10);
temp=Hcsr04GetLength();
delay_ms(10);
USARTx_Send_number(USART1,temp);
delay_ms(10);
USARTx_Send_String(USART1,"cm\r\n");
delay_ms(10);
LED4=!LED4;
delay_ms(10);
}
}
void SystemInit(void)
{
}
|
|