}
voidLED_GPIO_Config()
{
GPIO_InitTypeDefGPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);//使能PD端口时钟
=GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11;//LED0-->端口配置
=GPIO_Mode_Out_PP;//推挽输出
=GPIO_Speed_50MHz;//IO速度50MHz
GPIO_Init(GPIOD,&GPIO_InitStructure);//根据设定参数初始化
}
voidSysTick_Init()
{
if(SysTick_Config(SystemCoreClock/1000))
{
while
(1);
}
SysTick->CTRL&=~SysTick_CTRL_ENABLE_Msk;//关闭滴答定时器
//SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;//开启滴答定时器
}
voidDelay_ms(__IOu32nTime)
{
TimingDelay=nTime;
SysTick->CTRL|=SysTick_CTRL_ENABLE_Msk;//打开
while(TimingDelay!
=0);
}
voidRCC_Config(void)//配置时钟
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);//DMA
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOC,ENABLE);//ADC1andGPIOC
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA,ENABLE);//USART
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD,ENABLE);//使能PD端口时钟LED
}
voidGPIO_Config(void)
{
GPIO_InitTypeDefGPIO_InitStructure;
/***Config(ADC1)***/
=GPIO_Pin_1;
=GPIO_Mode_AIN;
GPIO_Init(GPIOC,&GPIO_InitStructure);
/***ConfigLED***/
=GPIO_Mode_Out_PP;//推挽输出
=GPIO_Speed_50MHz;//IO速度50MHz
GPIO_Init(GPIOD,&GPIO_InitStructure);//根据设定参数初始化
/***ConfigUSART***/
/*ConfigureUSART1Txasalternatefunctionpush-pull*/
=GPIO_Pin_9;
=GPIO_Mode_AF_PP;
=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
/*ConfigureUSART1Rxasinputfloating*/
=GPIO_Pin_10;
=GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
voidDMA_Config(void)
{
/*DMAchannel1configuration*/
DMA_InitTypeDefDMA_InitStructure;
DMA_DeInit(DMA1_Channel1);
=ADC1_DR_Address;/*ADC*/
=(u32)&ADC_ConvertedValue;
=DMA_DIR_PeripheralSRC;
=16;
=DMA_PeripheralInc_Disable;
=DMA_MemoryInc_Disable;
=DMA_PeripheralDataSize_HalfWord;
=DMA_MemoryDataSize_HalfWord;
=DMA_Mode_Circular;
=DMA_Priority_High;
=DMA_M2M_Disable;
DMA_Init(DMA1_Channel1,&DMA_InitStructure);
/*EnableDMAchannel1*/
DMA_Cmd(DMA1_Channel1,ENABLE);
}
voidADC1_Config(void)
{ADC_InitTypeDefADC_InitStructure;
=ADC_Mode_Independent;
=ENABLE;
=ENABLE;
=ADC_ExternalTrigConv_None;
=ADC_DataAlign_Right;
=1;
ADC_Init(ADC1,&ADC_InitStructure);
/*ADC1regularchannel16configuration*/
ADC_RegularChannelConfig(ADC1,ADC_Channel_16,1,ADC_SampleTime_55Cycles5);
ADC_TempSensorVrefintCmd(ENABLE);
ADC_DMACmd(ADC1,ENABLE);
ADC_Cmd(ADC1,ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
ADC_SoftwareStartConvCmd(ADC1,ENABLE);
}
voidUSART1_Config(void)
{
USART_InitTypeDefUSART_InitStructure;
=9600;
=USART_WordLength_8b;
=USART_StopBits_1;
=USART_Parity_No;
=USART_HardwareFlowControl_None;
=USART_Mode_Rx|USART_Mode_Tx;
USART_Init(USART1,&USART_InitStructure);
//USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//接收使能
//USART_ITConfig(USART1,USART_IT_TXE,ENABLE);//发送使能
USART_Cmd(USART1,ENABLE);//启动串口
}
staticuint8_tUSART_Scanf(uint32_tvalue)//字符串读取函数
{
uint32_tindex=0;
uint32_ttmp[2]={0,0};
while(index<2)
{
/*LoopuntilRXNE=1*/
while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==RESET)
{
}
tmp[index++]=(USART_ReceiveData(USART1));
if((tmp[index-1]<0x30)||(tmp[index-1]>0x39))
{
printf("\n\r请输入有效数字0到9-->:
");
index--;
}
}
index=(tmp[1]-0x30)+((tmp[0]-0x30)*10);
/*Checks*/
if(index>value)
{
printf("\n\r请输入有效数字0到%d",value);
return0xFF;
}
returnindex;
}
voidTime_Regulate(rtc_time*tm)//时间设定函数
{
uint32_tTmp_HH=0xFF,Tmp_MI=0xFF,Tmp_SS=0xFF;
uint32_tTmp_up=0xff,Tmp_low=0xff;
printf("\r\n设定温度范围");
printf("\r\n输入温度上限:
");
while(Tmp_up==0xFF)
{
Tmp_up=USART_Scanf(99);
}
printf("\n\r温度上限为%C\n\r",Tmp_up);
upper_bound=Tmp_up;
//-------------------
printf("\r\n输入温度下限:
");
while(Tmp_low==0xFF)
{
Tmp_low=USART_Scanf(99);
}
printf("\n\r温度下限为%C\n\r",Tmp_low);
lower_bound=Tmp_low;
printf("\r\n设定时间");
Tmp_HH=0xFF;
printf("\r\n设定小时:
");
while(Tmp_HH==0xFF)
{
Tmp_HH=USART_Scanf(23);
}
printf("\n\r设定小时为%d\n\r",Tmp_HH);
tm->tm_hour=Tmp_HH;
Tmp_MI=0xFF;
printf("\r\n设定分钟:
");
while(Tmp_MI==0xFF)
{
Tmp_MI=USART_Scanf(59);
}
printf("\n\r设定分钟为%d\n\r",Tmp_MI);
tm->tm_min=Tmp_MI;
Tmp_SS=0xFF;
printf("\r\n设定秒:
");
while(Tmp_SS==0xFF)
{
Tmp_SS=USART_Scanf(59);
}
printf("\n\r设定秒为%d\n\r",Tmp_SS);
tm->tm_sec=Tmp_SS;
}
intfputc(intch,FILE*f)//重定向函数
{
USART_SendData(USART1,(unsignedchar)ch);
//while(!
(USART1->SR&USART_FLAG_TXE));
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!
=SET);
return(ch);
}
/*****************************主函数***********************************************/
intmain(void)
{
#ifdefDEBUG
#endif
SysTick_Init();
LED_GPIO_Config();
RCC_Config();
GPIO_Config();
DMA_Config();
ADC1_Config();
USART1_Config();
Delay(5000);
Time_Regulate(&systmtime);
GPIO_SetBits(GPIOD,GPIO_Pin_8);
GPIO_SetBits(GPIOD,GPIO_Pin_9);
GPIO_SetBits(GPIOD,GPIO_Pin_10);
GPIO_SetBits(GPIOD,GPIO_Pin_11);
sec=;
min=;
hour=;
while
(1)
{
sec++;
if(sec==60)
{sec=0;min++;
if(min==60)
{
min=0;hour++;
if(hour==24)
{
hour=0;
}
}
}
printf("\r\n当前时间:
%d:
%d:
%d\r\n",hour,min,sec);
printf("\r\n当前温度:
%02dC温度上限:
%02dC温度下限:
%02dC\r\n",Average_Temp,upper_bound,lower_bound);
GPIO_SetBits(GPIOD,GPIO_Pin_8);
GPIO_SetBits(GPIOD,GPIO_Pin_9);
GPIO_SetBits(GPIOD,GPIO_Pin_10);
GPIO_SetBits(GPIOD,GPIO_Pin_11);
if(((int)Current_Temp)>((int)upper_bound))
{
GPIO_ResetBits(GPIOD,GPIO_Pin_8);
}
elseif(((int)Current_Temp)<((int)lower_bound))
{
GPIO_ResetBits(GPIOD,GPIO_Pin_11);
}
else{
GPIO_SetBits(GPIOD,GPIO_Pin_8);
GPIO_SetBits(GPIOD,GPIO_Pin_9);
GPIO_SetBits(GPIOD,GPIO_Pin_10);
GPIO_SetBits(GPIOD,GPIO_Pin_11);}
Delay_ms(1000);
}
}
文件:
/*Includes------------------------------------------------------------------*/
#include""
/*Privatefunctions---------------------------------------------------------*/
voiddisplay(void)
{
unsignedcharad_data,ad_value_max,ad_value_min;
ad_data=Current_Temp;
if(ad_sample_cnt==0)
{
ad_value_max=ad_data;
ad_value_min=ad_data;
}
elseif(ad_data{
ad_value_min=ad_data;
}
elseif(ad_data>ad_value_max)
{
ad_value_max=ad_data;
}
ad_value_sum+=ad_data;
ad_sample_cnt++;
if(ad_sample_cnt==10)
{
ad_value_sum-=ad_value_min;
ad_value_sum-=ad_value_max;
ad_value_sum/=8;
calculated_temp=ad_value_sum;
ad_sample_cnt=0;
ad_value_min=0;
ad_value_max=0;
}
}
voidSysTick_Handler(void)
{
TimingDelay--;
ADC_tempValueLocal=ADC_ConvertedValue;
//printf("\n%02d\n,ADC_ConvertedValue");
Current_Temp=(V25-ADC_tempValueLocal)/Avg_Slope+25;
temp_sum+=Current_Temp;
temp_cnt++;
if(temp_cnt>=10)
{
temp_cnt=0;
temp_sum/=10;
Average_Temp=temp_sum;
temp_sum=0;
}
//printf("\r\nThecurrenttemperature=%02dC\r\n",calculated_temp);
}
5、课程总结与个人体会
嵌入式开发是自动化专业的主要课程之一,现实生活中,嵌入式在应用可以说得是无处不在。
因此在大学中掌握嵌入式的开发技术是十分重要的,也是十分必要的。
本次使用基于Cortex-M3内核的32位ARM处理器stm32作为主控制器,设计了一种温度测控系统。
系统中,使用了ADC、DMA、温度传感器、USART、GPIO、定时器、NVIC等资源,实践了课上所学的内容,深深体会到了应用的重要性。
在课程设计的过程中,为了减小干扰的影响,数据采集后,平均算法进行温度输出。
并利用串口设计了简单的交互系统,虽然没有使用上位机,但也达到了比较好的效果。
通过本次课程设计,着实经历到了很多想象不到的困难,自己的一些想法也不够成熟,最后还是参考了别人的解决方案,这让我深深认识到在嵌入式开发这条路上,与别人交流学习是提升自己的非常有效的方式。
在设计串口设定时间的程序时,我最开始的想法是通过USART的中断进行输入字符的识别,从而分别设定时间以及温度上下限,可是经过自己的冥思苦想还是想不出来,怎么都实现不了。
无奈之下,我只好去隔壁寝室的大神那里虚心求教,在参考了他的程序之后我恍然大悟,选择了在循环之外先按顺序读取字符串的方法,顺利解决了我的问题,让我深深认识到了交流的重要性,在自己的想法不够完善时,多多了解些别人的算法对提升自己是有很大帮助的。
由于之前没有完整开发一个有较多功能系统的经历,在本次做课程设计的过程中,走了不少的弯路,也学到很多课本上没有的知识。
使用库开发Stm32时,非常注重模块化的概念,不