[应用相关] STM32系统学习——USART(串口通信)

[复制链接]
 楼主| 范德萨大师傅 发表于 2022-1-29 15:44 | 显示全部楼层
2)嵌套向量中断控制器NVIC配置

static void NVIC_Configuration(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 嵌套向量中断控制器组选择 */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

/* 配置 USART 为中断源 */
NVIC_InitStructure.NVIC_IRQChannel = DEBUG_USART_IRQ;
/* 抢断优先级为 1 */
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
/* 子优先级为 1 */
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
/* 使能中断 */
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
/* 初始化配置 NVIC */
NVIC_Init(&NVIC_InitStructure);
}
 楼主| 范德萨大师傅 发表于 2022-1-29 15:45 | 显示全部楼层
3)USART初始化配置
  1. void USART_Config(void)
  2. {
  3. GPIO_InitTypeDef GPIO_InitStructure;
  4. USART_InitTypeDef USART_InitStructure;

  5. // 打开串口 GPIO 的时钟
  6. DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);

  7. // 打开串口外设的时钟
  8. DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);

  9. // 将 USART Tx 的 GPIO 配置为推挽复用模式
  10. GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
  11. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  12. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  13. GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);

  14. // 将 USART Rx 的 GPIO 配置为浮空输入模式
  15. GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
  16. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  17. GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);

  18. // 配置串口的工作参数
  19. // 配置波特率
  20. USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;
  21. // 配置 针数据字长
  22. USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  23. // 配置停止位
  24. USART_InitStructure.USART_StopBits = USART_StopBits_1;
  25. // 配置校验位
  26. USART_InitStructure.USART_Parity = USART_Parity_No ;
  27. // 配置硬件流控制
  28. USART_InitStructure.USART_HardwareFlowControl =
  29. USART_HardwareFlowControl_None;
  30. // 配置工作模式,收发一起
  31. USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  32. // 完成串口的初始化配置
  33. USART_Init(DEBUG_USARTx, &USART_InitStructure);

  34. // 串口中断优先级配置
  35. NVIC_Configuration();

  36. // 使能串口接收中断
  37. USART_ITConfig(DEBUG_USARTx, USART_IT_RXNE, ENABLE);

  38. // 使能串口
  39. USART_Cmd(DEBUG_USARTx, ENABLE);
  40. }
 楼主| 范德萨大师傅 发表于 2022-1-29 15:45 | 显示全部楼层
调用RCC_APB2PeriphClockCmd函数开启GPIO端口时钟,使用GPIO之前必须开启对应的时钟。RCC_APB2PeriphClockCmd函数开启USART时钟。
使用GPIO之前需要初始化配置它,并且还要添加特殊设置,因为我们使用它作为外设引脚,一般都有特殊功能,模式设置为复用功能,把串口的Tx引脚配置为复用推挽输出,Rx引脚为浮空输入,数据完全由外部输入决定。
配置USAT1通信参数为:波特率115200,字长8,1个停止位,没有校验位,不使用硬件流控制,收发一体工作模式,然后调用USART初始化函数完成配置。
USART接收中断,需要配置NVIC,这里调用NVIC_Configuration函数完成配置,然后调用USART_ITConfig函数使能USART接收中断。
最后 调用USART_Cmd函数使能USART,最终配置的是USART_CR1的UE位,具体作用是开启USART工作时钟,没有时钟那USART这个外设就工作不了。
 楼主| 范德萨大师傅 发表于 2022-1-29 15:46 | 显示全部楼层
4)字符发送

/***************** 发送一个字符 **********************/
void Usart_SendByte( USART_TypeDef * pUSARTx, uint8_t ch)
{
/* 发送一个字节数据到 USART */
USART_SendData(pUSARTx,ch);

/* 等待发送数据寄存器为空 */
while (USART_GetFlagStatus(pUSARTx, USART_FLAG_TXE) == RESET);
}

