一、硬件部分
名称 | 作用 | 图片 |
stm32f103c8t6板子 | —— | —— |
HC08蓝牙模块 | 连接单片机通讯TX接单片机RX1,RX接单片机TX1。 | |
usb转ttl模块 | 模拟调试蓝牙通讯,同时在串口助手里修改蓝牙的波特率,让蓝牙的波特率和单片机相同 |
二、stm32cube操作部分
新建工程,选择stm32f103c8t6单片机,SYS选择Serial Wire,RCC选择的HSE选择Crystal/Ceramic Resonator模式。打开Clock Configuration,按照下图配置
在HCLK处输入72,回车。这里如果你不明白为什么进行这样的基础操作,可以看看我写的时钟树的文章,http://t.csdnimg.cn/heiro。
接着点击led1对应的PB8,右键,将其设置为GPIO_Output,然后点击GPIO将它的初始状态设置为高电平,这样通电不会亮。
接着配置串口一,Mode选择异步,即Asynchronous
记得这里的波特率是115200(后面的蓝牙是个坑),你也可以改成9600
最后点击Project Manager
在Project里起名字,记住,不管你的名字,还是保存路径,统统不要有中文,否则你绝对不会成功。接着在Toolchain/IED里修改成MDK-ARM,然后按照下面的配置
生成之后,打开文件即可
三、代码的书写(蓝色的是自己写的,黑色的是软件生成的)
#include "main.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>//fput函数代码
#include <string.h>//strlen函数头文件
/* USER CODE END Includes */
void SystemClock_Config(void);
/* USER CODE BEGIN 0 */
unsigned char ch[20] = {0};
int fputc(int ch, FILE *f)
{
unsigned char temp[1]={ch};
HAL_UART_Transmit(&huart1,temp,1,0xffff);
return ch;
}
/* USER CODE END 0 */
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART1_UART_Init();
/* USER CODE BEGIN 2 */
unsigned char ch[20] = {0};
HAL_UART_Transmit(&huart1, (uint8_t *)"hello world\n", strlen("hello world\n"), 100);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
HAL_UART_Receive(&huart1, ch, 19, 100);
printf("%s",ch);
if(!strcmp((const char *)ch,"open"))
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET);
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8)==GPIO_PIN_RESET)
{
printf("LED1已经打开\r\n");
}
}
else if(!strcmp((const char *)ch,"close"))
{
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET);
if(HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_8)==GPIO_PIN_SET)
{
printf("LED1已经关闭\r\n");
}
}
memset(ch, 0, strlen((const char *)ch));//这里面我加了许多的强制转换,不是我要加,而是如果你不加程序会报警告。
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
关于代码部分我要说的是,养成一个习惯把你自己写的代码写到
USER CODE BEGIN .......
USER CODE END ......
之间,这样的话,就算你在stm32cube里修改东西,更新代码,也不会影响你自己写的代码。
我不知道大家对这个代码有啥疑问,或者说为啥要把他写到这里
int fputc(int ch, FILE *f)
{
unsigned char temp[1]={ch};
HAL_UART_Transmit(&huart1,temp,1,0xffff);
return ch;
}
他是为printf函数的重映射服务的,学过C语言的同学应该知道,printf函数使用的时候,他的默认输出是在电脑屏上显示,但是这里我们是要让他在串口或者蓝牙上显示,所以所谓的重映射简单点说就是改变它的显示的地方。重映射的方法不止这一种,有兴趣的可以搜一搜,不想搜的记住这种方法就行了,比较固定。这里看起来好像我们只处理了一个字节,但是事实上,他是一个字节一个字节的处理,会处理完,这是这个函数自带的性质。
当然重映射的时候记得打开魔术棒,在Target中勾选Use MicroLIB,否则你的重映射也不会成功。
当时我写printf("LED1已经打开\r\n");printf("LED1已经关闭\r\n")的时候,keil还给我报警告说我的汉字非法,最后我上网查了一下,解决了,如果你也遇到了,可以像我这样操作
打开魔术棒,选择Target,在ARM Compiler中选择版本六
接着选择c/c++,在Misc Controls中输入 -Wno-invalid-source-encoding,点击ok即可
这两个步骤一定都要用,否则你无法成功
四、其它
这就要说一下坑爹的蓝牙了,之前让他与51单片机配合,设置的波特率是9600,但是到了32这里变成了11520,我也没注意这个问题。我拿着USB转TTL模块连接单片机和串口助手进行调试,我发现没有问题。但是一连接到蓝牙就不行了,我一直以为蓝眼坏了,但是当我单独测试的时候,我发现了波特率的问题。
这是我在知乎上找的蓝牙的修改命令
蓝牙的默认波特率是9600,因此刚开始的时候选择波特率是9600,在发送行里输入AT+BAUD=115200,N,勾选发送新行,点击发送。看到OK115200,NONE,表明波特率修改成功。
最后连接上我们的蓝牙就可以发送对应的命令,输入open,LED1亮,输入close,LED1灭。
如果你仅仅是用串口助手调试,你一定要注意两件事。一是波特率,而是发送框发送命令是不要勾选“发送新行”,否则你也不会成功。