前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【常用模块】HC-05蓝牙串口通信模块使用详解(实例:手机蓝牙控制STM32单片机)

【常用模块】HC-05蓝牙串口通信模块使用详解(实例:手机蓝牙控制STM32单片机)

原创
作者头像
ruochen
修改于 2021-11-15 05:50:14
修改于 2021-11-15 05:50:14
2.5K0
举报

HC-05蓝牙串口通信模块应该是使用最广泛的一种蓝牙模块之一了。为什么呢?

<p><strong>因为HC05模块是一款高性能主从一体蓝牙串口模块,可以不用知道太多蓝牙相关知识就可以很好的上手。说白了,只是个蓝牙转串口的设备,你只要知道串口怎么编程使用,就可以了,实现了所谓的透明传输。</strong></p>

<p>但是就是这么一个很常见的模块,网上很多的博客写的都是错的,或者都是很不详细的。</p>

<p>所以本文就介绍一下这款蓝牙通信模块的使用,包括<strong>蓝牙模块的调试、手机与蓝牙模块之间的传输、手机蓝牙控制STM32单片机,应该是逐渐深入的一个过程。</strong>但是这仅仅是使用,以后有时间应该会对蓝牙有一个稍微深度的学习,而不能仅仅是浮于表面,只会用。</p>

<p>&nbsp;</p>

<p>模块名称:HC-05蓝牙串口通信模块</p>

<p>参考资料:<a href="http://www.hc01.com/Upload/file/download/HC-05package.rar" rel="nofollow">HC-05蓝牙串口通信模块官方资料包</a></p>

<p>知识储备:<a href="https://blog.csdn.net/qq_38410730/article/details/79887200" rel="nofollow">【STM32】串口通信基本原理(超基础、详细版)</a></p>

<p>其他模块:USB转TTL模块、手机蓝牙串口助手app</p>

<p>手机蓝牙串口助手软件,可以点击链接下载:<a href="http://app.hicloud.com/app/C100166101" rel="nofollow">蓝牙串口</a>。因为这是我见过所有手机端界面最好看的了,其他的界面都有点太糟糕了。</p>

<p>&nbsp;</p>

<h2><a name="t0"></a>蓝牙模块的调试</h2>

<h3><a name="t1"></a>准备工作</h3>

<p>USB转TTL模块与HC-05蓝牙模块的接线:</p>

<p><strong>两模块共地,两模块共VCC(VCC取5V);蓝牙模块的RX接转换模块的TX,蓝牙模块的TX接转换模块的RX。</strong>如下图所示:</p>

<p style="text-align:center;"><img alt="" class="has" src="https://img-blog.csdn.net/20180518193331171"></p>

<p>这个时候就要将转换模块连接到电脑上,然后利用串口调试助手进行蓝牙模块的调试。</p>

<p>附可能会用到的驱动:链接:https://pan.baidu.com/s/1bpYLfCr 密码:yabv</p>

<h3><a name="t2"></a>蓝牙模块的调试</h3>

<p><strong>HC-05蓝牙串口通讯模块具有两种工作模式:命令响应工作模式和自动连接工作模式。</strong>在自动连接工作模式下模块又可分为主(Master)、从(Slave)和回环(Loopback)三种工作角色。</p>

<ul><li><strong>当模块处于自动连接工作模式时,将自动根据事先设定的方式连接的数据传输;</strong></li>

代码语言:txt
AI代码解释
复制
<li><strong>当模块处于命令响应工作模式时能执行AT命令,用户可向模块发送各种AT 指令,为模块设定控制参数或发布控制命令。</strong></li>

</ul><p>怎么进入命令响应工作模式?</p>

<p>进入命令响应工作模式有两种方法:</p>

<ul><li><strong>模块上电,未配对情况下就是AT模式,波特率为模块本身的波特率,默认:9600,发送一次AT指令时需要置高一次PIO11;</strong></li>

