文章目录
前言
环境
- 硬件:stm32f103c8t6 核心板
- 软件:STM32CubeMX 6.4.0
- 软件:keil5 mdk
一、创建StmCubeMX项目文件
- 选择相对应的芯片型号
- 时钟RCC配置,将HSE选为外部晶振模式
- SYS设置,选择Serial Wire模式。
-
设置USART
-
设置NVIC
-
时钟树设置
-
设置工程路径、工程名
-
设置工程文件,并导出
二、配置代码
1.定义全局变量
char c;//指令 s:停止 t:开始
char message[]="hello Windows\n";//输出信息
char tips[]="输错了!\n";//提示1
char tips1[]="Start.....\n";//提示2
char tips2[]="Stop......\n";//提示3
int flag=0;//标志 0:停止发送 1.开始发送
2、设置函数接受中断
1、在main函数里加入下面语句表示接受中断
HAL_UART_Receive_IT(&huart1, (uint8_t *)&c, 1);
2、在while循环里加入
if(flag==1){
//发送信息
HAL_UART_Transmit(&huart1, (uint8_t *)&message, strlen(message),0xFFFF);
//延时
HAL_Delay(1000);
}
3、重写中断回调函数
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
//当输入的指令为0时,发送提示并改变flag
if(c=='s'){
flag=0;
HAL_UART_Transmit(&huart1, (uint8_t *)&tips2, strlen(tips2),0xFFFF);
}
//当输入的指令为1时,发送提示并改变flag
else if(c=='t'){
flag=1;
HAL_UART_Transmit(&huart1, (uint8_t *)&tips1, strlen(tips1),0xFFFF);
}
//当输入不存在指令时,发送提示并改变flag
else {
flag=0;
HAL_UART_Transmit(&huart1, (uint8_t *)&tips, strlen(tips),0xFFFF);
}
//重新设置中断
HAL_UART_Receive_IT(&huart1, (uint8_t *)&c, 1);
}
3、编译&烧录
3、效果
三、拓展要求
当stm32接收到字符“stop stm32!”时,停止持续发送“hello windows!”; 当接收到字符“go stm32!”时,持续发送“hello windows!”
新建一个项目,与前面一致,不再赘述
1、打开目标文件
1、在usart.c和main.c中添加头文件
#include “stdio.h”
#include “string.h”
解释:因为后面我们需要用到printf和strcmp。
2、重定义printf函数和勾选项
- main函数外定义
int fputc(int ch, FILE *f)
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
return ch;
}
3、设置全局变量
uint8_t aRxBuffer;
uint8_t Uart1_RxBuff[256];
uint8_t start[20] = "go stm32!";
uint8_t stop[20] = "stop stm32!";
uint8_t Uart1_Rx_Cnt = 0;
uint8_t cAlmStr[] = "溢出了\r\n";
unsigned int flag = 1;
4、设置接收中断函数
- 1、在main函数里加入
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1);
- 2、在while循环中添加
while (1)
{
if(flag == 1){
printf("Hello windows!\r\n");
}
HAL_Delay(1000);
}
- 3、重写回调函数(写在main函数外)
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (strcmp(Uart1_RxBuff, start) == 0){
flag = 1;
printf("start....\r\n");
}
if (strcmp(Uart1_RxBuff, stop) == 0){
flag = 0;
printf("stop....\r\n");
}
if(Uart1_Rx_Cnt >= 255) //溢出判断
{
Uart1_Rx_Cnt = 0;
memset(Uart1_RxBuff,0x00,sizeof(Uart1_RxBuff));
HAL_UART_Transmit(&huart1, (uint8_t *)&cAlmStr, sizeof(cAlmStr),0xFFFF);
}
else
{
Uart1_RxBuff[Uart1_Rx_Cnt++] = aRxBuffer; //接收数据转存
if((Uart1_RxBuff[Uart1_Rx_Cnt-1] == 0x0A)&&(Uart1_RxBuff[Uart1_Rx_Cnt-2] == 0x0D)) //判断结束位
{
Uart1_Rx_Cnt = 0;
memset(Uart1_RxBuff,0x00,sizeof(Uart1_RxBuff)); //6清空数组
}
}
HAL_UART_Receive_IT(&huart1, (uint8_t *)&aRxBuffer, 1); //再开启接收中断
}
2、烧录运行
3、效果
四、采用串口DMA方式向上位机连续发送数据
1、新建工程项目
-新建工程,并找到芯片相对应型号
-
进行时钟RCC选项配置
-
设置串口
-
使能中断
-
DMA设置,将传输速率设置为中速Medium,模式设置为Normal,右侧选择Memory。
-
在System view下选择DMA
-
时钟树设置
-
设置工程路径、工程名
-
设置工程文件,并导出
2、main.c代码
1、定义一个全局变量
uint8_t Senbuff[] = "Hello world!"; //定义数据发送数组
2、在while循环里添加
HAL_UART_Transmit_DMA(&huart1, (uint8_t *)Senbuff, sizeof(Senbuff));
HAL_Delay(1000);
编译成功
下一步进行烧录,烧录成功后的效果如下:
五、总结
实验过程中遇到许多困难,最终还是得以解决。对两种中断模式的理解更加的深刻,以及对HAL库中的接口函数的深刻理解和基本使用。
六、参考资料
https://blog.csdn.net/qq_45917157/article/details/121141873
https://blog.csdn.net/qq_47281915/article/details/121053903