当前位置: 首页> 汽车> 车展 > stm32f103c8t6单片机实现电压测量

stm32f103c8t6单片机实现电压测量

时间:2025/7/9 16:36:15来源:https://blog.csdn.net/GFCLJY/article/details/140001362 浏览次数: 0次

一、概述

        因为课程需要的原因,我使用stm32f103c8t6单片机编写电压测量,用来对传感器的输出电压进行读取。并将单片机读取出来的电压值在OLED屏幕上显示。

二、引脚设置

(一)概述

        我们使用面包板进行操作,实际所需要stm32f103c8t6端口有三个,我选择PA0作为端口电压读取端口,PB8和PB9作为与OLED显示屏链接的端口。由于与OLED显示屏的链接不是我们所叙述的重点,不过多的叙述。重点说明与电压测量有关的PA0端口配置。

(二)具体设置

        PA0设置为模拟输入,PB8和PB9全部设置为开漏输出。

三、代码实现

(一)概述

        使用Keil uVision5进行代码编写。

(二)具体实现

        1.主要函数

        首先为主函数针对各个引脚的初始化部分,代码如下所示。这里将所有引脚的初始化全部封装为相应的函数。首先是GPIO引脚的初始化;其次是将首先初始化后的GPIO引脚配置为ADC模式,用于读取电压;最后是OLED屏幕所需要引脚的初始化,将读取电压进行可视化显示。

GPIO_Config();
ADC_Config();
OLED_Init();

        2.GPIO_Config()函数

        这里我们初始化两个引脚,其中PA0设置为模拟输入模式,用于后续的ADC配置,来读取电压;PA1设置为推挽输出,用于点亮LED灯。

void GPIO_Config(void) {// 需要注意系列号,不同系列号使用的库函数以及写法不同// 初始化时钟信号RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);// 配置引脚// 引脚A0用于读取电压GPIO_InitTypeDef GPIO_InitStructure; // 定义结构体变量
//	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; // 设置为模拟输入模式GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; // 选择A0号引脚GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 没有特别追求频率的话,50就可以GPIO_Init(GPIOA, &GPIO_InitStructure);// 引脚A1用于在传感器受到遮挡时,使LED发光GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; // 选择A1号引脚GPIO_Init(GPIOA, &GPIO_InitStructure);
}

        3.ADC_Config()函数

void ADC_Config(void) {// 启用ADC1时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);// ADC 初始化结构体ADC_InitTypeDef ADC_InitStruct;// 配置 ADC 参数ADC_InitStruct.ADC_Mode = ADC_Mode_Independent;ADC_InitStruct.ADC_ScanConvMode = DISABLE;ADC_InitStruct.ADC_ContinuousConvMode = ENABLE;ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right;ADC_InitStruct.ADC_NbrOfChannel = 1;// 初始化 ADCADC_Init(ADC1, &ADC_InitStruct);// 配置 ADC 通道ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5);// 启用 ADCADC_Cmd(ADC1, ENABLE);// 校准 ADCADC_ResetCalibration(ADC1);while (ADC_GetResetCalibrationStatus(ADC1));ADC_StartCalibration(ADC1);while (ADC_GetCalibrationStatus(ADC1));// 启动 ADC 转换ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}

        4.OLED_Init()函数

        是使用购买OLED显示屏时,商家所提供的对应库函数文件,不需要自己进行重新编写,只需调用商家所提供好的接口进行输入。下面主要展示对引脚的初始化部分,如下所示,使用PB8和PB9两个引脚。

/*引脚配置*/
#define OLED_W_SCL(x)		GPIO_WriteBit(GPIOB, GPIO_Pin_8, (BitAction)(x))
#define OLED_W_SDA(x)		GPIO_WriteBit(GPIOB, GPIO_Pin_9, (BitAction)(x))/*引脚初始化*/
void OLED_I2C_Init(void)
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;GPIO_Init(GPIOB, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;GPIO_Init(GPIOB, &GPIO_InitStructure);OLED_W_SCL(1);OLED_W_SDA(1);
}

        5.主函数

        主函数中功能性循环函数如下所示,用于处理端口接受到的电压值,将其处理之后,在OLED屏幕上显示。显示逻辑比较简单。

while (1){// 读取 ADC 值uint16_t adc_value = ADC_GetConversionValue(ADC1);// 将 ADC 值转换为电压值(假设参考电压为3.3V,12位 ADC)float voltage = (adc_value * 3.3) / 4095;// 整数部分uint32_t integer = (uint32_t)voltage;// 小数点第一位uint32_t pointOne = (uint32_t)(( voltage - (uint32_t)voltage ) * 10);// 小数点第二位uint32_t pointTwo = (uint32_t)((( voltage - (uint32_t)voltage ) * 10 - pointOne) * 10;		// 在屏幕上显示OLED_ShowString(1, 1, "voltage:");OLED_ShowNum(2, 1, integer, 1);OLED_ShowChar(2, 2, '.');OLED_ShowNum(2, 3, pointOne, 1);OLED_ShowNum(2, 4, pointTwo, 1);OLED_ShowChar(2, 5, 'V');}

(三)烧录

        将上述程序使用keil uvision5进行编译,发现无报错后烧录入stm32f103c8t6中,附加测量电路的制作和程序编写全部完成。

关键字:stm32f103c8t6单片机实现电压测量

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: