年前STM32作品总结


title: 年前STM32作品总结
tags: 总结
date: 2019-1-30 10:53:00

最近做了一些项目包括公司和个人的

自己平时很少玩32项目,所以还是比较吃力的,但是也勉强完成了这个项目。

实际的运行效果

src="//player.bilibili.com/player.html?aid=41993140&cid=73725287&page=1" scrolling="no" border="0" allowfullscreen="true">

从这个作品里 我真的学到了很多知识,有关STM32作品的知识,其实这也算我人生中第一个真正意义上的STM32作品,因为我之前确实没玩过STM32,也没有做过相关的项目,到了公司以后才开始真正的接触STM32,而且一上来就是STM32F4的芯片,当时我一脸懵逼,又怕赶不上大家的步伐,所以我就抓紧时间学习了一下32的知识,看了一些教程,有的是视频教程买更多的还是看代码,拷贝粘贴,再修改。最终历时半个月,终于算是完成了这个作品。

  • 项目来源:网上的朋友让我给他做毕业设计,收费的哦。
  • 传感器选型:基本都是一些常用的传感器除了GSM模块(后来发现这玩意儿贼简单5行代码搞定)
  • 遇到的瓶颈,作为一个初学者,还是遇到了很多问题的,比如我代码中注释的,例如IO方向的设置,模拟量的读取、I2C通讯协议的问题(不求甚解吧)

下面是main函数的代码:

#include "led.h"
#include "delay.h"
#include "dht11.h"   //温湿度传感器库
#include "sys.h"
#include "usart.h"
#include "usart2.h"
#include "OLED.h"
#include "ds1302.h"  //时钟模块库
#include "adc.h"     //ADC采样库
#include "motor.h"  //步进电机库
#include "key.h"
#include "beep.h"
#include "stmflash.h"
#include "iic.h"    //I2C库 用于驱动光照传感器
#include "BH1750.h" //光照传感器库
#define FLASH_SAVE_ADDR  0X0800fe00	//设置FLASH 保存地址(必须为偶数,且其值要大于本代码所占用FLASH的大小+0X08000000)
//本代码由  阿正整理(部分原创) 
//B站视频链接: https://www.bilibili.com/video/av41993140/
//本人小白 很少玩 STM32 这是第一个STM32作品,代码过于粗糙 也没时间整理,大神勿喷。
//转载请注明出处,欢迎加群一起学习;476840321
u16 test_flash = 100;
u16 data[1]={0};    //要写入的数据
uint8_t *bth_msg;
u16 adcx,dlx,ch2o=0;
u8 temperature=0; //温度 	    
u8 humidity=0;    //湿度
u16 set_T = 10;    //定时 小时
u16 set_M = 10;    //定时 分钟
int oled_clrflag = 0,guang_set=80;  //光照初始值
int chuang_flag = 0;
unsigned char cc[10] = "AT\r\n";
unsigned char hh[20] = "AT+CMGF=1\r\n";
unsigned char gsm[20] = "AT+CSCS=\"GSM\"\r\n";
unsigned char hm[40] = "AT+CMGS=\"17739782188\"\r\n";  //改成你的手机号
unsigned char xx[10] = "hello";  //报警信息
void DisInit();
void read_flash();
void HW_int();
void seting_oled ();
void send_GSM();
void open_chuang();
void close_chuang();
void float_char(float f,unsigned char *s);
unsigned char Dec2Asc(unsigned char input, char* output );
typedef union   //测试结构体
{   
   float  f;   
   unsigned char u[10];
}Float4Byte; 
 int main(void)
 {	
	unsigned char txd_data;
	unsigned int txd_databuffer; 
	#if USESPI
			SPI1_Config();
			DMA_SPI_Config();
	#endif
	u8 t,time[15],len;
	Float4Byte m1;
	float test = 8.12;
	float temp;
	float datalx;
	u16 times=0; 
	u8 DisFlag=0; //显示切换标志 
	 int x ;
	 int KEY2_flag = 0;
	SystemInit();	        //配置系统时钟为
	delay_init();	    	  //延时函数初始化	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置中断优先级分组2
	uart_init(9600);	    //主串口初始化为9600
	usart2_init(9600);    //串口2初始化9600  用于GSM通讯
	LED_Init();		  	    //初始化与LED连接的硬件接口 
  OLED_IOInit();        //OLEDIO初始化
	OLED_Init();          //OLED初始化
	Adc_Init();           //ADC初始化    A1 作为采集口
	DHT11_Init();         //DHT11初始化  PC13
	DS1302_Init();        //DS1302初始化
	Motor_Init();         //步进电机初始化
	HW_int();             //人体红外初始化
	iic_init();           //i2c初始化
	KEY_Init();           //按键初始化
	Beep_Init();          //蜂鸣器初始化
	bh_data_send(BHPowOn);
	bh_data_send(BHReset);
	bh_data_send(BHModeH2);
	delay_ms(10);
	//DS1302_Write_Time(); //初始化DS1302时间  时间不准确时,可以用它更新时间
	DisInit();              //显示屏开机画面显示
	delay_ms(1000);         //延时单次不能延时大于1000
	delay_ms(1000);         //延时 
	OLED_Fill(0x00);        //清屏
  read_flash();           //读取flash数据
	printf("\r\nflash存储的数据为:%d\r\n",test_flash);
	while(1)
	{
		t=KEY_Scan(0);		//得到键值
   if(t!=0){
	 Beep=1;
	 delay_ms(100);
	 Beep=0;
	 } 		
		//按键操作说明:在未进入设置页面情况下,上下按钮分别为开关窗,在进入设置页面后,上下按钮为设置阈值
	if (t==KEY0_PRES){    //+
		if(DisFlag == 1){
		guang_set++;
		}else if (DisFlag == 2){
		 set_M++;
			if (set_M>59)set_M =59;
		}	else{
		open_chuang();
		}
		}	
	if (t==KEY1_PRES){    //-
		if(DisFlag ==1) {
		guang_set--;
		}else if (DisFlag == 2){
		 set_M--;
		if (set_M<1)set_M =1;
		}	else{
		close_chuang();
		}
		}
	if (t==KEY2_PRES){   //设置翻页按钮
		KEY2_flag++;
		if (KEY2_flag>2) KEY2_flag = 0;
		switch (KEY2_flag){
		case 0:{
		DisFlag=0;
		}
		break;
		case 1:{
		DisFlag=1;
		oled_clrflag=1;
		}
		break;
		case 2:{
		DisFlag=2;
		oled_clrflag=1;
		}
		break;
	}
		}
		DS1302_Get_Time(time);   //获取时钟模块时间
		DHT11_Read_Data(&temperature,&humidity); //读取温湿度值	
		adcx=Get_Adc_Average(ADC_Channel_1,10);  //读取ADC采样
		temp=(float)adcx*(3.3/4096);             //转换为3.3V数据量
		ch2o=temp*1000;//先放大便于处理
		datalx = bh_data_read()/1.2; //获取光照强度
		dlx = datalx*1;
		if(dlx>99) dlx=99;
		if (dlx>guang_set) //自动开窗
		{
			if (chuang_flag == 0){
			open_chuang();	
			}	  
		}
		if(time[11]*10+time[12] > set_M)  //到达定时时间执行动作
		{
		if (chuang_flag == 0){
			open_chuang();	
			}	
		}
		x = GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_4); //读取红外状态
		if (x && (chuang_flag)){    //检测人体
		  printf("dangerous");
			Beep=1;
			send_GSM(); //发送报警短信信息。
		}else Beep=0;
//		printf("%d%d%d%d年%d%d月%d%d日 ", time[0],time[1],time[2],time[3],time[4],time[5],time[6],time[7]);
//		printf("%d%d时%d%d分%d%d秒 星期%d\n", time[9],time[10],time[11],time[12],time[13],time[14],time[8]);
		if (DisFlag == 0){
		//----------------------------------------//
		  LCD_P16x16Ch(32,0,27);    //"环"  
			LCD_P16x16Ch(32+16,0,28); //"境"
      LCD_P16x16Ch(32+32,0,29); //"检" 
      LCD_P16x16Ch(32+48,0,30); //"测" 
      LCD_P16x16Ch(32+64,0,31); //"仪" 	
	//----------------------------------------//
			LCD_P16x16Ch(0,2,25); //"烟雾"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
		  LCD_P16x16Ch(16,2,26); 
			LCD_8x16Ch(32,2,ch2o/100%10);
			LCD_8x16Ch(40,2,ch2o%100/10%10); 
			LCD_8x16Ch(48,2,ch2o%10%10);
	//----------------------------------------//
		  LCD_P16x16Ch(64,2,32); //"光照"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
		  LCD_P16x16Ch(80,2,33); 
			OLED_P8x16Str(96,2,":"); 
			LCD_8x16Ch(104,2,dlx/10%10);
			LCD_8x16Ch(112,2,dlx%10);
	//----------------------------------------//
	//------------温度------------//
		  LCD_P16x16Ch(0,4,0); //"温" 
		  LCD_P16x16Ch(16,4,1); //"度"
			OLED_P8x16Str(32,4,":");
			LCD_8x16Ch(40,4,temperature/10%10);	
			LCD_8x16Ch(48,4,temperature%10); 
	//------------湿度------------//
		  LCD_P16x16Ch(66,4,2); //"湿" 
		  LCD_P16x16Ch(66+16,4,3); //"度"
			OLED_P8x16Str(66+32,4,":");
			LCD_8x16Ch(66+40,4,humidity/10%10);	
			LCD_8x16Ch(66+48,4,humidity%10); 
	//------------时间------------//
		  LCD_P16x16Ch(0,6,23); //"时" 
		  LCD_P16x16Ch(16,6,24); //"间"
			OLED_P8x16Str(32,6,":");
			LCD_8x16Ch(48,6,time[9]);	
			LCD_8x16Ch(56,6,time[10]); 
			OLED_P8x16Str(64,6,":");
			LCD_8x16Ch(72,6,time[11]); 
			LCD_8x16Ch(80,6,time[12]); 	
		}else if (DisFlag ==1){
			if(oled_clrflag){
			OLED_Fill(0x00); 
				oled_clrflag=0;
			}
		  LCD_P16x16Ch(16,0,32);    //"设置页面"  
			LCD_P16x16Ch(32,0,33); 
      LCD_P16x16Ch(48,0,34); 
      LCD_P16x16Ch(64,0,35);
      LCD_P16x16Ch(80,0,36);
      LCD_P16x16Ch(96,0,37);   

			LCD_P16x16Ch(0,2,32); //"光照"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
		  LCD_P16x16Ch(16,2,33); 
			OLED_P8x16Str(32,2,":");
			LCD_8x16Ch(40,2,guang_set/10%10);
			LCD_8x16Ch(48,2,guang_set%10);
		}else if (DisFlag ==2){
			if(oled_clrflag){
			OLED_Fill(0x00); 
				oled_clrflag=0;
			}
		  LCD_P16x16Ch(16,0,23);    //"设置页面"  
			LCD_P16x16Ch(32,0,24); 
      LCD_P16x16Ch(48,0,34); 
      LCD_P16x16Ch(64,0,35);
      LCD_P16x16Ch(80,0,36);
      LCD_P16x16Ch(96,0,37);  			

			LCD_P16x16Ch(0,2,23); //"时间"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
		  LCD_P16x16Ch(16,2,24); 
			OLED_P8x16Str(32,2,":");
			LCD_8x16Ch(40,2,set_M/10%10);
			LCD_8x16Ch(48,2,set_M%10);
		}
		
		  delay_ms(100);
		  test_flash = 200;
		  data[0] = test_flash;
	    STMFLASH_Write(FLASH_SAVE_ADDR,data,1);  //测试缓存数据
	}	 
}
 void open_chuang()   //开窗
 {
 Motorcw_angle(180,10);
 chuang_flag = 1;
 }
 void close_chuang()  //关窗
 {
 Motorse_angle(180,10);
	 chuang_flag = 0;
 }
