目錄
- 軟體平臺
- 硬體平臺
- 所需硬體
- 超聲波原理
- 超聲波測距步驟
- 代碼
- usart.h
- usart.c
- motor.h
- motor.c
- ultrasonic.h
- ultrasonic.c
- main.c
- 遇到的問題
軟體平臺
Keil uVision5
Keil C51是美國Keil Software公司出品的51系列兼容單片機C語言軟體開發系統,與匯編相比,C語言在功能上、結構性、可讀性、可維護性上有明顯的優勢,因而易學易用,Keil提供了包括C編譯器、宏匯編、聯結器、庫管理和一個功能強大的仿真除錯器等在內的完整開發方案,通過一個集成開發環境(μVision)將這些部分組合在一起,運行Keil軟體需要WIN98、NT、WIN2000、WINXP等作業系統,如果你使用C語言編程,那么Keil幾乎就是你的不二之選,即使不使用C語言而僅用匯編語言編程,其方便易用的集成環境、強大的軟體仿真除錯工具也會令你事半功倍,
硬體平臺
stm32最小系統

所需硬體
SG90電機,STM32最小系統,超聲波模塊,ttl轉usb



超聲波原理

距離公式: 高電平持續時間 * 聲速(340/秒) / 2
超聲波測距步驟
1.配置GPIO引腳結構體(Trig,Echo),
2.配置定時器結構體
3.配置定時器中斷結構體
4.開啟時鐘(定時器,GPIO)
5.Trig引腳輸出高電平(10us以上),然后關閉
6.等待Echo引腳輸入高電平開始,定時器打開—>開啟計數器計數
7.等待Echo引腳輸入高電平結束,定時器關閉—>停止計數器計數
8.通過計數器的值計算得出超聲波測量距離
代碼
超聲波測距小于20cm,轉動舵機
usart.h
#include "stm32f10x.h"
#include <stdio.h>
void usart_init(void);
void usartSendByte(USART_TypeDef* USARTx, uint16_t Data);
void usartSendStr(USART_TypeDef* USARTx,char *str);
usart.c
#include "usart.h"
#include "stm32f10x.h"
void usart_init(void)
{
GPIO_InitTypeDef gpio_init;
USART_InitTypeDef usartStruct;
NVIC_InitTypeDef nvic_initStruct;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//1.????ê±?ó£oGPIO?úμ?ê±?ó£?òy???′ó?μ?ê±?ó£?′??úμ?ê±?ó
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
//2.????GPIOμ??á11ì?
//2.1 TX
gpio_init.GPIO_Mode = GPIO_Mode_AF_PP;
gpio_init.GPIO_Pin = GPIO_Pin_9;
gpio_init.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA,&gpio_init);
//2.2 RX
gpio_init.GPIO_Mode = GPIO_Mode_IN_FLOATING;
gpio_init.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA,&gpio_init);
//3.????′??úμ??á11ì?
usartStruct.USART_BaudRate = 115200;
usartStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
usartStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
usartStruct.USART_Parity = USART_Parity_No;
usartStruct.USART_StopBits = USART_StopBits_1;
usartStruct.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1,&usartStruct);
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//????′??ú?D??
USART_Cmd(USART1, ENABLE );
nvic_initStruct.NVIC_IRQChannel = USART1_IRQn;
nvic_initStruct.NVIC_IRQChannelPreemptionPriority = 1;
nvic_initStruct.NVIC_IRQChannelSubPriority = 1;
nvic_initStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&nvic_initStruct);
}
//·a×°á?ò???·¢?í×?·?
void usartSendByte(USART_TypeDef* USARTx, uint16_t Data)
{
USART_SendData(USARTx,Data);
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
}
//·¢?í×?·?′?
void usartSendStr(USART_TypeDef* USARTx,char *str)
{
uint16_t i = 0;
do{
usartSendByte(USARTx,*(str+i));
i++;
}while(*(str+i) != '\0');
//?D??ê?·?·¢?ííê
while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET);
}
int fputc(int ch,FILE *f)
{
USART_SendData(USART1,(uint8_t)ch);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
return (ch);
}
int fgetc(FILE *f)
{
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET);
return (int) USART_ReceiveData(USART1);
}
motor.h
#include "stm32f10x.h"
void motor_Init(void);
motor.c
#include "stm32f10x.h"
#include "motor.h"
/*
1.GPIO?á11ì?
2.í¨ó??¨ê±?÷?á11ì?
3.PWM?á11ì?
4.′ò?aê±?ó
*/
//ê1ó?μ?ê?PB_5òy??,??ó3é?TIM3£?í¨μà2
void motor_Init(void)
{
GPIO_InitTypeDef Motor_GPIOStruct;
TIM_TimeBaseInitTypeDef Motor_TIMStruct;
TIM_OCInitTypeDef Motor_TIMPWMStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//òy??μ?ê±?ó
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); //?¨ê±?÷ê±?ó
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //??ó3é?Dèòaμ?ê±?ó
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);//?a????ó3é?
//PartialRemap2?·???ó3é?
//FullRemapíêè???ó3é?
Motor_GPIOStruct.GPIO_Mode = GPIO_Mode_AF_PP; //í?íì?′ó?ê?3?(??ó3é?)
Motor_GPIOStruct.GPIO_Pin = GPIO_Pin_5; //òy?? 5
Motor_GPIOStruct.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOB,&Motor_GPIOStruct);
Motor_TIMStruct.TIM_ClockDivision = TIM_CKD_DIV1; //éè??ê±?ó·???£?TIM_CKD_DIV1ê?2?·???
Motor_TIMStruct.TIM_CounterMode = TIM_CounterMode_Up;//TIM?òé???êy?£ê?
Motor_TIMStruct.TIM_Period = 200 - 1; //éè???ú?????üD?ê??t×°è????ˉμ?×??ˉ??×°???μ
Motor_TIMStruct.TIM_Prescaler = 7200 - 1; //TIMxê±?ó?μ?ê?¤·??μ?μ
TIM_TimeBaseInit(TIM3,&Motor_TIMStruct);
Motor_TIMPWMStruct.TIM_OCMode = TIM_OCMode_PWM1; //?????¨ê±?÷?£ê??a±????????£ê?
Motor_TIMPWMStruct.TIM_OutputState = TIM_OutputState_Enable;//±è??ê?3?ê1?ü
Motor_TIMPWMStruct.TIM_OCPolarity = TIM_OCPolarity_Low; //????óDD§ê?3???D?
TIM_OC2Init(TIM3,&Motor_TIMPWMStruct);//OC2′ú±íí¨μà2 TIM3í¨μà2
TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);//ê1?ü?¤×°????′??÷
TIM_Cmd(TIM3,ENABLE);
}
ultrasonic.h
#ifndef __ULTRASONIC_H
#define __ULTRASONIC_H
#include "stm32f10x.h"
#define ECHO_Reci GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_10)
//è?1??a1à-??μ???£??a0à-μíμ???
#define TRIG_Send(a) if(a) \
GPIO_SetBits(GPIOB,GPIO_Pin_11);\
else \
GPIO_ResetBits(GPIOB,GPIO_Pin_11)
void ultrasonic_Config(void);
void Open_tim4(void);
void Close_tim4(void);
int GetEcho_time(void);
float Getlength(void);
#endif /* __ULTRASONIC_H */
ultrasonic.c
#include "stm32f10x.h"
#include "ultrasonic.h"
#include "SysTick.h"
/*
1.????GPIOòy???á11ì?(Trig PB11,Echo PB10)
2.?????¨ê±?÷?á11ì?
3.?????¨ê±?÷?D???á11ì?
4.?a??ê±?ó(?¨ê±?÷£?GPIO)
*/
uint16_t mscount;
void ultrasonic_Config(void)
{
//?á11ì?3?ê??ˉ
GPIO_InitTypeDef GPIO_UltrasonicInit;
TIM_TimeBaseInitTypeDef TIM_UltrasonicInit;
NVIC_InitTypeDef NVIC_UltrasonicInit;
//?a??ê±?ó
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);
//′′?¨ó??è??×é
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//Trig PB11
GPIO_UltrasonicInit.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_UltrasonicInit.GPIO_Pin = GPIO_Pin_11;
GPIO_UltrasonicInit.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOB, &GPIO_UltrasonicInit);
//Echo PB10
GPIO_UltrasonicInit.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_UltrasonicInit.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOB, &GPIO_UltrasonicInit);
//?????¨ê±?÷
TIM_UltrasonicInit.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_UltrasonicInit.TIM_CounterMode = TIM_CounterMode_Up;
TIM_UltrasonicInit.TIM_Period = 1000 - 1;
TIM_UltrasonicInit.TIM_Prescaler = 72 - 1;
TIM_TimeBaseInit(TIM4,&TIM_UltrasonicInit);
TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE);
TIM_Cmd(TIM4,DISABLE);
//?????D??
NVIC_UltrasonicInit.NVIC_IRQChannel = TIM4_IRQn;
NVIC_UltrasonicInit.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_UltrasonicInit.NVIC_IRQChannelSubPriority = 1;
NVIC_UltrasonicInit.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_UltrasonicInit);
}
//′ò?a?¨ê±?÷4
void Open_tim4(void)
{
TIM_SetCounter(TIM4,0);//′ó0?aê???êy
mscount = 0;
TIM_Cmd(TIM4,ENABLE);
}
//1?±??¨ê±?÷4
void Close_tim4(void)
{
TIM_Cmd(TIM4,DISABLE);
}
//?¨ê±?÷4?D??oˉêy
void TIM4_IRQHandler(void)
{
if(TIM_GetITStatus(TIM4,TIM_IT_Update) != RESET){
TIM_ClearITPendingBit(TIM4,TIM_IT_Update);
mscount++;
}
}
//??è??¨ê±?÷??êy?÷μ??μ
int GetEcho_time(void)
{
uint32_t t = 0;
t = mscount * 1000;
t += TIM_GetCounter(TIM4);
TIM4->CNT = 0;
ms_delay(50);
return t;
}
//??è?3?éù2¨2a?à?àà?
float Getlength(void)
{
int i = 0;
uint16_t t = 0;
float length = 0;
float total = 0;
for(i = 0;i<5;i++)
{
TRIG_Send(1);
us_delay(20);
TRIG_Send(0);
while(ECHO_Reci == 0);
Open_tim4();
while(ECHO_Reci == 1);
Close_tim4();
t = GetEcho_time();
length = ((float)t / 58.0);
total += length;
}
length = total/5.0;
return length;
}
main.c
#include "stm32f10x.h"
#include "usart.h"
#include "motor.h"
#include "ultrasonic.h"
void delay(uint16_t time)
{
uint16_t i =0;
while(time--){
i=12000;
while(i--);
}
}
int main()
{
float Length = 0;
usart_init();
motor_Init();
ultrasonic_Config();
//3?éù2¨???????ú
while(1)
{
Length = Getlength();
if(Length <= 20){
TIM_SetCompare2(TIM3,195);
printf("SG90 OK!");
}else{
TIM_SetCompare2(TIM3,185);
}
printf("Length = %.3fcm\r\n",Length);
ms_delay(500);
}
}

遇到的問題
extern表明變數或者函式是定義在其他其他檔案中
本來給mscount加了extern出現了Undefined symbol mscount (referred from ultrasonic.o).錯誤,開始以為是
1、沒有將包含該函式的頭檔案包含進來,
2、沒有頭檔案里面宣告該函式
3、沒有將該函式的.C檔案加入工程里面
對照了三步好像都沒啥問題,然后把extern洗掉就好了
注意:extern表明變數或者函式是定義在其他其他檔案中
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/290316.html
標籤:其他
