摘要:通信引腳與連接方式通信數據流動過程需要配置的串口參數與串口相關的的庫函數庫函數初始化串口步驟代碼二超聲波基礎知識前言是利用超聲波特性檢測距離的傳感器。其帶有兩個超聲波探頭,分別用作發射和接收超聲波。
注意!!!!一定要??RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
打開復用功能時鐘,雖然沒用復用功能。
一、串口通信基礎知識
1、STM32的串口通信接口 。
? ? ? ? UART:通用異步收發器 。
? ? ? ?USART:通用同步異步收發器 。
? ? ? ?大容量STM32F10x系列芯片,包含3個USART和2個UART。
2、通信引腳RXD與TXD連接方式
3、通信數據流動過程?
?
4、需要配置的串口參數?
?
5、與串口相關的的庫函數?
?
?6、庫函數初始化串口步驟
?6、代碼
void uart_init1(u32 bound) { //GPIO define GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //open USART1,GPIOA clk USART_DeInit(USART1); //release uart1 //USART1_TX PA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //output mode GPIO_Init(GPIOA, &GPIO_InitStructure); // Set PA9 //USART1_RX PA.10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING;// GPIO_Init(GPIOA, &GPIO_InitStructure); //Set PA10 //Usart1 NVIC NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=4 ;// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // NVIC_Init(&NVIC_InitStructure); // //USART1 USART_InitStructure.USART_BaudRate = bound;//9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b;// USART_InitStructure.USART_StopBits = USART_StopBits_1;// USART_InitStructure.USART_Parity = USART_Parity_No;// USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;// USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // USART_Init(USART1, &USART_InitStructure); // USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);// USART_Cmd(USART1, ENABLE); //}
二、超聲波基礎知識
前言:SR04是利用超聲波特性檢測距離的傳感器。其帶有兩個超聲波探頭,分別用作發射和接收超聲波。其測量的范圍是3-500cm。
1、基本原理
(1)先使用STM32的數字引腳13向TRIG腳輸入至少10us的高電平信號,觸發模塊的測距功能。
(2)測距功能觸發后,模塊將自動發出 8 個 40kHz 的超聲波脈沖,并自動檢測是否有信號返回,這一步由模塊內部自動完成。
(3)一旦檢測到有回波信號則ECHO引腳會輸出高電平。高電平持續的時間就是超聲波從發射到返回的時間。此時可以使用定時器獲取高電平的時間, 并計算出距被測物體的實際距離。公式: 距離=高電平時間*聲速(340M/S)/2。
2、電路圖
?
?3、庫函數編寫流程
(1)初始化超聲波引腳,打開相應管腳時鐘。
(2)由于需要運用定時器測量返回的高電平的時間,所以需要對定時器(周期為1ms)進行初始化。
(3)由公式: 距離=高電平時間*聲速(340M/S)/2,所以還需要編寫一個函數把測量的時間轉換為距離,測量五次取平均值。
三、總體編程流程
1、串口初始化(有中斷),打開串口。
2、超聲波管腳初始化。
3、定時器初始化(有中斷)。
4、測距函數編寫
4、主函數輸出
四、代碼(注釋詳細)
main.c
#include "motor.h"#include "stdio.h"#include "delay.h"#include "stm32f10x.h"#include "followline.h"#include "sys.h"#include "ultrasonic.h"u8 UART3_data,UART1_data;u8 UART3_rcv[20],UART3_rcv_count;u8 UART1_rcv[50],UART1_rcv_count,Uart1_finish;int main(void){ float length; delay_init();//延遲初始化 uart_init1(9600);//串口初始化 ultrasonic_gpio_init();//超聲波管腳初始化 ultrasonic_time2_init();//超聲波定時器初始化 while(1) { printf("start work!!/n"); length=transfer_ditigal(); printf("distance:%fcm/n",length); delay_s(1); }}
ultrasonic.c?
#include "ultrasonic.h"#include "stm32f10x_tim.h"#include "stm32f10x_rcc.h"int overcount;//計數變量/************************超聲波管腳初始化***************************************/ void ultrasonic_gpio_init(void){ //超聲波發送管腳 //定義GPIO_A初始化的結構體 GPIO_InitTypeDef GPIO_InitStruct_A; //打開PA管腳的時鐘 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //將管腳PB4特殊功能關掉 GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); // GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); //配置PA15的參數 GPIO_InitStruct_A.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStruct_A.GPIO_Pin=GPIO_Pin_15; GPIO_InitStruct_A.GPIO_Speed=GPIO_Speed_50MHz; //初始化PA15管腳 GPIO_Init(GPIOA, &GPIO_InitStruct_A); //置PA15低位 GPIO_ResetBits(GPIOA, GPIO_Pin_15); //超聲波接收管腳 //配置PA12的參數 GPIO_InitStruct_A.GPIO_Mode=GPIO_Mode_IPD; GPIO_InitStruct_A.GPIO_Pin=GPIO_Pin_12; //初始化PA12管腳 GPIO_Init(GPIOA, &GPIO_InitStruct_A); }/************************************************************************************************************//********************************超聲使用定時器2初始化*******************************************************/void ultrasonic_time2_init(void){ //定義TIME_2初始化的結構體 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct_TIME2; //打開定時器2的時鐘 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //配置TIME_2的參數 TIM_TimeBaseInitStruct_TIME2.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInitStruct_TIME2.TIM_CounterMode=TIM_CounterMode_Up; TIM_TimeBaseInitStruct_TIME2.TIM_Period=999; TIM_TimeBaseInitStruct_TIME2.TIM_Prescaler=71; //初始化TIME_2 TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStruct_TIME2); //定義NVIC初始化的結構體 NVIC_InitTypeDef NVIC_InitStruct; //中斷分組 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); //配置NVIC的參數 NVIC_InitStruct.NVIC_IRQChannel=TIM2_IRQn; NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE; NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=2; NVIC_InitStruct.NVIC_IRQChannelSubPriority=0; //中斷NVIC的初始化 NVIC_Init(&NVIC_InitStruct); //清除定時器TIME_2更新中斷標志 TIM_ClearITPendingBit(TIM2, TIM_IT_Update); //開啟定時器TIME_2的中斷 TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //使能定時器TIME_2 //TIM_Cmd(TIM2,ENABLE ); }/*************************************************************************************************************************//*********************************************距離測量函數*********************************************************************/float transfer_ditigal(void){ float length =0,sum=0; u16 time; unsigned int i=0;/*測則5次數據計算—次平均值*/ while(i!=5) { GPIO_SetBits(GPIOA,GPIO_Pin_15);//拉高信號,作為觸發信號 delay_us(20);//高電平信號超過10us GPIO_ResetBits(GPIOA,GPIO_Pin_15);/*等待回響信號*/ while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_12) ==RESET); TIM_Cmd(TIM2,ENABLE);//回響信號到來,開啟定時器計數 i+=1; //每收到一次回響信號+1收到5次就計算均值 while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_12)== SET);//回響信號消失 TIM_Cmd(TIM2,DISABLE) ;//關閉定時器 time=TIM_GetCounter(TIM2);//獲取計TIw2數寄存器中的計數值,一邊計算回響信號時間 length=(time+overcount*1000)/58.0;//通過回響信號計算距離 sum=length+sum; TIM2->CNT = 0; //將tiem2計數寄存器的計數值清零 overcount = 0;//中斷溢出次數清零 delay_ms(1); } length =sum/5; return length;//距離作為函數返回值}/**********************************************************************************************************************/void TIM2_IRQHandler() //TIM2中斷{ if (TIM_GetITStatus(TIM2, TIM_IT_Update))//檢查TIM2更新中斷發生與否 { TIM_ClearITPendingBit(TIM2, TIM_IT_Update);//清除TIM2更新中斷標志 overcount++; }}
ultrasonic.h
#ifndef __ULTRASONIC_H#define __ULTRASONIC_H#include "stm32f10x_tim.h"#include "stm32f10x_rcc.h"#include "delay.h"#include "stm32f10x.h"#include "stm32f10x_gpio.h"float transfer_ditigal(void);//距離展示void ultrasonic_gpio_init(void);//超聲波管腳初始化void ultrasonic_time2_init(void);//超聲波定時器初始化#endif
usart.c
#include "sys.h"#include "ultrasonic.h"#include "stdio.h"#include "sys.h"#include "usart.h"extern u8 UART3_data,UART1_data;extern u8 UART3_rcv[20],UART3_rcv_count;extern u8 UART1_rcv[50],UART1_rcv_count,Uart1_finish;//uart1 //bound:9600//加入以下代碼,支持printf函數,而不需要選擇use MicroLIB #if 1#pragma import(__use_no_semihosting) //標準庫需要的支持函數 struct __FILE { int handle; }; FILE __stdout; //定義_sys_exit()以避免使用半主機模式 void _sys_exit (int x) { x = x; } //重定義fputc函數 int fputc(int ch, FILE *f){ while((USART1->SR&0X40)==0) ; //循環發送,直到發送完畢 USART1->DR = (u8) ch; return ch;}#endif void uart_init1(u32 bound) { //GPIO define GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //open USART1,GPIOA clk USART_DeInit(USART1); //release uart1 //USART1_TX PA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //output mode GPIO_Init(GPIOA, &GPIO_InitStructure); // Set PA9 //USART1_RX PA.10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING;// GPIO_Init(GPIOA, &GPIO_InitStructure); //Set PA10 //Usart1 NVIC NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=4 ;// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // NVIC_Init(&NVIC_InitStructure); // //USART1 USART_InitStructure.USART_BaudRate = bound;//9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b;// USART_InitStructure.USART_StopBits = USART_StopBits_1;// USART_InitStructure.USART_Parity = USART_Parity_No;// USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;// USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // USART_Init(USART1, &USART_InitStructure); // USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);// USART_Cmd(USART1, ENABLE); //}//uart3 //bound:9600void uart_init3(u32 bound){ //GPIO GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); //open USART3 clk RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //open GPIOB clk USART_DeInit(USART3); //release uart3 //USART3_TX PB.10 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PB.10 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //output mode GPIO_Init(GPIOB, &GPIO_InitStructure); //configure PB10 //USART3_RX PB.11 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//input mode GPIO_Init(GPIOB, &GPIO_InitStructure); //configure PB11 //Usart3 NVIC NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=5 ;// NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // NVIC_Init(&NVIC_InitStructure); // //USART USART_InitStructure.USART_BaudRate = bound;//9600; USART_InitStructure.USART_WordLength = USART_WordLength_8b;//data bit USART_InitStructure.USART_StopBits = USART_StopBits_1;//stop bit USART_InitStructure.USART_Parity = USART_Parity_No;// USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;// USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; // USART_Init(USART3, &USART_InitStructure); // USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);// USART_Cmd(USART3, ENABLE); // } void USART1_SendByByter(u8 Data){ // USART_GetFlagStatus(USART1, USART_FLAG_TC); USART_SendData(USART1, Data); while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET); }void USART3_SendByByter(u8 Data){ // USART_GetFlagStatus(USART3, USART_FLAG_TC); USART_SendData(USART3, Data); while (USART_GetFlagStatus(USART3, USART_FLAG_TC) == RESET); }void USART1_IRQHandler(void) //uart1 ISR { u8 Res; if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) // { Res =USART_ReceiveData(USART1);//(USART1->DR); // UART1_data=Res; if(Res==0x7E && UART1_rcv_count==0) { UART1_rcv[UART1_rcv_count++]=Res; } else if(Res!=0x7E && UART1_rcv_count>0) { UART1_rcv[UART1_rcv_count++]=Res; } else if(Res==0x7E && UART1_rcv_count>0) { UART1_rcv[UART1_rcv_count++]=Res; Uart1_finish=2; } else ; } } void USART3_IRQHandler(void) //uart3 ISR { if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET) //RX set { UART3_data=USART_ReceiveData(USART3);//(USART1->DR); // UART3_rcv[UART3_rcv_count]=UART3_data; if(UART3_rcv_count<6) UART3_rcv_count++; } }
sys.h
#ifndef __SYS_H#define __SYS_H #include "stm32f10x.h"http:// //本程序只供學習使用,未經作者許可,不得用于其它任何用途//ALIENTEK STM32開發板 //正點原子@ALIENTEK//技術論壇:www.openedv.com//修改日期:2012/8/18//版本:V1.7//版權所有,盜版必究。//Copyright(C) 廣州市星翼電子科技有限公司 2009-2019//All rights reserved// //0,不支持ucos//1,支持ucos#define SYSTEM_SUPPORT_OS 0 //定義系統文件夾是否支持UCOS //位帶操作,實現51類似的GPIO控制功能//具體實現思想,參考<>第五章(87頁~92頁).//IO口操作宏定義#define BITBAND(addr, bitnum) ((addr & 0xF0000000)+0x2000000+((addr &0xFFFFF)<<5)+(bitnum<<2)) #define MEM_ADDR(addr) *((volatile unsigned long *)(addr)) #define BIT_ADDR(addr, bitnum) MEM_ADDR(BITBAND(addr, bitnum)) //IO口地址映射#define GPIOA_ODR_Addr (GPIOA_BASE+12) //0x4001080C #define GPIOB_ODR_Addr (GPIOB_BASE+12) //0x40010C0C #define GPIOC_ODR_Addr (GPIOC_BASE+12) //0x4001100C #define GPIOD_ODR_Addr (GPIOD_BASE+12) //0x4001140C #define GPIOE_ODR_Addr (GPIOE_BASE+12) //0x4001180C #define GPIOF_ODR_Addr (GPIOF_BASE+12) //0x40011A0C #define GPIOG_ODR_Addr (GPIOG_BASE+12) //0x40011E0C #define GPIOA_IDR_Addr (GPIOA_BASE+8) //0x40010808 #define GPIOB_IDR_Addr (GPIOB_BASE+8) //0x40010C08 #define GPIOC_IDR_Addr (GPIOC_BASE+8) //0x40011008 #define GPIOD_IDR_Addr (GPIOD_BASE+8) //0x40011408 #define GPIOE_IDR_Addr (GPIOE_BASE+8) //0x40011808 #define GPIOF_IDR_Addr (GPIOF_BASE+8) //0x40011A08 #define GPIOG_IDR_Addr (GPIOG_BASE+8) //0x40011E08 //IO口操作,只對單一的IO口!//確保n的值小于16!#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n) //輸出 #define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n) //輸入 #define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n) //輸出 #define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n) //輸入 #define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n) //輸出 #define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n) //輸入 #define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n) //輸出 #define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n) //輸入 #define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n) //輸出 #define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n) //輸入#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n) //輸出 #define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n) //輸入#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n) //輸出 #define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n) //輸入void USART1_SendByByter(u8 Data);void uart_init1(u32 bound);#endif
五、運行結果:?
最后,小白的學習筆記,歡迎大佬指教。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/119150.html
摘要:設計簡介本設計是基于藍牙的超聲波無線測距的設計,主要實現以下功能實現通過測量當前溫度值實現通過溫差補償法公式修改超聲波在當前空氣中的傳播速度實現通過超聲波傳感器測量距離值。 設計簡介: 本設計是基于藍牙的超聲波無線測距的設計,主要實現以下功能: ① 實現通過DS18B20測量當前溫度值 ② ...
摘要:中央對齊模式向上計數時當時通道為無效電平,否則為有效電平向下計數時一旦通道為有效電平,否則為無效電平。一般來說,舵機接收的信號頻率為,即周期為。 STM32——P...
摘要:超聲波傳感器,英文,既可以發射超聲波,也可以接收超聲波,它有一個重要作用,可以提前探測到附近的物體,而且通過聲波速度,能夠推算出附近物體離傳感器的大概距離。 超聲波...
摘要:由于擔心會對主干網造成影響人們開始轉向可以嚴格控制帶寬要求的產品和技術比如多址發送。對網絡造成的巨大負擔也是多址發送發展的巨大動力因為多址發送是一種發送大量數據包的有效方法。什么是push技術? 所謂PUSH技術是一種基于客戶服務器機制,由服務器主動的將信息發往客戶端的技術。同傳統的拉技術(PULL)相比,兩者最為主要的區別在于前者的是由服務器主動發送信息,而后者則是由客戶機主動請求信息。...
閱讀 2580·2021-11-22 12:01
閱讀 1105·2021-11-15 11:37
閱讀 3684·2021-09-22 14:59
閱讀 1746·2021-09-04 16:45
閱讀 1381·2021-09-03 10:30
閱讀 1013·2021-08-11 11:18
閱讀 2458·2019-08-30 10:53
閱讀 2012·2019-08-29 15:13