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);
- }
- }
- }
复制代码
|