1、本系統采用1602顯示時分秒,4個按鍵可以調整時間,一個按鍵是選擇按鍵,一個按鍵是加,一個按鍵是減,一個按鍵是退出按鍵。
2、當選擇按鍵按下的時候,該選擇位閃爍。
主函數代碼:
- #include "delay.h"
- #include "sys.h"
- #include "1602.h"
- #include "timer.h"
- #include "key.h"
- u8 table1[]="liyang " ;
- u8 table2[]="9876543210654321" ;
- signed char miao,fen,shi;
- u8 flag_100ms=0;
- u16 count_ms=0;
- u8 S1num;
- /*******************主函數************************/
- int main(void)
- {
- //u8 t;
- delay_init();//延時函數初始化
- LCD1602_Init();//LCD1602初始化函數
- TIM3_Int_Init(999,71);//1MS
- TIM4_Int_Init(999,71);//1MS
- KEY_Init(); //按鍵初始化
- #[color=#0066cc]IF[/color] 0 //注釋掉程序
- LCD_Write_Command(0x80);//第一行的首地址
- for(i=0;i<16;i++)
- {
- LCD_Write_Date(table1[i]);
- delay_ms(3);
- }
- LCD_Write_Command(0xc0);//第二行的首地址
- for(i=0;i<16;i++)
- {
- LCD_Write_Date(table2[i]);
- delay_ms(3);
- }
- #endif
- while(1)
- {
-
- display(shi,fen,miao);
- keyscan();
- }
-
- }
- 定時器代碼
- void TIM3_Int_Init(u16 arr,u16 psc)
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //[color=#0066cc]時鐘[/color]使能
- //定時器TIM3初始化
- TIM_TimeBaseStructure.TIM_Period = arr; //設置在下一個更新事件裝入活動的自動重裝載寄存器周期的值
- TIM_TimeBaseStructure.TIM_Prescaler =psc; //設置用來作為TIMx時鐘頻率除數的預分頻值
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //設置時鐘分割:TDTS = Tck_tim
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數模式
- TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根據指定的參數初始化TIMx的時間基數單位
- TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中斷,允許更新中斷
- //中斷優先級NVIC設置
- NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn; //TIM3中斷
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占優先級0級
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //從優先級3級
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
- NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
- TIM_Cmd(TIM3, ENABLE); //使能TIMx
- }
- //3中斷服務程序
- void TIM3_IRQHandler(void) //TIM3中斷
- {
- static u16 count=0;
- if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //檢查TIM3更新中斷發生與否
- {
- TIM_ClearITPendingBit(TIM3, TIM_IT_Update ); //清除TIMx更新中斷標志
- count++;
- count_ms++;
- if(count_ms==500)
- {
- count_ms=0;
- flag_100ms=~flag_100ms;
- }
- if(count==1000)
- {
- count=0;
- miao++;
- if(miao==60)
- {
- miao=0;
- fen++;
- if(fen==60)
- {
- fen=0;
- shi++;
- if(shi==24)
- shi=0;
- }
- }
- }
-
- }
- }
- //通用定時器4中斷初始化
- //這里時鐘選擇為APB1的2倍,而APB1為36M
- //arr:自動重裝值。
- //psc:時鐘預分頻數
- //這里使用的是定時器3!
- void TIM4_Int_Init(u16 arr,u16 psc)
- {
- TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE); //時鐘使能
- //定時器TIM4初始化
- TIM_TimeBaseStructure.TIM_Period = arr; //設置在下一個更新事件裝入活動的自動重裝載寄存器周期的值
- TIM_TimeBaseStructure.TIM_Prescaler =psc; //設置用來作為TIMx時鐘頻率除數的預分頻值
- TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //設置時鐘分割:TDTS = Tck_tim
- TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIM向上計數模式
- TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); //根據指定的參數初始化TIMx的時間基數單位
- TIM_ITConfig(TIM4,TIM_IT_Update,ENABLE ); //使能指定的TIM4中斷,允許更新中斷
- //中斷優先級NVIC設置
- NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn; //TIM4中斷
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //先占優先級0級
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 4; //從優先級3級
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
- NVIC_Init(&NVIC_InitStructure); //初始化NVIC寄存器
- TIM_Cmd(TIM4, ENABLE); //使能TIMx
- }
- //定時器4中斷服務程序
- void TIM4_IRQHandler(void) //TIM3中斷
- {
- if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) //檢查TIM3更新中斷發生與否
- {
- TIM_ClearITPendingBit(TIM4, TIM_IT_Update ); //清除TIMx更新中斷標志
- count_ms++;
- if(count_ms==500)
- {
- count_ms=0;
- flag_100ms=~flag_100ms;
- }
- }
- }
- 1602代碼
- #include"1602.h"
- #include"sys.h"
- #include "delay.h"
- extern u8 S1num;
- extern u8 flag_100ms;
- /*******************LCD1602初始化************************/
- void LCD1602_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOA, ENABLE); //使能PA,PC端口時鐘
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10; //LCD1602的三根控制線rs,rw,en
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //IO口速度為50MHz
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽輸出
- GPIO_Init(GPIOE, &GPIO_InitStructure);//根據設定參數初始化GPIOE
-
- 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跟數據線 //[color=#0066cc]LED[/color]1-->PE.5 端口配置, 推挽輸出
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽輸出
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//IO口速度為50MHz
- GPIO_Init(GPIOA, &GPIO_InitStructure);//根據設定參數初始化GPIOE
- LCD_Write_Command(0x01);//清除屏幕顯示
- delay_ms(2);
- LCD_Write_Command(0x38);//設置LCD兩行顯示,一個數據由5*7點陣表示,數據由8跟線傳輸
- delay_ms(2);
-
- LCD_Write_Command(0x06);//設定輸入方式,增量不移位
- delay_ms(2);
- LCD_Write_Command(0x0c);//開整體顯示,關光標,不閃爍
- delay_ms(2);
- }
- /*******************寫指令函數************************/
- void LCD_Write_Command(u8 com)
- {
- GPIO_Write(GPIOA, 0X00FF&com);//該函數一般用來往一次性一個GPIO的多個端口設置
- rs=0; //寫指令函數和寫數據函數其實可以并一起價格 BOOL變量判斷是寫指令就rs=0寫數據就rs=1。
- rw=0;
- en=0; //寫指令 輸入:RS=L,RW=L,E=下降沿脈沖
- delay_ms(2);
- en=1;
- delay_ms(2);
- en=0;
- }
- /*******************寫數據函數************************/
- void LCD_Write_Date(u8 date)
- {
- GPIO_Write(GPIOA,0X00FF&date);//GPIOA的第八位用來作為8位數據口
- rs=1;
- rw=0;
- en=0; //寫指令 輸入:RS=L,RW=L,E=下降沿脈沖
- delay_ms(2);
- en=1;
- delay_ms(2);
- en=0;
- }
- /******************************************************************************
- 函數名稱:LCD1602_MoveToPosition
- 函數功能:將液晶的光標移動到指定的位置
- 入口參數:x-液晶顯示的行數,范圍0-1
- x = 0:在液晶的第一行
- x = 1:在液晶的第二行
- y-液晶顯示的列數,范圍0-15
- y = 0:在液晶的第一列
- y = 1:在液晶的第二列
- ......
- y = 15:在液晶的第十六列
- 返回值:無
- 備注:通過指定x,y的值可以將液晶的光標移動到指定的位置
- *******************************************************************************/
- void LCD1602_MoveToPosition(u8 x,u8 y)
- {
- if(0 == x)
- LCD_Write_Command(0x80 | y); //光標定位到第一行的y列
- if(1 == x)
- LCD_Write_Command(0xC0 | y); //光標定義到第二行的y列
- }
- /******************************************************************************
- 函數名稱:LCD1602_DisplayOneCharOnAddr
- 函數功能:在指定的位置上顯示指定的字符
- 入口參數:x-液晶顯示的行數,范圍0-1
- x = 0:在液晶的第一行
- x = 1:在液晶的第二行
- y-液晶顯示的列數,范圍0-15
- y = 0:在液晶的第一列
- y = 1:在液晶的第二列
- ......
- y = 15:在液晶的第十六列
- ucData-要顯示的字符數據
- 返回值:無
- 備注:確保x,y的取值要在指定的范圍內
- *******************************************************************************/
- void LCD1602_DisplayOneCharOnAddr(u8 x,u8 y,u8 ucData)
- {
- LCD1602_MoveToPosition(x,y); //光標位置
- LCD_Write_Date(ucData); //寫入數據
- }
- /******************************************************************************
- 函數名稱:LCD1602_DisplayString
- 函數功能:顯示字符串
- 入口參數:ucStr-字符串的首地址
- 返回值:無
- 備注:無
- *******************************************************************************/
- void LCD1602_DisplayString(u8 *ucStr)
- {
- while(*ucStr != '\0') //字符串結束之前,循環顯示
- {
- LCD_Write_Date(*ucStr); //依次寫入每一個字符
- ucStr++; //指針增加
- }
- }
- /*****************控制光標函數********************/
- void write_guanbiao(u8 hang,u8 add,u8 date)
- {
- if(hang==1)
- LCD_Write_Command(0x80+add);
- else
- LCD_Write_Command(0x80+0x40+add);
- if(date == 1)
- LCD_Write_Command(0x0f); //顯示光標并且閃爍
- else
- LCD_Write_Command(0x0c); //關閉光標
- }
- void display(u8 aa,u8 bb,u8 cc)
- {
- if(S1num!=3)
- {
- LCD1602_DisplayOneCharOnAddr(1,0,aa/10+0x30);
- LCD1602_DisplayOneCharOnAddr(1,1,aa%10+0x30);
- }
- else
- {
- if(flag_100ms==0)
- {
- LCD1602_DisplayOneCharOnAddr(1,0,' ');
- LCD1602_DisplayOneCharOnAddr(1,1,' ');
-
-
- }
- else
- {
- LCD1602_DisplayOneCharOnAddr(1,0,aa/10+0x30);
- LCD1602_DisplayOneCharOnAddr(1,1,aa%10+0x30);
- }
- }
- LCD1602_DisplayOneCharOnAddr(1,2,':');
- if(S1num!=2)
- {
- LCD1602_DisplayOneCharOnAddr(1,3,bb/10+0x30);
- LCD1602_DisplayOneCharOnAddr(1,4,bb%10+0x30);
- }
- else
- {
- if(flag_100ms==0)
- {
- LCD1602_DisplayOneCharOnAddr(1,3,' ');
- LCD1602_DisplayOneCharOnAddr(1,4,' ');
-
-
- }
- else
- {
- LCD1602_DisplayOneCharOnAddr(1,3,bb/10+0x30);
- LCD1602_DisplayOneCharOnAddr(1,4,bb%10+0x30);
- }
- }
- LCD1602_DisplayOneCharOnAddr(1,5,':');
- if(S1num!=1)
- {
- LCD1602_DisplayOneCharOnAddr(1,6,cc/10+0x30);
- LCD1602_DisplayOneCharOnAddr(1,7,cc%10+0x30);
- }
- else
- {
- if(flag_100ms==0)
- {
- LCD1602_DisplayOneCharOnAddr(1,6,' ');
- LCD1602_DisplayOneCharOnAddr(1,7,' ');
- }
- else
- {
- LCD1602_DisplayOneCharOnAddr(1,6,cc/10+0x30);
- LCD1602_DisplayOneCharOnAddr(1,7,cc%10+0x30);
- }
- }
- }
復制代碼
|