#一、元器件原理图
##1、单片机及其原理图
##2、震动传感器
##3、继电器
##4、元器件接线图
#二、实现原理
##1、技术文档
#三、Keil软件实现
#四、编程代码
一、元器件及其原理图
1、STM32F103C8T6单片机介绍
本次项目主要应用stm32f10c8t6开发板,俗称哞哞一号开发板
2、振动传感器
应用原理:
当震动传感器感受到相应的震动会向单片机发出震动信号,信号灯LED2发光,可通过灵敏度旋钮来调节芯片内部震动力度的标准。
3、继电器
应用原理:
继电器内部有开关,会根据单片机的信号来实现开关的打开与关闭。
4、元器件接线图:
二、实现原理
1、技术文档
使能继电器、震动传感器所需的条件及原理:
1.使能ABP2的外设时钟
2.配置GPIOA为输出模式
3.配置GPIOA输出低电平
首先,打开 STM32F103C8T6的中文技术手册,找到储存器和总线构架章节,在第一部分的系统架构图中找到GPIOA输入输出所在的位置,位于ABP2总线上,而ABP2总线通过桥接连接在AHB系统总线上,我们要通过配置相应的固件库去实现配置GPIOA的输出模式(推挽输出或下拉输出),同时将电平拉低。
三、Keil软件实现
1、建立新的文件
1. 在固件库->USER->新建文件夹1008震动传感器控制继电器控制灯的亮灭文件夹
2.在文件夹中新建relay.c、relay.h、shake.c和shake.h文件。
3.固件库模板->project->STM32打开工程
4.将relay.c与shake.c添加进USER文件夹
5.在USER文件夹中打开relay.c文件
6.在relay.c文件中添加头文件,建立初始化函数,编译。7.在relay.h文件中添加头文件,声明初始化函数,编译。8.将relay.h头文件添加进main.c函数中,在主函数中调用relay初始化函数,编译。9.点开魔术棒,将.h文件添加到主函数中
10.添加完成后编译确认无错误。
11.与添加relay.c与relay.h文件一样添加shake.c与shake.h文件
12.在relay.c文件中进行继电器寄存器结构的配置13.打开FWLIB外设文件->rcc.c->rcc.h->调用ABP2周期时钟
14.为ABP2时钟配置GPIOA时钟
15.在rcc.c->rcc.h->使能GPIOA时钟(ENABLE)
16.在relay.c中配置好GPIOA时钟
17.在外设文件FWLIB中找到gpio.h文件,将结构体初始化函数复制18.将结构体函数粘贴在relay.c中,定义为GPIO_InitTypeDef relay_init;
19.输入relay_init后加小数点,然后逐项选中。
20.如图配置
21.打开gpio.h,配置GPIO的输出模式为推挽输出。
22.配置GPIOA 的速度为10Mhz。
23.将GPIOA的pin口调为3。
24.将配置好的结构体进行编译。
25.打开gpio.h文件,复制GPIOA的初始化函数。
26.将GPIOA初始化函数粘贴在relay.c文件中
27.将初始化函数配置为GPIOA时钟及结构体地址。
28.在shake.c文件中对震动传感器寄存器配置框架。
29.z在外设文件FWLIB->rcc.c->rcc.h->调用ABP2周期时钟(复制)。
30.将ABP2周期时钟粘贴在shake.c中。
31.将GPIOA 时钟配置完成,编译。
32.结构体初始化。
33.配置好的结构体,注意将输出配置为下拉输出(IPD)
34.在主函数中添加延时函数。
35.如图,在主函数中将继电器电平拉高。
36.配置震动传感器与继电器结合使用控制的灯的开关。
37.将程序烧录进单片机中。
四、编程代码
relay.c
#include "stm32f10x.h"
#include "relay.h"
void Relay_Init(void)
{
GPIO_InitTypeDef relay_init; //½á¹¹Ìå³õʼ»¯
//1.µ÷ÓÃGPIOAʱÖÓ
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//2.GPIOA3½á¹¹ÌåÅäÖÃ
relay_init.GPIO_Mode = GPIO_Mode_Out_PP; //Êä³öģʽ
relay_init.GPIO_Pin = GPIO_Pin_3; //Êä³öPIN¿Ú
relay_init.GPIO_Speed = GPIO_Speed_10MHz ;//Êä³öËÙ¶È
GPIO_Init(GPIOA,&relay_init ); //GPIOA³õʼ»¯º¯Êý
}
relay.h
#include "stm32f10x.h"
void Relay_Init(void);
shake.c
#include "stm32f10x.h"
#include "shake.h"
void Shake_Init(void)
{
GPIO_InitTypeDef shake_init;//½á¹¹Ìå³õʼ»¯
// 1.ÅäÖÃGPIOAʱÖÓ
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
// 2.½á¹¹ÌåÅäÖÃ
shake_init.GPIO_Mode = GPIO_Mode_IPD; //ÅäÖÃÊä³ö£¬ÏÂÀÊäÈë
shake_init.GPIO_Pin = GPIO_Pin_2; //ÅäÖÃpin¿Ú
shake_init.GPIO_Speed = GPIO_Speed_10MHz;//ÅäÖÃËÙ¶È
GPIO_Init(GPIOA,&shake_init); //GPIOAʱÖÓ³õʼ»¯
}
shake.h
#include "stm32f10x.h"
void Shake_Init(void);
main.h
#include "stm32f10x.h"
#include "led.h"
#include "usart.h"
#include "relay.h"
#include "shake.h"
#include "main.h"
void delay(uint16_t time)
{
uint16_t i=0;
while(time--)
{
i=12000;
while(i--);
}
}
int main()
{
LED_Init();
usart_init();
Relay_Init();
Shake_Init();
GPIO_SetBits(GPIOA,GPIO_Pin_3);//½«¼ÌµçÆ÷µçƽÀ¸ß
while(1)
{
if(GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2)==0)//µ±Õ𶯴«¸ÐÆ÷¸ÐÊܵ½Õ𶯣¬µçƽÀµÍ
{
GPIO_ResetBits(GPIOA,GPIO_Pin_3);//¼ÌµçÆ÷µçƽÀµÍ£¬µÆÁÁ
delay(1000); //ÑÓʱһÃëºó
GPIO_SetBits(GPIOA,GPIO_Pin_3); //¼ÌµçÆ÷µçƽÀ¸ß£¬µÆÃð
}
else
{
GPIO_SetBits(GPIOA,GPIO_Pin_3); //ÎÞÕð¶¯Ê±£¬¼ÌµçÆ÷µçƽÀ¸ß£¬µÆ²»ÁÁ
}
}
}
startup.c
#include "stm32f10x.h"
#include "usart.h"
void usart_init(void) //´®¿Ú³õʼ»¯
{
GPIO_InitTypeDef GPIO_initstructure;
USART_InitTypeDef USART_initstructure;
NVIC_InitTypeDef Nvic_Init;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //ÅäÖÃÖжÏ×éΪÖжÏ×é2 misc.h
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //ÅäÖÃÖжϸ´ÓÃʱÖÓ
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
//ÅäÖÃPA9 TX
GPIO_initstructure.GPIO_Mode =GPIO_Mode_AF_PP; //ÍÆÍìÊä³ö
GPIO_initstructure.GPIO_Pin =GPIO_Pin_9;
GPIO_initstructure.GPIO_Speed =GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_initstructure);
//ÅäÖÃPA10 RX
GPIO_initstructure.GPIO_Mode =GPIO_Mode_IN_FLOATING; //¸¡¿ÕÊäÈë
GPIO_initstructure.GPIO_Pin =GPIO_Pin_10;
GPIO_Init(GPIOA,&GPIO_initstructure);
//´®¿Ú1´ò¿ª
USART_initstructure.USART_BaudRate=115200; //²¨ÌØÂÊ
USART_initstructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
USART_initstructure.USART_Mode=USART_Mode_Rx | USART_Mode_Tx;
USART_initstructure.USART_Parity=USART_Parity_No; //УÑéλ
USART_initstructure.USART_StopBits= USART_StopBits_1; //ֹͣλ
USART_initstructure.USART_WordLength= USART_WordLength_8b; //ÓÐЧ×Ö½Ú³¤¶È 8λ
USART_Init(USART1,&USART_initstructure);
//ʹÄÜ´®¿Ú1
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //´®¿ÚÖжÏÅäÖÃ
USART_Cmd(USART1,ENABLE);
//ÅäÖÃÖжÏ
Nvic_Init.NVIC_IRQChannel =USART1_IRQn; //ÉèÖÃÖжÏͨµÀ stm32f10x.h
Nvic_Init.NVIC_IRQChannelCmd =ENABLE; //¿ØÖÆÊÇ·ñʹÄÜ
Nvic_Init.NVIC_IRQChannelPreemptionPriority =1; //ÉèÖÃÇÀÕ¼ÓÅÏȼ¶
Nvic_Init.NVIC_IRQChannelSubPriority =1; //ÉèÖÃ×ÓÓÅÏȼ¶
NVIC_Init(&Nvic_Init);
}
//·¢Ë͵¥¸ö×Ö·û µ÷Ó÷½·¨ USARTSendByte(USART1,'o');
void USARTSendByte(USART_TypeDef* USARTx, uint16_t Data){
USART_SendData(USART1,Data);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)==RESET); //ÅжÏÊÇ·ñ·¢ËÍÍê³É
}
//·¢ËÍ×Ö·û´® //ÔÀí×Ö·û·¢ËÍ×îºóһλÊÇ\0ÅжÏÊÇ·ñ×îºóһλ\0¾ÍÄÜ·¢ËÍ×Ö·û´® µ÷Ó÷½·¨ USARTSendStr(USART1,"ruanzebin");
void USARTSendStr(USART_TypeDef* USARTx, char *str){
uint16_t i=0; //ÎÞ·ûºÅÕûÐÎÊ®Áùλ
do{
USARTSendByte(USARTx, *(str+i));
i++;
}while(*(str+i)!='\0');
while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET); //ÅжÏÊÇ·ñ·¢ËÍÍê³É
}
//printf º¯Êý putcharº¯Êý(Êä³öµ¥¸ö×Ö·û) ͨ¹ýÖض¨Ïò Êä³öÊýÖµ
int fputc(int ch ,FILE *f){
USART_SendData(USART1,(uint8_t)ch);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)==RESET); //ÅжÏÊÇ·ñ·¢ËÍÍê³É
return (ch);
}
//scanf() getcharº¯Êý
int fgetc(FILE *f)
{
while(USART_GetFlagStatus(USART1, USART_FLAG_RXNE)==RESET); //ÅжÏÊÇ·ñ½ÓÊճɹ¦
return (int)USART_ReceiveData(USART1);
}