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

26 篇文章 2 订阅
7 篇文章 0 订阅

第八届决赛题目考察的知识主要是adc和频率发生和捕获。不知是不是第一次用到扩展板的缘故,考察的知识点不算多。

工程结构

init.c  (需要注意的是,因为用到两路adc,这里我们采用注入通道的方法,可以参考前文)

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


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

	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
                         RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD, ENABLE);
	//led
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10| GPIO_Pin_11| GPIO_Pin_12| GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOC, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_Init(GPIOD, &GPIO_InitStructure);


	//key
	//led
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2;
    GPIO_Init(GPIOB, &GPIO_InitStructure);


	GPIO_SetBits(GPIOC,GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10| GPIO_Pin_11| GPIO_Pin_12| GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15);
	GPIO_SetBits(GPIOD,GPIO_Pin_2);
	GPIO_ResetBits(GPIOD,GPIO_Pin_2);  


	//adc
	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 = 1;
  ADC_Init(ADC1, &ADC_InitStructure);

  /* ADC1 regular channel4 、5 configuration */ 
  ADC_InjectedChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_1Cycles5);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_1Cycles5);

  ADC_AutoInjectedConvCmd(ADC1,ENABLE);
  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);
  /* Start ADC1 calibration */
  ADC_StartCalibration(ADC1);
  /* Check the end of ADC1 calibration */
  while(ADC_GetCalibrationStatus(ADC1));


}


void LCD_Init(void)
{
    STM3210B_LCD_Init();
	LCD_Clear(Blue);
	LCD_SetBackColor(Blue);
	LCD_SetTextColor(White);
	
	SysTick_Config(SystemCoreClock/1000);

	LCD_DisplayStringLine(Line0,"       Measure      ");	
	LCD_DisplayStringLine(Line1,"                    ");	
	LCD_DisplayStringLine(Line2,"   PLUS1 : 2kHz     ");
	LCD_DisplayStringLine(Line3,"                    ");
	LCD_DisplayStringLine(Line4,"   PLUS2 : 1kHz     ");
	LCD_DisplayStringLine(Line5,"                    ");
	LCD_DisplayStringLine(Line6,"   AO1   : 2.20V    ");
	LCD_DisplayStringLine(Line7,"                    ");	
	LCD_DisplayStringLine(Line8,"   AO2   : 3.00V    ");
	LCD_DisplayStringLine(Line9,"                   1");	
}


unsigned char I2C_Read(unsigned char add)
{
	unsigned char temp;

	I2CStart();
	I2CSendByte(0xa0);
	I2CSendAck();

	I2CSendByte(add);
	I2CSendAck();

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

	return temp;

}

void I2C_Write(unsigned char add,unsigned char dat)
{
	I2CStart();
	I2CSendByte(0xa0);
	I2CSendAck();

	I2CSendByte(add);
	I2CSendAck();

	I2CSendByte(dat);
	I2CSendAck();
	I2CStop();
		
}

void TIM2_ICInit(void)
{
   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
   GPIO_InitTypeDef GPIO_InitStructure;
   TIM_ICInitTypeDef  TIM_ICInitStructure;

   //NVIC_InitTypeDef NVIC_InitStructure;

  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_Init(GPIOA, &GPIO_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_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);

  TIM_ITConfig(TIM2, TIM_IT_CC2|TIM_IT_CC3, ENABLE);


  /* Enable the TIM3 global Interrupt
  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); */

}


void TIM3_OCInit(void)
{
   TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
   GPIO_InitTypeDef GPIO_InitStructure;
   TIM_OCInitTypeDef  TIM_OCInitStructure;
   //NVIC_InitTypeDef NVIC_InitStructure;

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

  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);


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

  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  TIM_OCInitStructure.TIM_Pulse = 250;
  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  TIM_OC1Init(TIM3, &TIM_OCInitStructure);
  TIM_OC2Init(TIM3, &TIM_OCInitStructure);

  TIM_Cmd(TIM3, ENABLE);

  TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2, ENABLE);
  /*
  NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure); */

}



主程序

/*
因为PLUS1和PLUS2不同步且频率不同,所以只能分别进行捕获,具体方法是分别将两次相邻的捕获值相减得到周期值。
TIM2使用的是向上计数模式,当计数值溢出时必须对捕获值特殊处理。
同样,分频方波和倍频方波输出频率也不同,也只能分别进行比较,具体方法是当比较匹配时输出翻转,
并分别将比较值增加半个周期值,当比较溢出时必须对比较值特殊处理。
*/
#include "stm32f10x.h"
#include "lcd.h"
#include "i2c.h"
#include "init.h"
#include "stdio.h"
#define TIM_CK 1000000