/***************** 发送字符串 **********************/
void Usart_SendString( USART_TypeDef * pUSARTx, char *str)
{
unsigned int k=0;
do {
Usart_SendByte( pUSARTx, *(str + k) );
k++;
} while (*(str + k)!='\0');

/* 等待发送完成 */
while (USART_GetFlagStatus(pUSARTx,USART_FLAG_TC)==RESET) {
}
 楼主| 范德萨大师傅 发表于 2022-1-29 15:46 | 显示全部楼层
Usart_SendByte用来指定USART发送一个ASCLL码字符,它有2个形参:第一个USART第二个待发送的字符,它通过调用库函数USART_SendData来实现等待,并且增加了等待发送完成功能,它接收两个参数:一个是USART,一个是事件标志。这里循环检测发送数据寄存器这个标志,当跳出while循环时,说明发送数据寄存器为空。
Usart_SendString函数用来发送一个字符串,实际调用Usar_SendByte函数发送每个字符,直到遇到空字符才停止发送。最后使用循环检测发送完成的事件标志TC,保证数据完成后才退出函数。

5)USART中断服务函数

  1. void DEBUG_USART_IRQHandler(void)
  2. {
  3. uint8_t ucTemp;
  4. if (USART_GetITStatus(DEBUG_USARTx,USART_IT_RXNE)!=RESET)
  5. {
  6. ucTemp = USART_ReceiveData( DEBUG_USARTx );
  7. USART_SendData(USARTx,ucTemp);
  8. }

  9. }


USART_Config()函数完成USART初始化配置,包括GPIO USART配置,接收中断使能等。
接下来调用字符发送函数把数据发给串口调试助手。
最后什么也不做,等待接收中断产生,并在中断服务函数中回传数据。
 楼主| 范德萨大师傅 发表于 2022-2-21 23:16 | 显示全部楼层
七、USART1指令控制RGB彩灯实验
1、思路要点
1)初始化配置RGB彩色灯GPIO
2)使能RX和TX引脚GPIO时钟和USART时钟
3)初始化GPIO,并将GPIO复用到USART上
4)配置USART参数
5)使能USART
6)获取指令输入,根据控制RGB彩色灯
 楼主| 范德萨大师傅 发表于 2022-2-21 23:17 | 显示全部楼层
2、代码分析
1)GPIO和USART宏定义
  1. 1 #define DEBUG_USARTx USART1
  2. 2 #define DEBUG_USART_CLK RCC_APB2Periph_USART1
  3. 3 #define DEBUG_USART_APBxClkCmd RCC_APB2PeriphClockCmd
  4. 4 #define DEBUG_USART_BAUDRATE 115200
  5. 5
  6. 6 // USART GPIO 引脚宏定义
  7. 7 #define DEBUG_USART_GPIO_CLK (RCC_APB2Periph_GPIOA)
  8. 8 #define DEBUG_USART_GPIO_APBxClkCmd RCC_APB2PeriphClockCmd
  9. 9
  10. 10 #define DEBUG_USART_TX_GPIO_PORT GPIOA
  11. 11 #define DEBUG_USART_TX_GPIO_PIN GPIO_Pin_9
  12. 12 #define DEBUG_USART_RX_GPIO_PORT GPIOA
  13. 13 #define DEBUG_USART_RX_GPIO_PIN GPIO_Pin_10
  14. 14
  15. 15 #define DEBUG_USART_IRQ USART1_IRQn
  16. 16 #define DEBUG_USART_IRQHandler USART1_IRQHandler

 楼主| 范德萨大师傅 发表于 2022-2-21 23:18 | 显示全部楼层
