嵌入式系统 实验四 STM 应用设计

实验四 STM 应用设计

1 实验目的

1). 综合掌握 STM32 的 LED 显示、通用定时器 TIM2、中断控制及串口通讯的原理, 完成数据串口数据写到 PC 机上;
2). 设计一个具体的应用;
3). 掌握基于 STM32 工程开发流程。

2 实验环境

1). 硬件:1 个空气温湿度传感器模块、1 个 ST-Link 调试器、1 根 USB2.0 方口线、1
根 USB3.0 数据线、1 台 PC 机;
2). 软件:Windows 7/XP、MDK 集成开发环境。

3 实验功能

通过使用STM32的ADC模块将模拟信号转换为数字信号,通用定时器 TIM2 中断方式控制LED灯当温度超过设定阈值时亮起报警,将事实温度通过串口打印出来。

4 实验步骤

1.)将 USB3.0 数据线的一端连接感知执行模块的 USB3.0 调试烧写口,另一端连接
ST-Link 调试器的“Debug”接口。
2.)将 USB2.0 方口线的一端连接 PC 机的 USB 口,另一端连接 ST-Link 调试器的
“USB-232”接口,连接正确后效果如图 4.5 所示。
3.)双击打开工程文件“STM32-Timer.uvproj”。
4.)在工具栏中点击按钮 ,编译工程成功后,信息框会出现下图所示的信息。如果
编译失败,请确认相关选项是否配置正确。
5.)确认与硬件调试有关的选项已设置正确。
6.)点击按钮 ,将程序下载到温湿度传感器模块中。下载成功后,信息框显示下图
中所示的信息,表明程序下载成功并已自动运行。

5 实验程序

#include"stm32f10x.h"
#include<stdio.h>
void gpio_init(void)  //gpio初始化
{
	GPIO_InitTypeDef GPIO_InitStructure;  //初始化配置
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOF, ENABLE); //定义结构体
	
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); // 禁用 JTAG 功能, 功能存疑
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_5 |GPIO_Pin_6|GPIO_Pin_7; // 选择要控制的 GPIOB 引脚
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//PB7 的推挽输出
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //  PA 9 做TX脚进行输出。TX:发送数据输出端口
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  // PA 10 做RX引脚做输入。RX:接收数据输入端口
	GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void led_init(void) // 点亮 User1 指示灯
{
		 GPIO_SetBits(GPIOB,GPIO_Pin_4);  
	 GPIO_SetBits(GPIOB,GPIO_Pin_5);  
	 GPIO_SetBits(GPIOB,GPIO_Pin_6);  
  GPIO_ResetBits(GPIOB, GPIO_Pin_7);
}
void USART1_Config(void){   //USART的初始化配置
	USART_InitTypeDef USART_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);//开启USART1的时钟
	USART_InitStructure.USART_BaudRate = 115200;   
	USART_InitStructure.USART_WordLength = USART_WordLength_8b; // 设置数据位:1个起始位, 8个数据位
	USART_InitStructure.USART_StopBits = USART_Parity_No;// 1个停止位
	USART_InitStructure.USART_Parity = USART_Parity_No;   //无奇偶校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; // CTS失能
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //使能发送和接收
	USART_Init(USART1, &USART_InitStructure); //调用库函数,初始化USART1
	USART_Cmd(USART1, ENABLE);
}

int fputc(int ch, FILE *f)//写字符文件函数
{
	USART_SendData(USART1, (unsigned char)ch);
	while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET)
	{
	}
	return (int)ch;
}
// 时钟函数设置
void TIM2_Configuration(void)
{

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;  //定义一个定时器初始化参数结构体
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,  ENABLE); //开启APB2的TIM2的外设时钟
TIM_DeInit(TIM2); //TIM2相关参数进行缺省设置
	
TIM_TimeBaseStructure.TIM_Period = 10000; //自动装载值为1000
TIM_TimeBaseStructure.TIM_Prescaler = (7200 - 1); //预分频系数为7199 
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;//向上计数模式
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;//单倍分频
TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);//通过结构体初始化相关寄存器
TIM_ClearFlag(TIM2, TIM_FLAG_Update); //清除溢出中断标志
TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); //使能TIM2中断, 允许更新中断
	TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);
TIM_Cmd(TIM2, ENABLE);//使能TIM2外设

}

