第十届决赛题目考察的知识点较多,题目较为综合,主要考察两路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);
}