草庐IT

九、stm32-蓝牙HC_05(接发通信、控制LED亮灭)

洛尘~~ 2023-05-25 原文

目录

一、固件库模板

见博客:stm32f103c8t6新建固件库模板(可自取)

二、准备资料

  1. 固件库模板

  2. MDK5开发环境

  3. stm32参考手册

  4. UART串口协议

  5. stm32中断概念

  6. HC-05命令集

  7. 利用固件库模板点灯工程(下面第三行,手动狗头)

  8. CH340 USB→TTL模块

  9. 蓝牙HC-05模块

  10. 手机软件

实验程序已经发布到百度网盘,本文末有链接可以自取

stm32参考手册

串口协议查看这篇博客USART串口协议

stm32中断概念STM32中断应用概括

HC-05命令文件:HC-05命令

串口调试工具
https://pan.baidu.com/s/1V-jRJzb0INDXDLo9I4CJ6A 提取码:0000

手机软件管家下载下面两个工具

三、简介

1. 引脚

标号PIN引脚说明
1STATE状态引出引脚(未连接时输出低电平,连接时输出高电平)
2RXD接收端
3TXD发送端
4GND模块供电负极
5VCC模块供电正极
6EN使能端,需要进入命令模式时接3.3V

本模块使用USART协议,具体请看下面两个博客,这里就不继续讲解了
USART串口协议
四、stm32-USART串口通讯(重定向、接发通信、控制LED亮灭)

2. AT: 设置工作模式

工作模式: 自动连接(automatic connection) ,又称为透传模式;命令回应(order-response) ,又称为AT模式(AT mode)
进入 AT 命令有二种方法:

  1. 按住按键EN脚拉高,此时灯是慢闪, SPP-05进入AT命令模式,默认波特率是38400;
    此模式我们叫原始模式。原始模式下一直处于AT命令模式状态。
  2. HC-05上电开机,红灯快闪,按住按键或EN拉高, HC-05进入AT命令模式,默认波特率是9600;此模式我们叫正常模式。正常模式下只有按住按键或拉高EN才处于AT命令模式状态。
    注意:如果波特率没有设备正确, AT命令是执行无效的。

3. 基本配置(所有AT指令都必须换行)

正常模式是9600、AT模式波特率固定38400,8位数据位、1位停止位、无奇偶校验的通信格式。
(1)发送AT\r\n,回复OK;
(2)发送AT+UART?\r\n,回复+UART 9600,0,0
(3)发送AT+UART=115200,0,0\r\n,回复OK。即为波特率配置成功。

  • AT+NAME= “XXX” 修改蓝牙模块名称为XXX
  • AT+ROLE=0 蓝牙模式为从模式
  • AT+CMODE=1 蓝牙连接模式为任意地址连接模式,也就是说该模块可以被任意蓝牙设备连接
  • AT+PSWD=1234 蓝牙配对密码为1234
  • AT+UART=9600,0,0 蓝牙通信串口波特率为9600,停止位1位,无校验位
    配置完,需带电重启一次。