2)USART初始化配置
  1. 1 void USART_Config(void)
  2. 2 {
  3. 3 GPIO_InitTypeDef GPIO_InitStructure;
  4. 4 USART_InitTypeDef USART_InitStructure;
  5. 5
  6. 6 // 打开串口 GPIO 的时钟
  7. 7 DEBUG_USART_GPIO_APBxClkCmd(DEBUG_USART_GPIO_CLK, ENABLE);
  8. 8
  9. 9 // 打开串口外设的时钟
  10. 10 DEBUG_USART_APBxClkCmd(DEBUG_USART_CLK, ENABLE);
  11. 11
  12. 12 // 将 USART Tx 的 GPIO 配置为推挽复用模式
  13. 13 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_TX_GPIO_PIN;
  14. 14 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  15. 15 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  16. 16 GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStructure);
  17. 17
  18. 18 // 将 USART Rx 的 GPIO 配置为浮空输入模式
  19. 19 GPIO_InitStructure.GPIO_Pin = DEBUG_USART_RX_GPIO_PIN;
  20. 20 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  21. 21 GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStructure);
  22. 22
  23. 23 // 配置串口的工作参数
  24. 24 // 配置波特率
  25. 25 USART_InitStructure.USART_BaudRate = DEBUG_USART_BAUDRATE;
  26. 26 // 配置 针数据字长
  27. 27 USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  28. 28 // 配置停止位
  29. 29 USART_InitStructure.USART_StopBits = USART_StopBits_1;
  30. 30 // 配置校验位
  31. 31 USART_InitStructure.USART_Parity = USART_Parity_No ;
  32. 32 // 配置硬件流控制
  33. 33 USART_InitStructure.USART_HardwareFlowControl =
  34. 34 USART_HardwareFlowControl_None;
  35. 35 // 配置工作模式,收发一起
  36. 36 USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  37. 37 // 完成串口的初始化配置
  38. 38 USART_Init(DEBUG_USARTx, &USART_InitStructure);
  39. 39
  40. 40 // 使能串口
  41. 41 USART_Cmd(DEBUG_USARTx, ENABLE);
  42. 42 }

评论

与上实验基本一样,唯一不同没使用使能中断  发表于 2022-2-21 23:23
 楼主| 范德萨大师傅 发表于 2022-2-21 23:23 | 显示全部楼层
3)重定向printf和scanf函数
  1. 1 ///重定向 c 库函数 printf 到串口,重定向后可使用 printf 函数
  2. 2 int fputc(int ch, FILE *f)
  3. 3 {
  4. 4 /* 发送一个字节数据到串口 */
  5. 5 USART_SendData(DEBUG_USARTx, (uint8_t) ch);
  6. 6
  7. 7 /* 等待发送完毕 */
  8. 8 while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET);
  9. 9
  10. 10 return (ch);
  11. 11 }
  12. 12
  13. 13 ///重定向 c 库函数 scanf 到串口,重写向后可使用 scanf、getchar 等函数
  14. 14 int fgetc(FILE *f)
  15. 15 {
  16. 16 /* 等待串口输入数据 */
  17. 17 while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_RXNE) == RESET);
  18. 18
  19. 19 return (int)USART_ReceiveData(DEBUG_USARTx);
  20. 20 }
 楼主| 范德萨大师傅 发表于 2022-2-21 23:25 | 显示全部楼层
fputc函数是printf函数内部的一个函数,功能是将字符ch写入文件指针f所指向文件的当前写指针位置,我们使用USART函数重新修改fputc函数内容,达到类似写入的功能。
fgetc实现字符读取功能。
还有一点需要注意的,使用 fput和 fgetc函数达到重定向 C语言标准库输入输出函数必须在 MDK的工程选项把“Use MicroLIB”勾选上,MicoroLIB 是缺省 C库的备选库,它对标准 C库进行了高度优化使代码更少,占用更少资源。
为使用 printf、scanf 函数需要在文件中包含 stdio.h头文件。\
 楼主| 范德萨大师傅 发表于 2022-2-21 23:25 | 显示全部楼层
