完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
提出问题:STM32如何控制风扇转动、蜂鸣器响停、光敏电阻光强读取、以及温湿度传感器控制?这些都是学习单片机较为基本的知识, 本文将对以上问题作出详细解答希望能帮到大家:
本文以STM32F103R6为例 一、控制风扇转动和蜂鸣器响停 直流电风扇在proteus库中的名称是FAN-DC 蜂鸣器在proteus库中的名称是BUZZER #include "stm32f10x.h" #include "led.h" #include "uart.h" #include "stdio.h" #include "lcd.h" void main_delay(u32 time) { int i,j; for(i = 0; i < time; i++) { for(j = 0; j < 1000; j++) { j++; j--; } } } //风扇初始化函数 void fanInit(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStruct); GPIO_SetBits(GPIOA,GPIO_Pin_6);//置1,风扇关 } //蜂鸣器初始化函数 void buzzerInit(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Pin=GPIO_Pin_7; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOC,&GPIO_InitStruct); GPIO_SetBits(GPIOC,GPIO_Pin_7);//置1,蜂鸣器关 } int main(void) { int i = 0; fanInit();//风扇初始化 buzzerInit();//蜂鸣器初始化 LED_GPIO_Config(); while(1) { //如果 置1 是关风扇和蜂鸣器 GPIO_ResetBits(GPIOA,GPIO_Pin_6);//清零 风扇开 GPIO_ResetBits(GPIOC,GPIO_Pin_7);//清零 蜂鸣器开 } } 注意:蜂鸣器要将导通电压设置成1.8v,否则可能会因为导通电压不足而不响。 二、温湿度传感器 本文用到的温湿度传感器是DHT11 代码实现: int main(void) { //unsigned char //无符号的字符 u8 temp,hum;//用来保存温度和湿度整数 char buf_temp[30];//用来保存格式化的温度字符串 char buf_hum[30];//用来保存格式化的湿度字符串 LCD_Init();//LCD液晶屏的初始化 DHT11_Init();//温湿度传感器初始化 while(1) { //读取温湿度 参数上的地址传递 DHT11_Read_Data(&temp,&hum);//temp 和 hum保存了温度和湿度 sprintf(buf_temp,"temp:%d",temp);//格式化的温度字符串,放入字符数组 sprintf(buf_hum,"hum:%d",hum);//格式化的湿度字符串,放入字符数组 LCD_P8x16Str(10,1,(u8 *)buf_temp);//显示到屏幕上 LCD_P8x16Str(10,3,(u8 *)buf_hum);//显示到屏幕上 main_delay(2000);//延时 } } 例:当温度大于30红灯闪烁,蜂鸣器响,湿度大于50风扇转动 #include "stm32f10x.h" #include "LQ12864.h" #include "DTH11.h" #include //风扇初始化 void fanInit(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Pin=GPIO_Pin_1; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStruct); GPIO_SetBits(GPIOA, GPIO_Pin_1); //置1,风扇关 } //蜂鸣器初始化 void buzzerInit(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Pin=GPIO_Pin_2; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStruct); GPIO_SetBits(GPIOA, GPIO_Pin_2); //置1,风扇关 } void ledInit(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStruct); GPIO_SetBits(GPIOA, GPIO_Pin_0); //置1,风扇关 } void main_delay(int time) { int i,j; for(i = 0; i < time; i++) { for(j = 0; j < 1000; j++) { j++; j--; } } } int main(void) { u8是指//unsigned char //无符号的字符 u8 temp,hum;//用来保存温度和湿度整数 char buf_temp[30];//用来保存格式化的温度字符串 char buf_hum[30];//用来保存格式化的湿度字符串 LCD_Init(); DHT11_Init(); fanInit(); buzzerInit(); ledInit(); while(1) { //读取温湿度 参数上的地址传递 DHT11_Read_Data(&temp,&hum);//temp 和 hum保存了温度和湿度 sprintf(buf_temp,"temp:%d",temp);//格式化的温度字符串,放入字符数组 sprintf(buf_hum,"hum:%d",hum);//格式化的湿度字符串,放入字符数组 LCD_P8x16Str(10,1,(u8 *)buf_temp);//显示到屏幕上 LCD_P8x16Str(10,3,(u8 *)buf_hum);//显示到屏幕上 main_delay(2000);//延时 if(temp>30) { GPIO_ResetBits(GPIOA, GPIO_Pin_2); GPIO_ResetBits(GPIOA, GPIO_Pin_0); main_delay(200); GPIO_SetBits(GPIOA, GPIO_Pin_0); } else { GPIO_SetBits(GPIOA, GPIO_Pin_0); GPIO_SetBits(GPIOA, GPIO_Pin_2); } if(hum>50) { GPIO_ResetBits(GPIOA, GPIO_Pin_1); } else { GPIO_SetBits(GPIOA, GPIO_Pin_1); } } } 注意: DHT11的传输方式: 传输数据使用的是 单总线 即只有一根数据线 1 byte == 8 bit DHT11一次传输 40 bit 数据 8bit -->温度的整数部分 8bit -->温度的小数部分 8bit -->湿度的整数部分 8bit -->湿度的小数部分 8bit -->校验位 为什么要有检验位?因为单总线传输容易丢失数据,校验位的值便是前四位的和,若发送的和接受的校验位的值不等则说明数据丢失。 这个问题在LQ12864.c文件中充分的显示出来 LQ12864.c u8 DHT11_Read_Data(u8 *temp,u8 *humi) //u8是无符号的char----unsigned char { u8 buf[5]; u8 i; DHT11_Rst(); if(DHT11_Check()==0) { for(i=0;i<5;i++)//读取40位数据 { buf=DHT11_Read_Byte(); //buf[0]存放温度的整数部分 //buf[1]存放温度的小数部分 //buf[2]存放湿度的整数部分 //buf[3]存放湿度的小数部分 //buf[4]存放标志位 } if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]) //验证标志位,因为单总线传输容易丢失数据 { *humi=buf[0]; *temp=buf[2]; } }else return 1; return 0; } 三:光电传感器,光敏电阻 光敏电阻在proteus中的名称为TORCH 光敏电阻的工作原理:根据光照不同,电阻的阻值发生变化,光越强电阻越小电压小 。 ADC模数转换器 void Adc_Init(void) //ADC初始化 u16 Get_Adc(void) //读取光照强度 代码实现 int main(void) { int light;//用来保存读取到的光照强度 char buf[100] = { 0 };//用来保存格式化的光照强度的字符串 Adc_Init();//ADC初始化 LCD_Init();//LCD初始化 while(1) { light = Get_Adc();//读取光照强度 sprintf(buf,"light:%d ",light); LCD_P8x16Str(0,0,buf); main_delay(200); } } 例:光强度值高于1000(灯光变暗) //添加三个黄灯 0-1000 三个灯灭 1000-2000 一个灯亮 2000-3000 两个灯亮 3000-4500 三个灯亮 代码如下: #include "stm32f10x.h" #include "LQ12864.h" #include "DTH11.h" #include #include "adc.h" void main_delay(int time) { int i,j; for(i = 0; i < time; i++) { for(j = 0; j < 1000; j++) { j++; j--; } } } //风扇初始化 void fanInit() { GPIO_InitTypeDef init; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); init.GPIO_Mode = GPIO_Mode_Out_PP; init.GPIO_Pin = GPIO_Pin_3; init.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&init); GPIO_SetBits(GPIOA,GPIO_Pin_3);//置1,风扇关 } //蜂鸣器初始化 void buzzerInit() { GPIO_InitTypeDef init; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); init.GPIO_Mode = GPIO_Mode_Out_PP; init.GPIO_Pin = GPIO_Pin_5; init.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&init); GPIO_SetBits(GPIOA,GPIO_Pin_5);//置1,蜂鸣器关 } //LED初始化 void ledInit() { GPIO_InitTypeDef init; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); init.GPIO_Mode = GPIO_Mode_Out_PP; init.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12; init.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&init); GPIO_SetBits(GPIOA,GPIO_Pin_7|GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12);//置1,LED关 } //控制灯的亮灭 //0 000 //4 100 //6 110 //7 111 void ledSwitch(int num) { num & 4 ? GPIO_ResetBits(GPIOA,GPIO_Pin_10) : GPIO_SetBits(GPIOA,GPIO_Pin_10); num & 2 ? GPIO_ResetBits(GPIOA,GPIO_Pin_11) : GPIO_SetBits(GPIOA,GPIO_Pin_11); num & 1 ? GPIO_ResetBits(GPIOA,GPIO_Pin_12) : GPIO_SetBits(GPIOA,GPIO_Pin_12); } int main(void) //休息10分钟 { int light;//用来保存读取到的光照强度 char buf[100] = { 0 };//用来保存格式化的光照强度的字符串 Adc_Init();//ADC初始化 LCD_Init();//LCD初始化 ledInit();//LED初始化 while(1) { light = Get_Adc();//读取光照强度 if(light > 0 && light <= 1000) ledSwitch(0);//三个灯灭 else if(light > 1000 && light <= 2000) ledSwitch(4); else if(light > 2000 && light <= 3000) ledSwitch(6); else if(light > 3000 && light <= 4500) ledSwitch(7); sprintf(buf,"light:%d ",light); LCD_P8x16Str(0,0,buf); main_delay(200); } } 注意:
例:添加两个按键,分别控制风扇和蜂鸣器的开关,按一下开,再按一下关。 #include "stm32f10x.h" #include "led.h" #include "uart.h" #include "stdio.h" #include "lcd.h" #define KEY_FAN 1 #define KEY_BUZZER 2 #define NONE 0 void main_delay(u32 time) { int i,j; for(i = 0; i < time; i++) { for(j = 0; j < 1000; j++) { j++; j--; } } } //风扇初始化函数 void fanInit(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOA,&GPIO_InitStruct); GPIO_SetBits(GPIOA,GPIO_Pin_6);//置1,风扇关 } //蜂鸣器初始化函数 void buzzerInit(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Pin=GPIO_Pin_7; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOC,&GPIO_InitStruct); GPIO_SetBits(GPIOC,GPIO_Pin_7);//置1,蜂鸣器关 } //按键初始化 void keyInit(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPU;//输入模式 GPIO_InitStruct.GPIO_Pin=GPIO_Pin_2 | GPIO_Pin_5; GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz; GPIO_Init(GPIOB,&GPIO_InitStruct); } //读取按键的值 int keyRead() { if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_2) == 0)//风扇 return KEY_FAN; if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_5) == 0)//蜂鸣器 return KEY_BUZZER; return NONE; } int main(void) { int i = 0; int key; char status[2] = {0,0};//两个元素分别代表 风扇和蜂鸣器开关的状态 fanInit();//风扇初始化 buzzerInit();//蜂鸣器初始化 keyInit();//按键初始化 LED_GPIO_Config(); while(1) { //读取按键的值 key = keyRead(); if(key == KEY_FAN) {// ! 取非, 原来为真,加上!后变为假 C语言中 1 真 0 假 //原来为假,加上!后变为真 status[0] = !status[0];// !status[0] 1 //1 代表开 0 代表关 status[0] ? GPIO_ResetBits(GPIOA,GPIO_Pin_6) : GPIO_SetBits(GPIOA,GPIO_Pin_6); } else if(key == KEY_BUZZER) { status[1] = !status[1];// !status[0] 1 //1 代表开 0 代表关 status[1] ? GPIO_ResetBits(GPIOC,GPIO_Pin_7) : GPIO_SetBits(GPIOC,GPIO_Pin_7); } main_delay(200);//按键消抖 } } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1617 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1543 浏览 1 评论
977 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
683 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1595 浏览 2 评论
1863浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
644浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
515浏览 3评论
531浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
504浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 07:03 , Processed in 0.625044 second(s), Total 76, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号