4. AT命令的详细说明

  1. AT+ROLE设置主从模式: AT+ROLE?是查询主从状态;AT+ROLE=1是设成主, AT+ROLE=0是设成从, AT+ROLE=2设成回环角色(Slave-Loop(回环角色)——被动连接,接收远程蓝牙主设备数据并将数据原样返回给远程蓝牙)。
  2. AT+RESET: HC-05复位
  3. AT+VERSION? :获取HC-05的软件版本号,只能获取,不能修改。
  4. AT+ORGL:恢复出厂默认设置,当把模块设置乱了,使用此命令进行恢复默认值。
  5. AT+ADDR? :获取HC-05的蓝牙地址码,只能获取,不能修改。
  6. AT+NAME? :获取HC-05的名字,AT+NAME=BSP-06,修改模块的名字为BSP-06,具体名字自行修改。
  7. AT+CLASS? :设置查询设备的类型,尽量不要去修改此参数。默认是1F00。
  8. AT+IAC? :查询设置查询访问码,默认是9E8B33,尽量不要去修改此参数。
  9. AT+PSWD? :查询设置配对密码,AT+PSWD=”0000”,密码要有双引号,密码是四位数字.
  10. AT+UART: AT+UART?是查询当前模块的波特率, AT+UART=波特率是设置.
  11. AT+CMODE: AT+CMODE?是查询当前连接模式。 AT+CMODE=0, 1, 2(0——指定蓝牙地址连接模式(指定蓝牙地址由绑定指令设置) 1——任意蓝牙地址连接模式(不受绑定指令设置地址的约束)2——回环角色(Slave-Loop) 默认连接模式:0) 。
  12. AT+BIND:AT+BIND?查询当前绑定地址,AT+BIND=NAP, UAP, LAP (用逗号隔开)。
  13. AT+RMADD:从蓝牙配对列表中删除所有认证设备.
  14. AT+STATE? :获取蓝牙模块工作状态.
  15. AT+LINK=NAP,UAP,LAP:与远程设备建立连接。
  16. AT+DISC:断开连接.
  17. AT+RNAME? NAP, UAP, LAP:获取远程蓝牙设备名称.
  18. AT+ADCN? :获取蓝牙配对列表中认证设备数。
  19. AT+MRAD?获取最近使用过的蓝牙认证设备地址。
  20. AT+INQM:设置查询模式,AT+INQM=1, 9, 48(1-带RSSI信号强度指示,9-超过9个蓝牙设备响应则终止查询,48-设定超时为48*1.28=61.44秒)

四、实验

1.硬件设计

  1. 手机与HC-05通信
    GND接GND
    VCC接3.3
    RXD—CH340的TXD
    TXD—CH340的RXD
  2. 用HC-05控制mcu
    CH340的TXD-----USART1的RX引脚相连(c8t6 的PA10)
    CH340的RXD-----USART1的TX引脚相连(c8t6 的PA9)
    HC-05的TXD-----USART2的RX引脚相连(c8t6 的PA3)
    HC-05的RXD-----USART2的TX引脚相连(c8t6 的PA2)

2.软件设计

  1. 使能 RX 和 TX 引脚 GPIO 时钟和 USART 时钟;

  2. 初始化 GPIO,并将 GPIO 复用到 USART 上;

  3. 配置 USART 参数;

  4. 配置中断控制器并使能 USART 接收中断;

  5. 使能 USART;

  6. 在 USART 接收中断服务函数实现数据接收和发送。

2.1 复制工程 (复制stm32-USART串口通讯工程)

四、stm32-USART串口通讯(重定向、接发通信、控制LED亮灭)

2.2 新建hc_05文件(打开工程)



2.3 编写代码

1. 配置HC-05

  1. 进入AT模式,前面已经讲过了,
  2. AT+ORGL(先将AT恢复出厂设置,避免之前影响)

这里已经勾选发送新行,直接AT就行,否则为AT\r\n
4. 发送AT,回复OK;
5. 发送AT+UART?,回复+UART 9600,0,0
6. 发送AT+UART=115200,0,0,回复OK。即为波特率配置成功。
7. AT+NAME= "XXX"修改蓝牙模块名称为XXX
8. AT+ROLE=0 蓝牙模式为从模式
9. AT+CMODE=1蓝牙连接模式为任意地址连接模式,也就是说该模块可以被任意蓝牙设备连接
10. AT+PSWD= "1234"蓝牙配对密码为1234
11. AT+UART=9600,0,0 蓝牙通信串口波特率为9600,停止位1位,无校验位.

配置结束,需带电重启一次。

2. 手机和串口接发通信



  1. 手机寻找蓝牙,并填写配对码
  2. 蓝牙调试宝连接对应蓝牙
  3. 发送数据,串口接收,串口发送,手机接收

