以下是我学习基于uVision中的STM32F103C8编程的一点感悟和指导,分享出来,希望对大家有所帮助。如果有错误的地方可以留言指出来,我一定耐心听取。相信大家只要付出努力,就一定学有所成!

目录

1.设计思路

2.模块讲解

       整理了几天,接下来我来讲解一下如何利用STM32F103C8、蓝牙模块、C语言代码结合进行心率的测量、
数据传输、数据显示。

1.设计思路

本次实践结果一共涉及了LED驱动、按键驱动(KEY)、通用输入和输出(GPIO)、系统通用定时器(TIM)、time中断、嵌套向量寄存器(NVIC),通用同步异步收发器(USART)、模拟\数字转换器(ADC)等内容,并将这些内容有机结合。本次实践结果的主要设计思路:总结所学的知识并进行系统设计–>初始化RCC复位时钟–>初始化GPIO–>初始化NVIC–>初始化系统通用时钟并书写time中断服务函数–>初始化USART并书写USART1_SData()发送数据函数和USART1_IRQHandler()中断服务函数–>初始化模拟/数字转换器(ADC)–>main函数中书写相应逻辑–>点击安装手机蓝牙助手,至此我们的项目就已经可以通过外在传感器来进行心跳监控并可以将数据以八进制形式传输到手机端。再结合led驱动和按键驱动,就可以实现led灯亮暗来反映心跳,利用按键来控制程序的开始、暂停。

2 模块讲解

对于LED驱动、按键驱动、定时器、中断控制器、我就不多详述了。至于DMA模块,可以不用使用,是自己学习的时候学这写的。我主要讲解一下USRT和ADC模数转换器,我来讲解下具体的使用和注意的地方。

2.1 USART模块

模块的功能在用上面的介绍表格中和户手册中有,我主要讲下大家比较在意的使用部分。

