[嵌入式软件][启蒙篇][仿真平台] STM32F103实现串口输出输入、ADC采集

发布时间:2024年01月21日

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

一、串口输出

(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数值与转换出的电压值一并打印。

#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(1000);
    }
}

(3) 仿真效果 (电压)

  1. 操作: 打开串口–调整电压
    在这里插入图片描述

(4) 示例代码(光敏)

todo

(5) 仿真效果 (光敏)

todo

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

todo

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

todo

文章来源:https://blog.csdn.net/qq_29246181/article/details/135712364
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。