找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7083|回復(fù): 7
打印 上一主題 下一主題
收起左側(cè)

基于STM32單片機(jī)電子時(shí)鐘程序,1602顯示,時(shí)間可調(diào)

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:190577 發(fā)表于 2019-10-14 19:27 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
1、本系統(tǒng)采用1602顯示時(shí)分秒,4個(gè)按鍵可以調(diào)整時(shí)間,一個(gè)按鍵是選擇按鍵,一個(gè)按鍵是加,一個(gè)按鍵是減,一個(gè)按鍵是退出按鍵。
2、當(dāng)選擇按鍵按下的時(shí)候,該選擇位閃爍。
主函數(shù)代碼:
  1. #include "delay.h"
  2. #include "sys.h"
  3. #include "1602.h"
  4. #include "timer.h"
  5. #include "key.h"
  6. u8  table1[]="liyang          " ;
  7. u8  table2[]="9876543210654321" ;
  8. signed char  miao,fen,shi;
  9. u8 flag_100ms=0;
  10. u16 count_ms=0;
  11. u8 S1num;
  12. /*******************主函數(shù)************************/
  13. int main(void)
  14. {
  15.     //u8 t;
  16.   delay_init();//延時(shí)函數(shù)初始化
  17.   LCD1602_Init();//LCD1602初始化函數(shù)
  18.   TIM3_Int_Init(999,71);//1MS
  19.    TIM4_Int_Init(999,71);//1MS
  20.   KEY_Init(); //按鍵初始化
  21.    #[color=#0066cc]IF[/color] 0   //注釋掉程序
  22.     LCD_Write_Command(0x80);//第一行的首地址
  23.        for(i=0;i<16;i++)
  24.      {
  25.          LCD_Write_Date(table1[i]);
  26.         delay_ms(3);
  27.     }
  28.      LCD_Write_Command(0xc0);//第二行的首地址
  29.      for(i=0;i<16;i++)
  30.       {
  31.         LCD_Write_Date(table2[i]);
  32.       delay_ms(3);
  33.       }
  34.    #endif
  35.     while(1)
  36.     {
  37.   
  38.       display(shi,fen,miao);
  39.    keyscan();
  40.   }
  41.   

  42. }
  43. 定時(shí)器代碼
  44. void TIM3_Int_Init(u16 arr,u16 psc)
  45. {
  46.   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  47. NVIC_InitTypeDef NVIC_InitStructure;
  48. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //[color=#0066cc]時(shí)鐘[/color]使能

  49. //定時(shí)器TIM3初始化
  50. TIM_TimeBaseStructure.TIM_Period = arr; //設(shè)置在下一個(gè)更新事件裝入活動(dòng)的自動(dòng)重裝載寄存器周期的值
  51. TIM_TimeBaseStructure.TIM_Prescaler =psc; //設(shè)置用來作為TIMx時(shí)鐘頻率除數(shù)的預(yù)分頻值
  52. TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //設(shè)置時(shí)鐘分割:TDTS = Tck_tim
  53. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上計(jì)數(shù)模式
  54. TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根據(jù)指定的參數(shù)初始化TIMx的時(shí)間基數(shù)單位

  55. TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中斷,允許更新中斷
  56. //中斷優(yōu)先級NVIC設(shè)置
  57. NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中斷
  58. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占優(yōu)先級0級
  59. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;  //從優(yōu)先級3級
  60. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
  61. NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器
  62. TIM_Cmd(TIM3, ENABLE);  //使能TIMx      
  63. }
  64. //3中斷服務(wù)程序
  65. void TIM3_IRQHandler(void)   //TIM3中斷
  66. {
  67. static u16 count=0;
  68. if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //檢查TIM3更新中斷發(fā)生與否
  69.   {
  70.     TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中斷標(biāo)志
  71.      count++;
  72.      count_ms++;
  73.      if(count_ms==500)
  74.     {
  75.       count_ms=0;
  76.        flag_100ms=~flag_100ms;
  77.     }
  78.      if(count==1000)
  79.     {
  80.      count=0;
  81.      miao++;
  82.        if(miao==60)
  83.       {
  84.         miao=0;
  85.          fen++;
  86.          if(fen==60)
  87.         {
  88.           fen=0;
  89.            shi++;
  90.            if(shi==24)
  91.            shi=0;
  92.         }
  93.       }
  94.     }
  95.    
  96.   }
  97. }
  98. //通用定時(shí)器4中斷初始化
  99. //這里時(shí)鐘選擇為APB1的2倍,而APB1為36M
  100. //arr:自動(dòng)重裝值。
  101. //psc:時(shí)鐘預(yù)分頻數(shù)
  102. //這里使用的是定時(shí)器3!
  103. void TIM4_Int_Init(u16 arr,u16 psc)
  104. {
  105.   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  106. NVIC_InitTypeDef NVIC_InitStructure;
  107. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //時(shí)鐘使能

  108. //定時(shí)器TIM4初始化
  109. TIM_TimeBaseStructure.TIM_Period = arr; //設(shè)置在下一個(gè)更新事件裝入活動(dòng)的自動(dòng)重裝載寄存器周期的值
  110. TIM_TimeBaseStructure.TIM_Prescaler =psc; //設(shè)置用來作為TIMx時(shí)鐘頻率除數(shù)的預(yù)分頻值
  111. TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //設(shè)置時(shí)鐘分割:TDTS = Tck_tim
  112. TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上計(jì)數(shù)模式
  113. TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根據(jù)指定的參數(shù)初始化TIMx的時(shí)間基數(shù)單位

  114. TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); //使能指定的TIM4中斷,允許更新中斷
  115. //中斷優(yōu)先級NVIC設(shè)置
  116. NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;  //TIM4中斷
  117. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;  //先占優(yōu)先級0級
  118. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4;  //從優(yōu)先級3級
  119. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
  120. NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器
  121. TIM_Cmd(TIM4, ENABLE);  //使能TIMx      
  122. }
  123. //定時(shí)器4中斷服務(wù)程序
  124. void TIM4_IRQHandler(void)   //TIM3中斷
  125. {
  126. if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)  //檢查TIM3更新中斷發(fā)生與否
  127.   {
  128.     TIM_ClearITPendingBit(TIM4, TIM_IT_Update  );  //清除TIMx更新中斷標(biāo)志
  129.      count_ms++;
  130.      if(count_ms==500)
  131.     {
  132.       count_ms=0;
  133.        flag_100ms=~flag_100ms;
  134.     }
  135.   }
  136. }
  137. 1602代碼
  138. #include"1602.h"
  139. #include"sys.h"
  140. #include "delay.h"
  141. extern u8 S1num;
  142. extern u8 flag_100ms;
  143. /*******************LCD1602初始化************************/
  144. void LCD1602_Init(void)
  145. {      
  146.      GPIO_InitTypeDef  GPIO_InitStructure;
  147.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOA, ENABLE);  //使能PA,PC端口時(shí)鐘
  148.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;     //LCD1602的三根控制線rs,rw,en
  149.      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度為50MHz
  150.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出
  151.      GPIO_Init(GPIOE, &GPIO_InitStructure);//根據(jù)設(shè)定參數(shù)初始化GPIOE      
  152.    
  153.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;//LCD1602的8跟數(shù)據(jù)線        //[color=#0066cc]LED[/color]1-->PE.5 端口配置, 推挽輸出
  154.      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽輸出
  155.      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO口速度為50MHz
  156.      GPIO_Init(GPIOA, &GPIO_InitStructure);//根據(jù)設(shè)定參數(shù)初始化GPIOE
  157.     LCD_Write_Command(0x01);//清除屏幕顯示
  158.     delay_ms(2);

  159.     LCD_Write_Command(0x38);//設(shè)置LCD兩行顯示,一個(gè)數(shù)據(jù)由5*7點(diǎn)陣表示,數(shù)據(jù)由8跟線傳輸
  160.      delay_ms(2);
  161.   
  162.     LCD_Write_Command(0x06);//設(shè)定輸入方式,增量不移位
  163.     delay_ms(2);
  164.     LCD_Write_Command(0x0c);//開整體顯示,關(guān)光標(biāo),不閃爍
  165.     delay_ms(2);
  166. }
  167. /*******************寫指令函數(shù)************************/
  168. void LCD_Write_Command(u8 com)      
  169. {
  170.   GPIO_Write(GPIOA, 0X00FF&com);//該函數(shù)一般用來往一次性一個(gè)GPIO的多個(gè)端口設(shè)置
  171. rs=0; //寫指令函數(shù)和寫數(shù)據(jù)函數(shù)其實(shí)可以并一起價(jià)格 BOOL變量判斷是寫指令就rs=0寫數(shù)據(jù)就rs=1。
  172. rw=0;
  173. en=0;  //寫指令     輸入:RS=L,RW=L,E=下降沿脈沖
  174.   delay_ms(2);
  175.   en=1;
  176. delay_ms(2);
  177.   en=0;
  178. }
  179. /*******************寫數(shù)據(jù)函數(shù)************************/
  180. void LCD_Write_Date(u8 date)         
  181. {  
  182.   GPIO_Write(GPIOA,0X00FF&date);//GPIOA的第八位用來作為8位數(shù)據(jù)口
  183. rs=1;
  184. rw=0;
  185. en=0;  //寫指令     輸入:RS=L,RW=L,E=下降沿脈沖
  186.   delay_ms(2);
  187.   en=1;
  188. delay_ms(2);
  189.   en=0;
  190. }
  191. /******************************************************************************
  192. 函數(shù)名稱:LCD1602_MoveToPosition
  193. 函數(shù)功能:將液晶的光標(biāo)移動(dòng)到指定的位置
  194. 入口參數(shù):x-液晶顯示的行數(shù),范圍0-1
  195.    x = 0:在液晶的第一行
  196.    x = 1:在液晶的第二行
  197.     y-液晶顯示的列數(shù),范圍0-15
  198.       y = 0:在液晶的第一列
  199.    y = 1:在液晶的第二列
  200.    ......
  201.    y = 15:在液晶的第十六列
  202. 返回值:無
  203. 備注:通過指定x,y的值可以將液晶的光標(biāo)移動(dòng)到指定的位置
  204. *******************************************************************************/
  205. void LCD1602_MoveToPosition(u8 x,u8 y)
  206. {
  207. if(0 == x)
  208.   LCD_Write_Command(0x80 | y);    //光標(biāo)定位到第一行的y列
  209. if(1 == x)
  210.   LCD_Write_Command(0xC0 | y);    //光標(biāo)定義到第二行的y列
  211. }
  212. /******************************************************************************
  213. 函數(shù)名稱:LCD1602_DisplayOneCharOnAddr
  214. 函數(shù)功能:在指定的位置上顯示指定的字符
  215. 入口參數(shù):x-液晶顯示的行數(shù),范圍0-1
  216.    x = 0:在液晶的第一行
  217.    x = 1:在液晶的第二行
  218.     y-液晶顯示的列數(shù),范圍0-15
  219.       y = 0:在液晶的第一列
  220.    y = 1:在液晶的第二列
  221.    ......
  222.    y = 15:在液晶的第十六列
  223.     ucData-要顯示的字符數(shù)據(jù)
  224. 返回值:無
  225. 備注:確保x,y的取值要在指定的范圍內(nèi)
  226. *******************************************************************************/
  227. void LCD1602_DisplayOneCharOnAddr(u8 x,u8 y,u8 ucData)
  228. {
  229. LCD1602_MoveToPosition(x,y);   //光標(biāo)位置
  230.   LCD_Write_Date(ucData);   //寫入數(shù)據(jù)
  231. }
  232. /******************************************************************************
  233. 函數(shù)名稱:LCD1602_DisplayString
  234. 函數(shù)功能:顯示字符串
  235. 入口參數(shù):ucStr-字符串的首地址
  236. 返回值:無
  237. 備注:無
  238. *******************************************************************************/
  239. void LCD1602_DisplayString(u8 *ucStr)
  240. {
  241. while(*ucStr != '\0')    //字符串結(jié)束之前,循環(huán)顯示
  242. {
  243.    LCD_Write_Date(*ucStr);  //依次寫入每一個(gè)字符
  244.    ucStr++;         //指針增加
  245. }
  246. }
  247. /*****************控制光標(biāo)函數(shù)********************/
  248. void write_guanbiao(u8 hang,u8 add,u8 date)
  249. {  
  250. if(hang==1)   
  251.   LCD_Write_Command(0x80+add);
  252. else
  253.   LCD_Write_Command(0x80+0x40+add);
  254. if(date == 1)
  255.   LCD_Write_Command(0x0f);     //顯示光標(biāo)并且閃爍
  256. else
  257.   LCD_Write_Command(0x0c);   //關(guān)閉光標(biāo)
  258. }
  259. void display(u8 aa,u8 bb,u8 cc)
  260. {
  261.    if(S1num!=3)
  262.   {
  263.    LCD1602_DisplayOneCharOnAddr(1,0,aa/10+0x30);
  264.    LCD1602_DisplayOneCharOnAddr(1,1,aa%10+0x30);
  265.   }
  266.   else
  267.   {
  268.    if(flag_100ms==0)
  269.    {
  270.     LCD1602_DisplayOneCharOnAddr(1,0,' ');
  271.     LCD1602_DisplayOneCharOnAddr(1,1,' ');
  272.   
  273.    
  274.    }
  275.    else
  276.    {
  277.       LCD1602_DisplayOneCharOnAddr(1,0,aa/10+0x30);
  278.       LCD1602_DisplayOneCharOnAddr(1,1,aa%10+0x30);
  279.    }
  280.   }
  281.     LCD1602_DisplayOneCharOnAddr(1,2,':');
  282.   if(S1num!=2)
  283.   {
  284.    LCD1602_DisplayOneCharOnAddr(1,3,bb/10+0x30);
  285.    LCD1602_DisplayOneCharOnAddr(1,4,bb%10+0x30);
  286.   }
  287.   else
  288.   {
  289.    if(flag_100ms==0)
  290.    {
  291.     LCD1602_DisplayOneCharOnAddr(1,3,' ');
  292.     LCD1602_DisplayOneCharOnAddr(1,4,' ');
  293.   
  294.    
  295.    }
  296.    else
  297.    {
  298.       LCD1602_DisplayOneCharOnAddr(1,3,bb/10+0x30);
  299.       LCD1602_DisplayOneCharOnAddr(1,4,bb%10+0x30);
  300.    }
  301.   }
  302.    LCD1602_DisplayOneCharOnAddr(1,5,':');
  303.   if(S1num!=1)
  304.   {
  305.    LCD1602_DisplayOneCharOnAddr(1,6,cc/10+0x30);
  306.    LCD1602_DisplayOneCharOnAddr(1,7,cc%10+0x30);
  307.   }
  308.   else
  309.   {
  310.    if(flag_100ms==0)
  311.    {
  312.     LCD1602_DisplayOneCharOnAddr(1,6,' ');
  313.     LCD1602_DisplayOneCharOnAddr(1,7,' ');
  314.    }
  315.    else
  316.    {
  317.       LCD1602_DisplayOneCharOnAddr(1,6,cc/10+0x30);
  318.       LCD1602_DisplayOneCharOnAddr(1,7,cc%10+0x30);
  319.    }
  320.   }
  321. }