// 中断函数设置
void TIM2_NVIC_Configuration(void)
{

NVIC_InitTypeDef NVIC_InitStructure; // 定义 NVIC 初始化结构体
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); // 选择中断优先级分组 0
NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; // 选择配置 TIM2 全局中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级为 0
NVIC_InitStructure.NVIC_IRQChannelSubPriority =1; // 响应优先级为 1
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; // 使能 TIM2 中断通道
NVIC_Init(&NVIC_InitStructure); // 根据以上配置初始化 NVIC
}
//ADC初始化
void T_Adc_Init(void)
{
ADC_InitTypeDef ADC_InitStructure; 
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE );
// 开启外设时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置分频因子为 6 则时钟频率为 72M/6=12MHz
 ADC_DeInit(ADC1); // 复位 ADC1
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 数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 1; // 顺序进行规则转换的 ADC 通道数为 1
ADC_Init(ADC1, &ADC_InitStructure); // 初始化外设 ADC1 的寄存器
ADC_TempSensorVrefintCmd(ENABLE); // 开启内部温度传感器
ADC_Cmd(ADC1, ENABLE); // 使能 ADC1
ADC_ResetCalibration(ADC1); // 执行复位校准
 while(ADC_GetResetCalibrationStatus(ADC1)); // 等待复位校准结束
ADC_StartCalibration(ADC1); // 执行 ADC1 校准
while(ADC_GetCalibrationStatus(ADC1)); //等待 ADC1 校准结束
}
int main(void)
{
  gpio_init();
	led_init();
	USART1_Config();
	TIM2_Configuration();
	TIM2_NVIC_Configuration();
	T_Adc_Init();
	printf("welcome to the temperature warning system!");
	while(1);
}

float adcx,temperate,temp;
uint16_t T_Get_Adc(uint8_t ch)
{
ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );
ADC_SoftwareStartConvCmd(ADC1, ENABLE); // 使能 ADC1 的软件转换启动功能
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC )); // 等待转换结束
return ADC_GetConversionValue(ADC1); // 返回最近一次 ADC1 规则组的转换结果
}
void TIM2_IRQHandler(void)
{
if ( TIM_GetITStatus(TIM2 , TIM_IT_Update) != RESET )
// 0.1S 时间到,检测到 TIM2 中断
{ 
		adcx=T_Get_Adc(ADC_Channel_16); // 读取 ADC1 转换值
		temp=(float)adcx*(3.3/4096); // 计算电压值
		temperate=(1.43-temp)/0.0043+25; // 计算温度
		if(temperate >= 30)
{
		printf("warning:temperate is so high!\n");
	printf("temp:%0.1f℃ \r\n", temperate); // 打印警报消息 
	GPIO_ResetBits(GPIOB,GPIO_Pin_5);//指示灯亮
}
		else{		
		printf("the temperate is proper!\n");
			printf("temp:%0.1f ℃\r\n", temperate); // 通过 USART1 打印温度值 
}
	}
TIM_ClearITPendingBit(TIM2 , TIM_FLAG_Update); // 清除中断标志位
} 

6 实验结果

程序成功运行后,将可以看到User1灯常亮,代表工作状态, 当温度高于30摄氏度时橙灯亮开始报警。
在这里插入图片描述
在这里插入图片描述

7 实验心得

通过综合实验熟悉STM32嵌入式系统的设计与使用,尤其是ADC将模拟信号转换为数字信号。实现的功能为每过一秒发送一次温度数据,如果高于30摄氏度就报警,并亮起橙灯,熟悉了中断的ADC的用法。

  • 2
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
嵌入式基于STM32的多量程电压表是一种用来测量电压的设备,它的特点是使用STM32作为主控芯片,通过嵌入式技术来实现多量程的功能。 首先,STM32是一款高性能的32位微控制器,具有丰富的外设接口和强大的计算能力,可以满足多量程电压表的数据处理和控制需求。同时,STM32系列芯片还拥有低功耗和高稳定性的特点,非常适合嵌入式应用。 多量程电压表的设计是基于不同的电压范围进行测量,一般包括多个电压档位,如0-5V、0-10V、0-20V等。嵌入式基于STM32的电压表利用STM32的模拟引脚和ADC(模数转换器)模块来实现对不同电压范围的测量。 在硬件设计上,需要将被测电压与STM32的模拟引脚相连接,并采用适当的电阻分压网络来进行电压划分,以确保被测电压在不同的量程下都能正常工作。 在软件设计上,首先需要初始化STM32的ADC模块,并设置合适的参数,如采样率和转换精度等。然后,通过使用合适的转换公式,将ADC测得的原始数值转换为对应的电压值。为了实现多量程的功能,可以通过设置不同的ADC参考电压或调整电压划分比例来切换不同的量程档位。 除了基本的测量功能,嵌入式基于STM32的多量程电压表还可以具备其他附加功能,如数据存储、显示和通信等。通过添加合适的外设,如存储器芯片、LCD显示屏和通信模块,可以将测量结果保存、显示出来,并且可以通过串口或无线通信将数据传输到其他设备。 总之,嵌入式基于STM32的多量程电压表利用STM32的强大功能和灵活性,通过硬件和软件的设计实现对多个量程电压的测量,可以广泛应用于电子实验、工业控制和科学研究等领域。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值