代码语言:txt
AI代码解释
复制
<li><strong>PIO11 置高电平后,再给模块上电,此时模块进入AT 模式,波特率固定为:38400,可以直接发送AT指令。</strong></li>

</ul><p>什么叫做置高一次PIO11?</p>

<p><strong>在蓝牙模块中有一个小按键,按一下就置高一次PIO11。</strong>也就是说,第一种方法需要每发送一次AT指令按一次;而第二种方式是长按的过程中上电,之后就无需再管了,直接发送AT命令即可。</p>

<p><strong>需要注意一下,两种进入命令响应工作模式的方式使用的波特率是不一样的,建议使用第二种方式。</strong></p>

<p>怎么区分进了命令响应工作模式呢?</p>

<p>在蓝牙模块上有灯,<strong>当灯快闪的时候,就是自动连接工作模式;当灯慢闪的时候,就是命令响应工作模式。</strong></p>

<h3><a name="t3"></a>AT命令</h3>

<p>进入到命令响应工作模式之后,就可以使用串口调试助手进行蓝牙调试了。</p>

<p>首先有一点,<strong>AT指令不区分大小写,均以回车、换行结尾。</strong>下面介绍常用的AT指令:</p>

<div class="table-box"><table cellspacing="1" cellpadding="1" border="1" align="center"><caption>常用AT指令</caption>

代码语言:txt
AI代码解释
复制
<tbody><tr><td style="text-align:center;">指令名</td>
代码语言:txt
AI代码解释
复制
		<td style="text-align:center;">响应</td>
代码语言:txt
AI代码解释
复制
		<td style="text-align:center;">含义</td>
代码语言:txt
AI代码解释
复制
	</tr><tr><td>AT</td>
代码语言:txt
AI代码解释
复制
		<td>OK</td>
代码语言:txt
AI代码解释
复制
		<td>测试指令</td>
代码语言:txt
AI代码解释
复制
	</tr><tr><td>AT+RESET</td>
代码语言:txt
AI代码解释
复制
		<td>OK</td>
代码语言:txt
AI代码解释
复制
		<td>模块复位</td>
代码语言:txt
AI代码解释
复制
	</tr><tr><td>AT+VERSION?</td>
代码语言:txt
AI代码解释
复制
		<td>+VERSION:&lt;Param&gt; OK</td>
代码语言:txt
AI代码解释
复制
		<td>获得软件版本号</td>
代码语言:txt
AI代码解释
复制
	</tr><tr><td>AT+ORGL</td>
代码语言:txt
AI代码解释
复制
		<td>OK</td>
代码语言:txt
AI代码解释
复制
		<td>恢复默认状态</td>
代码语言:txt
AI代码解释
复制
	</tr><tr><td>AT+ADDR?</td>
代码语言:txt
AI代码解释
复制
		<td>+ADDR:&lt;Param&gt; OK</td>
代码语言:txt
AI代码解释
复制
		<td>获得蓝牙模块地址</td>
代码语言:txt
AI代码解释
复制
	</tr><tr><td>AT+NAME=&lt;Param&gt;</td>
代码语言:txt
AI代码解释
复制
		<td>OK</td>
代码语言:txt
AI代码解释
复制
		<td>设置设备名称</td>
代码语言:txt
AI代码解释
复制
	</tr><tr><td>AT+NAME?</td>
代码语言:txt
AI代码解释
复制
		<td>+NAME:&lt;Param&gt; OK</td>
代码语言:txt
AI代码解释
复制
		<td>获得设备名称</td>
代码语言:txt
AI代码解释
复制
	</tr><tr><td>AT+PSWD=&lt;Param&gt;</td>
代码语言:txt
AI代码解释
复制
		<td>OK</td>
代码语言:txt
AI代码解释
复制
		<td>设置模块密码</td>
代码语言:txt
AI代码解释
复制
	</tr><tr><td>AT+PSWD?</td>
代码语言:txt
AI代码解释
复制
		<td>+PSWD:&lt;Param&gt; OK</td>
