蓝桥杯嵌入式第十届国赛程序

第十届决赛题目考察的知识点较多,题目较为综合,主要考察两路adc,pwm输入捕获,ds18b20,数码管等。两路ADC,本程序采用注入通道。

工程结构

蓝桥杯嵌入式第十届国赛程序

 

init.c

#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_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC| RCC_APB2Periph_GPIOD, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, 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);

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


	//key
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_8;
    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);


	//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 channel14 configuration */ 
	ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_13Cycles5);
	ADC_InjectedChannelConfig(ADC1, ADC_Channel_5, 1, ADC_SampleTime_13Cycles5);

	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));
	
	/* Start ADC1 Software Conversion */ 
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);

	NVIC_Configuration();


}

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

	LCD_DisplayStringLine(Line0,"      Main          ");	
	LCD_DisplayStringLine(Line1,"                    ");	
	LCD_DisplayStringLine(Line2,"  AO1 : 2.21V       ");
	LCD_DisplayStringLine(Line3,"                    ");
	LCD_DisplayStringLine(Line4,"  AO2 : 3.00V       ");
	LCD_DisplayStringLine(Line5,"                    ");
	LCD_DisplayStringLine(Line6,"  PWM2: 10%         ");
	LCD_DisplayStringLine(Line7,"                    ");	
	LCD_DisplayStringLine(Line8,"  Temp: 26.56C      ");
	LCD_DisplayStringLine(Line9,"  N   : 2           ");

}

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 TIM3_ICInit(void)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_ICInitTypeDef  TIM_ICInitStructure;

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

	GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_7;
	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 = TIM_CKD_DIV1;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	
	TIM_TimeBaseInit(TIM3, &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 = 0;
	TIM_PWMIConfig(TIM3, &TIM_ICInitStructure);

	TIM_SelectInputTrigger(TIM3,TIM_TS_TI2FP2);
	TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);
	
	/* TIM enable counter */
	TIM_Cmd(TIM3, ENABLE);
    
}

void USART2_Init(void)
{
	USART_InitTypeDef USART_InitStructure;
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);


	USART_InitStructure.USART_BaudRate = 9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl =   USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	

	/* Configure USART2 */
	USART_Init(USART2, &USART_InitStructure);
	
	
	/* Enable USART2 Receive and Transmit interrupts */
	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
	
	
	/* Enable the USART2 */
	USART_Cmd(USART2, ENABLE);

}

void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
 
 
  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
  
 
  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
 
 
  
}





主程序,需要注意的是usart与数码管的引脚重合,所以用到usart时需要关闭数码管,用到数码管时需要关闭usart

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

u32 TimingDelay = 0;
u8 string[20];
unsigned int uiTemp;
float uiAO1,uiAO2;
unsigned char ucPwm;
u8 shuju=0,canshu=0;
unsigned long ulTick_ms=0,ulSec=0,ulSec1=0,ulKey_Time;
u8 qie=0,shezhi=0,key_val=0,Long_Val;
unsigned char ucNum=0,ucT=30,ucX=1,ucT1,ucX1,ucKey_Long;
unsigned char  pucRcv[6],ucRno=0;
u16 ucled=0;


void Delay_Ms(u32 nTime);
void Key_Scan(void);
unsigned int ADC1_Conv(void);
unsigned int ADC1_InjConv(void);
void LCD_Proc(void);
unsigned char TIM3_Pwm(void);
void USART_Send(u8 *str);
unsigned char KEY_Scan(void);
void Key_Proc(void);
void UART_Proc(void);
void LED_Disp(u16 ucled);


//Main Body
int main(void)
{

	LCD_Init();
	GPIO_Int();
	i2c_init();
	TIM3_ICInit();

	SEG_Init();
	SEG_Disp(0x10,0x10,0x10,0);

	//USART2_Init();
	//STM3210B_SEG_Init();
	//SEG_DisplayValue(0x10,0x10,0x10);	 //熄灭数码管
	
	//USART_Send("hello world\r\n");
	Delay_Ms(5);
	if(I2C_Read(0x20)!=0)
	{
	Delay_Ms(5);
	I2C_Write(0x20,0);
	Delay_Ms(5);
	I2C_Write(0x00,0);
	
	}
	
	Delay_Ms(5);
	ucNum=I2C_Read(0x00);	
	
	while(1)
	{
	Key_Proc();
	LCD_Proc();
	LED_Disp(ucled);
	UART_Proc();
	if(shuju==1)
	{
	shuju=0;
	sprintf((char*)string,"$%5.2f\r\n",uiTemp/16.0);
	USART_Send(string);
	}
	else if(canshu==1)
	{
	canshu=0;
	sprintf((char*)string,"#%2d,AO%1d\r\n",ucT,ucX);
	USART_Send(string);
	}
	


	}
}

