找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 7672|回復(fù): 21
收起左側(cè)

STM32單片機(jī)程序:溫度、萬(wàn)年歷、PWM、輸入捕捉高電平、ADC、DAC、EEPROM、IIC

  [復(fù)制鏈接]
ID:283012 發(fā)表于 2018-8-29 09:47 | 顯示全部樓層 |閱讀模式
STM32單片機(jī)程序:溫度、萬(wàn)年歷、PWM、輸入捕捉高電平、ADC、DAC、EEPROM、IIC

0.png

單片機(jī)源程序如下:
  1. #include "SysTick.h"
  2. #include "public.h"
  3.                     

  4.           
  5. _calendar calendar;//時(shí)鐘結(jié)構(gòu)體

  6. static void RTC_NVIC_Config(void)
  7. {       
  8.         NVIC_InitTypeDef NVIC_InitStructure;
  9.         NVIC_InitStructure.NVIC_IRQChannel = RTC_IRQn;                //RTC全局中斷
  10.         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;        //先占優(yōu)先級(jí)1位,從優(yōu)先級(jí)3位
  11.         NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        //先占優(yōu)先級(jí)0位,從優(yōu)先級(jí)4位
  12.         NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                //使能該通道中斷
  13.         NVIC_Init(&NVIC_InitStructure);                //根據(jù)NVIC_InitStruct中指定的參數(shù)初始化外設(shè)NVIC寄存器
  14. }


  15. /*******************************************************************************
  16. * 函 數(shù) 名         : RTC_Init
  17. * 函數(shù)功能                   : RTC初始化
  18. * 輸    入         : 無(wú)
  19. * 輸    出         : 0,初始化成功
  20.                                  1,LSE開(kāi)啟失敗
  21. *******************************************************************************/
  22. u8 RTC_Init(void)
  23. {
  24.         //檢查是不是第一次配置時(shí)鐘
  25.         u8 temp=0;
  26.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);        //使能PWR和BKP外設(shè)時(shí)鐘   
  27.         PWR_BackupAccessCmd(ENABLE);        //使能后備寄存器訪(fǎng)問(wèn)  
  28.         if (BKP_ReadBackupRegister(BKP_DR1) != 0xA0A0)                //從指定的后備寄存器中讀出數(shù)據(jù):讀出了與寫(xiě)入的指定數(shù)據(jù)不相乎
  29.         {                        
  30.                 //????RTC
  31.                 //RTC_Configuration();                
  32.                 BKP_DeInit();        //復(fù)位備份區(qū)域        
  33.                 RCC_LSEConfig(RCC_LSE_ON);        //設(shè)置外部低速晶振(LSE),使用外設(shè)低速晶振
  34.                 while (RCC_GetFlagStatus(RCC_FLAG_LSERDY) == RESET&&temp<250)        //檢查指定的RCC標(biāo)志位設(shè)置與否,等待低速晶振就緒
  35.                 {
  36.                         temp++;
  37.                         delay_ms(10);
  38.                 }
  39.                 if(temp>=250)return 1;//初始化時(shí)鐘失敗,晶振有問(wèn)題            
  40.                 RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);                //設(shè)置RTC時(shí)鐘(RTCCLK),選擇LSE作為RTC時(shí)鐘   
  41.                 RCC_RTCCLKCmd(ENABLE);        //使能RTC時(shí)鐘  
  42.                 RTC_WaitForLastTask();        //等待最近一次對(duì)RTC寄存器的寫(xiě)操作完成
  43.                 RTC_WaitForSynchro();                //等待RTC寄存器同步  
  44.                 RTC_ITConfig(RTC_IT_SEC, ENABLE);                //使能RTC秒中斷
  45.                 RTC_WaitForLastTask();        //等待最近一次對(duì)RTC寄存器的寫(xiě)操作完成
  46.                 RTC_EnterConfigMode();// 允許配置       
  47.                 RTC_SetPrescaler(32767); //設(shè)置RTC預(yù)分頻的值
  48.                 RTC_WaitForLastTask();        //等待最近一次對(duì)RTC寄存器的寫(xiě)操作完成
  49.                 RTC_Set(2018,8,20,14,39,55);  //設(shè)置時(shí)間       
  50.                 RTC_ExitConfigMode(); //退出配置模式  
  51.                 BKP_WriteBackupRegister(BKP_DR1, 0XA0A0);        //向指定的后備寄存器中寫(xiě)入用戶(hù)程序數(shù)據(jù)
  52.         }
  53.         else//系統(tǒng)繼續(xù)計(jì)時(shí)
  54.         {
  55.                 RTC_WaitForSynchro();        //等待最近一次對(duì)RTC寄存器的寫(xiě)操作完成
  56.                 RTC_ITConfig(RTC_IT_SEC, ENABLE);        //使能RTC秒中斷
  57.                 RTC_WaitForLastTask();        //等待最近一次對(duì)RTC寄存器的寫(xiě)操作完成
  58.         }
  59.         RTC_NVIC_Config();//RCT中斷分組設(shè)置                                                         
  60.         RTC_Get();//更新時(shí)間       
  61.         return 0; //ok

  62. }                                                     
  63. //RTC時(shí)鐘中斷
  64. //每秒觸發(fā)一次  
  65. //extern u16 tcnt;
  66. int jishu;
  67. void RTC_IRQHandler(void)
  68. {                 
  69.         if (RTC_GetITStatus(RTC_IT_SEC) != RESET)//秒鐘中斷
  70.         {                                                       
  71.                 RTC_Get();//更新時(shí)間  
  72.                 printf("RTC Time:%d-%d-%d %d:%d:%d\n",calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);//輸出鬧鈴時(shí)間       
  73.                 LCD_ShowFontHZ(82,270,"日期");
  74.                 LCD_ShowxNum(0,300,calendar.w_year,2,24,0);               
  75.                 LCD_ShowString(24,300,tftlcd_data.width,tftlcd_data.height,24,"-");
  76.                 LCD_ShowxNum(36,300,calendar.w_month,2,24,0);       
  77.                 LCD_ShowString(60,300,tftlcd_data.width,tftlcd_data.height,24,"-");
  78.                 LCD_ShowxNum(72,300,calendar.w_date,2,24,0);       
  79.                 //小時(shí)
  80.                 LCD_ShowxNum(146,300,calendar.hour,2,24,0);       
  81.                 LCD_ShowString(170,300,tftlcd_data.width,tftlcd_data.height,24,":");
  82.                 LCD_ShowxNum(182,300,calendar.min,2,24,0);       
  83.                 LCD_ShowString(206,300,tftlcd_data.width,tftlcd_data.height,24,":");
  84.                 LCD_ShowxNum(218,300,calendar.sec,2,24,0);       
  85.                 //星期
  86.                 LCD_ShowFontHZ(70,340,"星期");
  87.                 LCD_ShowNum(135,343,calendar.week,2,24);       
  88.                
  89.                 //原定時(shí)器1s計(jì)數(shù)
  90.                 jishu++;
  91.                 LCD_ShowxNum(110,120,jishu,5,24,0);
  92.                 LCD_ShowString(50,120,tftlcd_data.width,tftlcd_data.height,24,"time:");
  93.                 LCD_ShowString(180,120,tftlcd_data.width,tftlcd_data.height,24,"s");
  94.                
  95.                
  96.         }
  97.         if(RTC_GetITStatus(RTC_IT_ALR)!= RESET)//鬧鐘中斷
  98.         {
  99.                 RTC_ClearITPendingBit(RTC_IT_ALR);                //清鬧鐘中斷                 
  100.                 RTC_Get();                                //更新時(shí)間   
  101.                 printf("Alarm Time:%d-%d-%d %d:%d:%d\n",calendar.w_year,calendar.w_month,calendar.w_date,calendar.hour,calendar.min,calendar.sec);//輸出鬧鈴時(shí)間       
  102.                
  103.           }                
  104.                        
  105.         RTC_ClearITPendingBit(RTC_IT_SEC|RTC_IT_OW);                //清鬧鐘中斷
  106.         RTC_WaitForLastTask();                                                                                           
  107. }
  108. //判斷是否是閏年函數(shù)
  109. //月份   1  2  3  4  5  6  7  8  9  10 11 12
  110. //閏年   31 29 31 30 31 30 31 31 30 31 30 31
  111. //非閏年 31 28 31 30 31 30 31 31 30 31 30 31
  112. //輸入:年份
  113. //輸出:該年份是不是閏年.1,是.0,不是
  114. u8 Is_Leap_Year(u16 year)
  115. {                          
  116.         if(year%4==0) //必須能被4整除
  117.         {
  118.                 if(year%100==0)
  119.                 {
  120.                         if(year%400==0)return 1;//如果以00結(jié)尾,還要能被400整除           
  121.                         else return 0;   
  122.                 }else return 1;   
  123.         }else return 0;       
  124. }                                   


  125. //月份數(shù)據(jù)表                                                                                         
  126. u8 const table_week[12]={0,3,3,6,1,4,6,2,5,0,3,5}; //月修正數(shù)據(jù)表          
  127. //平年的月份日期表
  128. const u8 mon_table[12]={31,28,31,30,31,30,31,31,30,31,30,31};

  129. /*******************************************************************************
  130. * 函 數(shù) 名         : RTC_Set
  131. * 函數(shù)功能                   : RTC設(shè)置日期時(shí)間函數(shù)(以1970年1月1日為基準(zhǔn),把輸入的時(shí)鐘轉(zhuǎn)換為秒鐘)
  132.                                                 1970~2099年為合法年份
  133. * 輸    入         : syear:年  smon:月  sday:日
  134.                                         hour:時(shí)   min:分         sec:秒                       
  135. * 輸    出         : 0,成功
  136.                                  1,失敗
  137. *******************************************************************************/
  138. u8 RTC_Set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec)
  139. {
  140.         u16 t;
  141.         u32 seccount=0;
  142.         if(syear<1970||syear>2099)return 1;          
  143.         for(t=1970;t<syear;t++)        //把所有年份的秒鐘相加
  144.         {
  145.                 if(Is_Leap_Year(t)) seccount+=31622400;//閏年的秒鐘數(shù)
  146.                 else seccount+=31536000;                          //平年的秒鐘數(shù)
  147.         }
  148.         smon-=1;
  149.         for(t=0;t<smon;t++)           //把前面月份的秒鐘數(shù)相加
  150.         {
  151.                 seccount+=(u32)mon_table[t]*86400;//月份秒鐘數(shù)相加
  152.                 if(Is_Leap_Year(syear)&&t==1)seccount+=86400;//閏年2月份增加一天的秒鐘數(shù)          
  153.         }
  154.         seccount+=(u32)(sday-1)*86400;//把前面日期的秒鐘數(shù)相加
  155.         seccount+=(u32)hour*3600;//小時(shí)秒鐘數(shù)
  156.     seccount+=(u32)min*60;         //分鐘秒鐘數(shù)
  157.         seccount+=sec;//最后的秒鐘加上去

  158.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);        //使能PWR和BKP外設(shè)時(shí)鐘  
  159.         PWR_BackupAccessCmd(ENABLE);        //使能RTC和后備寄存器訪(fǎng)問(wèn)
  160.         RTC_SetCounter(seccount);        //設(shè)置RTC計(jì)數(shù)器的值

  161.         RTC_WaitForLastTask();        //等待最近一次對(duì)RTC寄存器的寫(xiě)操作完成         
  162.         return 0;            
  163. }

  164. //初始化鬧鐘                  
  165. //以1970年1月1日為基準(zhǔn)
  166. //1970~2099年為合法年份
  167. //syear,smon,sday,hour,min,sec:鬧鐘的年月日時(shí)分秒   
  168. //返回值:0,成功;其他:錯(cuò)誤代碼.
  169. u8 RTC_Alarm_Set(u16 syear,u8 smon,u8 sday,u8 hour,u8 min,u8 sec)
  170. {
  171.         u16 t;
  172.         u32 seccount=0;
  173.         if(syear<1970||syear>2099)return 1;          
  174.         for(t=1970;t<syear;t++)        //把所有年份的秒鐘相加
  175.         {
  176.                 if(Is_Leap_Year(t))seccount+=31622400;//閏年的秒鐘數(shù)
  177.                 else seccount+=31536000;                          //平年的秒鐘數(shù)
  178.         }
  179.         smon-=1;
  180.         for(t=0;t<smon;t++)           //把前面月份的秒鐘數(shù)相加
  181.         {
  182.                 seccount+=(u32)mon_table[t]*86400;//月份秒鐘數(shù)相加
  183.                 if(Is_Leap_Year(syear)&&t==1)seccount+=86400;//閏年2月份增加一天的秒鐘數(shù)          
  184.         }
  185.         seccount+=(u32)(sday-1)*86400;//把前面日期的秒鐘數(shù)相加
  186.         seccount+=(u32)hour*3600;//小時(shí)秒鐘數(shù)
  187.     seccount+=(u32)min*60;         //分鐘秒鐘數(shù)
  188.         seccount+=sec;//最后的秒鐘加上去                             
  189.         //設(shè)置時(shí)鐘
  190.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR | RCC_APB1Periph_BKP, ENABLE);        //使能PWR和BKP外設(shè)時(shí)鐘   
  191.         PWR_BackupAccessCmd(ENABLE);        //使能后備寄存器訪(fǎng)問(wèn)  
  192.         //上面三步是必須的!
  193.        
  194.         RTC_SetAlarm(seccount);

  195.         RTC_WaitForLastTask();        //等待最近一次對(duì)RTC寄存器的寫(xiě)操作完成         
  196.        
  197.         return 0;            
  198. }


  199. //得到當(dāng)前的時(shí)間
  200. //返回值:0,成功;其他:錯(cuò)誤代碼.
  201. u8 RTC_Get(void)
  202. {
  203.         static u16 daycnt=0;
  204.         u32 timecount=0;
  205.         u32 temp=0;
  206.         u16 temp1=0;          
  207.     timecount=RTC_GetCounter();         //得到計(jì)數(shù)器中的秒鐘值
  208.         temp=timecount/86400;   //得到天數(shù)(秒鐘數(shù)對(duì)應(yīng)的)一天86400s
  209.         if(daycnt!=temp)//超過(guò)一天了
  210.         {          
  211.                 daycnt=temp;
  212.                 temp1=1970;        //從1970年開(kāi)始
  213.                 while(temp>=365)
  214.                 {                                 
  215.                         if(Is_Leap_Year(temp1))//是閏年
  216.                         {
  217.                                 if(temp>=366)temp-=366;//閏年的秒鐘數(shù)
  218.                                 else {temp1++;break;}  
  219.                         }
  220.                         else temp-=365;          //平年
  221.                         temp1++;  
  222.                 }   
  223.                 calendar.w_year=temp1;//得到年份
  224.                 temp1=0;
  225.                 while(temp>=28)//超過(guò)了一個(gè)月
  226.                 {
  227.                         if(Is_Leap_Year(calendar.w_year)&&temp1==1)//當(dāng)年是不是閏年/2月份
  228.                         {
  229.                                 if(temp>=29)temp-=29;//閏年的秒鐘數(shù)
  230.                                 else break;
  231.                         }
  232.                         else
  233.                         {
  234.                                 if(temp>=mon_table[temp1])temp-=mon_table[temp1];//平年
  235.                                 else break;
  236.                         }
  237.                         temp1++;  
  238.                 }
  239. ……………………

  240. …………限于本文篇幅 余下代碼請(qǐng)從51黑下載附件…………
復(fù)制代碼

所有資料51hei提供下載:
8.20 DAC+ADC+定時(shí)器+溫度+日期+輸入捕捉+數(shù)碼管+按鍵+TFT屏+蜂鳴器.rar (2.31 MB, 下載次數(shù): 291)


評(píng)分

參與人數(shù) 1黑幣 +30 收起 理由
gvin + 30 絕世好帖!

查看全部評(píng)分

回復(fù)

使用道具 舉報(bào)

ID:1 發(fā)表于 2018-8-29 17:10 | 顯示全部樓層
補(bǔ)全原理圖或者詳細(xì)說(shuō)明一下電路連接即可獲得100+黑幣
回復(fù)

使用道具 舉報(bào)

ID:267330 發(fā)表于 2018-9-14 09:03 | 顯示全部樓層
學(xué)習(xí)學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

ID:393539 發(fā)表于 2018-9-14 14:21 | 顯示全部樓層
mark  學(xué)習(xí)
回復(fù)

使用道具 舉報(bào)

ID:306028 發(fā)表于 2018-9-14 17:37 | 顯示全部樓層
nice, 學(xué)習(xí)一波
回復(fù)

使用道具 舉報(bào)

ID:183432 發(fā)表于 2018-9-20 15:37 | 顯示全部樓層
不錯(cuò)不錯(cuò)
回復(fù)

使用道具 舉報(bào)

ID:33544 發(fā)表于 2018-9-20 16:58 | 顯示全部樓層
不錯(cuò)不錯(cuò)學(xué)習(xí)了
回復(fù)

使用道具 舉報(bào)

ID:425297 發(fā)表于 2019-6-2 15:20 | 顯示全部樓層
膜拜大佬
回復(fù)

使用道具 舉報(bào)

ID:496408 發(fā)表于 2019-6-11 23:38 | 顯示全部樓層
看標(biāo)題覺(jué)得很厲害,下載之后發(fā)現(xiàn)沒(méi)有protues接線(xiàn)也沒(méi)原理圖,確實(shí)不知道怎么拿來(lái)用,期待大佬補(bǔ)上原理圖或者protues接線(xiàn)圖
回復(fù)

使用道具 舉報(bào)

ID:261930 發(fā)表于 2019-6-12 08:03 | 顯示全部樓層
好帖謝謝分享。
回復(fù)

使用道具 舉報(bào)

ID:560549 發(fā)表于 2019-6-12 08:49 | 顯示全部樓層
mark !
回復(fù)

使用道具 舉報(bào)

ID:445069 發(fā)表于 2019-6-21 10:08 | 顯示全部樓層
好全面的參考代碼。在懂得原理的情況下,可以借鑒。
回復(fù)

使用道具 舉報(bào)

ID:392473 發(fā)表于 2019-6-22 12:59 | 顯示全部樓層
感謝樓主,努力學(xué)習(xí)中!
回復(fù)

使用道具 舉報(bào)

ID:473159 發(fā)表于 2019-6-24 07:02 | 顯示全部樓層
沒(méi)實(shí)際意義,網(wǎng)上原子的免費(fèi)例程就是這些東東,這也是樓主提供不了單一電路圖的原因
回復(fù)

使用道具 舉報(bào)

ID:489682 發(fā)表于 2019-6-24 09:22 | 顯示全部樓層
如樓主真想幫助大家就發(fā)完整一些的資料。單片機(jī)開(kāi)發(fā)是軟硬件緊密結(jié)合的,光有軟件不夠
回復(fù)

使用道具 舉報(bào)

ID:384522 發(fā)表于 2019-8-19 18:47 | 顯示全部樓層
內(nèi)容不全?
回復(fù)

使用道具 舉報(bào)

ID:58110 發(fā)表于 2020-6-18 08:04 | 顯示全部樓層
這個(gè)附件凈坑人
點(diǎn)擊下載,彈出下載提示,等待,沒(méi)有下載文件

刷新頁(yè)面,依然沒(méi)有下載
再點(diǎn)下載,再扣黑B,扣了我N次,結(jié)果還沒(méi)有下載下來(lái)
回復(fù)

使用道具 舉報(bào)

ID:310120 發(fā)表于 2020-6-19 14:45 | 顯示全部樓層
感謝分享,學(xué)習(xí)了
回復(fù)

使用道具 舉報(bào)

ID:545054 發(fā)表于 2020-6-19 18:01 | 顯示全部樓層
太棒了,謝謝樓主
回復(fù)

使用道具 舉報(bào)

ID:784555 發(fā)表于 2020-6-19 22:44 | 顯示全部樓層
謝謝分享
回復(fù)

使用道具 舉報(bào)

ID:780228 發(fā)表于 2020-6-20 18:37 | 顯示全部樓層
有沒(méi)有proteus仿真
回復(fù)

使用道具 舉報(bào)

ID:147215 發(fā)表于 2020-6-21 10:38 | 顯示全部樓層
謝謝分享!,,,,
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表