3. 使用HC-05控制mcu

stm32f103c8t6自带一个led灯,使用PC13引脚就行了,

切记尽量避免使用PB3、PB4,具体看stm32f103c8t6使用PB3和PB4做普通GPIO使用时发现异常

led.c
#include "led.h"	//绑定led.h

void LED_GPIO_Config(void) {
    GPIO_InitTypeDef GPIO_InitStruct; //初始化参数结构体指针,结构体类型为 GPIO_InitTypeDef。
    //开启RCC时钟
    RCC_APB2PeriphClockCmd(LED_G_GPIO_CLK, ENABLE);

    //配置初始化,推挽输出方式和LED_G_GPIO_PIN管脚、赫兹
    GPIO_InitStruct.GPIO_Pin = LED_G_GPIO_PIN;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    //GPIO口初始化
    GPIO_Init(LED_G_GPIO_PORT, &GPIO_InitStruct);
}

led.h
#ifndef __LED_H_
#define __LED_H_

#include "stm32f10x.h"
#include "sys.h"

#define LED_G_GPIO_PIN         GPIO_Pin_13
#define LED_G_GPIO_PORT        GPIOC
#define LED_G_GPIO_CLK         RCC_APB2Periph_GPIOC
//使用位带操作来实现操作某个IO口的 1个位,由sys.h实现
#define LED 				   PCout(13)

void LED_GPIO_Config(void); //函数定义

#endif
usart.c

在USART1_IRQHandler方法下面添加 usart2的初始化和中断

struct  STRUCT_USARTx_Fram strHC05_Fram_Record = { 0 };


void uart2_init(u32 bound) {
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);
    //USART2_TX   GPIOA.2
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA2
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA2

    //USART2_RX	  GPIOA.3初始化
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA3
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.3

    //Usart2 NVIC 配置
	  NVIC_PriorityGroupConfig(macNVIC_PriorityGroup_x);
	
    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		//子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器

    //USART 初始化设置

    USART_InitStructure.USART_BaudRate = bound;//串口波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
    USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;	//收发模式

    USART_Init(USART2, &USART_InitStructure); //初始化串口1
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启串口接受中断
		USART_ITConfig(USART2, USART_IT_IDLE, ENABLE);//使能串口总线空闲中断
		
    USART_Cmd(USART2, ENABLE);
}

void USART2_IRQHandler(void)                	//串口1中断服务程序
{
    u8 Res;
    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
    {
        Res =USART_ReceiveData(USART2);	//读取接收到的数据
			  //USART_SendData(USART1,Res);
        if ( strHC05_Fram_Record .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) )                       //预留1个字节写结束符
            strHC05_Fram_Record .Data_RX_BUF [ strHC05_Fram_Record .InfBit .FramLength ++ ]  = Res;
    }

    if ( USART_GetITStatus( USART2, USART_IT_IDLE ) == SET )                                         //数据帧接收完毕
    {
        strHC05_Fram_Record .InfBit .FramFinishFlag = 1;
        Res = USART_ReceiveData( USART2 );
    }
}

usart.h

添加strHC05_Fram_Record结构体和uart2_init(u32 bound)函数

extern struct  STRUCT_USARTx_Fram                                  //串口数据帧的处理结构体
{
    //STRUCT_USARTx_Fram 读取的数据
    char  Data_RX_BUF [ RX_BUF_MAX_LEN ];

    union {
        __IO u16 InfAll;
        struct {
            __IO u16 FramLength       :15;                               // 14:0
            __IO u16 FramFinishFlag   :1;                                // 15
        } InfBit;
    };

}strUSART_Fram_Record,strHC05_Fram_Record;

//如果想串口中断接收,请不要注释以下宏定义
void uart1_init(u32 bound);
void uart2_init(u32 bound);
hc_05.c
#include "hc_05.h"
#include "delay.h"
#include "usart.h"
#include "stdbool.h"
#include <string.h>

