蓝桥杯嵌入式第八届决赛-频率控制器

一、题目
蓝桥杯嵌入式第八届决赛-频率控制器_第1张图片
二、代码
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};
void KEY_Driver(void){
     
  u8 i;
  static u8 backup[4]={
     1,1,1,1};
  for(i=0;i<4;i++){
     
  	if(backup[i]!=key_status[i]){
     
	  if(backup[i]!=0){
     
	    Key_action(i+1);
	  }
	  backup[i]=key_status[i];
	}
  }
}

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;
	else if(key_buf[i]==0xff)
	   key_status[i]=1;
  }
}

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 PA7
u32 CH1_val;
u32 CH1_duty;
u32 CH2_val;
u32 CH2_duty;
void PWM_out(u32 fre1,u16 fre2,u8 en1,u8 en2){
     
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
  TIM_OCInitTypeDef  TIM_OCInitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;

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

  CH1_val=1000000/fre1;
  CH1_duty=CH1_val*50/100;
  CH2_val=1000000/fre2;
  CH2_duty=CH2_val*50/100;	  

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

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

  TIM_TimeBaseStructure.TIM_Period = 65535;
  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_Toggle;
  if(en1)
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  else
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
  TIM_OCInitStructure.TIM_Pulse = CH1_val;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; 
  TIM_OC1Init(TIM3, &TIM_OCInitStructure);

  if(en2)
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  else
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;
  TIM_OCInitStructure.TIM_Pulse = CH2_val;	  
  TIM_OC2Init(TIM3, &TIM_OCInitStructure);

  TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2, ENABLE);
  TIM_Cmd(TIM3, ENABLE);

}
//PA1 PA2
void PWM_in(void){
     
  TIM_ICInitTypeDef  TIM_ICInitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;
  NVIC_InitTypeDef NVIC_InitStructure;
  TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;

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

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_1|GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 
  GPIO_Init(GPIOA, &GPIO_InitStructure);

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

  TIM_TimeBaseStructure.TIM_Period = 65535;
  TIM_TimeBaseStructure.TIM_Prescaler = 71;
  TIM_TimeBaseStructure.TIM_ClockDivision = 0;
  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

  TIM_ICInitStructure.TIM_Channel = TIM_Channel_2;
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  TIM_ICInitStructure.TIM_ICFilter = 0x0; 
  TIM_ICInit(TIM2, &TIM_ICInitStructure);

  TIM_ICInitStructure.TIM_Channel = TIM_Channel_3;
  TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
  TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  TIM_ICInitStructure.TIM_ICFilter = 0x0; 
  TIM_ICInit(TIM2, &TIM_ICInitStructure);

  TIM_Cmd(TIM2, ENABLE);

  /* Enable the CC2 Interrupt Request */
  TIM_ITConfig(TIM2, TIM_IT_CC2|TIM_IT_CC3, ENABLE); 
}

void Adc1_Init(void){
     
  ADC_InitTypeDef ADC_InitStructure;
  GPIO_InitTypeDef GPIO_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA, ENABLE);

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfChannel = 2;
  ADC_Init(ADC1, &ADC_InitStructure);
  ADC_Cmd(ADC1, ENABLE);

  /* Enable ADC1 reset calibration register */   
  ADC_ResetCalibration(ADC1);
  /* Check the end of ADC1 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC1));

  /* Start ADC1 calibration */
  ADC_StartCalibration(ADC1);
  /* Check the end of ADC1 calibration */
  while(ADC_GetCalibrationStatus(ADC1));
}

u16 Get_adc(u8 channel){
     
  u16 temp;
  ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_239Cycles5);
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);
  while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==0);
  temp=ADC_GetConversionValue(ADC1);
  ADC_SoftwareStartConvCmd(ADC1, DISABLE);
  return temp;
}


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 PWM_out(u32 fre1,u16 fre2,u8 en1,u8 en2);
void PWM_in(void);
void Adc1_Init(void);
u16 Get_adc(u8 channel);
extern void Key_action(int code);
#endif /* __TX_H */

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

i2c.c追加

void i2c_write(u16 add,u8 data){
     
  I2CStart();
  I2CSendByte(0xa0);
  I2CWaitAck();
  I2CSendByte(add);
  I2CWaitAck();
  I2CSendByte(data);
  I2CWaitAck();
  I2CStop();

}
u8 i2c_read(u16 add){
     
  u8 temp;
  I2CStart();
  I2CSendByte(0xa0);
  I2CWaitAck();
  I2CSendByte(add);
  I2CWaitAck();

  I2CStart();
  I2CSendByte(0xa1);
  I2CWaitAck();
  temp=I2CReceiveByte();
  I2CSendAck();
  I2CStop();
  return temp;
}

2.中断
stm32f10x_it.h

