藍橋杯嵌入式第九屆省賽-電子定時器

一、題目
在這裏插入圖片描述
二、代碼
1.初始化函數
tx.c

#include "tx.h"

void LED_Init(void){
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOD, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = 0xff00;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  GPIOD->ODR|=(1<<2);
  GPIOC->ODR|=0xff00;
  GPIOD->ODR&=~(1<<2);
}

void KEY_Init(void){
  GPIO_InitTypeDef GPIO_InitStructure;
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOB, ENABLE);
  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_Init(GPIOB, &GPIO_InitStructure);
}
u8 key_status[4]={1,1,1,1};
u16 key_downtime[4]={0,0,0,0};
void KEY_Driver(void){
  u8 i;
  static u8 backup[4]={1,1,1,1};
  static u16 timethr[4]={1000,1000,1000,1000};
  for(i=0;i<4;i++){
    if( backup[i]!=key_status[i]){
	  if(backup[i]!=0){
	  	Key_action(i+1,0);
	  }
	  backup[i]=key_status[i];
	}
	if(key_downtime[i]>0){
	  if(key_downtime[i]>timethr[i]){
	  	 Key_action(i+1,1);
		 timethr[i]+=200;
	  }
	}
	else 
	  timethr[i]=1000;
  }
}

void KEY_Scan(void){
  u8 i;
  static u8 key_buf[4]={0xff,0xff,0xff,0xff};
  key_buf[0]=(key_buf[0]<<1)|KEY1;
  key_buf[1]=(key_buf[1]<<1)|KEY2;
  key_buf[2]=(key_buf[2]<<1)|KEY3;
  key_buf[3]=(key_buf[3]<<1)|KEY4;
  for(i=0;i<4;i++){
    if(key_buf[i]==0x00){
	  key_status[i]=0;
	  key_downtime[i]+=4;
	}
	else if(key_buf[i]==0xff){
	  key_status[i]=1;
	  key_downtime[i]=0;
	}
  }	
}

void Tim4_Init(u16 arr,u16 psc){
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  NVIC_InitTypeDef NVIC_InitStructure;

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

  NVIC_InitStructure.NVIC_IRQChannel = TIM4_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
  NVIC_Init(&NVIC_InitStructure);

  TIM_TimeBaseStructure.TIM_Period = arr-1;
  TIM_TimeBaseStructure.TIM_Prescaler = psc-1;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;	
  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);
  TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);

  /* TIM2 enable counter */
  TIM_Cmd(TIM4, ENABLE);

}

//PA6 PWM輸出
void Tim3_Init(u32 fre,u8 en){
  u32 arr;

  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_OCInitTypeDef  TIM_OCInitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  
  arr=1000000/fre;

  
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  GPIO_Init(GPIOA, &GPIO_InitStructure);

  TIM_TimeBaseStructure.TIM_Period = arr-1;
  TIM_TimeBaseStructure.TIM_Prescaler = 71;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);


  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  if(en)
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  else
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
  TIM_OCInitStructure.TIM_Pulse = (arr-1)*80/100;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;	  
  TIM_OC1Init(TIM3, &TIM_OCInitStructure);	
  TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE);

  /* TIM2 enable counter */
  TIM_Cmd(TIM3, ENABLE);

}


tx.h

/*
  程序說明: CT117E嵌入式競賽板LCD驅動程序
  軟件環境: Keil uVision 4.10 
  硬件環境: CT117E嵌入式競賽板
  日    期: 2011-8-9
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __TX_H
#define __TX_H

/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* LCD Registers */

#define KEY1 GPIO_ReadInputDataBit( GPIOA, GPIO_Pin_0)
#define KEY2 GPIO_ReadInputDataBit( GPIOA, GPIO_Pin_8)
#define KEY3 GPIO_ReadInputDataBit( GPIOB, GPIO_Pin_1)
#define KEY4 GPIO_ReadInputDataBit( GPIOB, GPIO_Pin_2)

void LED_Init(void);
void KEY_Init(void);
void KEY_Driver(void);
void KEY_Scan(void);
void Tim4_Init(u16 arr,u16 psc);
void Tim3_Init(u32 fre,u8 en);

extern void Key_action(int code,u8 sta);

#endif /* __TX_H */

/******************* (C) COPYRIGHT 2008 STMicroelectronics *****END OF FILE****/