bool HC05_AT_Test ( void )
{
    char count = 0;

    printf("\r\nAT测试.....\r\n");
    Delay_ms ( 2000 );
    while ( count < 10 )
    {
        printf("\r\nAT测试次数 %d......\r\n", count);
        if( HC05_Set_Cmd ( "AT", "OK", NULL, 500 ) )
        {
            printf("\r\nAT测试启动成功 %d......\r\n", count);
            return 1;
        }
        ++ count;
    }
    return 0;
}


/**
  * @brief  HC05 配置测试函数
  * @param  无
  * @retval 无
  */
void HC05_ConfigTest(void)
{
    printf( "\r\n正在配置 HC05 ......\r\n" );
    printf( "\r\n请按住按钮 ......\r\n" );
    while( ! HC05_AT_Test() );
    printf ( "\r\n连接成功......\r\n" );
}

/*
 * 函数名:hc05_Cmd
 * 描述  :对hc05模块发送AT指令
 * 输入  :cmd,待发送的指令
 *         reply1,reply2,期待的响应,为NULL表不需响应,两者为或逻辑关系
 *         waittime,等待响应的时间
 * 返回  : 1,指令发送成功
 *         0,指令发送失败
 * 调用  :被外部调用
 */
bool HC05_Set_Cmd( char *cmd, char *reply1, char *reply2, u32 waittime )
{
    strHC05_Fram_Record .InfBit .FramLength = 0;              		 //从新开始接收新的数据包
    hc05_Usart ( "%s\r\n", cmd );
    if ( ( reply1 == 0 ) && ( reply2 == 0 ) )                      //不需要接收数据
        return true;
    Delay_ms ( waittime );                 //延时
    //增加一个结束符。
    strHC05_Fram_Record .Data_RX_BUF [ strHC05_Fram_Record .InfBit .FramLength ]  = '\0';
    //将USART2接收到的东西全部打印出来,接收到的保存在这个数组里,
    //通过串口1发送出来,这样就能看到,我们发送的指令的响应,是否出错,
    //例如:发送AT,响应是OK, HC05_USART接收到的数据是AT OK.在交给USART1发送,在PC机的串口调试助手可以看到这些信息,
    PC_Usart ( "%s", strHC05_Fram_Record .Data_RX_BUF );

    strHC05_Fram_Record .InfBit .FramLength = 0;                             //清除接收标志
    strHC05_Fram_Record.InfBit.FramFinishFlag = 0;
    if ( ( reply1 != 0 ) && ( reply2 != 0 ) )
        return ( ( bool ) strstr ( strHC05_Fram_Record .Data_RX_BUF, reply1 ) ||
                 ( bool ) strstr ( strHC05_Fram_Record .Data_RX_BUF, reply2 ) );
    else if ( reply1 != 0 )
        return ( ( bool ) strstr ( strHC05_Fram_Record .Data_RX_BUF, reply1 ) );

    else
        return ( ( bool ) strstr ( strHC05_Fram_Record .Data_RX_BUF, reply2 ) );
}

hc_05.h

#ifndef __HC_05_H_
#define __HC_05_H_

#include "stm32f10x.h"
#include "stdbool.h"
#include "sys.h"


/*********************************************** HC05 函数宏定义 *******************************************/
#define     hc05_Usart( fmt, ... )           USART_printf ( USART2, fmt, ##__VA_ARGS__ )
#define     PC_Usart( fmt, ... )             printf ( fmt, ##__VA_ARGS__ )
//#define     macPC_Usart( fmt, ... )

bool HC05_Set_Cmd( char *cmd, char *reply1, char *reply2, u32 waittime );
bool HC05_AT_Test ( void );
void HC05_ConfigTest(void);

#endif
/******************************** END OF FILE *********************************/

main.c


#include "delay.h"
#include "sys.h"
#include "usart.h"
#include "stm32f10x.h"
#include "led.h"
#include "hc_05.h"