復(fù)制代碼



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏5 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:190577 發(fā)表于 2020-2-27 14:09 | 只看該作者

庫函數(shù)開發(fā)的小結(jié):
我們一般使用ST庫對外設(shè)進(jìn)行初始化,一般有以下布驟:
1)定義一個(gè)XXX_InitTypeDef類型的初始化結(jié)構(gòu)體。
2)根據(jù)自己的需求,向這些初始化結(jié)構(gòu)體的成員寫入特定的控制參數(shù)。
3)填充好結(jié)構(gòu)體之后,把這個(gè)結(jié)構(gòu)體作為輸入?yún)?shù)調(diào)用相應(yīng)的外設(shè)庫函數(shù)XXX _Init();從而實(shí)現(xiàn)向寄存器寫入控制參數(shù),并配置好外設(shè)。
回復(fù)

使用道具 舉報(bào)

板凳
ID:669679 發(fā)表于 2020-5-15 11:45 | 只看該作者
樓主  請問有電路圖嗎?
回復(fù)

使用道具 舉報(bào)

地板
ID:890487 發(fā)表于 2021-3-13 10:43 | 只看該作者
有工程文件嗎 UP主
回復(fù)

使用道具 舉報(bào)

5#
ID:190577 發(fā)表于 2022-7-31 20:13 | 只看該作者
kidxpp 發(fā)表于 2021-3-13 10:43
有工程文件嗎 UP主

有的
回復(fù)

使用道具 舉報(bào)

6#
ID:1081448 發(fā)表于 2023-12-2 20:20 | 只看該作者
可以發(fā)一下工程文件嗎樓主
回復(fù)

使用道具 舉報(bào)

7#
ID:1120527 發(fā)表于 2024-5-13 15:31 | 只看該作者
能分享一下文件嗎樓主
回復(fù)

使用道具 舉報(bào)

8#
ID:159495 發(fā)表于 2024-5-17 23:43 來自手機(jī) | 只看該作者
謝謝樓主分享的資料
回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

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

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

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