2.中斷函數
stm32f10x_it.c

extern u8 ms200_flag;
extern u8 ms500_flag;
extern u8 s1_flag;
void TIM4_IRQHandler(void)
{
  static u16 ms200_count=0;
  static u16 ms500_count=0;
  static u16 s1_count=0;
  if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
  {
    TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
	KEY_Scan();
	ms200_count++;
	s1_count++;
	if(ms200_count>=100){
	  ms200_count=0;
	  ms200_flag=1;
	}
	if(ms500_count>=250){
	  ms500_count=0;
	  ms500_flag=1;
	}
	if(s1_count>=500){
	  s1_count=0;
	  s1_flag=1;
	}
  }
}

3.主函數
main.c

#include "stm32f10x.h"
#include "lcd.h"
#include "i2c.h"
#include "tx.h"
#include "stdio.h"

u32 TimingDelay = 0;

u8 ms200_flag=1;
u8 ms500_flag=0;
u8 s1_flag=0;

u8 str[20];

u16 LED_MODE=0xffff;

u8 SAVE_flag=0;//0-位置1...
u8 Time_flag=0;//0-無,1-時,2-分,3-秒
u8 Status_flag=0;//0-Standby,1-Setting,2-Running,3-Pause

u16 time; 
u8 hour=0,min=1,sec=55;

void Running_action(void);
void Key_action(int code,u8 sta);
void Write_action(void);
void Read_action(void);
void In_data(void);
void Show_Setdata(void);
void Show_time(void);
void Delay_Ms(u32 nTime);


//Main Body
int main(void)
{
	SysTick_Config(SystemCoreClock/1000);

	Delay_Ms(200);
	
	STM3210B_LCD_Init();
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	i2c_init();
	LED_Init();
	KEY_Init();
	Tim4_Init(2000,72);

	Read_action();	 
	
	while(1){
	  KEY_Driver();
	  if(ms200_flag){
	    ms200_flag=0;
		Show_Setdata();
		Running_action();
	  }
	  if(s1_flag){
	    s1_flag=0;
		if(Status_flag==2){	
		  time=hour*3600+min*60+sec;
		  time--;
		  if(time<=0)
		    time=0;
		  hour=time/3600;
		  min=time%3600/60;
		  sec=time%3600%60;
		}
	  }
	}
}

void Running_action(void){ //定時器運行 PWM輸出,LD1以1Hz頻率閃爍
  if(Status_flag==2){
  	Tim3_Init(1000,1);
	if(ms500_flag){
	  ms500_flag=0;
	  LED_MODE^=(1<<8);
	  GPIOC->ODR=LED_MODE;
	  GPIOD->ODR|=(1<<2);
   	  GPIOD->ODR&=~(1<<2);
	}
  }
  else {
  	Tim3_Init(1000,0);
	LED_MODE|=(1<<8);
	GPIOC->ODR=LED_MODE;
	GPIOD->ODR|=(1<<2);
   	GPIOD->ODR&=~(1<<2);
  }
}

void Key_action(int code,u8 sta){
  if(code==1){
    if(sta==0){	  //key1短按
	  if(Status_flag!=1){
	    SAVE_flag++;
	    if(SAVE_flag>4)
	      SAVE_flag=0;
		}
	  Read_action();
	}
  }
  else if(code==2){
    if(sta==0){
	  if(Status_flag==0){
	    Status_flag=1;
		Time_flag=1;
	  }
	  else if(Status_flag==1){
	    Time_flag++;
		if(Time_flag>3)
		  Time_flag=1;
	  }
	}
	else if(sta==1){	//key2長按,存儲
	  Write_action();
	  Time_flag=0;
	  Status_flag=0;
	}
  }
  else if(code==3){
    if(Status_flag==1){
	  In_data();
	}
  }
  else if(code==4){
    if(sta==0){
	  if(Status_flag!=2){
	  	 Status_flag=2;
		 Time_flag=0;
	  }	  	   
	  else if(Status_flag==2)
	    Status_flag=3;
	  else if(Status_flag==3)
	    Status_flag=2;
	}
	else if(sta==1){
	  Status_flag=0;
	}
  }
}

