STM32F103嵌入式软件启蒙篇:串口输出输入与ADC采集的仿真平台实现

上一篇:[嵌入式软件][启蒙篇][仿真平台] STM32F103实现LED、按键
本文章使用的电路,见上一篇。

文章目录

  • 一、串口输出
  • (1) 简介
  • (2) 示例代码
  • (3) 仿真效果
  • 二、串口输入
  • (1) 简介
  • (2) 示例代码
  • (3) 仿真效果
  • 三、ADC采集
  • (1) 简介
  • (2) 采集电压
  • (3) 示例代码(电压)
  • (4) 仿真效果 (电压)
  • (5) 采集光敏
  • (6) 示例代码(光敏)
  • (6) 仿真效果 (光敏)
  • (7) 内部温度
  • (8) 示例代码(内部温度)
  • (9) 仿真效果 (内部温度)
  • 一、串口输出

    (1) 简介

    1. 学C语言时,使用的printf()函数,就是通过串口打印出来的。
    2. 跟外部器件通信,比如GPS模块、蓝牙模块、wifi模块;
    3. 两个开发板之间通信,制定私有协议。
    4. PC电脑通信,使用上位机显示数据或控制下位机。

    (2) 示例代码

    #include <stdint.h>
    #include <stdio.h>
    #include "sys.h"
    #include "stm32f10x_conf.h"
    
    #include "delay.h"
    #include "led.h"
    #include "key.h"
    #include "usart.h"
    
    int main() {
        // LED初始化
        LED_Init();
        // 按键初始化
        KEY_Init();
        //串口初始化
        uart_init(115200);
        // 由于LED接了VCC, 引脚高电平,无法导通电路,所以低电平点亮,即VCC(火线)-->GND(地线/零线)
        while(1) {
            if (Key_Scan(GPIOA, GPIO_Pin_1)) { // 检测按键整个过程。按下->松开
                LED = !LED;  // 每次按下,切换开关。低电平点亮 高电平熄灭
                printf("key pressed. led state:%u\n", LED);
            }
        }
    }
    

    (3) 仿真效果

    1. 操作:打开串口–按下按键

    二、串口输入

    (1) 简介

    1. 跟外部器件通信,比如GPS模块、蓝牙模块、wifi模块;
    2. 两个开发板之间通信,制定私有协议。
    3. PC电脑通信,使用上位机输入参数或控制下位机。

    (2) 示例代码

    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    #include "sys.h"
    #include "stm32f10x_conf.h"
    
    #include "delay.h"
    #include "led.h"
    #include "key.h"
    #include "usart.h"
    
    int main() {
        // LED初始化
        LED_Init();
        // 按键初始化
        KEY_Init();
        //串口初始化
        uart_init(115200);
        // 由于LED接了VCC, 引脚高电平,无法导通电路,所以低电平点亮,即VCC(火线)-->GND(地线/零线)
        while(1) {
            if (Key_Scan(GPIOA, GPIO_Pin_1)) { // 检测按键整个过程。按下->松开
                LED = !LED;  // 每次按下,切换开关。低电平点亮 高电平熄灭
                printf("key pressed. led state:%u\n", LED);
            }
            if ((USART_RX_STA & 0x8000) == 0x8000) { // 接收完成
                printf("rx:%s\r\n", USART_RX_BUF); // 打印刚刚接收的数据
                USART_RX_STA = 0; // 继续接收数据
                memset(USART_RX_BUF, 0, USART_REC_LEN); // 将刚刚接收到的数据清空
            }
        }
    }
    
    

    重点:还有一个地方需要小修改(平台没有实现,我们这里替换下就行),有兴趣可以研究下功能的实现

    void USART1_IRQHandler(void) { //串口1中断服务程序
    	uint16_t Res;
    	// 接收中断(接收到的数据必须是0x0d 0x0a结尾, 就是换行符\r\n)
    	if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) {
    		Res = USART_ReceiveData(USART1); //读取接收到的数据
    		if ((USART_RX_STA & 0x8000) == 0) { //接收未完成
    			if (USART_RX_STA & 0x4000) { //接收到了0x0d
    				if (Res != 0x0a)
    					USART_RX_STA = 0; //接收错误,重新开始
    				else
    					USART_RX_STA |= 0x8000; //接收完成了
    			} else { //还没收到0X0D
    				if (Res == 0x0d)
    					USART_RX_STA |= 0x4000;
    				else {
    					USART_RX_BUF[USART_RX_STA & 0X3FFF] = Res;
    					USART_RX_STA++;
    					if (USART_RX_STA > (USART_REC_LEN - 1))
    						USART_RX_STA = 0; //接收数据错误,重新开始接收
    				}
    			}
    		}
    	}
    }
    

    (3) 仿真效果

    1. 操作:打开串口–发送消息:123456\r\n

    三、ADC采集

    这个实验需要添加电路,如下图:

    1. 将按钮移除
    2. 添加电压调节器

    (1) 简介

    1. ADC是一个专门采集模拟量转为为数字信号的外设。
    2. ADC一般采集电压、电流、光敏(光亮度)、温度、湿度、压力、声音等等。

    (2) 采集电压

    本实验使用STM32采样ADC模拟输入器的数据,开启仿真后,串口助手将ADC数值与转换出的电压值一并打印。

    (3) 示例代码(电压)

    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    #include "sys.h"
    #include "stm32f10x_conf.h"
    
    #include "delay.h"
    #include "led.h"
    #include "adc.h"
    #include "usart.h"
    
    uint32_t adc_value = 0;
    float voltage_value = 0;        //用于保存转换计算后的电压值
    
    int main() {
        // LED初始化
        LED_Init();
        // ADC1通道1初始化
        Adc_Init();
        //串口初始化
        uart_init(115200);
        while(1) {
            // 通过ADC_GetConversionValue函数查询ADC的DR寄存器获取ADC转换结果值
            adc_value = Get_Adc(1);
            // 计算出模拟输入的电压值
            voltage_value=(float)adc_value*(3.3/4095);           
            
            // 打印ADC转换结果值
            printf("AD value is %d\n", adc_value);
            //打印计算出的电压值
            printf("voltage value is %f V\n", voltage_value);
            LED = !LED;
            delay_ms(50);
        }
    }
    

    (4) 仿真效果 (电压)

    1. 操作: 打开串口–调整电压

    (5) 采集光敏

    1. 光敏电阻的特性:光线越亮,阻值越小。
    2. 一般用于走廊,白天不亮,晚上亮,做到省电的效果。
    3. 按下图搭建电路

    (6) 示例代码(光敏)

    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    #include "sys.h"
    #include "stm32f10x_conf.h"
    
    #include "delay.h"
    #include "led.h"
    #include "adc.h"
    #include "usart.h"
    
    //设定基于ADC信号的模拟光强阈值
    #define lux 2200
    uint32_t adc_value = 0;
    
    int main() {
        // LED初始化
        LED_Init();
        // ADC1通道1初始化
        Adc_Init();
        //串口初始化
        uart_init(115200);
        while(1) {
            // 通过ADC_GetConversionValue函数查询ADC的DR寄存器获取ADC转换结果值
            adc_value = Get_Adc(1);
            // 打印ADC转换结果值
            printf("AD value is %d\n", adc_value);
            if (adc_value > lux) {
                LED = 0; // 点亮
            } else {
                LED = 1; // 熄灭
            }
            delay_ms(50);
        }
    }
    
    

    (6) 仿真效果 (光敏)

    1. 操作:打开串口–调节光敏电阻–从0-100%调整–当阻值>2000,点亮;阻值<2000,熄灭。

    (7) 内部温度

    1. 芯片内部温度,目的:让电阻计算更佳准确,因为温度会影响阻值。 (一般用不上,不精确)
    2. 测量CPU以及周围的温度,测量范围为-40~125度,误差为±1.5度
    3. 内部温度传感器更适合于检测温度的变化,需要测量精确温度的情况下,应使用外置传感器。
    4. 温度传感器模拟输入推荐采样时间是 17.1us。
    5. 温度的计算公式如下:
      T(℃)= {( V25-Vsense)/ Avg_Slope} + 25
      上式中:V25=Vsense 在 25 度时的数值(典型值为: 1.43)。
      Avg_Slope=温度与 Vsense 曲线的平均斜率(单位: mv/℃或 uv/℃)(典型值: 4.3mv/℃)。

    (8) 示例代码(内部温度)

    #include <stdint.h>
    #include <stdio.h>
    #include <string.h>
    #include "sys.h"
    #include "stm32f10x_conf.h"
    
    #include "delay.h"
    #include "led.h"
    #include "adc.h"
    #include "usart.h"
    
    float temperate = 0;        //用于保存转换计算后的温度值
    uint32_t adc_value = 0;
    
    int main() {
        // LED初始化
        LED_Init();
        // ADC1通道1初始化
        Adc_Init();
        //串口初始化
        uart_init(115200);
        while(1) {
            // 通过ADC_GetConversionValue函数查询ADC的DR寄存器获取ADC转换结果值
            adc_value = Get_Adc(1);
            // 打印ADC转换结果值
            printf("AD value is %d\n", adc_value);
    
            temperate = (float)adc_value * (3.3 / 4095); // 先转成电压值
            temperate = (1.43 - temperate) / 0.0043 + 25;  // 再转换为温度值
            //打印计算出的温度值
            printf("MCU temperature is %f C \n", temperate);
            
            LED = !LED;
            delay_ms(50);
        }
    }
    

    (9) 仿真效果 (内部温度)

    下一篇:[嵌入式软件][启蒙篇][仿真平台]STM32F103实现定时器

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32F103嵌入式软件启蒙篇:串口输出输入与ADC采集的仿真平台实现

    发表评论