提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助檔案
基于STM32F407ZGT6芯片,實作小車前進后退,左轉右轉,ADC調速,紅外以及藍牙,尋跡,避障,螢屏顯示功能
- 開源代碼,共同提高,共同學習,
- 程式會陸續發布(一)
- *紅外部分*
- 遇到的部分問題:
- 最重要的事:
程式初衷是對stm開發板有初步認識以及提高學習興趣,以便更好地理解配置和使用程序,至于原理如何實作,請猿友自行查閱相關書籍細細品味,
開源代碼,共同提高,共同學習,
板子型別演示

程式會陸續發布(一)
紅外部分
以下代碼是利用開發板上的紅外,并不是利拓展版上的紅外,查閱板子的功能圖發現具有IR(紅外)的引腳為PA8,ok,下面開始配置嘍,,,,,,,
`
初始化配置,任何功能都提前需要配好,這里不贅述了,
red.c
#include "red.h"
#include "SysTick.h"
u32 hw_jsm; //定義一個32位資料變數,保存接收碼
u8 hw_jsbz; //定義一個8位資料的變數,用于指示接收標志
void red_Init()
{
GPIO_InitTypeDef GPIO_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
/* 開啟GPIO時鐘及管腳復用時鐘 */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE); //復用時鐘打開
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource8);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;//管腳設定
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化結構體
EXTI_ClearITPendingBit(EXTI_Line8);
/* 設定外部中斷的模式 */
EXTI_InitStructure.EXTI_Line=EXTI_Line8;
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd=ENABLE;
EXTI_Init(&EXTI_InitStructure);
/* 設定NVIC引數 */
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn; //打開全域中斷
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //搶占優先級為0
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; //回應優先級為1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能
NVIC_Init(&NVIC_InitStructure);
}
red.h
#ifndef _red_H
#define _red_H
#include "system.h"
void Hwjs_Init(void);
u8 HW_jssj(void);
//定義全域變數
extern u32 hw_jsm;
extern u8 hw_jsbz;
#endif
下邊函式功能:高電平持續時間,將記錄的時間保存在t中回傳,其中一次大約20us ,該函式放在red.c里就行,(后邊在具體實作中要用到的哦,)
u8 HW_jssj()
{
u8 t=0;
while(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)==1)//高電平
{
t++;
delay_us(20);
if(t>=250) return t;//超時溢位
}
return t;
}
void EXTI9_5_IRQHandler(void) //紅外遙控外部中斷
{
u8 Tim=0,Ok=0,Data,Num=0;
while(1)
{
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)==1)
{
Tim=HW_jssj();//獲得此次高電平時間
if(Tim>=250) break;//不是有用的信號
if(Tim>=200 && Tim<250)
{
Ok=1;//收到起始信號
}
else if(Tim>=60 && Tim<90)
{
Data=1;//收到資料 1
}
else if(Tim>=10 && Tim<50)
{
Data=0;//收到資料 0
}
if(Ok==1)
{
hw_jsm<<=1;
hw_jsm+=Data;
if(Num>=32)
{
hw_jsbz=1;
break;
}
}
Num++;
}
}
EXTI_ClearITPendingBit(EXTI_Line8);
}
初始化部分已經OK,下邊需要是在你的main.c,里面開啟即可,要不然不作業的,,,,,
red_Init(); //紅外模塊初始化(main.c里的)
下面就是主函式了,老大哥總是需要最后出來,**********為我們需要改的部分,因為不同遙控器通過串口回傳的值時不同的,其中********代表10進制的一串數字,如16432111
,16432111怎么來的?往下看嘍,
void red()
{
if(hw_jsbz==1) //如果紅外接收到
{
hw_jsbz=0; //清零
printf("紅外接收碼 %0.8X\r\n",hw_jsm); //列印
switch(hw_jsm)
{
case ********:
move();//你自己設定好的前進函式
//此處也可顯示當前狀態到顯示屏上后邊,在把開發板初始化配置好螢屏后,添加函式用即可,此處不贅述了
//其他功能..也可..
//..其他功能..也可..
//
break; //按下K_UP按鍵 實作前進
case ********:
back();//你自己設定好的后退函式
break; //按下K_DOWN按鍵 實作后退
case ********:
left();//你自己設定好的向左轉函式
break; //按下K_LEFT按鍵 實作右轉
case ********:
right();//你自己設定好的向右轉函式
break; //按下K_RIGHT按鍵 實作左轉
case ********:
stop();//你自己設定好的停止函式
break; //按下K_RIGHT按鍵 實作左轉
}
hw_jsm=0; //接收碼清零
}
}
要想到1643211這類數字,利用串口通信是必不可少的,此處用的usart.c,復用發送接收用的pa9、10,不想用這倆引腳也可從407參考手冊和資料手冊查找其他復用引腳即可,
#include "usart.h"
int fputc(int ch,FILE *p) //函式默認的,在使用printf函式時自動呼叫
{
USART_SendData(USART1,(u8)ch);
while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
return ch;
}
void USART1_Init(u32 bound)
{
//GPIO埠設定
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA時鐘
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1時鐘
//串口1對應引腳復用映射
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9復用為USART1
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10復用為USART1
//USART1埠配置
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_10 ; //GPIOA9與GPIOA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//復用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽復用輸出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9,PA10
//USART1 初始化設定
USART_InitStructure.USART_BaudRate = bound;//波特率設定
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字長為8位資料格式
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); //初始化串口1
USART_Cmd(USART1, ENABLE); //使能串口1
USART_ClearFlag(USART1, USART_FLAG_TC);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//開啟相關中斷
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中斷通道
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3;//搶占優先級3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =3; //子優先級3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根據指定的引數初始化VIC暫存器、
}
void USART1_IRQHandler(void) //串口1中斷服務程式
{
u8 r;
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中斷
{
r =USART_ReceiveData(USART1);//(USART1->DR); //讀取接收到的資料
USART_SendData(USART1,r);
while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET);
}
USART_ClearFlag(USART1,USART_FLAG_TC);
}
usart.h如下:
#ifndef __usart_H
#define __usart_H
#include "system.h"
#include "stdio.h"
void USART1_Init(u32 bound);
#endif
初始化部分已經OK,下邊需要是在你的main.c,里面開啟即可,要不然不作業的,,,,,
USART1_Init(115200); //波特率設定
這個115200為我們與串口通信軟體商量好的,兩者保持一致才可實作通信的喲,
串口助手的選擇網上有很多,隨便下一個即可,如秉火串口除錯助手,按照usart中設定的引數配置秉火串口除錯助手,如圖:
然后,點擊打開串口,此時對準開發板的紅外部分,按遙控器的一個按鍵,就會回傳一個值形如:

然后將00FF4AB5,轉化為10進制就能放到void red()里的case:的后面使用了,
遇到的部分問題:
1.打開串口助手,配置完波特率,校驗位,資料位,停止位后,依然無法打開串口,此時可能需要升級一下stlink,去網上查閱資料即可解決,
最重要的事:
覺得有幫助的話可以點個贊哦^^
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/239574.html
標籤:其他