void Write_action(void){
  if(SAVE_flag==0){
  	ic2_write(0x00,hour);Delay_Ms(5);
	ic2_write(0x01,min);Delay_Ms(5);
	ic2_write(0x02,sec);Delay_Ms(5);
  }
  else if(SAVE_flag==1){
  	ic2_write(0x03,hour);Delay_Ms(5);
	ic2_write(0x04,min);Delay_Ms(5);
	ic2_write(0x05,sec);Delay_Ms(5);
  }
  else if(SAVE_flag==2){
  	ic2_write(0x06,hour);Delay_Ms(5);
	ic2_write(0x07,min);Delay_Ms(5);
	ic2_write(0x08,sec);Delay_Ms(5);
  }
  else if(SAVE_flag==3){
  	ic2_write(0x09,hour);Delay_Ms(5);
	ic2_write(0x0A,min);Delay_Ms(5);
	ic2_write(0x0B,sec);Delay_Ms(5);
  }
  else if(SAVE_flag==4){
  	ic2_write(0x0C,hour);Delay_Ms(5);
	ic2_write(0x0D,min);Delay_Ms(5);
	ic2_write(0x0E,sec);Delay_Ms(5);
  }
}

void Read_action(void){
  if(SAVE_flag==0){
  	hour=i2c_read(0x00);Delay_Ms(5);
	min=i2c_read(0x01);Delay_Ms(5);
	sec=i2c_read(0x02);Delay_Ms(5);
  }
  else if(SAVE_flag==1){
  	hour=i2c_read(0x03);Delay_Ms(5);
	min=i2c_read(0x04);Delay_Ms(5);
	sec=i2c_read(0x05);Delay_Ms(5);
  }
  else if(SAVE_flag==2){
  	hour=i2c_read(0x06);Delay_Ms(5);
	min=i2c_read(0x07);Delay_Ms(5);
	sec=i2c_read(0x08);Delay_Ms(5);
  }
  else if(SAVE_flag==3){
  	hour=i2c_read(0x09);Delay_Ms(5);
	min=i2c_read(0x0A);Delay_Ms(5);
	sec=i2c_read(0x0B);Delay_Ms(5);
  }
  else if(SAVE_flag==4){
  	hour=i2c_read(0x0C);Delay_Ms(5);
	min=i2c_read(0x0D);Delay_Ms(5);
	sec=i2c_read(0x0E);Delay_Ms(5);
  }
}

void In_data(void){
  if(Time_flag==1){
  	hour++;
	if(hour>23)
	  hour=0;
  }
  else if(Time_flag==2){
  	min++;
	if(min>59)
	  min=0;
  }
  else if(Time_flag==3){
    sec++;
	if(sec>59)
	  sec=0;
  }
}
void Show_Setdata(void){
  sprintf((char*)str,"       No:%d     ",SAVE_flag+1);
  LCD_DisplayStringLine(Line2,str);

  Show_time();

  if(Status_flag==0)
    sprintf((char*)str,"     Standby   ");
  else if(Status_flag==1)
    sprintf((char*)str,"     Setting   ");
  else if(Status_flag==2)
    sprintf((char*)str,"     Running   ");
  else if(Status_flag==3)
    sprintf((char*)str,"     Pause   ");

  LCD_DisplayStringLine(Line6,str);
}

void Show_time(void){    
  if(Time_flag==0)
    LCD_SetTextColor(White);

  if(Time_flag==1)
    LCD_SetTextColor(Green);
  else
    LCD_SetTextColor(White);
  LCD_DisplayChar(Line4, 240, hour/10+'0');
  LCD_DisplayChar(Line4, 225, hour%10+'0');	
  LCD_DisplayChar(Line4, 210, ':');	
  LCD_SetTextColor(White);

  if(Time_flag==2)
    LCD_SetTextColor(Green);
  else
    LCD_SetTextColor(White);
  LCD_DisplayChar(Line4, 195, min/10+'0');
  LCD_DisplayChar(Line4, 180, min%10+'0');	
  LCD_DisplayChar(Line4, 165, ':');	
  LCD_SetTextColor(White);

  if(Time_flag==3)
    LCD_SetTextColor(Green);
  else
    LCD_SetTextColor(White);
  LCD_DisplayChar(Line4, 150, sec/10+'0');
  LCD_DisplayChar(Line4, 135, sec%10+'0');	
  LCD_SetTextColor(White);

}
void Delay_Ms(u32 nTime)
{
	TimingDelay = nTime;
	while(TimingDelay != 0);	
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章