开发过程经常需要查看某些特定参数。通常的方法可以使用paintf进行打印输出,观察具体的变量值。STM32内部集成有USART的串口功能,可以通过串口直接输出到电脑(上位机)。使用非常方便,基本不需要不需要写代码,只要配置一下就可以使用。
简单设置就可以看到上面的效果
配置方法: 1、重定向printf的输出函数 int fputc(int ch, FILE *f) 2、配置STM32F10x的USART串口
重定向方法 stdio.h 的输出内容 - int fputc(int ch, FILE *f)
- {
- // 等待USART1 数据发送完成(发送区域空)
- while (!(USART1->SR & USART_SR_TXE));
- // 填充发送寄存器,数据 + 校验位 最多9位
- USART1->DR = (ch & 0x1FF);
-
- return (ch);
- }
复制代码
启动STM32的 USART1 串口 1、使能 复用功能 2、使能 A引脚(USART1 在 PA9,PA10) 3、使能 USART1 4、设置 PA9(TX)复用推挽输出 5、设置 PA10(RX)输入浮空 6、 设置串口参数:波特率、数据位、校验、停止位、流控制 7、使能串口、使能输入、使能输出 OK - void serial_init(void)
- {
- //
- // 设置串口调试
- //
- // 输 出: USART1
- // 引 脚: PA9(TX), PA10(RX)
- // 波特率: 9600
- // 数据位: 8 bit (default) (CR1)
- // 校 验: none (default) (CR1)
- // 停止位: 1 bit (default) (CR2)
- // 流控制: none (default) (CR3)
- //
- // 清除设置后上面配置为系统默认状态
-
- int i;
- /// 使能复用功能,使能GPIOA,使能USART1
- RCC->APB2ENR |= RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_USART1EN;
- // 关闭映射,确保USART使用 PA9,PA10
- AFIO->MAPR &= ~AFIO_MAPR_USART1_REMAP;
-
- // 清除PA9,PA10状态
- GPIOA->CRH &= ~( GPIO_CRH_CNF9 | GPIO_CRH_MODE9 |
- GPIO_CRH_CNF10 | GPIO_CRH_MODE10 );
- // 设置PA9 发送 为复用推挽输出 2MHz
- GPIOA->CRH |= GPIO_CR_AFOUT_PP2MHz & ( GPIO_CRH_CNF9 | GPIO_CRH_MODE9 );
- // 设置PA10接收 为复用上拉下拉模式
- GPIOA->CRH |= GPIO_CR_AFIN_PULLDOWN & ( GPIO_CRH_CNF10 | GPIO_CRH_MODE10 );
-
- // 设置波特率为 9600
- // 计算方法
- // 系统时钟 / (16分频 * 波特率)
- // Baud = 72,000,000 / (16 * 9600) = 468.75
- // 整数部分 << 4 + 取整(小数部分 * 16)
- // 468 << 4 + 0.75 * 16
- USART1->BRR = __USART_BRR(SystemCoreClock, 9600);
-
- // 清除寄存器状态
- USART1->CR1 = USART_CR1_REST;
- USART1->CR2 = USART_CR2_REST; // 停止位 1
- USART1->CR3 = USART_CR3_REST; // 没用控制流
-
- // 防止产生不必要的信息
- for (i = 0; i < 0x1000; i++) __NOP();
-
- // USART1 使能, 使能输出,使能输入
- USART1->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE;
-
- }
复制代码
整个过程中关键的输出定向主要用到了2个寄存器: 一个状态寄存器,检查发送是否为空(USART_ST_TXE) 一个数据寄存器,用于发送数据 - int main(void)
- {
- uint8_t ud = 'a';
- Delay_init();
- // 初始化串口调试
- serial_init();
-
- // 使用寄存器直接 输出 a~z
- while (ud <= 'z') {
- while (!(USART1->SR & USART_SR_TXE));
- USART1->DR = ud;
- ud++;
- }
-
- // 使用打印重定向输出字符串
- printf("\ntest!\n");
- printf("USART1 使能, 使能输出,使能输入\n");
-
- ud = 'a';
- while (1) {
- Delay(20); // 太快降低速度方便看结果(200ms延迟)
- // 使用寄存器直接输出
- while (!(USART1->SR & USART_SR_TXE));
- USART1->DR = ud;
- ud++;
-
- // 使用打印输出换行
- if (ud > 'z') {
- ud = 'a';
- printf("\n");
- }
- };
-
- }
复制代码
具体的配置寄存器可以查看《参考手册》
完整代码
- #define GPIO_CR_RESET (uint32_t)0x44444444
- #define GPIO_CR_MODE_INPUT (uint32_t)0x00000000
- #define GPIO_CR_MODE_2MHz (uint32_t)0x22222222
- #define GPIO_CR_MODE_10MHz (uint32_t)0x11111111
- #define GPIO_CR_MODE_50MHz (uint32_t)0x33333333
- #define GPIO_CR_GP_PUSHPULL (uint32_t)0x00000000
- #define GPIO_CR_GP_OPENDRAIN (uint32_t)0x44444444
- #define GPIO_CR_OUT_PP2MHz (GPIO_CR_MODE_2MHz | GPIO_CR_GP_PUSHPULL)
- #define GPIO_CR_OUT_PP50MHz (GPIO_CR_MODE_50MHz | GPIO_CR_GP_PUSHPULL)
-
- #define GPIO_CR_AFO_PUSHPULL (uint32_t)0x88888888
- #define GPIO_CR_AFO_OPENDRAIN (uint32_t)0xcccccccc
- #define GPIO_CR_AFOUT_PP2MHz (GPIO_CR_MODE_2MHz | GPIO_CR_AFO_PUSHPULL) // 复用推挽输出,2MHz
- #define GPIO_CR_AFIN_FLOAT (uint32_t)0x44444444 // 复用开漏输入
- #define GPIO_CR_AFIN_PULLDOWN (uint32_t)0x88888888 // 复用上拉下拉输入
- #define USART_CR1_REST (uint32_t)0x00000000
- #define USART_CR2_REST (uint32_t)0x00000000
- #define USART_CR3_REST (uint32_t)0x00000000
复制代码- /**
- ********************************************************************
- *
- * @file serial.c
- * @author fpack
- * @version v1.0
- * @date 2014-9-1
- * @brief 小穆妹纸串口调试
- *
- ********************************************************************
- **/
- #include <stdio.h>
- #include "armsis.h"
- /*----------------------------------------------------------------------------
- Define Baudrate setting (BRR) for USART
- *----------------------------------------------------------------------------*/
- #define __DIV(__PCLK, __BAUD) ((__PCLK*25)/(4*__BAUD))
- #define __DIVMANT(__PCLK, __BAUD) (__DIV(__PCLK, __BAUD)/100)
- #define __DIVFRAQ(__PCLK, __BAUD) (((__DIV(__PCLK, __BAUD) - (__DIVMANT(__PCLK, __BAUD) * 100)) * 16 + 50) / 100)
- #define __USART_BRR(__PCLK, __BAUD) ((__DIVMANT(__PCLK, __BAUD) << 4)|(__DIVFRAQ(__PCLK, __BAUD) & 0x0F))
- //struct __FILE { int handle; /* Add whatever you need here */ };
- //FILE __stdout;
- //FILE __stdin;
- int fputc(int ch, FILE *f)
- {
- // 等待USART1 数据发送完成(发送区域空)
- while (!(USART1->SR & USART_SR_TXE));
- USART1->DR = (ch & 0x1FF);
-
- return (ch);
- }
- void serial_init(void)
- {
- //
- // 设置串口调试
- //
- // 输 出: USART1
- // 引 脚: PA9(TX), PA10(RX)
- // 波特率: 9600
- // 数据位: 8 bit (default) (CR1)
- // 校 验: none (default) (CR1)
- // 停止位: 1 bit (default) (CR2)
- // 流控制: none (default) (CR3)
- //
- // 清除设置后上面配置为系统默认状态
-
- int i;
- /// 使能复用功能,使能GPIOA,使能USART1
- RCC->APB2ENR |= RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN | RCC_APB2ENR_USART1EN;
- // 关闭映射,确保USART使用 PA9,PA10
- AFIO->MAPR &= ~AFIO_MAPR_USART1_REMAP;
-
- // 清除PA9,PA10状态
- GPIOA->CRH &= ~( GPIO_CRH_CNF9 | GPIO_CRH_MODE9 |
- GPIO_CRH_CNF10 | GPIO_CRH_MODE10 );
- // 设置PA9 发送 为复用推挽输出 2MHz
- GPIOA->CRH |= GPIO_CR_AFOUT_PP2MHz & ( GPIO_CRH_CNF9 | GPIO_CRH_MODE9 );
- // 设置PA10接收 为复用上拉下拉模式
- GPIOA->CRH |= GPIO_CR_AFIN_PULLDOWN & ( GPIO_CRH_CNF10 | GPIO_CRH_MODE10 );
-
- // 设置波特率为 9600
- // 计算方法
- // 系统时钟 / (16分频 * 波特率)
- // Baud = 72,000,000 / (16 * 9600) = 468.75
- // 整数部分 << 4 + 取整(小数部分 * 16)
- // 468 << 4 + 0.75 * 16
- USART1->BRR = __USART_BRR(SystemCoreClock, 9600);
-
- // 清除寄存器状态
- USART1->CR1 = USART_CR1_REST;
- USART1->CR2 = USART_CR2_REST; // 停止位 1
- USART1->CR3 = USART_CR3_REST; // 没用控制流
-
- // 防止产生不必要的信息
- for (i = 0; i < 0x1000; i++) __NOP();
-
- // USART1 使能, 使能输出,使能输入
- USART1->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE;
-
- }
复制代码- /**
- ********************************************************************
- *
- * @file serial.h
- * @author fpack
- * @version v1.0
- * @date 2014-9-1
- * @brief 小穆妹纸串口调试
- *
- ********************************************************************
- **/
- #ifndef __SERIAL_H__
- #define __SERIAL_H__
- #ifdef __cplusplus
- extern "C" {
- #endif
- void serial_init(void);
- #ifdef __cplusplus
- }
- #endif
- #endif
复制代码
|