通過超聲波模塊測距,然后把結果打印到串口助手上。
dbf7712737f9419dce583eee6cfa6db.jpg (4.38 MB, 下載次數: 38)
下載附件
2019-3-5 16:15 上傳
c87f1bf97a7b8b92ad3fa1aff146ac2.png (34.42 KB, 下載次數: 38)
下載附件
2019-3-5 16:14 上傳
單片機源程序如下:
- #include "system.h"
- #include "SysTick.h"
- #include "led.h"
- #include "usart.h"
- //位帶操作,實現51類似的GPIO控制功能
- //具體實現思想,參考<<CM3權威指南>>第五章(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) //輸入
- #define RX PFin(3)
- #define TX PFout(4)
- /*通用延時函數*/
- #define TIME_MS 12000 //@72M
- #define TIME_US 10 //@72M
- /********聲明*********/
- void StartModule(void);//啟動模塊
- void Timer_Count(void);//開關定時器
- void Conut(void);//計算距離
- void dispaly(void);//打印函數
- void clear(void);//清零函數
- /*長延時函數*/
- void Delay_ms(u16 n)
- {
- u16 i,j;
-
- for(i=n;i>0;i--)
- for(j=TIME_MS;j>0;j--);
- }
- /*短延時函數*/
- void Delay_us(u16 n)
- {
- u16 i,j;
-
- for(i=n;i>0;i--)
- for(j=TIME_US;j>0;j--);
- }
- unsigned int time=0;
- unsigned long S=0;
- unsigned int flag =0;
- unsigned int num;
- unsigned int average;
- unsigned int sum;
- /* 配置定時器2 */
- void TIM2_Init(void)
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
-
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE );
- TIM_DeInit(TIM2); //缺省復位TIM2定時器
- TIM_TimeBaseStructure.TIM_Period = 65535; //周期65536 自動重裝寄存器 65356us
- TIM_TimeBaseStructure.TIM_Prescaler = 71; //分頻值71+1 預分頻器
- TIM_TimeBaseStructure.TIM_ClockDivision = 0x0; //采樣分割(濾波,外部才要,因為有很多毛刺)
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //計數模式:向上計數
- TIM_TimeBaseInit(TIM2, & TIM_TimeBaseStructure);
-
- TIM_ClearFlag(TIM2, TIM_FLAG_Update); //清除TIM2溢出中斷標志
- TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //TIM2溢出中斷允許
-
- // TIM_Cmd(TIM2, ENABLE); //TIM2使能
- /* 中斷優先級分組配置 */
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
-
- /* 設置中斷嵌套控制器 */
- NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //設置TIM2中斷
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;//主優先級
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; //從優先級
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //中斷通道使能
- NVIC_Init(&NVIC_InitStructure);
-
- TIM_Cmd(TIM2, DISABLE);
- }
- /*GPIO初始化函數*/
- void GPIOF_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;//定義結構體變量
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF,ENABLE);//使能GPIOF時鐘
-
- GPIO_InitStructure.GPIO_Pin=GPIO_Pin_3;//選擇你要設置的IO口
- GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; //設置
-
- GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4;//選擇你要設置的IO口
- GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; //設置推挽輸出模式
- GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;//設置傳輸速率
-
- GPIO_Init(GPIOF,&GPIO_InitStructure); //初始化GPIO
-
- }
- /*******************************************************************************
- * 函 數 名 : main
- * 函數功能 : 主函數
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- int main()
- {
- SysTick_Init(72);
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //中斷優先級分組 分2組
- USART1_Init(9600);
- GPIOF_Init();
- TIM2_Init();
- while(1)
- {
- while(num<5) //每五次算平均數
- {
- RX = 1;
- StartModule(); //啟動模塊
- Timer_Count(); //開關定時器
- Conut(); //計算距離
- num++;
- sum+=S; //總數
- }
- average=sum/num; //平均數
- dispaly(); //打印函數
- clear(); //清零函數
- }
- }
- void StartModule(void) //啟動模塊
- {
- TX=1;
- Delay_us(20);
- TX=0;
- }
- void Timer_Count(void) //開啟關閉定時器模塊
- {
- while(RX==0);
- TIM_Cmd(TIM2, ENABLE); //TIM2使能
- while(RX==1);
- TIM_Cmd(TIM2, DISABLE); //TIM2使能
- }
- /********************************************************/
- void Conut(void) //超聲波距離計算函數
- {
- time = TIM2->CNT; //讀計數器值
- TIM2->CNT = 0; //清除計數器
- S=(time*1.7)/10; //算出來是MM
- if(S>=10) //校準
- S=S-10;
- }
- /*******************************************************************************
- * 函 數 名 : TIM2_IRQHandler
- * 函數功能 : TIM2中斷函數
- * 輸 入 : 無
- * 輸 出 : 無
- *******************************************************************************/
- void TIM2_IRQHandler(void)
- {
- if(TIM_GetITStatus(TIM2,TIM_IT_Update))
- {
- RX=0;
- flag=1;//超出量程標志
- }
- TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
- }
- /********打印函數*******/
- void dispaly(void)
- {
- if(average>=4000||flag==1)
- printf("超出量程\n");
- else
- printf("測距:%dMM\r\n",average);
- }
- /********清零函數*******/
- void clear(void)
- {
- flag=0;
- num=0;
- sum=0;
- average=0;
- }
復制代碼
所有資料51hei提供下載:
超聲波測距-printf重定向.7z
(182.84 KB, 下載次數: 47)
2019-3-5 17:33 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|