u32 TimingDelay = 0;

void Delay_Ms(u32 nTime);
void Key_Scan(void);
void ADC_Read(void);
unsigned int ADC_Conv(void);
unsigned int ADC_InjeConv(void);
void TIM2_Proc(void);
void TIM3_Proc(void);
void LED_Disp(u16 led);

float ao1,ao2;
u8 string[20];
unsigned long ulIc1,ulIc2,ulOc1,ulOc2;
unsigned int uiId1,uiId2;
unsigned char ucDiv,ucMul;
unsigned long ulTick_ms=0,ulSec=0,ulSec1=0;
u8 shezhi=0,qie=0;
u16 led=0;

//Main Body
int main(void)
{
	LCD_Init();
	GPIO_Int();
	i2c_init();
	TIM2_ICInit();
    TIM3_OCInit();

	Delay_Ms(5);
	if(I2C_Read(0x20)!=20)
	{
	Delay_Ms(5);
	I2C_Write(0x20,20);
	Delay_Ms(5);
	I2C_Write(0x00,1);
	Delay_Ms(5);
	I2C_Write(0x01,1);	
	}

	Delay_Ms(5);
	ucDiv=I2C_Read(0x00);
	Delay_Ms(5);
	ucMul=I2C_Read(0x01);
	
	while(1)
	{
	Key_Scan();
	ADC_Read();
	TIM2_Proc();
	TIM3_Proc();
	LED_Disp(led);

	}
}

void Key_Scan(void)
{
if(RB1==0)
{
Delay_Ms(5);
if(RB1==0)
{
if(shezhi==0)
{
shezhi=1;
LCD_DisplayStringLine(Line0,"       Setting      ");
sprintf((char*)string,"      DIV : %1d       ",ucDiv);
LCD_DisplayStringLine(Line2,string);
sprintf((char*)string,"      MUL : %1d       ",ucMul);
LCD_DisplayStringLine(Line4,string);
LCD_DisplayStringLine(Line6,"                    ");
LCD_DisplayStringLine(Line8,"                    ");
LCD_DisplayStringLine(Line9,"                   2");

}
else if(shezhi==1)
{
	shezhi=0;
	Delay_Ms(5);
	I2C_Write(0x00,ucDiv);
	Delay_Ms(5);
	I2C_Write(0x01,ucMul);	
}

}while(!RB1);
}

else if(RB2==0)
{
Delay_Ms(5);
if(RB2==0)
{
if(shezhi==1)
{
 if(qie==0||qie==2)
 {
 qie=1;
 LCD_SetTextColor(Red);
 sprintf((char*)string,"      DIV : %1d       ",ucDiv);
 LCD_DisplayStringLine(Line2,string);

 LCD_SetTextColor(White);
 sprintf((char*)string,"      MUL : %1d       ",ucMul);
 LCD_DisplayStringLine(Line4,string);

 }
 else if(qie==1)
 {
 qie=2;
 LCD_SetTextColor(Red);
 sprintf((char*)string,"      MUL : %1d       ",ucMul);
 LCD_DisplayStringLine(Line4,string);

 LCD_SetTextColor(White);
 sprintf((char*)string,"      DIV : %1d       ",ucDiv);
 LCD_DisplayStringLine(Line2,string);
 

 }
}
}while(!RB2);
}


else if(RB3==0)
{
Delay_Ms(5);
if(RB3==0)
{
	if(shezhi==1)
	{
		if(qie==1)
		{
		if(ucDiv<4)ucDiv++;
		LCD_SetTextColor(Red);	
		sprintf((char*)string,"      DIV : %1d       ",ucDiv);
        LCD_DisplayStringLine(Line2,string);
        LCD_SetTextColor(White);
 
		}
		else if(qie==2)
		{
		 if(ucMul<4)ucMul++;
		 LCD_SetTextColor(Red);
 		 sprintf((char*)string,"      MUL : %1d       ",ucMul);
         LCD_DisplayStringLine(Line4,string);
 		 LCD_SetTextColor(White);
		}
	}
}while(!RB3);
}


else if(RB4==0)
{
Delay_Ms(5);
if(RB4==0)
{
if(shezhi==1)
	{
		if(qie==1)
		{
		if(ucDiv>1)ucDiv--;
		LCD_SetTextColor(Red);	
		sprintf((char*)string,"      DIV : %1d       ",ucDiv);
        LCD_DisplayStringLine(Line2,string);
        LCD_SetTextColor(White);
 
		}
		else if(qie==2)
		{
		 if(ucMul>1)ucMul--;
		 LCD_SetTextColor(Red);
 		 sprintf((char*)string,"      MUL : %1d       ",ucMul);
         LCD_DisplayStringLine(Line4,string);
 		 LCD_SetTextColor(White);
		}
	}
}while(!RB4);
}


}


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

