年前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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章