试验实现红外避障模块被遮挡时点亮LED功能。
//主函数
#include "stm32f10x.h"
#include "bsp_led.h"
#include "IREva.h"
#include "bsp_rccclkconfig.h"
int main(void)
{
HSE_SetSysClk( RCC_PLLMul_6 );
/* LED端口初始化 */
LED_GPIO_Config();
/* 按键端口初始化 */
IREva_GPIO_Config();
/* 轮询按键状态,若按键按下则反转LED */
while(1)
{
if( IREva_Scan(IREva_GPIO_PORT,IREva_GPIO_PIN) == IREva_LO )
{
/*LED1亮*/
LED1_ON;
}
else
{
/*LED1灭*/
LED1_OFF;
}
}
}
//IREva.c红外避障.C程序
#include "IREva.h"
void IREva_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*开启按键端口的时钟*/
RCC_APB2PeriphClockCmd(IREva_GPIO_CLK,ENABLE);
//选择按键的引脚
GPIO_InitStructure.GPIO_Pin = IREva_GPIO_PIN;
// 设置按键的引脚为浮空输入
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
//使用结构体初始化按键
GPIO_Init(IREva_GPIO_PORT, &GPIO_InitStructure);
}
/*
* 函数名:IREva_Scan
* 描述 :检测是否有按键按下
* 输入 :GPIOx:x 可以是 A,B,C,D或者 E
* GPIO_Pin:待读取的端口位
* 输出 :KEY_OFF(没按下按键)、KEY_ON(按下按键)
*/
uint8_t IREva_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin)
{
if(GPIO_ReadInputDataBit(GPIOx,GPIO_Pin) == IREva_LO ) return IREva_LO;
else
return IREva_HI;
}
/*********************************************END OF FILE**********************/
//IREva.h红外避障.h函数
#ifndef __IREVA_H
#define __IREVA_H
#include "stm32f10x.h"
// 引脚定义
#define IREva_GPIO_CLK RCC_APB2Periph_GPIOB
#define IREva_GPIO_PORT GPIOB
#define IREva_GPIO_PIN GPIO_Pin_12
/** 按键按下标置宏
* 按键按下为高电平,设置 KEY_ON=1, KEY_OFF=0
* 若按键按下为低电平,把宏设置成KEY_ON=0 ,KEY_OFF=1 即可
*/
#define IREva_HI 1
#define IREva_LO 0
void IREva_GPIO_Config(void);
uint8_t IREva_Scan(GPIO_TypeDef* GPIOx,uint16_t GPIO_Pin);
#endif
//LED.c函数
#include "bsp_led.h"
void LED_GPIO_Config(void)
{
/*定义一个GPIO_InitTypeDef类型的结构体*/
GPIO_InitTypeDef GPIO_InitStructure;
/*开启LED相关的GPIO外设时钟*/
RCC_APB2PeriphClockCmd( LED1_GPIO_CLK, ENABLE);
/*选择要控制的GPIO引脚*/
GPIO_InitStructure.GPIO_Pin = LED1_GPIO_PIN;
/*设置引脚模式为通用推挽输出*/
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
/*设置引脚速率为50MHz */
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/*调用库函数,初始化GPIO*/
GPIO_Init(LED1_GPIO_PORT, &GPIO_InitStructure);
/* 关闭所有led灯 */
GPIO_ResetBits(LED1_GPIO_PORT, LED1_GPIO_PIN);
}
/*********************************************END OF FILE**********************/
//Led.h函数
#ifndef __BSP_LED_H
#define __BSP_LED_H
#include "stm32f10x.h"
/* 定义LED连接的GPIO端口, 用户只需要修改下面的代码即可改变控制的LED引脚 */
#define LED1_GPIO_PORT GPIOC /* GPIO端口 */
#define LED1_GPIO_CLK RCC_APB2Periph_GPIOC /* GPIO端口时钟 */
#define LED1_GPIO_PIN GPIO_Pin_3 /* 连接到SCL时钟线的GPIO */
#define ON 1
#define OFF 0
/* 使用标准的固件库控制IO*/
#define LED1(a) if (a) \
GPIO_SetBits(LED1_GPIO_PORT,LED1_GPIO_PIN);\
else \
GPIO_ResetBits(LED1_GPIO_PORT,LED1_GPIO_PIN)
/* 直接操作寄存器的方法控制IO */
#define digitalHi(p,i) {p->BSRR=i;} //输出为高电平
#define digitalLo(p,i) {p->BRR=i;} //输出低电平
#define digitalToggle(p,i) {p->ODR ^=i;} //输出反转状态
/* 定义控制IO的宏 */
#define LED1_TOGGLE digitalToggle(LED1_GPIO_PORT,LED1_GPIO_PIN)
#define LED1_ON digitalHi(LED1_GPIO_PORT,LED1_GPIO_PIN)
#define LED1_OFF digitalLo(LED1_GPIO_PORT,LED1_GPIO_PIN)
void LED_GPIO_Config(void);
#endif /* __LED_H */
//如果使用12M晶振,还需加上设置频率程序,如果报flash错误,需要将stm32f10x_flash.c加入文件
#include "bsp_rccclkconfig.h"
void HSE_SetSysClk( uint32_t RCC_PLLMul_x )
{
ErrorStatus HSEStatus;
// 把RCC 寄存器复位成复位值
RCC_DeInit();
// 使能 HSE
RCC_HSEConfig(RCC_HSE_ON);
HSEStatus = RCC_WaitForHSEStartUp();
if( HSEStatus == SUCCESS )
{
// 使能预取指
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
FLASH_SetLatency(FLASH_Latency_2);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PCLK2Config(RCC_HCLK_Div1);
// 配置 PLLCLK = HSE * RCC_PLLMul_x
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_x);
// 使能PLL
RCC_PLLCmd(ENABLE);
// 等待PLL稳定
while( RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET );
// 选择系统时钟
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while( RCC_GetSYSCLKSource() != 0x08 );
}
else
{
/* 如果HSE 启动失败,用户可以在这里添加处理错误的代码 */
}
}
void HSI_SetSysClk( uint32_t RCC_PLLMul_x )
{
__IO uint32_t HSIStatus = 0;
// 把RCC 寄存器复位成复位值
RCC_DeInit();
// 使能 HSI
RCC_HSICmd(ENABLE);
HSIStatus = RCC->CR & RCC_CR_HSIRDY;
if( HSIStatus == RCC_CR_HSIRDY )
{
// 使能预取指
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
FLASH_SetLatency(FLASH_Latency_2);
RCC_HCLKConfig(RCC_SYSCLK_Div1);
RCC_PCLK1Config(RCC_HCLK_Div2);
RCC_PCLK2Config(RCC_HCLK_Div1);
// 配置 PLLCLK = HSE * RCC_PLLMul_x
RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_x);
// 使能PLL
RCC_PLLCmd(ENABLE);
// 等待PLL稳定
while( RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET );
// 选择系统时钟
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
while( RCC_GetSYSCLKSource() != 0x08 );
}
else
{
/* 如果HSI 启动失败,用户可以在这里添加处理错误的代码 */
}
}
void MCO_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
#ifndef __BSP_RCCCLKCONFIG_H
#define __BSP_RCCCLKCONFIG_H
#include "stm32f10x.h"
void HSE_SetSysClk( uint32_t RCC_PLLMul_x );
void MCO_GPIO_Config(void);
void HSI_SetSysClk( uint32_t RCC_PLLMul_x );
#endif /*__BSP_RCCCLKCONFIG_H */