unsigned char KEY_Scan(void)
{
unsigned char ucKey_Val=0;
if(~GPIO_ReadInputData(GPIOA)&0x101)
{
Delay_Ms(5);
if(RB1==0)
ucKey_Val=1;
if(RB2==0)
ucKey_Val=2;

}

else if(~GPIO_ReadInputData(GPIOB)&6)
{
Delay_Ms(5);
if(RB3==0)
ucKey_Val=3;
if(RB4==0)
ucKey_Val=4;

}
return ucKey_Val;

}

void Key_Proc(void)
{
unsigned char ucKey_Val;
ucKey_Val=KEY_Scan();
if(ucKey_Val!=ucKey_Long)
{
ucKey_Long=	ucKey_Val;
ulKey_Time=ulTick_ms;
}
else 
ucKey_Val=0;

switch(ucKey_Val)
{
case 1:
if(shezhi==0)
	{
	shezhi=1;

	ucT1=ucT;
	ucX1=ucX;
	
	LCD_DisplayStringLine(Line0,"       Para         ");
	sprintf((char*)string,"      T : %2dC        ",ucT);
	LCD_DisplayStringLine(Line2,string);
	sprintf((char*)string,"      X : AO%1d       ",ucX);
	LCD_DisplayStringLine(Line4,string);


	LCD_DisplayStringLine(Line6,"                    ");
	LCD_DisplayStringLine(Line8,"                    ");
	LCD_DisplayStringLine(Line9,"                    ");

	}
	else if(shezhi==1)
	{
	shezhi=0;
	if((ucX1!=ucX)||(ucT1!=ucT))
	{
	ucNum++;
	Delay_Ms(5);
	I2C_Write(0x00,ucNum);
	}

	}
break;

case 2:
if(shezhi==1)
	{
	if(qie==0||qie==2)
	{
	qie=1;
	LCD_SetBackColor(Red);
	sprintf((char*)string,"      T : %2dC        ",ucT);
	LCD_DisplayStringLine(Line2,string);
	LCD_SetBackColor(Blue);
	sprintf((char*)string,"      X : AO%1d       ",ucX);
	LCD_DisplayStringLine(Line4,string);

	}

	else if(qie==1)
	{
	qie=2;
	LCD_SetBackColor(Red);
	sprintf((char*)string,"      X : AO%1d       ",ucX);
	LCD_DisplayStringLine(Line4,string);	
	LCD_SetBackColor(Blue);
	sprintf((char*)string,"      T : %2dC        ",ucT);
	LCD_DisplayStringLine(Line2,string);
	}

	}
break;

case 3:	
if(shezhi==1)
	{
		if(qie==1)
		{
		
		if(ucT<40)
		ucT++;
		
		LCD_SetBackColor(Red);
		sprintf((char*)string,"      T : %2dC        ",ucT);
		LCD_DisplayStringLine(Line2,string);
		LCD_SetBackColor(Blue);
				
		}
	
		else if(qie==2)
		{
		if(ucX==1)
		ucX=2;
		else 
		ucX=1;
		LCD_SetBackColor(Red);
		sprintf((char*)string,"      X : AO%1d       ",ucX);
		LCD_DisplayStringLine(Line4,string);	
		LCD_SetBackColor(Blue);
		}
	}
break;
case 4:
if(shezhi==1)
	{
		if(qie==1)
		{
		if(ucT>20)
		ucT--;
		LCD_SetBackColor(Red);
		sprintf((char*)string,"      T : %2dC        ",ucT);
		LCD_DisplayStringLine(Line2,string);
		LCD_SetBackColor(Blue);
		}
		else 	if(qie==2)
		{
		if(ucX==1)
		ucX=2;
		else 
		ucX=1;
		LCD_SetBackColor(Red);
		sprintf((char*)string,"      X : AO%1d       ",ucX);
		LCD_DisplayStringLine(Line4,string);	
		LCD_SetBackColor(Blue);
		}
	}


}
	if(ulTick_ms-ulKey_Time>800)
	{
	switch(ucKey_Long)
		{
		case 3:
		if(ucT<40)
		ucT++;
		LCD_SetBackColor(Red);
		sprintf((char*)string,"      T : %2dC        ",ucT);
		LCD_DisplayStringLine(Line2,string);
		LCD_SetBackColor(Blue);
		break;

		case 4:
		if(ucT>20)
		ucT--; 
		LCD_SetBackColor(Red);
		sprintf((char*)string,"      T : %2dC        ",ucT);
		LCD_DisplayStringLine(Line2,string);
		LCD_SetBackColor(Blue);
		}
	}

}