extern u8 ms200_flag;

void TIM4_IRQHandler(void)
{
     
  static u8 ms200_count=0;
  if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET)
  {
     
    TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
	KEY_Scan();
	ms200_count++;
	if(ms200_count>=100){
     
	  ms200_count=0;
	  ms200_flag=1;
	}
  }
}
extern u32 CH1_val;
extern u32 CH1_duty;
extern u32 CH2_val;
extern u32 CH2_duty;
void TIM3_IRQHandler(void)
{
     
  u16 capture1,capture2;
  static u8 flag1=0;
  static u8 flag2=0;
  if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)
  {
     
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);
    capture1 = TIM_GetCapture1(TIM3);
	if(flag1)
      TIM_SetCompare1(TIM3, capture1 + CH1_duty);
	else
	  TIM_SetCompare1(TIM3, capture1 + CH1_val-CH1_duty);
	flag1^=1;
  }
  else if (TIM_GetITStatus(TIM3, TIM_IT_CC2) != RESET)
  {
     
    TIM_ClearITPendingBit(TIM3, TIM_IT_CC2);
	capture2 = TIM_GetCapture2(TIM3);
	if(flag2)
      TIM_SetCompare2(TIM3, capture2 + CH2_duty);
	else
	  TIM_SetCompare2(TIM3, capture2 + CH2_val-CH2_duty);
	flag2^=1;
  }
}
__IO uint16_t IC3ReadValue1 = 0, IC3ReadValue2 = 0;
__IO uint16_t CaptureNumber = 0;
__IO uint32_t Capture = 0;
__IO uint32_t TIM3Freq = 0;

__IO uint16_t IC3ReadValue1_2 = 0, IC3ReadValue2_2 = 0;
__IO uint16_t CaptureNumber_2 = 0;
__IO uint32_t Capture_2 = 0;
__IO uint32_t TIM3Freq_2 = 0;

void TIM2_IRQHandler(void)
{
      
  if(TIM_GetITStatus(TIM2, TIM_IT_CC2) == SET) 
  {
     
    /* Clear TIM3 Capture compare interrupt pending bit */
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
    if(CaptureNumber == 0)
    {
     
      /* Get the Input Capture value */
      IC3ReadValue1 = TIM_GetCapture2(TIM2);
      CaptureNumber = 1;
    }
    else if(CaptureNumber == 1)
    {
     
      /* Get the Input Capture value */
      IC3ReadValue2 = TIM_GetCapture2(TIM2); 
      
      /* Capture computation */
      if (IC3ReadValue2 > IC3ReadValue1)
      {
     
        Capture = (IC3ReadValue2 - IC3ReadValue1); 
      }
      else
      {
     
        Capture = ((0xFFFF - IC3ReadValue1) + IC3ReadValue2); 
      }
      /* Frequency computation */ 
      TIM3Freq = 1000000/ Capture;
      CaptureNumber = 0;
    }
  }
  else if(TIM_GetITStatus(TIM2, TIM_IT_CC3) == SET) 
  {
     
    /* Clear TIM3 Capture compare interrupt pending bit */
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC3);
    if(CaptureNumber_2 == 0)
    {
     
      /* Get the Input Capture value */
      IC3ReadValue1_2 = TIM_GetCapture3(TIM2);
      CaptureNumber_2 = 1;
    }
    else if(CaptureNumber_2 == 1)
    {
     
      /* Get the Input Capture value */
      IC3ReadValue2_2 = TIM_GetCapture3(TIM2); 
      
      /* Capture computation */
      if (IC3ReadValue2_2 > IC3ReadValue1_2)
      {
     
        Capture_2 = (IC3ReadValue2_2 - IC3ReadValue1_2); 
      }
      else
      {
     
        Capture_2 = ((0xFFFF - IC3ReadValue1_2) + IC3ReadValue2_2); 
      }
      /* Frequency computation */ 
      TIM3Freq_2 = 1000000 / Capture_2;
      CaptureNumber_2 = 0;
    }
  }
}

3.主函数
main.c

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

u32 TimingDelay = 0;

extern __IO uint32_t TIM3Freq_2 ; //PLUS1
extern __IO uint32_t TIM3Freq ;	 //PLUS2

u8 ms200_flag=1;

u8 fre_1=1;
u8 fre_2=1;
u8 mul=1;
u8 div=1;

float ao1;
float ao2;

u8 SET_flag=0;//0-实时,1-配置
u8 Index_flag=0;//0-分频系数,1-倍频系数
u8 str[20];

u16 LED_MODE=0xffff;
u8 LD1_flag=0;
u8 LD2_flag=0;