4)输出提示信息
  1. 1 static void Show_Message(void)
  2. 2 {
  3. 3 printf("\r\n 这是一个通过串口通信指令控制 RGB 彩灯实验 \n");
  4. 4 printf("使用 USART 参数为:%d 8-N-1 \n",USART_BAUDRATE);
  5. 5 printf("开发板接到指令后控制 RGB 彩灯颜色,指令对应如下:\n");
  6. 6 printf(" 指令 ------ 彩灯颜色 \n");
  7. 7 printf(" 1 ------ 红 \n");
  8. 8 printf(" 2 ------ 绿 \n");
  9. 9 printf(" 3 ------ 蓝 \n");
  10. 10 printf(" 4 ------ 黄 \n");
  11. 11 printf(" 5 ------ 紫 \n");
  12. 12 printf(" 6 ------ 青 \n");
  13. 13 printf(" 7 ------ 白 \n");
  14. 14 printf(" 8 ------ 灭 \n");
  15. 15 }
 楼主| 范德萨大师傅 发表于 2022-2-21 23:27 | 显示全部楼层
5)main函数
  1. 1 int main(void)
  2. 2 {
  3. 3 char ch;
  4. 4
  5. 5 /* 初始化 RGB 彩灯 */
  6. 6 LED_GPIO_Config();
  7. 7
  8. 8 /* 初始化 USART 配置模式为 115200 8-N-1 */
  9. 9 USART_Config();
  10. 10
  11. 11 /* 打印指令输入提示信息 */
  12. 12 Show_Message();
  13. 13 while (1)
  14. 14 {
  15. 15 /* 获取字符指令 */
  16. 16 ch=getchar();
  17. 17 printf("接收到字符:%c\n",ch);
  18. 18
  19. 19 /* 根据字符指令控制 RGB 彩灯颜色 */
  20. 20 switch (ch)
  21. 21 {
  22. 22 case '1':
  23. 23 LED_RED;
  24. 24 break;
  25. 25 case '2':
  26. 26 LED_GREEN;
  27. 27 break;
  28. 28 case '3':
  29. 29 LED_BLUE;
  30. 30 break;
  31. 31 case '4':
  32. 32 LED_YELLOW;
  33. 33 break;
  34. 34 case '5':
  35. 35 LED_PURPLE;
  36. 36 break;
  37. 37 case '6':
  38. 38 LED_CYAN;
  39. 39 break;
  40. 40 case '7':
  41. 41 LED_WHITE;
  42. 42 break;
  43. 43 case '8':
  44. 44 LED_RGBOFF;
  45. 45 break;
  46. 46 default:
  47. 47 /* 如果不是指定指令字符,打印提示信息 */
  48. 48 Show_Message();
  49. 49 break;
  50. 50 }
  51. 51 }
  52. 52 }
 楼主| 范德萨大师傅 发表于 2022-2-21 23:29 | 显示全部楼层
首先我们定义一个字符变量来存放接收到的字符。
接下来调用 LED_GPIO_Config 函数完成 RGB 彩色 GPIO 初始化配置,该函数定义在bsp_led.c 文件内。
调用 USART_Config 函完成 USART初始化配置。
Show_Message函数使用 printf 函数打印实验指令说明信息。
getchar函数用于等待获取一个字符,并返回字符。我们使用 ch变量保持返回的字符,接下来判断 ch内容执行对应的程序。
我们使用 switch语句判断 ch 变量内容,并执行对应的功能程序。
Uriah 发表于 2023-11-5 07:15 | 显示全部楼层

作为功率开关管和整流器的散热部分
Bblythe 发表于 2023-11-5 09:11 | 显示全部楼层

在主要开关电源拓扑中主要的电流环路
Uriah 发表于 2023-11-5 10:14 | 显示全部楼层

每条大电流的地线要短而宽
Bblythe 发表于 2023-11-5 12:10 | 显示全部楼层

每个环路要与其他环路分开
Wordsworth 发表于 2023-11-5 13:13 | 显示全部楼层

布置PCB的时候,电源地的安排要十分小心
Bblythe 发表于 2023-11-5 15:09 | 显示全部楼层

从邻近的引线上引入RF(射频)信号
Wordsworth 发表于 2023-11-5 16:12 | 显示全部楼层

这些电流环路的布线
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部