一、创新实践实习内容
一:指导老师给我们介绍了广州粤嵌通信科技股份有限公司的企业文化与企业环境,简要地介绍了本行业的发展历史及未来发展趋势。讲解了Keil5的功能与应用。指导我们搭建STM32F407驱动环境以及学习相关芯片包的安装使用方法。并且带着我们对C语言的基础知识进行了回顾。通过一些实例操作介绍了STM32F407 常用的编程指令,完成创建工程,学习程序编译与运行。
二:学习STM32F407相关开关板,Keil5下的代码编辑器的使用方法;学习使用库函数建立相关工程,完成流水灯:亮的个数一次递增,再依次递减完实验。学习外部中断初始化,NVIC初始化,建立工程完成外部中断控制灯的亮灭。
三:开始学习对系统定时器system的使用,完成系统精确延时的程序,使用精确延时控制LED灯闪烁。学习串口通信,串口初始化结构体,实现数据收发,实现对STM32F407开发板的控制。
四:学习了解DHT11温湿度传感器,编辑相关程序完成温湿度的获取并用串口显示在PC上。学习OLED显示屏,了解其通讯方式,以及连接方法。编辑相关程序完成温湿度的获取以及随意一张图片显示在OLED显示屏上。
五:学习了解adc模数转换器,将模拟信号转换为数字信号; 按键测温,结果显示在oled,温度过低,蜂鸣器响。测烟雾,测光照,测湿度 显示在oled。都设定一个阈值,低于阈值报警。
项目答辩环节。
二、实习过程
第一阶段主要是学习Keil5的功能与应用,STM32F407 常用的编程指令,完成创建工程。简要简介了公司的企业文化及企业环境,让我们对本行业的未来发展有了一个初步的认识。老师带我们回顾了C语言的基础知识,如基本数据类型、运算符、数组、指针、结构体、typedef取别名、头文件的编写、条件编译、文件操作等内容。为后面编程奠定了基础。懂得库函数常用的命令以及一些快捷键的使用方式。
第二阶段学系STM32F407相关开关板的组成,了解程序烧录接线及步骤,Keil5下的代码编辑器的使用方法;学习使用库函数建立相关工程,学习GPIO口的初始化步骤并完成相关IO初始化,完成流水灯程序编写:亮的个数一次递增,再依次递减完实验。学习外部中断初始化,NVIC初始化相关步骤,建立工程完成外部中断控制灯的亮灭。
第三阶段:开始学习对系统定时器system的使用,了解systic计数方式:向下计数的24为计数器;以及其时钟频率21MHz;完成系统精确延时的程序,使用精确延时控制LED灯闪烁。学习串口通信,串行接口 (Serial Interface)是指数据一位一位地顺序传送。其特点是通信线路简单,只要一对传输线就可以实现双向通信,串口初始化结构体,实现数据收发,实现对STM32F407开发板灯及蜂鸣器的控制。
第四阶段:学习了解DHT11温湿度传感器,DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分,一次完整的数据传输为40bit,高位先出。 例如:37.2 00100101 00000010;数据格式:8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验和,通讯过程如图a所示;编辑相关程序完成温湿度的获取并用串口显示在PC上。学习OLED显示屏,了解其通讯方式,以及连接方法。编辑相关程序完成温湿度的获取以及随意一张图片显示在OLED显示屏上。

图a
第五阶段: 学习了解adc模数转换器,将模拟信号转换为数字信号; 按键测温,结果显示在oled,温度过低,蜂鸣器响。测烟雾,测光照,测湿度 显示在oled。都设定一个阈值,低于阈值报警。是前面所有项目的验收答辩环节,具体在下面部分结果里说明。
三、实践结果
(1)使用库函数建立相关工程,完成流水灯:亮的个数一次递增,再依次递减完实验。建立工程完成外部中断控制灯的亮灭。


图1 外部中断控制流水灯灯的亮灭。
(2)使用精确延时控制LED灯闪烁

图2 LED灯闪烁
(3)串口通信,实现数据收发,实现对STM32F407开发板的控制

