本届国赛题目较为综合,涉及adc、串口、输入捕获、输出比较等。
工程结构
init.c
#include "stm32f10x.h"
#include "lcd.h"
#include "init.h"
#include "i2c.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_0;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
GPIO_Init(GPIOB, &GPIO_InitStructure);
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
ADC_InitStructure.ADC_ScanConvMode = DISABLE;
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
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 channel8 configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_13Cycles5);
/* Enable AWD interrupt */
ADC_ITConfig(ADC1, ADC_IT_AWD, ENABLE);
/* Enable ADC1 */
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));
NVIC_Configuration();
}
void TIM2_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
GPIO_InitTypeDef GPIO_InitStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
/* TIM3 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
/* GPIOA clock enable */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
TIM_TimeBaseStructure.TIM_Period = 999;
TIM_TimeBaseStructure.TIM_Prescaler = 71;
TIM_TimeBaseStructure.TIM_ClockDivision = 0;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);
/* PWM1 Mode configuration: Channel1 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_Pulse = 500;
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OC2Init(TIM2, &TIM_OCInitStructure);
TIM_Cmd(TIM2, ENABLE);
}
void TIM3_Init(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
GPIO_InitTypeDef GPIO_InitStructure;
TIM_ICInitTypeDef TIM_ICInitStructure;
/* TIM3 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
/* GPIOA clock 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 = 0;
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 = 0x0;
TIM_ICInit(TIM3, &TIM_ICInitStructure);
TIM_SelectSlaveMode(TIM3,TIM_SlaveMode_Reset);
TIM_SelectInputTrigger(TIM3,TIM_TS_TI2FP2);
/* TIM enable counter */
TIM_Cmd(TIM3, ENABLE);
}
void LCD_Init(void)
{
STM3210B_LCD_Init();
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
SysTick_Config(SystemCoreClock/1000);
LCD_DisplayStringLine(Line0," Real-time Data ");
//LCD_DisplayStringLine(Line1,"Now Temp -20C ");
LCD_DisplayStringLine(Line2," ");
//LCD_DisplayStringLine(Line3,"Now Humi 60% ");
LCD_DisplayStringLine(Line4," ");
//LCD_DisplayStringLine(Line5,"Clock 12-50-00 ");
LCD_DisplayStringLine(Line6," ");
//LCD_DisplayStringLine(Line7,"Number 20 ");
LCD_DisplayStringLine(Line8," ");
LCD_DisplayStringLine(Line9," ");
}
void USART2_Init(void)
{
USART_InitTypeDef USART_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
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 ;
USART_Init(USART2, &USART_InitStructure);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
USART_Cmd(USART2, ENABLE);
}
void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the NVIC Preemption Priority Bits */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
/* Enable the USART2 Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
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();
}
主程序
/*
温度与数模转换的关系 T=kN+b,(N为模数转换值,T是温度)
由已知条件得 T=80N/4095-20;
湿度与捕获值得关系
H=m/C+n;(C为捕获值,H是湿度)
由已知条件得
H=(8000/C+10)/9
*/
#include "stm32f10x.h"
#include "lcd.h"
#include "init.h"
#include "i2c.h"
#include "stdio.h"
u32 TimingDelay = 0;
u8 string[20];
void Key_Scan(void);
void Delay_Ms(u32 nTime);
unsigned int TIM3_Cap(void);
void USART2_Send(u8 *str);
void ADC_Read(void);
void LED_Disp(u16 led);
u8 miao_flag=0;
u16 miao=0;
u8 fazhi=0,shuju=0;
u16 led=0;
int i;
signed char scTemp,scTemp1;
unsigned char ucHumi,ucHumi1,ucFreq; //eeprom只能存整数,所以这里的频率是实际频率的一百分之一
unsigned char ucHour,ucMin,ucSec;
unsigned char ucDataNo=0,ucDataNum=0,Data[60][5];
unsigned long ulTick_ms=0;
unsigned char ucInte;
unsigned long ulSec=0,ulSec1=0,ulSec2=0;
u8 shezhi=0,qie=0;
//Main Body
int main(void)
{
LCD_Init();
GPIO_Int();
TIM2_Init();
TIM3_Init();
i2c_init();
USART2_Init();
Delay_Ms(5);
if(I2C_Read(0x20)!=0)
{
Delay_Ms(5);
I2C_Write(0x20,0);
Delay_Ms(5);
I2C_Write(0x00,40);
Delay_Ms(5);
I2C_Write(0x01,80);
Delay_Ms(5);
I2C_Write(0x02,1);
Delay_Ms(5);
I2C_Write(0x03,15);
}
Delay_Ms(5);
scTemp1=I2C_Read(0x00);
Delay_Ms(5);
ucHumi1=I2C_Read(0x01);
Delay_Ms(5);
ucInte=I2C_Read(0x02);
Delay_Ms(5);
ucFreq=I2C_Read(0x03);
TIM_SetAutoreload(TIM2,10000/ucFreq-1); //周期值
TIM_SetCompare2(TIM2,5000/ucFreq-1); //占比1/2
while(1)
{
Key_Scan();
if(fazhi==1)
{
fazhi=0;
sprintf((char*)string,"C %02u-%02u-%02u %3dC %2u%%\r\n",ucHour,ucMin,ucSec,scTemp1,ucHumi1);
USART2_Send(string);
}
else if(shuju==1)
{
shuju=0;
for(i=0;i<ucDataNum;i++)
{
sprintf((char*)string,"S %02u-%02u-%02u %3dC %2u%%\r\n",Data[i][0],Data[i][1],Data[i][2],Data[i][3],Data[i][4]);
USART2_Send(string);
}
}
ADC_Read();
LED_Disp(led);
}
}
void Key_Scan(void)
{
if(RB1==0)
{
Delay_Ms(5);
if(RB1==0)
{
if(shezhi==0)
{
shezhi=1;
LCD_DisplayStringLine(Line0," Parameter Setup ");
sprintf((char*)string,"Temp Upper:%3dC ",scTemp1);
LCD_DisplayStringLine(Line1,string);
sprintf((char*)string,"Humi Upper:%3d%% ",ucHumi1);
LCD_DisplayStringLine(Line3,string);
sprintf((char*)string,"Interval : %1us ",ucInte);
LCD_DisplayStringLine(Line5,string);
sprintf((char*)string,"Frequency :%2u.%1ukHz ",ucFreq/10,ucFreq%10);
LCD_DisplayStringLine(Line7,string);
}
else if(shezhi==1)
{
shezhi=0;
LCD_DisplayStringLine(Line0," Real-time Data ");
Delay_Ms(5);
I2C_Write(0x00,scTemp1);
Delay_Ms(5);
I2C_Write(0x01,ucHumi1);
Delay_Ms(5);
I2C_Write(0x02,ucInte);
Delay_Ms(5);
I2C_Write(0x03,ucFreq);
}
}while(!RB1);
}
else if(RB2==0)
{
Delay_Ms(5);
if(RB2==0)
{
if(shezhi==1)
{
if(qie==0||qie==4)
{
qie=1;
LCD_SetTextColor(Red);
sprintf((char*)string,"Temp Upper:%3dC ",scTemp1);
LCD_DisplayStringLine(Line1,string);
LCD_SetTextColor(White);
sprintf((char*)string,"Humi Upper:%3d%% ",ucHumi1);
LCD_DisplayStringLine(Line3,string);
sprintf((char*)string,"Interval : %1us ",ucInte);
LCD_DisplayStringLine(Line5,string);
sprintf((char*)string,"Frequency :%2u.%1ukHz ",ucFreq/10,ucFreq%10);
LCD_DisplayStringLine(Line7,string);
}
else if(qie==1)
{
qie=2;
LCD_SetTextColor(Red);
sprintf((char*)string,"Humi Upper:%3d%% ",ucHumi1);
LCD_DisplayStringLine(Line3,string);
LCD_SetTextColor(White);
sprintf((char*)string,"Temp Upper:%3dC ",scTemp1);
LCD_DisplayStringLine(Line1,string);
sprintf((char*)string,"Interval : %1us ",ucInte);
LCD_DisplayStringLine(Line5,string);
sprintf((char*)string,"Frequency :%2u.%1ukHz ",ucFreq/10,ucFreq%10);
LCD_DisplayStringLine(Line7,string);
}
else if(qie==2)
{
qie=3;
LCD_SetTextColor(Red);
sprintf((char*)string,"Interval : %1us ",ucInte);
LCD_DisplayStringLine(Line5,string);
LCD_SetTextColor(White);
sprintf((char*)string,"Temp Upper:%3dC ",scTemp1);
LCD_DisplayStringLine(Line1,string);
sprintf((char*)string,"Humi Upper:%3d%% ",ucHumi1);
LCD_DisplayStringLine(Line3,string);
sprintf((char*)string,"Frequency :%2u.%1ukHz ",ucFreq/10,ucFreq%10);
LCD_DisplayStringLine(Line7,string);
}
else if(qie==3)
{
qie=4;
LCD_SetTextColor(Red);
sprintf((char*)string,"Frequency :%2u.%1ukHz ",ucFreq/10,ucFreq%10);
LCD_DisplayStringLine(Line7,string);
LCD_SetTextColor(White);
sprintf((char*)string,"Temp Upper:%3dC ",scTemp1);
LCD_DisplayStringLine(Line1,string);
sprintf((char*)string,"Humi Upper:%3d%% ",ucHumi1);
LCD_DisplayStringLine(Line3,string);
sprintf((char*)string,"Interval : %1us ",ucInte);
LCD_DisplayStringLine(Line5,string);
}
}
}while(!RB2);
}
else if(RB3==0)
{
Delay_Ms(5);
if(RB3==0)
{
if(shezhi==1)
{
if(qie==1)
{
if(scTemp1<60)
scTemp1+=1;
LCD_SetTextColor(Red);
sprintf((char*)string,"Temp Upper:%3dC ",scTemp1);
LCD_DisplayStringLine(Line1,string);
LCD_SetTextColor(White);
}
else if(qie==2)
{
if(ucHumi1<90)
ucHumi1+=5;
LCD_SetTextColor(Red);
sprintf((char*)string,"Humi Upper:%3d%% ",ucHumi1);
LCD_DisplayStringLine(Line3,string);
LCD_SetTextColor(White);
}
else if(qie==3)
{
if(ucInte<5)
ucInte+=1;
LCD_SetTextColor(Red);
sprintf((char*)string,"Interval : %1us ",ucInte);
LCD_DisplayStringLine(Line5,string);
LCD_SetTextColor(White);
}
else if(qie==4)
{
if(ucFreq<100)
ucFreq+=5;
LCD_SetTextColor(Red);
sprintf((char*)string,"Frequency :%2u.%1ukHz ",ucFreq/10,ucFreq%10);
LCD_DisplayStringLine(Line7,string);
LCD_SetTextColor(White);
TIM_SetAutoreload(TIM2,10000/ucFreq-1);
TIM_SetCompare2(TIM2,5000/ucFreq-1);
}
}
}while(!RB3);
}
else if(RB4==0)
{
Delay_Ms(5);
if(RB4==0)
{
if(shezhi==1)
{
if(qie==1)
{
if(scTemp1>-20)
scTemp1-=1;
LCD_SetTextColor(Red);
sprintf((char*)string,"Temp Upper:%3dC ",scTemp1);
LCD_DisplayStringLine(Line1,string);
LCD_SetTextColor(White);
}
else if(qie==2)
{
if(ucHumi1>10)
ucHumi1-=5;
LCD_SetTextColor(Red);
sprintf((char*)string,"Humi Upper:%3d%% ",ucHumi1);
LCD_DisplayStringLine(Line3,string);
LCD_SetTextColor(White);
}
else if(qie==3)
{
if(ucInte>1)
ucInte-=1;
LCD_SetTextColor(Red);
sprintf((char*)string,"Interval : %1us ",ucInte);
LCD_DisplayStringLine(Line5,string);
LCD_SetTextColor(White);
}
else if(qie==4)
{
if(ucFreq>10)
ucFreq-=5;
LCD_SetTextColor(Red);
sprintf((char*)string,"Frequency :%2u.%1ukHz ",ucFreq/10,ucFreq%10);
LCD_DisplayStringLine(Line7,string);
LCD_SetTextColor(White);
TIM_SetAutoreload(TIM2,10000/ucFreq-1);
TIM_SetCompare2(TIM2,5000/ucFreq-1);
}
}
}while(!RB4);
}
}
void Delay_Ms(u32 nTime)
{
TimingDelay = nTime;
while(TimingDelay != 0);
}
void ADC_Read(void)
{
if(shezhi==0)
{
if(ulSec!=ulSec1)
{
ulSec1=ulSec;
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
scTemp=(ADC_GetConversionValue(ADC1)*80)/0xfff-20;
sprintf((char*)string,"Now Temp %3dC ",scTemp);
LCD_DisplayStringLine(Line1,string);
ucHumi=(80000/TIM3_Cap()+10)/9;
sprintf((char*)string,"Now Humi %3d%% ",ucHumi);
LCD_DisplayStringLine(Line3,string);
sprintf((char*)string,"Clock %02u-%02u-%02u ",ucHour,ucMin,ucSec);
LCD_DisplayStringLine(Line5,string);
sprintf((char*)string,"Number %2u ",ucDataNum);
LCD_DisplayStringLine(Line7,string);
}
if((ulSec-ulSec2)>=ucInte)
{
ulSec2=ulSec;
Data[ucDataNo][0]=ucHour;
Data[ucDataNo][1]=ucMin;
Data[ucDataNo][2]=ucSec;
Data[ucDataNo][3]=scTemp;
Data[ucDataNo][4]=ucHumi;
if(++ucDataNo==60)ucDataNo=0;
if(ucDataNum!=60)ucDataNum++;
sprintf((char*)string,"Number %2u ",ucDataNum);
LCD_DisplayStringLine(Line7,string);
led^=4;
}
}
}
unsigned int TIM3_Cap(void)
{
if(TIM_GetFlagStatus(TIM3,TIM_FLAG_CC2))
{
return TIM_GetCapture2(TIM3)+1;
}
else
return 0;
}
void USART2_IRQHandler(void)
{
u8 temp;
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
USART_ClearITPendingBit(USART2, USART_IT_RXNE);
temp = USART_ReceiveData(USART2);
if(temp == 'C')
{
fazhi=1;
}
else if(temp=='S')
{
shuju=1;
}
}
}
void USART2_Send(u8 *str)
{
u8 index=0;
do{
USART_SendData(USART2,str[index++]);
while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
}while(str[index]!=0);
}
void LED_Disp(u16 led)
{
GPIO_Write(GPIOC,~led<<8);
GPIO_SetBits(GPIOD,GPIO_Pin_2);
GPIO_ResetBits(GPIOD,GPIO_Pin_2);
}
void SysTick_Handler(void)
{
TimingDelay--;
// if(++miao==1000)
// {
// miao=0;
// miao_flag=1;
// }
ulTick_ms++;
if(ulTick_ms%1000==0)
{
ulSec++;
ucHour=ulSec/3600;
ucMin=ulSec%3600/60;
ucSec=ulSec%3600%60;
}
if(scTemp>=scTemp1)
{
if(ulTick_ms%200==0)
led^=1;
}
else led&=0xfe;
if(ucHumi>=ucHumi1)
{
if(ulTick_ms%200==0)
led^=2;
}
else led&=0xfd;
}