代码语言:txt
AI代码解释
复制
		<td>获得模块密码</td>
代码语言:txt
AI代码解释
复制
	</tr><tr><td>AT+UART=&lt;Param1&gt;,&lt;Param2&gt;,&lt;Param3&gt;</td>
代码语言:txt
AI代码解释
复制
		<td>OK</td>
代码语言:txt
AI代码解释
复制
		<td>设置串口参数</td>
代码语言:txt
AI代码解释
复制
	</tr><tr><td>AT+UART?</td>
代码语言:txt
AI代码解释
复制
		<td>+UART:&lt;Param1&gt;,&lt;Param2&gt;,&lt;Param3&gt; OK</td>
代码语言:txt
AI代码解释
复制
		<td>获得串口参数</td>
代码语言:txt
AI代码解释
复制
	</tr></tbody></table></div><p>对于AT指令,有几点注意:</p>

<ul><li>AT+NAME?:获得设备名称,这个AT指令有很大可能性是没有返回的,因为我也看到了很多的例子……,但是其他的指令都是没有问题的,直接设置设备名称就行了;</li>

代码语言:txt
AI代码解释
复制
<li>AT+UART?:<strong>获得串口参数,串口的参数一共有三个,波特率、停止位、检验位。</strong>其取值如下:</li>

</ul><div class="table-box"><table cellspacing="1" cellpadding="1" border="1" align="center"><caption>串口参数</caption>

代码语言:txt
AI代码解释
复制
<tbody><tr><td style="text-align:center;">参数名称</td>
代码语言:txt
AI代码解释
复制
		<td style="text-align:center;">取值</td>
代码语言:txt
AI代码解释
复制
	</tr><tr><td>波特率</td>
代码语言:txt
AI代码解释
复制
		<td>
代码语言:txt
AI代码解释
复制
		<p>2400、4800、9600、19200、38400、5760、</p>
代码语言:txt
AI代码解释
复制
		<p>115200、230400、460800、921600、1382400</p>
代码语言:txt
AI代码解释
复制
		</td>
代码语言:txt
AI代码解释
复制
	</tr><tr><td>停止位</td>
代码语言:txt
AI代码解释
复制
		<td>
代码语言:txt
AI代码解释
复制
		<p>0:1位</p>
代码语言:txt
AI代码解释
复制
		<p>1:2位</p>
代码语言:txt
AI代码解释
复制
		</td>
代码语言:txt
AI代码解释
复制
	</tr><tr><td>校验位</td>
代码语言:txt
AI代码解释
复制
		<td>0:NONE&nbsp; 1:Odd&nbsp; 2:Even</td>
代码语言:txt
AI代码解释
复制
	</tr></tbody></table></div><p><strong>其默认值为:9600,0,0。</strong></p>

<p>例子:</p>

<p style="text-align:center;"><img alt="" class="has" src="https://img-blog.csdn.net/20180518202920760"></p>

<p>本文中,蓝牙串口的波特率设置成115200。之后的内容,就会采用这个波特率来进行通讯了。</p>

<p>&nbsp;</p>

<h2><a name="t4"></a>手机与蓝牙模块之间的传输</h2>

<p>直接将蓝牙模块与转换模块连接,再讲其连接到电脑上,蓝牙模块直接进入自动连接工作模式。</p>

<p>此时手机打开蓝牙串口调试应用,用其来连接蓝牙模块。手机蓝牙串口助手软件,可以点击链接下载:<a href="http://app.hicloud.com/app/C100166101" rel="nofollow">蓝牙串口</a>。万分推荐这款,因为界面脱离了那种黑不溜秋的感觉,比较简洁、清爽。</p>

<p>这个软件的使用:<strong>点击界面右下角蓝牙的标志,选择蓝牙进行连接。</strong></p>

<p>然后在电脑上的调试助手和手机的蓝牙串口调试应用之间就可以相互传输了,比如:</p>

<p style="text-align:center;"><img alt="" class="has" src="https://img-blog.csdn.net/20180518204035218"></p>