/*
从flash读出保存的参数
*/
void read_flash()
{
	u16 data[1]={0};
	STMFLASH_Read(FLASH_SAVE_ADDR,data,1);
	if(data[0]==0xffff) return;  //如果为空,直接返回。
	//取数据
 test_flash=data[0];
	//yyFlag =data[1];
}
void HW_int()   //人体红外初始化
{
   GPIO_InitTypeDef GPIO_InitStructure;    
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//使能PE端时钟
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;           // HWBZ-->PE1 端口配置
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;       //上拉输入
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   //IO口速度为50MHz
   GPIO_Init(GPIOA,&GPIO_InitStructure);               //根据参数设定初始化GPIOE1
}
void DisInit()
{
    	OLED_Fill(0x00); //初始清屏
	    OLED_P8x16Str(0,0,"Hello my STM32");
	    OLED_P8x16Str(10,2,"2019 Come on!");
	    OLED_P8x16Str(10,6,"wenzheng.club");
}
void send_GSM()  //发送报警短信
{
usart2_SendStringByLen(cc,sizeof(cc));
	delay_ms(1000);
	usart2_SendStringByLen(hh,sizeof(hh));
	delay_ms(1000);
	usart2_SendStringByLen(gsm,sizeof(gsm));
	delay_ms(1000);
	usart2_SendStringByLen(hm,sizeof(hm));
	delay_ms(1000);
	usart2_SendStringByLen(xx,sizeof(xx));
	delay_ms(1000);
	USART2SendByte(0x1A);
	delay_ms(1000);
}
//学习笔记:
/*
注意:SIM800L供电为5V供电。
OLED显示的所有数据都是有位图组成的,且都存在于codetab.h中。
//OLED_P8x16Str(0,2,"ok");  第一个参数为横坐标,第二个参数为纵坐标。
LCD_P16x16Ch(0,0,5);  //中文字符取模存储在 codetab.h中
LCD_8x16Ch(48+16,2,temperature/10%10);	
# 正点原子的代码单次延时不能超过1000   delay_ms(1000);
欲显示浮点型数据,需要把数据拼接(乘以1000)为整型,再取余即可
如: temp实际数值为1.700
    u16 ch2o=0;
    adcx=Get_Adc_Average(ADC_Channel_1,10);
		temp=(float)adcx*(3.3/4096);
		temp= temp*1000;
		ch2o=temp;
		LCD_8x16Ch(48,0,ch2o/1000);
		OLED_P8x16Str(48+8,0,".");  //m  
		LCD_8x16Ch(48+16,0,ch2o%1000/100%10);
		LCD_8x16Ch(48+24,0,ch2o%1000%100/10%10);
		LCD_8x16Ch(48+32,0,ch2o%10);	
下面是IO方向设置的代码**重要**
#define IIC_SDA_OUT()  {GPIOC->CRH&=0X0FFFFFFF;GPIOC->CRH|=0x30000000;}//输入模式上拉下拉输入模式
#define IIC_SDA_IN()   {GPIOC->CRH&=0X0FFFFFFF;GPIOC->CRH|=0x80000000;}//通用推挽输出50MZ

*/

具体的代码文件我已经上传到了群文件:阿正工作站
476840321

猜你喜欢

转载自blog.csdn.net/switch_love_case/article/details/87110204