void USART_Send(u8 *str)
{
u8 index=0;
do{
USART_SendData(USART2,str[index++]);
while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);

}while(str[index]!=0) ;

}





unsigned int ADC1_Conv(void)
{

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

}

unsigned int ADC1_InjConv(void)
{

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

}

void LCD_Proc(void)
{

	if(shezhi==0)
	{
	LCD_DisplayStringLine(Line0,"      Main          ");

	if(ulSec!=ulSec1)
	{
	ulSec1=ulSec;
	uiAO1=(float)ADC1_Conv()*3.3/4095.0;
	sprintf((char*)string,"  AO1 :%5.2fV       ",uiAO1);
	LCD_DisplayStringLine(Line2,string);

	uiAO2=(float)ADC1_InjConv()*3.3/4095.0;
	sprintf((char*)string,"  AO2 :%5.2fV       ",uiAO2);
	LCD_DisplayStringLine(Line4,string);

	ucPwm=TIM3_Pwm();
	sprintf((char*)string,"  PWM2: %2d%%         ",ucPwm);
	LCD_DisplayStringLine(Line6,string);

	uiTemp=dsb_read();
	sprintf((char*)string,"  Temp:%5.2fC      ",uiTemp/16.0);
	LCD_DisplayStringLine(Line8,string);
	}
	sprintf((char*)string,"  N   : %d           ",ucNum);
	LCD_DisplayStringLine(Line9,string);

   }

   if((uiAO1>ucPwm*0.033)||(uiAO2>ucPwm*0.333))
   {
   	sprintf((char*)string,"$%5.2f\r\n",uiTemp/16.0);
	USART_Send(string);
	Delay_Ms(1000);
	ucled|=0x01;
   }
   else 
   ucled&=0xfe;
}


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

void SysTick_Handler(void)
{
TimingDelay--;
ulTick_ms++;

if(ulTick_ms%500==0)
{
ulSec++;
}

if(uiTemp/16.0>ucT)
{
if(ulTick_ms%200==0)
{
ucled^=0x80;
}

}
else 
ucled&=0x7f;



if(ulTick_ms%1000==0)
{
STM3210B_SEG_Init();
SEG_DisplayValue(0x10,0x10,0x10);

if(ulSec&2)
SEG_DisplayValue(0xc,ucT/10,ucT%10);	
else 
SEG_DisplayValue(0xa,0,ucX);

USART2_Init();
}
}


unsigned char TIM3_Pwm(void)
{
if(TIM_GetFlagStatus(TIM3,TIM_FLAG_CC2))
return ((TIM_GetCapture1(TIM3)+1)*100.0/(TIM_GetCapture2(TIM3)+1));
else 
return 1;

}

void USART2_IRQHandler(void)
{
  u8 temp;
  if(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) != RESET)
  {
    USART_ClearITPendingBit(USART2, USART_FLAG_RXNE);
	/* Read one byte from the receive data register */
    temp = USART_ReceiveData(USART2);

    if(temp=='S')
    {
      shuju=1;
    }
	else if(temp=='P')
	{
	 canshu=1;
	}
  }

//pucRcv[ucRno++]=USART_ReceiveData(USART2);
  
  
}

void UART_Proc(void)
{
//0x0D(asc码是13) 指的是“回车”   \r是把光标置于本行行首

 

//0x0A(asc码是10) 指的是“换行”    \n是把光标置于下一行的同一列
if(ucRno)
{
if(pucRcv[ucRno-1]==0xa)
{
if((pucRcv[0]=='S')&&(pucRcv[1]=='T')&&(pucRcv[3]==0xd))
{
sprintf((char*)string,"$%5.2f\r\n",uiTemp/16.0);
USART_Send(string);
}
else if((pucRcv[0]=='P')&&(pucRcv[1]=='A')&&(pucRcv[3]=='R')&&(pucRcv[3]=='A')&&(pucRcv[3]==0xd))
{
sprintf((char*)string,"#%2d,AO%1d\r\n",ucT,ucX);
USART_Send(string);
}
else 
USART_Send("ERROR\r\n");
ucRno=0;
}

else if(ucRno==6)
{
USART_Send("ERROR\r\n");
ucRno=0;

}
}

}

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

 

上一篇:关于php插件pdo_mysql的安装


下一篇:嵌入式Linux开发9——RGBLCD显示