/*

 CH340的TXD-----USART1的RX引脚相连(c8t6 的PA10)
 CH340的RXD-----USART1的TX引脚相连(c8t6 的PA9)
 HC-05的TXD-----USART2的RX引脚相连(c8t6 的PA3)
 HC-05的RXD-----USART2的TX引脚相连(c8t6 的PA2)


*/
int main()
{
    /********************************************************************************
    *    Delay_init();				  //本实验使用的是SysTick时钟
    *    CPU_TS_TmrInit();      //已经使能宏,不需要初始化
    *    uart1_init(115200);	 	//串口初始化为115200,需要在usart.h中使能
    ********************************************************************************/

    /* 初始化 */
    uart1_init(115200);		//usart1初始化,
	uart2_init(9600);		//usart2初始化,
    LED_GPIO_Config();		//初始化led使用的GPIO口
    printf("--HC_05初始化完成--");
	HC05_ConfigTest();	//看看HC-05AT命令是否有效
    while (1)
    {
        if(strHC05_Fram_Record .InfBit .FramFinishFlag)  	//如果串口接收到数据,并结束
        {
            //增加一个结束符。
            strHC05_Fram_Record .Data_RX_BUF [ strHC05_Fram_Record .InfBit .FramLength ]  = '\0';
            //将HC05接收到的东西全部打印出来,接收到的保存在这个数组里,再通过串口1发送出来,这样就能看到,我们发送的指令的响应,是否出错,
            printf( "\r\n%s\r\n", strHC05_Fram_Record .Data_RX_BUF );
            if(strstr ( strHC05_Fram_Record .Data_RX_BUF, "LED=1" ))	//如果手机发送的数据存在LED=1,则if成立
            {
                PCout(13) = 1; //PC口13引脚输出,高电平
								printf("\r\nLED灭\r\n");
                Delay_ms(500);		//已经在delay.h中初始化

            }
					 else	if(strstr ( strHC05_Fram_Record .Data_RX_BUF, "LED=0" ))
            {
                PCout(13) = 0; //PC口13引脚输出,低电平
								printf("\r\nLED亮\r\n");
								Delay_ms(500);

            }
            strHC05_Fram_Record .InfBit .FramLength = 0;                             //清除接收标志
            strHC05_Fram_Record.InfBit.FramFinishFlag = 0;
        }
    }
}

3. 编译

编译成功

4. 选择烧录工具并配置MDK

本文选择的是ST_Link烧录工具


如果没有ID号看博客:ST-Link V2烧录问题(已解决)

5. 成品

1. 测试stm32向hc-05发送AT命令

2. 通过hc-05控制mcu



这里PC13已经亮灭了就没有上传截图,大家自己可以试试

工程链接

链接:https://pan.baidu.com/s/1QkiPecASH7St9YDvSWHfpA 提取码:0000