void Key_action(int code);
void Refresh(void);
void Show_real(void);
void Show_set(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);
	
	LED_Init();
	KEY_Init();
	Tim4_Init(2000,72);
	i2c_init();
	PWM_in();
	Adc1_Init();

    div=i2c_read(0x00);	Delay_Ms(5);
	mul=i2c_read(0x01);	Delay_Ms(5);  	

	while(1){
     
	  KEY_Driver();
	  if(ms200_flag){
     
	    ms200_flag=0;
		Refresh();
		if(SET_flag==0)
		  Show_real();
		else
		  Show_set();  
	  }
	 
	}
}

void Key_action(int code){
     
  if(code==1){
     
  	SET_flag^=1;
	if(SET_flag==0){
     
	 i2c_write(0x00,div);Delay_Ms(5); 
	 i2c_write(0x00,mul);Delay_Ms(5);
	}
  }
  else if(code==2){
     
    if(SET_flag==1)
	  Index_flag^=1;	
  }
  else if(code==3){
     
    if(SET_flag==1){
     
	  if(Index_flag==0){
     
	    div++;
		if(div>4)
		  div=4;
	  }
	  else if(Index_flag==1){
     
	    mul++;
		if(mul>4)
		  mul=4;
	  }
	}
  }
  else if(code==4){
     
    if(SET_flag==1){
     
	  if(Index_flag==0){
     
	    div--;
		if(div<1)
		  div=1;
	  }
	  else if(Index_flag==1){
     
	    mul--;
		if(mul<1)
		  mul=1;
	  }
	}
  }
}
void Refresh(void){
     
  ao1=Get_adc(ADC_Channel_4)*3.3/4096;
  ao2=Get_adc(ADC_Channel_5)*3.3/4096;

  if(ao1>ao2)
    LD2_flag=1;
  else if(ao1<=ao2) 
    LD2_flag=0;

  fre_1=TIM3Freq/1000;
  fre_2=TIM3Freq_2/1000;

  if(SET_flag==0){
     
    LD1_flag=0;
	PWM_out(fre_1*1000/div,fre_2*1000*1000*mul,1,1);
  }	    
  else{
     
  	LD1_flag=1;
	PWM_out(fre_1*1000/div,fre_2*1000*1000*mul,0,0);
  }
    

  if(LD1_flag){
     
    LED_MODE&=~(1<<8);
	GPIOC->ODR=LED_MODE;
	GPIOD->ODR|=(1<<2);
    GPIOD->ODR&=~(1<<2);
  }
  else{
     
  	LED_MODE|=(1<<8);
	GPIOC->ODR=LED_MODE;
	GPIOD->ODR|=(1<<2);
    GPIOD->ODR&=~(1<<2);
  }
  if(LD2_flag){
     
    LED_MODE&=~(1<<9);
	GPIOC->ODR=LED_MODE;
	GPIOD->ODR|=(1<<2);
    GPIOD->ODR&=~(1<<2);
  }
  else{
     
  	LED_MODE|=(1<<9);
	GPIOC->ODR=LED_MODE;
	GPIOD->ODR|=(1<<2);
    GPIOD->ODR&=~(1<<2);
  }

}
void Show_real(void){
     
   sprintf((char*)str,"      Measure       ");
   LCD_DisplayStringLine( Line1, str);

   sprintf((char*)str,"    PLUS1:%dkHz        ",fre_1);
   LCD_DisplayStringLine( Line3, str);
   sprintf((char*)str,"    PLUS2:%dkHz        ",fre_2);
   LCD_DisplayStringLine( Line5, str);

   sprintf((char*)str,"     AO1:%.2fV              ",ao1);
   LCD_DisplayStringLine( Line7, str);

   sprintf((char*)str,"     AO2:%.2fV    1      ",ao2);
   LCD_DisplayStringLine( Line9, str);
}
void Show_set(void){
     
  sprintf((char*)str,"      Setting       ");
  LCD_DisplayStringLine( Line1, str);

  sprintf((char*)str,"                                   ");
  LCD_DisplayStringLine( Line3, str);
  sprintf((char*)str,"                  2      ");
  LCD_DisplayStringLine( Line9, str);

  if(Index_flag==0)
    LCD_SetTextColor(Green);
  else
    LCD_SetTextColor(White);
  sprintf((char*)str,"     Div-n:%d         ",div);
  LCD_DisplayStringLine( Line5, str);
  LCD_SetTextColor(White);

  if(Index_flag==1)
    LCD_SetTextColor(Green);
  else
    LCD_SetTextColor(White);
  sprintf((char*)str,"     Mul-n:%d        ",mul);
  LCD_DisplayStringLine( Line7, str);
  LCD_SetTextColor(White);
}
void Delay_Ms(u32 nTime)
{
     
	TimingDelay = nTime;
	while(TimingDelay != 0);	
}

你可能感兴趣的:(蓝桥杯嵌入式)