采用學(xué)過的STM32微控制器芯片設(shè)計一個溫度采集報警儀。該溫度采集報警儀可以通過數(shù)...
1、溫度采集和顯示功能:通過電位器模擬溫度傳感器,量程范圍0~3.3V對應(yīng)-10~+200度,在LCD上顯示電位器所模擬的溫度值;蛘咄ㄟ^DS18B20數(shù)字溫度傳感器采集環(huán)境溫度,并通過LCD進(jìn)行顯示。 2、溫度報警功能:環(huán)境溫度如果超過設(shè)定的溫度高報警值,報警指示燈LED1開始閃爍,溫度越高閃爍的頻率越快;如果低于溫度高報警值,LED1熄滅,在LCD上顯示溫度報警值。 3、溫度高報警值修改功能:可以通過紅外遙控器或按鍵調(diào)整溫度高報警值。 4、在LCD上顯示自己的中文名字。 5、時鐘功能:在LCD上顯示當(dāng)前的時間。 6、定時控制功能:根據(jù)設(shè)定的動作時間控制LED2開始閃爍或停止閃爍(熄滅);也可在定時控制動作后延遲一段時間熄滅LED2燈,或者通過紅外遙控器及按鍵直接消除LED2的閃爍(類似鬧鐘功能)。 7、時間修改功能:可以通過紅外遙控器或按鍵調(diào)整當(dāng)前時間和定時時間。
單片機(jī)源程序如下:
- /******************** 尚學(xué)科技 **************************
- * 實(shí)驗平臺:開拓者STM32開發(fā)板
- * 庫版本 :ST3.5.0
- * 本程序只供學(xué)習(xí)使用,未經(jīng)作者許可,不得用于其它任何用途
- *版權(quán)所有,盜版必究。
- **********************************************************************************/
- #include "usart1.h"
- #include "lcd.h"
- #include "text.h"
- #include "temperature.h"
- #include "delay.h"
- #include "text.h"
- #include "LED.h"
- #include "Key.h"
- #include "rtc.h"
- #include "remote.h"
- const unsigned char HZ_1616[][32]={
- {0x00, 0x10, 0x1F, 0xF8, 0x10, 0x10, 0x10, 0x10, 0x1F, 0xF0, 0x00, 0x00, 0x00, 0x10, 0x3F, 0xF8,
- 0x01, 0x00, 0x01, 0x04, 0xFF, 0xFE, 0x02, 0x80, 0x02, 0x40, 0x04, 0x20, 0x18, 0x1C, 0x60, 0x08,},
- {0x00, 0x08, 0x7F, 0xFC, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x10, 0x3F, 0xF8,
- 0x01, 0x00, 0x01, 0x00, 0x01, 0x40, 0x01, 0x30, 0x01, 0x10, 0x01, 0x04, 0xFF, 0xFE, 0x00, 0x00,},
- {0x10, 0x40, 0x10, 0x24, 0x13, 0xFE, 0x10, 0x00, 0xFC, 0xF8, 0x24, 0x88, 0x24, 0xF8, 0x24, 0x00,
- 0x27, 0xFE, 0x4A, 0x02, 0x29, 0xFC, 0x10, 0x20, 0x28, 0x20, 0x44, 0x20, 0x84, 0xA0, 0x00, 0x40}
- };
- void LCD_DrawPoint1(u16 x,u16 y,u16 Color)
- {
- LCD_SetCursor(x,y);//設(shè)置光標(biāo)位置
- LCD_WriteRAM_Prepare(); //開始寫入GRAM
- LCD_WR_DATA(Color);
- }
- void LCD_ShowHZ(u16 x,u16 y,u8 num,u8 size,u8 mode,u16 Color)
- {
- u8 temp;
- u8 j,k;
- u8 count;
- u16 x0=x;
- // Char_Horizontal_or_Vertical_Set();
- if(x>MAX_CHAR_POSX||y>MAX_CHAR_POSY)return;
- //設(shè)置窗口
- ;//得到偏移后的值
- if(mode==0) //正常顯示
- {
- for(j=0;j<size;j++)
- {
- //字體大小選擇
- temp=HZ_1616[num][2*j];
- count=8;
- for(k=0;k<count;k++)
- {
- if(temp&0x80)
- {
- LCD_DrawPoint1(x,y,BLACK);
- }
- else
- {
- LCD_DrawPoint1(x,y,WHITE);
- }
- temp<<=1;
- x++;
- }
-
- temp=HZ_1616[num][2*j+1];
- count=8;
- for(k=0;k<count;k++)
- {
- if(temp&0x80)
- {
- LCD_DrawPoint1(x,y,BLACK);
- }
- else
- {
- LCD_DrawPoint1(x,y,WHITE);
- }
- temp<<=1;
- x++;
- }
- x=x0;
- y++;
- }
- }
- }
- void LED2_GPIO_Config(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- /*開啟GPIOC的外設(shè)時鐘*/
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
- /*選擇要控制的GPIOC引腳*/
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
- /*設(shè)置引腳模式為通用推挽輸出*/
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- /*設(shè)置引腳速率為50MHz */
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- /*調(diào)用庫函數(shù),初始化GPIOC*/
- GPIO_Init(GPIOD, &GPIO_InitStructure);
-
- }
- void TIME_NVIC_Configuration(void)
- {
- NVIC_InitTypeDef NVIC_InitStructure;
- /*設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級,2位響應(yīng)優(yōu)先級*/
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- /*TIM3中斷*/
- NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
- /*先占優(yōu)先級0級*/
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- /*從優(yōu)先級3級*/
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- /*IRQ通道被使能*/
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- /*根據(jù)NVIC_InitStruct中指定的參數(shù)初始化外設(shè)NVIC寄存器*/
- NVIC_Init(&NVIC_InitStructure);
- }
- void TIME_Configuration(void)
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- /*定時器TIM3時鐘使能*/
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
- /*設(shè)置在下一個更新事件裝入活動的自動重裝載寄存器周期的值,計數(shù)到5000為500ms*/
- TIM_TimeBaseStructure.TIM_Period = 36000-1;
- /*設(shè)置用來作為TIMx時鐘頻率除數(shù)的預(yù)分頻值*/
- TIM_TimeBaseStructure.TIM_Prescaler =(2000-1);
- /*設(shè)置時鐘分割:TDTS = Tck_tim*/
- TIM_TimeBaseStructure.TIM_ClockDivision = 0;
- /*TIM向上計數(shù)模式*/
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
- /*根據(jù)TIM_TimeBaseInitStruct中指定的參數(shù)初始化TIMx的時間基數(shù)單位*/
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);
- /*使能或者失能指定的TIM中斷*/
- TIM_ITConfig(TIM3,TIM_IT_Update|TIM_IT_Trigger,ENABLE);
- /*使能TIMx外設(shè)*/
- // TIM_Cmd(TIM3, ENABLE);
- }
- void TIM3_IRQHandler(void)
- {if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)
- {
- GPIOD->ODR^=1<<2;
- TIM_ClearITPendingBit(TIM3,TIM_IT_Update);//清除標(biāo)志位
- }
- }
-
- int main(void)
- {
- u8 acer;
- u8 ACER;
- u8 H=18;
- u8 M=1;
- u8 S;
- u8 flag;
- u8 FLAG;
- u16 temp;
- u8 key;
- float t,A=0;
- float temp_value;
- float temperate;
- float temp_set=40;
- char str[5];
- unsigned char value=0;
- USART1_Config(); //串口初始化
-
- Stm32_Clock_Init(9); //系統(tǒng)時鐘設(shè)置
- uart_init(72,9600); //串口初始化為9600
- delay_init(72); //延時初始化
- LED_GPIO_Config(); //LED 端口初始化
- Key_GPIO_Config(); // 按鍵端口初始化
- Temperature_Adc_Init();//溫度轉(zhuǎn)換器初始化
- Remote_Init(); //紅外接收初始化
- LED2_GPIO_Config();
- TIME_NVIC_Configuration();
- TIME_Configuration();
- GPIO_WriteBit(GPIOD,GPIO_Pin_2,(BitAction)1);
-
- RTC_Init();
- POINT_COLOR=RED;
- LCD_Init(); //屏幕初始化
- LCD_Clear(WHITE);
- LCD_ShowString(30,30,"wu yu ting",POINT_COLOR);
- LCD_ShowString(30,70,"1503150108",POINT_COLOR);
- LCD_ShowString(30,90,"warninig:",POINT_COLOR);
- LCD_ShowString(90,110,"C:",POINT_COLOR);
- LCD_ShowString(30,130,"temp:",POINT_COLOR);
- LCD_ShowString(90,150,"C",POINT_COLOR);
- LCD_ShowString(30,170,"RTC IS READY! ",POINT_COLOR);
- LCD_ShowString(30,190," - - ",POINT_COLOR);
- LCD_ShowString(30,210," : : ",POINT_COLOR);
- LCD_ShowString(30,250," : : ",POINT_COLOR);
- LCD_ShowHZ(30,50,0,16,0,BLACK);
- LCD_ShowHZ(55,50,1,16,0,BLACK);
- LCD_ShowHZ(80,50,2,16,0,BLACK);
-
- while(1)
- { temp=Get_Temperature_value();//得到內(nèi)部溫度的數(shù)字量的值
- temperate=temp*(3.3/4095);//保存溫度傳感器的電壓值
- temp_value=(1.43-temperate)/0.0043+25; //得到芯片內(nèi)部的溫度
- key=Remote_Scan();
- if(key)
- {
- switch(key)
- {
- case 56://按鍵5
- FLAG=0;
- ACER=0;
- LCD_ShowString(30,10," ",POINT_COLOR);break;
-
- case 226: //按鍵MENU
- { FLAG++;
- if(FLAG==1){LCD_ShowString(30,10,"Set year",POINT_COLOR);flag=1;break;}
- else if(FLAG==2){LCD_ShowString(30,10,"Set month",POINT_COLOR);flag=2;break;}
- else if(FLAG==3){LCD_ShowString(30,10,"Set date ",POINT_COLOR);flag=3;break;}
- else if(FLAG==4){LCD_ShowString(30,10,"Set hour ",POINT_COLOR);flag=4;break;}
- else if(FLAG==5){LCD_ShowString(30,10,"Set min ",POINT_COLOR);flag=5;break;}
- else if(FLAG==6){LCD_ShowString(30,10,"Set sec ",POINT_COLOR);flag=6;break;}
- else if(FLAG>6&&FLAG%6==1){FLAG==1;LCD_ShowString(30,10,"Set year",POINT_COLOR);flag=1;break;}
- break;
- }
- case 144://按鍵right
- {
- if(flag==1){calendar.w_year++;RTC_Set(calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);break;}
- else if(flag==2){calendar.w_month++;RTC_Set(calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);break;}
- else if(flag==3){calendar.w_date++;RTC_Set(calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);break;}
- else if(flag==4){calendar.hour++;RTC_Set(calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);break;}
- else if(flag==5){calendar.min++;RTC_Set(calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);break;}
- else if(flag==6){calendar.sec++;RTC_Set(calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);break;}
- break;
- }
- case 224: //按鍵left
- {
- if(flag==1){calendar.w_year--;RTC_Set(calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);break;}
- else if(flag==2){calendar.w_month--;RTC_Set(calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);break;}
- else if(flag==3){calendar.w_date--;RTC_Set(calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);break;}
- else if(flag==4){calendar.hour--;RTC_Set(calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);break;}
- else if(flag==5){calendar.min--;RTC_Set(calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);break;}
- else if(flag==6){calendar.sec--;RTC_Set(calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);break;}
- break;
- }
-
- case 152:
- temp_set =temp_set -1; //("按鍵:VOL- \r\n");
- break;
- case 2:
- temp_set=temp_set +1; //("按鍵:VOL+\r\n");
-
- case 162://按鍵power
- { ACER++;
- if(ACER==1){LCD_ShowString(30,10,"Set clock hour",POINT_COLOR);acer=1;break;}
- else if(ACER==2){LCD_ShowString(30,10,"Set clock min",POINT_COLOR);acer=2;break;}
- else if(ACER==3){LCD_ShowString(30,10,"Set clock sec ",POINT_COLOR);acer=3;break;}
- else if(ACER>3&&ACER%3==1){ACER==1;LCD_ShowString(30,10,"Set clock hour",POINT_COLOR);acer=1;break;}
- break;
- }
- case 90://按鍵6
- {
- if(acer==1){H++;break;}
- else if(acer==2){M++;break;}
- else if(acer==3){S++;break;}
- break;
- }
- case 16://按鍵4
- {
- if(acer==1){H--;break;}
- else if(acer==2){M--;break;}
- else if(acer==3){S--;break;}
- break;
- }
- case 34: //按鍵:text
- A=1;
- break;
- }
- }
- if((calendar.hour==H)&&(calendar.min==M)&&(calendar.sec==S))
- {TIM_Cmd(TIM3, ENABLE);}
- if(A)
- {
- {
- TIM_Cmd(TIM3,DISABLE );
- LED2_OFF;
- A=0;
- }
- }
- //時間顯示
- POINT_COLOR=RED;
- if(t!=calendar.sec)
- {
- t=calendar.sec;
- LCD_ShowNum(30,190,calendar.w_year,4,16);
- LCD_ShowNum(70,190,calendar.w_month,2,16);
- LCD_ShowNum(94,190,calendar.w_date,2,16);
- LCD_ShowNum(30,210,calendar.hour,2,16);
- LCD_ShowNum(54,210,calendar.min,2,16);
- LCD_ShowNum(78,210,calendar.sec,2,16);
- LCD_ShowNum(30,250,H,2,16);
- LCD_ShowNum(54,250,M,2,16);
- LCD_ShowNum(78,250,S,2,16);
- switch(calendar.week)
- {
- case 0:
- LCD_ShowString(30,230,"Sunday ",POINT_COLOR);
- break;
- case 1:
- LCD_ShowString(30,230,"Monday ",POINT_COLOR);
- break;
- case 2:
- LCD_ShowString(30,230,"Tuesday ",POINT_COLOR);
- break;
- case 3:
- LCD_ShowString(30,230,"Wednesday",POINT_COLOR);
- break;
- case 4:
- LCD_ShowString(30,230,"Thursday ",POINT_COLOR);
- break;
- case 5:
- LCD_ShowString(30,230,"Friday ",POINT_COLOR);
- break;
- case 6:
- LCD_ShowString(30,230,"Saturday ",POINT_COLOR);
- break;
- }
-
- }
-
- /*按鍵控制報警上限*/
- {
- value=KEY_Scan(); //獲取按鍵值
- if(value==2)
- temp_set+=1;
- else if(value==1)
- temp_set-=1;
- }
-
- /*報警閃爍*/
- { if(temp_value>temp_set)
- { LED1_ON;
- Delay(100000/(temp_value-temp_set));
- LED1_OFF;
- Delay(100000/(temp_value-temp_set));
- }
- else
- { LED1_OFF;
- }
- }
-
- /*溫度顯示*/
- {
- fun(temp_set,str);
- LCD_ShowString(50,110,str,POINT_COLOR);
- fun(temp_value,str);
- LCD_ShowString(50,150,str,POINT_COLOR);
- Delay(500000);
- }
- }
- }
復(fù)制代碼
rtc程序:
- #include "delay.h"
- #include "usart.h"
- #include "rtc.h"
-
- _calendar_obj calendar;//時鐘結(jié)構(gòu)體
-
- //實(shí)時時鐘配置
- //初始化RTC時鐘,同時檢測時鐘是否工作正常
- //BKP->DR1用于保存是否第一次配置的設(shè)置
- //返回0:正常
- //其他:錯誤代碼
- u8 RTC_Init(void)
- {
- //檢查是不是第一次配置時鐘
- u8 temp=0;
- if(BKP->DR1!=0X5050)//第一次配置
- {
- RCC->APB1ENR|=1<<28; //使能電源時鐘
- RCC->APB1ENR|=1<<27; //使能備份時鐘
- PWR->CR|=1<<8; //取消備份區(qū)寫保護(hù)
- RCC->BDCR|=1<<16; //備份區(qū)域軟復(fù)位
- RCC->BDCR&=~(1<<16); //備份區(qū)域軟復(fù)位結(jié)束
- RCC->BDCR|=1<<0; //開啟外部低速振蕩器
- while((!(RCC->BDCR&0X02))&&temp<250)//等待外部時鐘就緒
- {
- temp++;
- delay_ms(10);
- };
- if(temp>=250)return 1;//初始化時鐘失敗,晶振有問題
- RCC->BDCR|=1<<8; //LSI作為RTC時鐘
- RCC->BDCR|=1<<15;//RTC時鐘使能
- while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成
- while(!(RTC->CRL&(1<<3)));//等待RTC寄存器同步
- RTC->CRH|=0X01; //允許秒中斷
- while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成
- RTC->CRL|=1<<4; //允許配置
- RTC->PRLH=0X0000;
- RTC->PRLL=32767; //時鐘周期設(shè)置(有待觀察,看是否跑慢了?)理論值:32767
- RTC_Set(2017,6,22,18,00,00); //設(shè)置時間
- RTC->CRL&=~(1<<4); //配置更新
- while(!(RTC->CRL&(1<<5))); //等待RTC寄存器操作完成
- BKP->DR1=0X5050;
- printf("FIRST TIME\n");
- }else//系統(tǒng)繼續(xù)計時
- {
- while(!(RTC->CRL&(1<<3)));//等待RTC寄存器同步
- RTC->CRH|=0X01; //允許秒中斷
- while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成
- printf("OK\n");
- }
- MY_NVIC_Init(0,0,RTC_IRQn,2);//優(yōu)先級設(shè)置
- RTC_Get();//更新時間
- return 0; //ok
- }
- //RTC時鐘中斷
- //每秒觸發(fā)一次
- void RTC_IRQHandler(void)
- {
- if(RTC->CRL&0x0001)//秒鐘中斷
- {
- RTC_Get();//更新時間
- //printf("sec:%d\r\n",calendar.sec);
- }
- if(RTC->CRL&0x0002)//鬧鐘中斷
- {
- RTC->CRL&=~(0x0002); //清鬧鐘中斷
- //printf("Alarm!\n");
- }
- RTC->CRL&=0X0FFA; //清除溢出,秒鐘中斷標(biāo)志
- while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成
- }
- //判斷是否是閏年函數(shù)
- //月份 1 2 3 4 5 6 7 8 9 10 11 12
- //閏年 31 29 31 30 31 30 31 31 30 31 30 31
- //非閏年 31 28 31 30 31 30 31 31 30 31 30 31
- //year:年份
- //返回值:該年份是不是閏年.1,是.0,不是
- u8 Is_Leap_Year(u16 year)
- {
- if(year%4==0) //必須能被4整除
- {
- if(year%100==0)
- {
- if(year%400==0)return 1;//如果以00結(jié)尾,還要能被400整除
- else return 0;
- }else return 1;
- }else return 0;
- }
- //設(shè)置時鐘
- //把輸入的時鐘轉(zhuǎn)換為秒鐘
- //以1970年1月1日為基準(zhǔn)
- //1970~2099年為合法年份
- //返回值:0,成功;其他:錯誤代碼.
- //月份數(shù)據(jù)表
- u8 const table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5}; //月修正數(shù)據(jù)表
- //平年的月份日期表
- const u8 mon_table[12]={31,28,31,30,31,30,31,31,30,31,30,31};
- //syear,smon,sday,hour,min,sec:年月日時分秒
- //返回值:設(shè)置結(jié)果。0,成功;1,失敗。
- u8 RTC_Set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec)
- {
- u16 t;
- u32 seccount=0;
- if(syear<1970||syear>2099)return 1;
- for(t=1970;t<syear;t++) //把所有年份的秒鐘相加
- {
- if(Is_Leap_Year(t))seccount+=31622400;//閏年的秒鐘數(shù)
- else seccount+=31536000; //平年的秒鐘數(shù)
- }
- smon-=1;
- for(t=0;t<smon;t++) //把前面月份的秒鐘數(shù)相加
- {
- seccount+=(u32)mon_table[t]*86400;//月份秒鐘數(shù)相加
- if(Is_Leap_Year(syear)&&t==1)seccount+=86400;//閏年2月份增加一天的秒鐘數(shù)
- }
- seccount+=(u32)(sday-1)*86400;//把前面日期的秒鐘數(shù)相加
- seccount+=(u32)hour*3600;//小時秒鐘數(shù)
- seccount+=(u32)min*60; //分鐘秒鐘數(shù)
- seccount+=sec;//最后的秒鐘加上去
-
- //設(shè)置時鐘
- RCC->APB1ENR|=1<<28;//使能電源時鐘
- RCC->APB1ENR|=1<<27;//使能備份時鐘
- PWR->CR|=1<<8; //取消備份區(qū)寫保護(hù)
- //上面三步是必須的!
- RTC->CRL|=1<<4; //允許配置
- RTC->CNTL=seccount&0xffff;
- RTC->CNTH=seccount>>16;
- RTC->CRL&=~(1<<4);//配置更新
- while(!(RTC->CRL&(1<<5)));//等待RTC寄存器操作完成
- RTC_Get();//設(shè)置完之后更新一下數(shù)據(jù)
- return 0;
- }
- //得到當(dāng)前的時間,結(jié)果保存在calendar結(jié)構(gòu)體里面
- //返回值:0,成功;其他:錯誤代碼.
- u8 RTC_Get(void)
- {
- static u16 daycnt=0;
- u32 timecount=0;
- u32 temp=0;
- u16 temp1=0;
- timecount=RTC->CNTH;//得到計數(shù)器中的值(秒鐘數(shù))
- timecount<<=16;
- timecount+=RTC->CNTL;
- temp=timecount/86400; //得到天數(shù)(秒鐘數(shù)對應(yīng)的)
- if(daycnt!=temp)//超過一天了
- {
- daycnt=temp;
- temp1=1970; //從1970年開始
- while(temp>=365)
- {
- if(Is_Leap_Year(temp1))//是閏年
- {
- if(temp>=366)temp-=366;//閏年的秒鐘數(shù)
- else break;
- }
- else temp-=365; //平年
- temp1++;
- }
- calendar.w_year=temp1;//得到年份
- temp1=0;
- while(temp>=28)//超過了一個月
- {
- if(Is_Leap_Year(calendar.w_year)&&temp1==1)//當(dāng)年是不是閏年/2月份
- {
- if(temp>=29)temp-=29;//閏年的秒鐘數(shù)
- else break;
- }
- else
- {
- if(temp>=mon_table[temp1])temp-=mon_table[temp1];//平年
- else break;
- }
- temp1++;
- }
- calendar.w_month=temp1+1; //得到月份
- calendar.w_date=temp+1; //得到日期
- }
- temp=timecount%86400; //得到秒鐘數(shù)
- calendar.hour=temp/3600; //小時
- calendar.min=(temp%3600)/60; //分鐘
- calendar.sec=(temp%3600)%60; //秒鐘
- calendar.week=RTC_Get_Week(calendar.w_year,calendar.w_month,calendar.w_date);//獲取星期
- return 0;
- }
- //獲得現(xiàn)在是星期幾
- //功能描述:輸入公歷日期得到星期(只允許1901-2099年)
- //year,month,day:公歷年月日
- //返回值:星期號
- u8 RTC_Get_Week(u16 year,u8 month,u8 day)
- {
- u16 temp2;
- u8 yearH,yearL;
-
- yearH=year/100; yearL=year%100;
- // 如果為21世紀(jì),年份數(shù)加100
- if (yearH>19)yearL+=100;
- // 所過閏年數(shù)只算1900年之后的
- temp2=yearL+yearL/4;
- temp2=temp2%7;
- temp2=temp2+day+table_week[month-1];
- if (yearL%4==0&&month<3)temp2--;
- return(temp2%7);
- }
復(fù)制代碼
紅外遙控程序:
- #include "remote.h"
- #include "delay.h"
- void Remote_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- TIM_ICInitTypeDef TIM_ICInitStructure;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //PA1 輸入
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //上拉輸入
- GPIO_Init(GPIOA, &GPIO_InitStructure);
- GPIO_SetBits(GPIOA,GPIO_Pin_1); //初始化GPIOA1
-
-
- TIM_TimeBaseStructure.TIM_Period = 10000; //設(shè)定計數(shù)器自動重裝值 最大10ms溢出
- TIM_TimeBaseStructure.TIM_Prescaler =(72-1); //預(yù)分頻器,1M的計數(shù)頻率,1us加1.
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //設(shè)置時鐘分割:TDTS = Tck_tim
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數(shù)模式
- TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //根據(jù)指定的參數(shù)初始化TIMx
- TIM_ICInitStructure.TIM_Channel = TIM_Channel_2; // 選擇輸入端 IC2映射到TI2上
- TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //上升沿捕獲
- TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
- TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //配置輸入分頻,不分頻
- TIM_ICInitStructure.TIM_ICFilter = 0x03;//IC4F=0011 配置輸入濾波器 8個定時器時鐘周期濾波
- TIM_ICInit(TIM2, &TIM_ICInitStructure);//初始化定時器輸入捕獲通道
- TIM_Cmd(TIM2,ENABLE ); //使能定時器2
-
-
- NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM2中斷
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //先占優(yōu)先級0級
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //從優(yōu)先級3級
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
- NVIC_Init(&NVIC_InitStructure); //根據(jù)NVIC_InitStruct中指定的參數(shù)初始化外設(shè)NVIC寄存器
-
- TIM_ITConfig( TIM2,TIM_IT_Update|TIM_IT_CC2,ENABLE);//允許更新中斷 ,允許CC2IE捕獲中斷
- }
-
- //遙控器接收狀態(tài)
- //[7]:收到了引導(dǎo)碼標(biāo)志
- //[6]:得到了一個按鍵的所有信息
- //[5]:保留
- //[4]:標(biāo)記上升沿是否已經(jīng)被捕獲
- //[3:0]:溢出計時器
- u8 RmtSta=0;
- u16 Dval; //下降沿時計數(shù)器的值
- u32 RmtRec=0; //紅外接收到的數(shù)據(jù)
- u8 RmtCnt=0; //按鍵按下的次數(shù)
- //定時器5中斷服務(wù)程序
- void TIM2_IRQHandler(void)
- {
- if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)
- {
- if(RmtSta&0x80)//上次有數(shù)據(jù)被接收到了
- {
- RmtSta&=~0X10; //取消上升沿已經(jīng)被捕獲標(biāo)記
- if((RmtSta&0X0F)==0X00)RmtSta|=1<<6;//標(biāo)記已經(jīng)完成一次按鍵的鍵值信息采集
- if((RmtSta&0X0F)<14)RmtSta++;
- else
- {
- RmtSta&=~(1<<7);//清空引導(dǎo)標(biāo)識
- RmtSta&=0XF0; //清空計數(shù)器
- }
- }
- }
- if(TIM_GetITStatus(TIM2,TIM_IT_CC2)!=RESET)
- {
- if(RDATA)//上升沿捕獲
- {
- TIM_OC2PolarityConfig(TIM2,TIM_ICPolarity_Falling); //CC2P=1 設(shè)置為下降沿捕獲
- TIM_SetCounter(TIM2,0); //清空定時器值
- RmtSta|=0X10; //標(biāo)記上升沿已經(jīng)被捕獲
- }else //下降沿捕獲
- {
- Dval=TIM_GetCapture2(TIM2);//讀取CCR2也可以清CC2IF標(biāo)志位
- TIM_OC2PolarityConfig(TIM2,TIM_ICPolarity_Rising); //CC2P=0 設(shè)置為上升沿捕獲
-
- if(RmtSta&0X10) //完成一次高電平捕獲
- {
- if(RmtSta&0X80)//接收到了引導(dǎo)碼
- {
-
- if(Dval>300&&Dval<800) //560為標(biāo)準(zhǔn)值,560us
- {
- RmtRec<<=1; //左移一位.
- RmtRec|=0; //接收到0
- }else if(Dval>1400&&Dval<1800) //1680為標(biāo)準(zhǔn)值,1680us
- {
- RmtRec<<=1; //左移一位.
- RmtRec|=1; //接收到1
- }else if(Dval>2200&&Dval<2600) //得到按鍵鍵值增加的信息 2500為標(biāo)準(zhǔn)值2.5ms
- {
- RmtCnt++; //按鍵次數(shù)增加1次
- RmtSta&=0XF0; //清空計時器
- }
- }else if(Dval>4200&&Dval<4700) //4500為標(biāo)準(zhǔn)值4.5ms
- {
- RmtSta|=1<<7; //標(biāo)記成功接收到了引導(dǎo)碼
- RmtCnt=0; //清除按鍵次數(shù)計數(shù)器
- }
- }
- RmtSta&=~(1<<4);
- }
- }
- TIM_ClearFlag(TIM2,TIM_IT_Update|TIM_IT_CC2);
- }
- //處理紅外鍵盤
- //返回值:
- // 0,沒有任何按鍵按下
- //其他,按下的按鍵鍵值.
- u8 Remote_Scan(void)
- {
- u8 sta=0;
- u8 t1,t2;
- if(RmtSta&(1<<6))//得到一個按鍵的所有信息了
- {
- t1=RmtRec>>24; //得到地址碼
- t2=(RmtRec>>16)&0xff; //得到地址反碼
- if((t1==(u8)~t2)&&t1==REMOTE_ID)//檢驗遙控識別碼(ID)及地址
- {
- t1=RmtRec>>8;
- t2=RmtRec;
- if(t1==(u8)~t2)sta=t1;//鍵值正確
- }
- if((sta==0)||((RmtSta&0X80)==0))//按鍵數(shù)據(jù)錯誤/遙控已經(jīng)沒有按下了
- {
- RmtSta&=~(1<<6);//清除接收到有效按鍵標(biāo)識
- RmtCnt=0; //清除按鍵次數(shù)計數(shù)器
- }
- RmtSta&=~(1<<6);//清除接收到有效按鍵標(biāo)識
- }
-
- return sta;
- }
復(fù)制代碼
所有資料51hei提供下載:
基礎(chǔ)功能_RTC-修改-定時器.rar
(336.2 KB, 下載次數(shù): 22)
2018-11-20 16:17 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|