void usart_configer()
//声明变量USART_InitTypeDef USART_INIT;NVIC_InitTypeDef NVIC_USART_INIT;GPIO_InitTypeDef GPIO_USART_INIT;//初始化时钟,要用到两个RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO,ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); ////初始化GPIOGPIO_USART_INIT.GPIO_Pin = GPIO_Pin_9;GPIO_USART_INIT.GPIO_Speed = GPIO_Speed_50MHz;GPIO_USART_INIT.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_Init(GPIOA,&GPIO_USART_INIT);//GPIO_USART_INIT.GPIO_Pin = GPIO_Pin_10;GPIO_USART_INIT.GPIO_Speed = GPIO_Speed_50MHz;GPIO_USART_INIT.GPIO_Mode = GPIO_Mode_IN_FLOATING;GPIO_Init(GPIOA,&GPIO_USART_INIT);//初始化USARTUSART_INIT.USART_BaudRate = 9600;USART_INIT.USART_HardwareFlowControl = USART_HardwareFlowControl_None;USART_INIT.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;USART_INIT.USART_Parity = USART_Parity_No;USART_INIT.USART_StopBits = USART_StopBits_1;USART_INIT.USART_WordLength = USART_WordLength_8b;USART_Init(USART1,&USART_INIT);USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//初始化NVICNVIC_USART_INIT.NVIC_IRQChannel = USART1_IRQn;NVIC_USART_INIT.NVIC_IRQChannelPreemptionPriority = 2;NVIC_USART_INIT.NVIC_IRQChannelSubPriority = 1;NVIC_USART_INIT.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_USART_INIT);USART_Cmd(USART1,ENABLE);
}
//数据发送函数
void USART1_SData(u8 Data){USART_SendData(USART1,Data);while(USART_GetFlagStatus(USART1,USART_FLAG_TC) != SET){;//检测发送完成}USART_ClearITPendingBit(USART1,USART_FLAG_TC);
}u16 Recvdata;//定义16位数据,用来接受测试到的数据
void USART1_IRQHandler(){if(USART_GetITStatus(USART1,USART_IT_RXNE) == SET){Recvdata = USART_ReceiveData(USART1);
ART_ClearITPendingBit(USART1,USART_IT_RXNE | USART_IT_TXE);return;
}

2.2ADC模数转换模块

void AD_init(){ADC_InitTypeDef ADC_1;GPIO_InitTypeDef GPIO_ADC_INIT;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);GPIO_ADC_INIT.GPIO_Pin = GPIO_Pin_5;//选用通道PA5传输数据GPIO_ADC_INIT.GPIO_Speed = GPIO_Speed_50MHz;GPIO_ADC_INIT.GPIO_Mode = GPIO_Mode_AIN;GPIO_Init(GPIOA,&GPIO_ADC_INIT);RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);RCC_ADCCLKConfig(RCC_PCLK2_Div6);//六分频
//初始化内容根据自己要求定ADC_1.ADC_Mode = ADC_Mode_Independent;ADC_1.ADC_ScanConvMode = DISABLE;ADC_1.ADC_ContinuousConvMode = DISABLE;ADC_1.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;ADC_1.ADC_DataAlign = ADC_DataAlign_Right;ADC_1.ADC_NbrOfChannel = 1;ADC_Init(ADC1,&ADC_1); ADC_Cmd(ADC1,ENABLE);//校检ADC_ResetCalibration(ADC1);while(ADC_GetCalibrationStatus(ADC1)){;}ADC_StartCalibration(ADC1);//while(ADC_GetCalibrationStatus(ADC1)){//;} return;
}
//获取传感器测试结果,16位
u16 AD_Get_Value(){ADC_RegularChannelConfig(ADC1,ADC_Channel_5,1,ADC_SampleTime_239Cycles5 );ADC_SoftwareStartConvCmd(ADC1,ENABLE);//软启动while(! ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)){;}ADC_ClearFlag(ADC1,ADC_FLAG_EOC);//清除标志位return  ADC_GetConversionValue(ADC1);//琥获取数据
}

2.3main模块

主要算法思路:计算100-200个点的平均值,作为中轴线的估计值,然后每次获取的数据的值远大于或者远小于中轴线就算做一次,然后算五秒内多少次,结果在乘12即可。或者算3s的结果乘20,。但是中轴线的值也是可以变化的,浮动变化,每次都考虑新加进来的值

while(1){if(key_scan() == 0){if(begin == 0){allon();begin = 1;//开始和结束的标志i = 1;value = 0.0;ans = 0;//多少个波形num = 0;多少个20mstrend = 0;t = 0;//用来表示num+100} }if(begin == 1){while(i < test){re=AD_Get_Value();data=(float)re*(3.3/4096);//数据转换成电压value+=data; i++;delay_ms(20);}if(i == test){value = value/100.0;i++;}while(1 && (key_scan() != 0)){re=AD_Get_Value();data=(float)re*(3.3/4096);//计算波峰,消除噪音干扰的波峰if(data > value){if((data - value)/value >= 0.0745){if(trend == 1){trend = 0;allon();}t--;}else{value += (data - value)/(t + 100 +1);}  }else if(data < value){if((value - data)/value >= 0.0745){ if(trend == 0){ans++;trend = 1;  alloff();}t--;}else{value -= (value - data)/(t + 100 +1);}}if(num%100==0){  data1 = (int)((float)ans * 3000.0 / ((float)num));data1+=num%10;USART1_SData((u8)((data1%100/10)+'0'));USART1_SData((u8)((data1%10)+'0'));   }delay_ms(20);num++;t++;}begin = 0;alloff();}}

基于uVision的STM32F103C8编程-----心率测量相关推荐

  1. 基于uVision中的STM32F103C8编程第一弹

    以下是我学习基于uVision中的STM32F103C8编程的一点感悟和指导,分享出来,希望对大家有所帮助.如果有错误的地方可以留言指出来,我一定耐心听取.相信大家只要付出努力,就一定学有所成! 目录 ...

  2. 面部表情视频中进行远程心率测量:ICCV2019论文解析

    面部表情视频中进行远程心率测量:ICCV2019论文解析 Remote Heart Rate Measurement from Highly Compressed Facial Videos: an ...

  3. 基于uFUN开发板的心率计(三)Qt上位机的实现

    前言 上两周利用周末的时间,分别写了基于uFUN开发板的心率计(一)DMA方式获取传感器数据和基于uFUN开发板的心率计(二)动态阈值算法获取心率值,介绍了AD采集传感器数据和数据的滤波处理获取心率值 ...

  4. axivion和astree_基于LabVIEW的IVI编程 IVI Programme Based on LabVIEW.pdf

    基于LabVIEW的IVI编程 IVI Programme Based on LabVIEW 计测技术 计算机技术与应用 ·55· 基于LabVIEW的IVI编程 屈建胜,蒋雪根,王亚栋 (中国人民解 ...

  5. request[limit]取不到前台的值_基于uFUN开发板的心率计(二)动态阈值算法获取心率值...

    前言 上一篇文章:基于uFUN开发板的心率计(一)DMA方式获取传感器数据,介绍了如何获取PulseSensor心率传感器的电压值,并对硬件电路进行了计算分析.心率计,重要的是要获取到心率值,本篇文章 ...

  6. 基于视频分析的rPPG心率检测

    基于视频分析的rPPG心率检测 YTimo PKU EECS 注:本文内容主要来自于综述文章:Video-Based Heart Rate Measurement: Recent Advances a ...

  7. 【P4论文分享】基于P4的可编程数据平面研究及其应用

    前言 本文是本人学习的笔记,如有错误欢迎指正. 论文下载地址:基于P4的可编程数据平面研究及其应用 本文目录 前言 1 引 言 传统交换机的局限性 如何增强网络开放性? OpenFlow局限性 解决O ...

  8. 基于uFUN开发板的心率计(二)动态阈值算法获取心率值

    文章目录 前言 IBI和BPM 核心操作 -- 识别一个脉搏信号 问题一:阈值的选取 问题二:特征点识别 算法整体框架与代码实现 总结 基于uFUN开发板的Keil源码下载 uFUN评测系列文章 前言 ...

  9. 基于C#的可编程仪器标准命令(SCPI)实践 (附源代码)

    基于C#的可编程仪器标准命令(SCPI)实践 (附源代码) SCPI 概述 SCPI于1990与IEEE 488.2协议一起面世.这套标准定义了可用于控制一切仪器的语法,命令结构以及数据格式.比如,通 ...

最新文章

  1. angular图片传到后台_告诉你,SpringBoot+Angular有多牛逼!
  2. 彪悍的人生不需要解释
  3. android从服务端获取json解析显示在客户端上面,Android服务端获取json解析显示在客户端上面.doc...
  4. codeforces 842 D. Vitya and Strange Lesson(01字典树+思维+贪心)
  5. MGraph图(代码、分析、汇编)
  6. class 和 struct的区别
  7. 互联网传真 传真指令_传真的完整形式是什么?
  8. MYSQL添加约束的两种方法
  9. 新手学java 学哪方面_初学者学Java应从哪些方面学习?
  10. jq+ajax前端上传多张图片_史上最轻量的前端框架-VanillaJS
  11. require(): open_basedir restriction in effect. 解决方法
  12. mongodb 系列 ~ mongo的两种引擎对比
  13. Linux 下子线程 exit code 在主线程中的使用
  14. 机器人码垛手持式编程_码垛机器人编程软件图解教程
  15. 如何下载贵州省卫星地图高清版大图
  16. 闪灵CMS插件自动采集文章主动推送给搜索引擎
  17. SQL教程——常见的约束类型
  18. 上海大华条码称代码_上海大华条码秤使用说明书
  19. 适合客厅的挂画 山水画让家活色生香
  20. Third season seventeenth episode,Ross and Rachel can not stay at one place???

热门文章

  1. 零信任架构的实施规划——针对联邦系统管理员的规划指南
  2. python计算两经纬度坐标距离和角度以及给定第一个坐标、距离和航向角计算第二个坐标
  3. ArrayBlockingQueue 迭代器
  4. 数字人和DeepFaceLab(DeepFake)的结合会有怎样的效果
  5. 年终答卷 腾讯云智能综合实力稳居国内第一梯队
  6. VIPLE初学者日记(三)实现一个简单定时器
  7. ElasticSearch~ES文档操作~对文档的增删改查
  8. 算法学习笔记 网络流之最大流算法
  9. 5S现场管理的八个口诀
  10. ZCMU-2014: 一生之敌(数学+枚举)