<p style="text-align:center;"><img alt="" class="has" src="https://img-blog.csdn.net/20180518204256287"></p>

<p>可以清楚的看到:电脑向手机发送了“hello you”,手机向电脑发送了“hello world”。</p>

<p>&nbsp;</p>

<h2><a name="t5"></a>手机蓝牙控制STM32单片机</h2>

<p>之前的两个例子都是相比较而言比较简单的,这个例子将会涉及到程序的内容了。</p>

<p>实现功能:手机通过蓝牙,向STM32单片机发送消息,STM32接收到消息之后原封不动的返回给手机。当然如果掌握了这个例子,也可以修改成,手机发送特定的消息,然后,STM32单片机做出相对应的动作。比如:点亮LED等、发动电机等等。</p>

<h3><a name="t6"></a>连接说明</h3>

<p style="text-align:center;"><img alt="" class="has" src="https://img-blog.csdn.net/20180518205159600"></p>

<p>使用USART1进行试验,也就是说STM32选取PA9、PA10来和HC-05进行连接。同时手机通过蓝牙来和HC-05进行连接。</p>

<p><strong>原理就是:手机通过蓝牙传输到HC-05上,再通过串口通信和STM32通信;而之前一般都是电脑上通过USB线转串口的方式,通过串口和STM32通信。本质上没有区别的。</strong></p>

<p><strong>这个时候就应该更加深刻地体会到了本文开篇的一句话:说白了,只是个蓝牙转串口的设备,你只要知道串口怎么编程使用,就可以了,实现了所谓的透明传输。蓝牙的相关一切都被封装起来了,都不需要接触到。</strong></p>

<h3><a name="t7"></a>STM32控制程序</h3>

<pre class="has" name="code"><code class="language-objc language-cpp hljs objectivec"><ol class="hljs-ln"><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="1"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-meta">#include <span class="hljs-meta-string">"stm32f10x.h"</span></span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="2"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="3"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword">void</span> My_USART1_Init(<span class="hljs-keyword">void</span>) </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="4"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">{ </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="5"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> GPIO_InitTypeDef GPIO_InitStrue; </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="6"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> USART_InitTypeDef USART_InitStrue; </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="7"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> NVIC_InitTypeDef NVIC_InitStrue; </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="8"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="9"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);<span class="hljs-comment">//GPIO端口使能 </span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="10"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);<span class="hljs-comment">//串口端口使能 </span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="11"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="12"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> GPIO_InitStrue.GPIO_Mode=GPIO_Mode_AF_PP; </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="13"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> GPIO_InitStrue.GPIO_Pin=GPIO_Pin_9; </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="14"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz; </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="15"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> GPIO_Init(GPIOA,&amp;GPIO_InitStrue); </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="16"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="17"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> GPIO_InitStrue.GPIO_Mode=GPIO_Mode_IN_FLOATING; </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="18"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> GPIO_InitStrue.GPIO_Pin=GPIO_Pin_10; </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="19"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> GPIO_InitStrue.GPIO_Speed=GPIO_Speed_10MHz; </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="20"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> GPIO_Init(GPIOA,&amp;GPIO_InitStrue); </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="21"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="22"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> USART_InitStrue.USART_BaudRate=<span class="hljs-number">115200</span>; </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="23"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> USART_InitStrue.USART_HardwareFlowControl=USART_HardwareFlowControl_None; </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="24"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> USART_InitStrue.USART_Mode=USART_Mode_Tx|USART_Mode_Rx; </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="25"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> USART_InitStrue.USART_Parity=USART_Parity_No; </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="26"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> USART_InitStrue.USART_StopBits=USART_StopBits_1; </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="27"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> USART_InitStrue.USART_WordLength=USART_WordLength_8b; </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="28"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="29"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> USART_Init(USART1,&amp;USART_InitStrue);</div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="30"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="31"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> USART_Cmd(USART1,ENABLE);<span class="hljs-comment">//使能串口1 </span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="32"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="33"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);<span class="hljs-comment">//开启接收中断 </span></div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="34"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="35"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> NVIC_InitStrue.NVIC_IRQChannel=USART1_IRQn; </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="36"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> NVIC_InitStrue.NVIC_IRQChannelCmd=ENABLE; </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="37"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> NVIC_InitStrue.NVIC_IRQChannelPreemptionPriority=<span class="hljs-number">1</span>; </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="38"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> NVIC_InitStrue.NVIC_IRQChannelSubPriority=<span class="hljs-number">1</span>; </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="39"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> NVIC_Init(&amp;NVIC_InitStrue); </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="40"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="41"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">} </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="42"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="43"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"><span class="hljs-keyword">void</span> USART1_IRQHandler(<span class="hljs-keyword">void</span>) </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="44"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">{ </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="45"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> u8 res; </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="46"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword">if</span>(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET) </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="47"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> { </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="48"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> res= USART_ReceiveData(USART1); </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="49"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> USART_SendData(USART1,res); </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="50"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> } </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="51"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line">} </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="52"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="53"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword">int</span> main(<span class="hljs-keyword">void</span>) </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="54"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> { </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="55"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="56"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> My_USART1_Init(); </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="57"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> <span class="hljs-keyword">while</span>(<span class="hljs-number">1</span>); </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="58"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> </div></div></li><li><div class="hljs-ln-numbers"><div class="hljs-ln-line hljs-ln-n" data-line-number="59"></div></div><div class="hljs-ln-code"><div class="hljs-ln-line"> } </div></div></li></ol></code><div class="hljs-button {2}" data-title="复制" onclick="hljs.copyCode(event)"></div></pre>