图3 串口通信
(3)完成温湿度的获取并用串口显示在PC上

图4 温湿度的获取
(4)完成温湿度的获取以及随意一张图片显示在OLED显示屏上。

图5 OLED显示屏
(5) 按键测温,结果显示在oled,温度过低,蜂鸣器响。测烟雾,测光照,测湿度 显示在oled。都设定一个阈值,低于阈值报警。

图6 OLED显示屏温度报警

图7 OLED显示屏湿度报警

图7 OLED显示光强度报警
四、实习总结及体会
在本次的创新实践实习中,我对c语言有了更深刻的了解,巩固了C语言基础,提高了C语言编辑能力。加深理解Keil5的功能与应用。还有通过此次实习,加强了动手思考能力开拓了视野,增长了见识。学习对系统定时器system的使用,了解systic计数方式:向下计数的24为计数器;以及其时钟频率21MHz;学习了串口通信,串行接口(Serial Interface)是指数据一位一位地顺序传送。了解DHT11温湿度传感器,DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分,一次完整的数据传输为40bit,高位先出。 例如:37.2 00100101 00000010;数据格式:8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验和。发现了自己对于软硬件操作以及与组员间的交流沟通能力还有待提高,明白团队协作的重要性,学会换位思考。
附录:程序
验收main.c文件
#include <stm32f4xx.h>
 #include <led.h>
 #include <adc.h>
 #include <beep.h>
 #include <key.h>
 #include <delay.h>
 #include <usb.h>
 #include <string.h>
 #include <DS18B20.h>
 #include <stdio.h>
 #include "oled.h"
 #include "bmp.h"
 #include <mq.h>
 char date[5]={0};
 int ret;
 char buf[20];
 u16 flag=0;
 void EXTI0_IRQHandler(void)
 {
   //确保是否产生了EXTI Line中断
 if(EXTI_GetITStatus(EXTI_Line0) != RESET) 
 {
 delay_ms(30);
 if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)==0)
 {
 OLED_ShowNum(46,2,date[2],2,16);//整数部分
 OLED_ShowChar(64,2,'.');
 OLED_ShowNum(69,2,date[3],1,16);//小数部分
 if(date[2]<=27)
 {
 // if(date[3]<=1)
 // {
 GPIO_SetBits(GPIOF,GPIO_Pin_8);
 OLED_DrawBMP(93, 2,109, 4, BMP1);
 // }
 } 
 delay_s(2);
 GPIO_ResetBits(GPIOF,GPIO_Pin_8);
 }
 EXTI_ClearITPendingBit(EXTI_Line0);  //清除中断标志位
 }  
 }
 void USART1_IRQHandler(void)
 {
 //确保是否产生了中断
 if(USART_GetITStatus(USART1, USART_IT_RXNE))
 {
 buf[flag]=USART_ReceiveData(USART1);
 USART_SendData(USART1, buf[flag]);
 flag++;
 if(flag==20)
 {
 flag=0;
 }
 if(buf[flag-1]=='#')
 {
 buf[flag]=0;
 flag=0;
 }
 }
 }
 int main()
 {
 u16 adcx,yw;
 char temp;
 init_mq();
 init_adc();
 init_led();//led初始化
 init_key();//key初始化
 init_beep();
 init_usart1(9600);//串口初始化
 init_DS18B20();
 OLED_Init(); //OLED初始化
 OLED_Clear(); 
 SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
 ADC_SoftwareStartConv(ADC3);//ADC3开始转换
 ADC_SoftwareStartConv(ADC1);//ADC1开始转换
 printf("模块加载完成\r\n");
 while(1)
 {
 LED_RUN();
 ret=get_data(date);//读湿度和温度
 while(ADC_GetFlagStatus(ADC3, ADC_FLAG_EOC)==RESET);
 ADC_ClearFlag(ADC3, ADC_FLAG_EOC);
 adcx = ADC_GetConversionValue(ADC3);
 adcx=((4095-adcx)*100)/4095;
 //printf("%d\r\n",yw);
   while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)==RESET);
 ADC_ClearFlag(ADC1, ADC_FLAG_EOC);
 yw = ADC_GetConversionValue(ADC1);
 yw=(yw*100)/4095;
 if(date[0]>=80||adcx<=30||yw>8)
 {
 GPIO_SetBits(GPIOF,GPIO_Pin_8);
 }
 //   if()
 // {
 // GPIO_SetBits(GPIOF,GPIO_Pin_8);
 // }
 OLED_Clear();
 // OLED_DrawBMP(0,0,128,8,BMP2);delay_s(2);
   OLED_ShowCHinese(0,0,3);//湿
 OLED_ShowCHinese(18,0,1);//度
 OLED_ShowChar(36,0,':');
 OLED_ShowNum(46,0,date[0],2,16);
 OLED_ShowChar(64,0,'.');
 OLED_ShowNum(69,0,date[1],1,16);
 OLED_ShowChar(77,0,'%');
 // OLED_DrawBMP(90, 0,106, 16, BMP1);
 OLED_ShowCHinese(0,2,0);//温
 OLED_ShowCHinese(18,2,1);//度
 OLED_ShowChar(36,2,':');
 OLED_ShowCHinese(77,2,4);
 OLED_ShowCHinese(0,4,5);//光
 OLED_ShowCHinese(18,4,6);//强
 OLED_ShowChar(36,4,':');
 OLED_ShowNum(46,4,adcx,2,16);
 OLED_ShowChar(64,4,'%');
 OLED_ShowCHinese(0,6,7);//烟
 OLED_ShowCHinese(18,6,8);//雾
 OLED_ShowChar(36,6,':');
 // adcx=Get_Adc_Average(ADC_Channel_5,10);
 OLED_ShowNum(46,6,yw,2,16);
 OLED_ShowChar(64,6,'%');
 if(date[0]>=80)  OLED_DrawBMP(93, 0,109, 2, BMP1);
 if(adcx<=30)  OLED_DrawBMP(93, 4,109, 6, BMP1);
 if(yw>8)  OLED_DrawBMP(93, 6,109, 8, BMP1);
 delay_s(1);
 GPIO_ResetBits(GPIOF,GPIO_Pin_8);
 OLED_DrawBMP(93, 0,109, 2, BMP2);
 OLED_DrawBMP(93, 4,109, 6, BMP2);
 OLED_DrawBMP(93, 6,109, 8, BMP2);
 delay_s(1);
 }
 }