有关九、stm32-蓝牙HC_05(接发通信、控制LED亮灭)的更多相关文章

  1. Ruby Readline 在向上箭头上使控制台崩溃 - 2

    当我在Rails控制台中按向上或向左箭头时,出现此错误:irb(main):001:0>/Users/me/.rvm/gems/ruby-2.0.0-p247/gems/rb-readline-0.4.2/lib/rbreadline.rb:4269:in`blockin_rl_dispatch_subseq':invalidbytesequenceinUTF-8(ArgumentError)我使用rvm来管理我的ruby​​安装。我正在使用=>ruby-2.0.0-p247[x86_64]我使用bundle来管理我的gem,并且我有rb-readline(0.4.2)(人们推荐的最少

  2. ruby-on-rails - 带 Spring 锁的 Rails 4 控制台 - 2

    我正在使用Ruby2.1.1和Rails4.1.0.rc1。当执行railsc时,它被锁定了。使用Ctrl-C停止,我得到以下错误日志:~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`gets':Interruptfrom~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.2/lib/spring/client/run.rb:47:in`verify_server_version'from~/.rvm/gems/ruby-2.1.1/gems/spring-1.1.

  3. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  4. STM32读取串口传感器数据(颗粒物传感器,主动上传) - 2

    文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,

  5. C51单片机——实现用独立按键控制LED亮灭(调用函数篇) - 2

    说在前面这部分我本来是合为一篇来写的,因为目的是一样的,都是通过独立按键来控制LED闪灭本质上是起到开关的作用,即调用函数和中断函数。但是写一篇太累了,我还是决定分为两篇写,这篇是调用函数篇。在本篇中你主要看到这些东西!!!1.调用函数的方法(主要讲语法和格式)2.独立按键如何控制LED亮灭3.程序中的一些细节(软件消抖等)1.调用函数的方法思路还是比较清晰地,就是通过按下按键来控制LED闪灭,即每按下一次,LED取反一次。重要的是,把按键与LED联系在一起。我打算用K1来作为开关,看了一下开发板原理图,K1连接的是单片机的P31口,当按下K1时,P31是与GND相连的,也就是说,当我按下去时

  6. ruby-on-rails - 在 Rails 控制台中使用 asset_path - 2

    在我的Character模型中,我添加了:字符.rbbefore_savedoself.profile_picture_url=asset_path('icon.png')end但是,对于数据库中已存在的所有角色,它们的profile_picture_url为nil。因此,我想进入控制台并遍历所有这些并进行设置。在我试过的控制台中:Character.find_eachdo|c|c.profile_picture_url=asset_path('icon.png')end但这给出了错误:NoMethodError:undefinedmethod`asset_path'formain:O

  7. ruby-on-rails - 带有 Pry 的 Rails 控制台 - 2

    当我进入Rails控制台时,我已将pry设置为加载代替irb。我找不到该页面或不记得如何将其恢复为默认行为,因为它似乎干扰了我的Rubymine调试器。有什么建议吗? 最佳答案 我刚发现问题,pry-railsgem。忘记了它的目的是让“railsconsole”打开pry。 关于ruby-on-rails-带有Pry的Rails控制台,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/question

  8. ruby - 将全局 $stdout 重新分配给控制台 - ruby - 2

    我正在尝试将$stdout设置为临时写入一个文件,然后返回到一个文件。test.rb:old_stdout=$stdout$stdout.reopen("mytestfile.out",'w+')puts"thisgoesinmytestfile"$stdout=old_stdoutputs"thisshouldbeontheconsole"$stdout.reopen("mytestfile1.out",'w+')puts"thisgoesinmytestfile1:"$stdout=old_stdoutputs"thisshouldbebackontheconsole"这是输出。r

  9. ruby-on-rails - Ruby 流量控制 : throw an exception, 返回 nil 还是让它失败? - 2

    我在思考流量控制的最佳实践。我应该走哪条路?1)不要检查任何东西并让程序失败(更清晰的代码,自然的错误消息):defself.fetch(feed_id)feed=Feed.find(feed_id)feed.fetchend2)通过返回nil静默失败(但是,“CleanCode”说,你永远不应该返回null):defself.fetch(feed_id)returnunlessfeed_idfeed=Feed.find(feed_id)returnunlessfeedfeed.fetchend3)抛出异常(因为不按id查找feed是异常的):defself.fetch(feed_id

  10. ruby-on-rails - ruby 新手,有人可以帮我从控制台破译这个错误吗? - 2

    我真的只是不确定这意味着什么或我应该做什么才能让网页在我的本地主机上运行。现在它只是显示一个错误,上面写着“我们很抱歉,但出了点问题。”当我运行railsserver并在chrome中打开localhost:3000时。这是控制台输出:StartedGET"/users/sign_in"for127.0.0.1at2013-07-0512:07:07-0400ProcessingbyDevise::SessionsController#newasHTMLCompleted500InternalServerErrorin55msNoMethodError(undefinedmethod`

随机推荐