转载自 https://blog.csdn.net/qq_38410730/article/details/80368485

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
3 条评论
热度
最新
请问对nrun的设置怎么选择呢,nrun的选择是不是对矩阵分解的效果有影响?
请问对nrun的设置怎么选择呢,nrun的选择是不是对矩阵分解的效果有影响?
22点赞举报
那个要靠经验
那个要靠经验
回复回复点赞举报
那按照您的经验,对于530列,1500行的矩阵,nrun设置为多少分解效果比较好
那按照您的经验,对于530列,1500行的矩阵,nrun设置为多少分解效果比较好
回复回复点赞举报
推荐阅读
基于R语言利用NMF(非负矩阵分解)替代层次聚类进行肿瘤分型
随着芯片和测序水平的发展,使得我们研究所有基因在整个基因组里的表达情况成为了可能。合理地利用和解释这些数据,能够帮助我们探索相关的生物过程和人类疾病的机制。目前已经有一些软件或方法,可以将具有相似表达模式的基因或者样本进行聚类,但是都有自身的限制。NMF包基于非负矩阵分解(non-negative matrix factorization,以下简称NMF)方法,提取基因表达矩阵内数据的生物相关系数,通过对基因和样本进行组织,抓住数据的内部结构特征,从而对样本进行分组,目前在疾病分型方面受到广泛应用。我前面已经介绍过了NMF的基本原理【NMF(非负矩阵分解)的算法原理】,这里我介绍R语言实现NMF。下面是一篇今年刚发的一篇纯生信的分析文章,用的就是NMF这个方法来对肿瘤进行分型。影响因子为4.8。
DoubleHelix
2022/01/19
20.1K0
基于R语言利用NMF(非负矩阵分解)替代层次聚类进行肿瘤分型
RNAseq|组学分型-ConsensusClusterPlus(一致性聚类), NMF(非负矩阵分解)
肿瘤分型分析是生信文章中的常客,大致是通过将基因的表达量进行聚类或者非负矩阵分解,发现新的亚型,然后对不同亚型的临床特征,免疫特征等进行比较分析,文章末尾简单的列了一些应用。
生信补给站
2023/08/25
6K2
RNAseq|组学分型-ConsensusClusterPlus(一致性聚类), NMF(非负矩阵分解)
使用NMF代替层次聚类
前面我们在教程:使用R包deconstructSigs根据已知的signature进行比例推断,顺利的把508个病人,根据11个signature进行了比例推断,得到的比例矩阵以普通的热图,以及pheatmap包自带的层次聚类如下:
生信技能树
2020/06/09
3.2K0
转录组非负矩阵分解(NMF)/一致性聚类(ConsensusClusterPlus)
非负矩阵分解(NMF)和一致性聚类(ConsensusClusterPlus)是两种常用的聚类和模式识别方法,它们在算法原理、使用场景和结果解读上都有相似和不同之处。这两种代码流程已经被诸多老师所解析和展示,本次也是跟着老师们发布在网上的流程进行练习和整理。
凑齐六个字吧
2024/08/13
7720
转录组非负矩阵分解(NMF)/一致性聚类(ConsensusClusterPlus)
使用MutationalPatterns进行肿瘤突变频谱分析
MutationalPatterns是一个bioconductor上的R包,可以用于肿瘤突变频谱的分析。肿瘤突变频谱针对点突变进行定义,A,T,C,G四种碱基两两突变,共有4X3=12种排列,考虑到正负链碱基配对原则,正链上的A->C突变,对应负链上为T->G, 所以进一步转换成了一个组合的问题,所以某个位点的突变可以划分为以下6种模式
生信修炼手册
2019/12/19
3K1
使用MutationalPatterns进行肿瘤突变频谱分析
基于非负矩阵分解的单细胞降维聚类分群
可以看到,在CD4和CD8的T细胞的各自矩阵内部降维聚类分群,这6个细分亚群都并不是泾渭分明的界限。听完分享才知道,原来作者这个时候的细分亚群其实并不关心它们内部是不是有不同的独立的单细胞亚群,仅仅是有这6个不同状态或者说发挥不同功能单细胞亚群。而区分它们的手段是非负矩阵分解,并不需要有很清晰的界限,只需要各个亚群的核心功能基因集有差异即可。
生信技能树
2022/03/03
3.1K0
基于非负矩阵分解的单细胞降维聚类分群
单细胞分析十八般武艺:NMF
非负矩阵分解(Non-negative Matrix Factorization, NMF)本质上说是一种矩阵分解的方法,对于任意给定的一个非负矩阵V,NMF算法能够寻找到一个非负矩阵W和一个非负矩阵H,使得 V≈W*H成立 ,从而将一个非负的矩阵分解为左右两个非负矩阵的乘积。
生信技能树jimmy
2021/03/25
13.3K0
单细胞分析十八般武艺:NMF
使用 sigminer 进行突变模式分析
突变模式分析(Mutual Signature Analysis)已经逐步成为变异检测后一个通用分析,本文简单介绍如何使用sigminer进行突变模式分析,以解决2大分析任务:
生信菜鸟团
2020/06/10
2.1K0
使用 sigminer 进行突变模式分析
推荐算法——非负矩阵分解(NMF)
在博文推荐算法——基于矩阵分解的推荐算法中,提到了将用户-商品矩阵进行分解,从而实现对未打分项进行打分。矩阵分解是指将一个矩阵分解成两个或者多个矩阵的乘积。对于上述的用户-商品矩阵(评分矩阵),记为Vm×nV_{m\times n},可以将其分解成两个或者多个矩阵的乘积,假设分解成两个矩阵Wm×kW_{m\times k}和Hk×nH_{k\times n},我们要使得矩阵Wm×kW_{m\times k}和Hk×nH_{k\times n}的乘积能够还原原始的矩阵Vm×nV_{m\times n}:
felixzhao
2019/02/13
1.5K0
【机器学习】NMF(非负矩阵分解)
  本篇文章主要介绍NMF算法原理以及使用sklearn中的封装方法实现该算法,最重要的是理解要NMF矩阵分解的实际意义,将其运用到自己的数据分析中!