验收key.c文件
#include "stm32f4xx.h"
 static void NVIC_Configuration(void)
 {
   NVIC_InitTypeDef NVIC_InitStructure;
   /* 配置NVIC为优先级组1 */
   NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
   
   /* 配置中断源:按键1 */
   NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
   /* 配置抢占优先级 */
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
   /* 配置子优先级 */
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
   /* 使能中断通道 */
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);
 }
 void init_key(void)
 {
 GPIO_InitTypeDef GPIO_InitStruct;
 EXTI_InitTypeDef EXTI_InitStructure;
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
 GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
   GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
 NVIC_Configuration(); /* 配置 NVIC 中断*/
 GPIO_Init(GPIOE, &GPIO_InitStruct);
 GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_0;
   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
   GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
 SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
 GPIO_Init(GPIOA, &GPIO_InitStruct);
   EXTI_InitStructure.EXTI_Line = EXTI_Line0;         //中断线0
   EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; /* EXTI为中断模式 边沿触发*/
   EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; /* 下降沿中断 */
   EXTI_InitStructure.EXTI_LineCmd = ENABLE; /* 使能中断 */
   EXTI_Init(&EXTI_InitStructure);
 }
验收beep.c文件
#include "stm32f4xx.h"
 void init_beep(void)
 {
 GPIO_InitTypeDef GPIO_InitStruct;
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
 GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_8;
   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
   GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
 GPIO_Init(GPIOF, &GPIO_InitStruct);
 }