unsigned int ADC_Conv(void)
{
/* Start ADC1 Software Conversion */ 
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);

  while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));
  return ADC_GetConversionValue(ADC1);

}

unsigned int ADC_InjeConv(void)
{
/* Start ADC1 Software Conversion */ 
  ADC_SoftwareStartConvCmd(ADC1, ENABLE);

  ADC_SoftwareStartInjectedConvCmd(ADC1, ENABLE);
  
  while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_JEOC));
  ADC_ClearFlag(ADC1,ADC_FLAG_JEOC);
  return ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1);

}

void ADC_Read(void)
{
  if(shezhi==0)
  {
  if(ulSec1!=ulSec)
  {
  	  ulSec1=ulSec;

	  LCD_DisplayStringLine(Line0,"       Measure      ");
	  ao1=ADC_InjeConv()*3.3/0xfff;
	  sprintf((char*)string,"   AO1   : %3.2fV    ",ao1);
	  LCD_DisplayStringLine(Line6,string);
	  ao2=ADC_Conv()*3.3/0xfff;
	  sprintf((char*)string,"   AO2   : %3.2fV    ",ao2);
	  LCD_DisplayStringLine(Line8,string);
	
	  sprintf((char*)string," %5dHz /%1d %5dHz ",TIM_CK/uiId1,ucDiv,TIM_CK/uiId1/ucDiv);
	  LCD_DisplayStringLine(Line2,string);
	
	  sprintf((char*)string," %5dHz *%1d %5dHz ",TIM_CK/uiId2,ucMul,TIM_CK/uiId2*ucMul);
	  LCD_DisplayStringLine(Line4,string);

	  LCD_DisplayStringLine(Line9,"                   1");

   }
   }

}

void SysTick_Handler(void)
{
	TimingDelay--;
	ulTick_ms++;
	if(ulTick_ms%1000==0)
	ulSec++;

	if(shezhi==0)
	led&=0xfe;
	else 
	led|=0x01;

	if(ao1>ao2)
	led|=0x80;
	else 
	led&=0x7f;
}

void TIM2_Proc(void)
{ 
unsigned long ic;
  if(TIM_GetFlagStatus(TIM2, TIM_FLAG_CC2) == SET) 
  {
    ic=ulIc1;
    ulIc1=TIM_GetCapture2(TIM2);
    if(ulIc1>ic)
      uiId1=ulIc1-ic;
	else
	  uiId1=65536+ulIc1-ic;
  
  }

  if(TIM_GetFlagStatus(TIM2, TIM_FLAG_CC3) == SET) 
  {
    ic=ulIc2;
    ulIc2=TIM_GetCapture3(TIM2);
    if(ulIc2>ic)
      uiId2=ulIc2-ic;
	else
	  uiId2=65536+ulIc2-ic;
  
  }
}

void TIM3_Proc(void)
{
if (TIM_GetFlagStatus(TIM2, TIM_FLAG_CC1) != RESET)
  {
    ulOc1+=uiId1*ucDiv>>1;
	if(ulOc1>65535)
	ulOc1-=65536;
    TIM_SetCompare1(TIM3, ulOc1);
	TIM_ClearFlag(TIM3,TIM_FLAG_CC1);
  }


  if (TIM_GetFlagStatus(TIM2, TIM_FLAG_CC2) != RESET)
  {
    ulOc2+=uiId2/ucMul>>1;
	if(ulOc2>65535)
	ulOc2-=65536;
    TIM_SetCompare2(TIM3, ulOc2);
	TIM_ClearFlag(TIM3,TIM_FLAG_CC2);
  }

}

void LED_Disp(u16 led)
{
GPIO_Write(GPIOC,~led<<8);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

身在江湖的郭大侠

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值