全栈程序员站长
2022/07/04
1.8K0
【机器学习】NMF(非负矩阵分解)
R语言实现突变信号(Mutational Signatures)分析
突变信号(Mutational Signatures)首次2013年在《nature》进行报道。并做了相关的定义:细胞在成长过程中,基因组不断受到内源性和外源性DNA损伤的威胁,正是由于这些威胁,使得细胞基因组不断发生变化,并最终发生一些突变的积累。每一个突变过程都会留下一个不同的基因组标记,也就称为突变信号。
一粒沙
2019/07/31
9.4K6
「R」使用NMF包绘制热图
学习文档: https://cran.r-project.org/web/packages/NMF/vignettes/heatmaps.pdf
王诗翔呀
2020/07/03
3K0
跟着生信技能树,学习 CIBERSORT
首先有一些背景知识需要了解(特别是一些算法),但是我的理解方法特别粗暴,不知道Jimmy老师会不会打我。当然了,如果是原始的CIBERSORT R脚本 https://rdrr.io/github/singha53/amritr/src/R/supportFunc_cibersort.R 其实懂得使用即可。
生信技能树
2021/02/03
7.4K1
跟着生信技能树,学习 CIBERSORT
单细胞非负矩阵分解分析python版(cNMF)学习
前置一个推文,老师的推文已经详细讲解了非负矩阵分解的算法原理~ 如果对算法原理感兴趣的可以点击以下链接~
凑齐六个字吧
2024/09/15
4410
单细胞非负矩阵分解分析python版(cNMF)学习
推荐算法——非负矩阵分解(NMF)
一、矩阵分解回顾 image.png 二、非负矩阵分解 2.1、非负矩阵分解的形式化定义 image.png 2.2、损失函数 image.png 2.3、优化问题的求解 image.png imag
felixzhao
2018/03/20
1.8K0
推荐算法——非负矩阵分解(NMF)
单细胞实战之单细胞非负矩阵分解(cNMF)——入门到进阶(高级篇4)
接下来将回顾学习非负矩阵分解这个工具, 单细胞实战之单细胞hdWGCNA分析——入门到进阶(高级篇3):https://mp.weixin.qq.com/s/KGSoRx3klmliKPVL7ml28Q
凑齐六个字吧
2025/05/11
2580
单细胞实战之单细胞非负矩阵分解(cNMF)——入门到进阶(高级篇4)
R语言实现meta分析过程中的可视化展示
大家应该很熟悉meta分析,所谓meta分析就是一个全面收集所有相关研究并逐个进行严格评价和分析,再用定量合成的方法对资料进行统计学处理得出综合结论的整个过程。今天我们给大家介绍一个在R语言中进行meta分析的工具metafor包。我们通过这个包把相应的meta分析的常规的一些图为大家介绍下。
一粒沙
2019/07/31
4K0
R语言中的突变signature分析工具
新的一年开始了,今天给大家介绍一款用于发现、预测和探索突变特征的综合分析工具包musicatk。此包主要基于COSMIC突变数据中的最新数据进行肿瘤突变模式的探索。我们首先看下包的安装:
一粒沙
2022/03/14
1.6K0
R语言中的突变signature分析工具
R语言中多组学的因子分析
多组学的研究在不断进入各个疾病领域,那么如何整合这些多组学的特征成为多组学因子综合分析的挑战,今天给大家介绍一个可以类似于PCA分析对多维组学数据进行降维分析的工具包MOFA2。首先看下包的安装:
一粒沙
2022/03/14
1.2K0
R语言中多组学的因子分析
预测三分类变量模型的ROC介绍
我们对Logistics回归很熟悉,预测变量y为二分类变量,然后对预测结果进行评估,会用到2*2 Matrix,计算灵敏度、特异度等及ROC曲线,判断模型预测准确性。
Jamesjin63
2022/11/03
1.2K0
预测三分类变量模型的ROC介绍
推荐阅读
相关推荐
基于R语言利用NMF(非负矩阵分解)替代层次聚类进行肿瘤分型
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档