验收adc.c文件
#include "stm32f4xx.h"
 #include "delay.h"
 void init_adc(void)
 {
 ADC_CommonInitTypeDef ADC_CommonInitStruct;
 ADC_InitTypeDef ADC_InitStruct;
 GPIO_InitTypeDef GPIO_InitStruct;
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
 //引脚初始化
 GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_7;
   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;
   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
   GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
 GPIO_Init(GPIOF, &GPIO_InitStruct);
 //adc通用初始化
 ADC_CommonInitStruct.ADC_Mode=ADC_Mode_Independent;                                                                
 ADC_CommonInitStruct.ADC_Prescaler=ADC_Prescaler_Div2;                
 ADC_CommonInitStruct.ADC_DMAAccessMode=ADC_DMAAccessMode_Disabled;            
 ADC_CommonInitStruct.ADC_TwoSamplingDelay=ADC_TwoSamplingDelay_5Cycles;         
 ADC_CommonInit(&ADC_CommonInitStruct);
 //adc1初始化
 ADC_InitStruct.ADC_Resolution =ADC_Resolution_12b;
 ADC_InitStruct.ADC_DataAlign =ADC_DataAlign_Right;
 ADC_InitStruct.ADC_ExternalTrigConv =ADC_ExternalTrigConvEdge_None;
 ADC_InitStruct.ADC_ContinuousConvMode =ENABLE;
 ADC_InitStruct.ADC_ScanConvMode =DISABLE;
 ADC_InitStruct.ADC_NbrOfConversion = 1;
 ADC_Init(ADC3, &ADC_InitStruct);
 ADC_RegularChannelConfig(ADC3, ADC_Channel_5, 1, ADC_SampleTime_3Cycles);
 //使能
 ADC_Cmd(ADC3, ENABLE);
 }
 u16 Get_Adc(u8 ch)   
 {
    //设置指定ADC的规则组通道,一个序列,采样时间
 ADC_RegularChannelConfig(ADC3, ch, 1, ADC_SampleTime_3Cycles ); //ADC1,ADC通道,采样时间为239.5周期        
   
 ADC_SoftwareStartConv(ADC3); //使能指定的ADC1的软件转换启动功能
  
 while(!ADC_GetFlagStatus(ADC3, ADC_FLAG_EOC ));//等待转换结束
 ADC_ClearFlag(ADC3, ADC_FLAG_EOC);
 return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果
 }
 u16 Get_Adc_Average(u8 ch,u8 times)
 {
 u32 temp_val=0;
 u8 t;
 for(t=0;t<times;t++)
 {
 temp_val+=Get_Adc(ch);
 delay_ms(5);
 }
 return temp_val/times;
 }
验收led.c文件
#include "stm32f4xx.h"
 #include<delay.h>
 void Delay(u32 nCount)
 {
     for(;nCount!=0;nCount--);
 }
 void init_led(void)
 {
 GPIO_InitTypeDef GPIO_InitStruct;
 GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_9|GPIO_Pin_10;
   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
   GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
 GPIO_Init(GPIOF, &GPIO_InitStruct);
 GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_13|GPIO_Pin_14;
   GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
   GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
   GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
   GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
 GPIO_Init(GPIOE, &GPIO_InitStruct);
 }
 void LED_RUN(void)
 {
 GPIO_ResetBits(GPIOF,GPIO_Pin_9);
 delay_ms(50);
 GPIO_ResetBits(GPIOF,GPIO_Pin_10);
 delay_ms(50);
 GPIO_ResetBits(GPIOE,GPIO_Pin_13);
 delay_ms(50);
 GPIO_ResetBits(GPIOE,GPIO_Pin_14);
 delay_ms(50);
 GPIO_SetBits(GPIOE,GPIO_Pin_14);
 delay_ms(50);
 GPIO_SetBits(GPIOE,GPIO_Pin_13);
   delay_ms(50);
 GPIO_SetBits(GPIOF,GPIO_Pin_10);
 delay_ms(50);
 GPIO_SetBits(GPIOF,GPIO_Pin_9);
 delay_ms(50);
 }