stm32补课(遇到的问题集合)

keil清晰度问题:

Keil界面模糊,怎样设置高清界面? - 知乎

右击keil>属性>兼容性>更改高DPI设置:

 keil连接st-link下载及调试程序:

安装st-link驱动, 配置keil并编译下载例程

STLINK驱动获取: https://docs.qq.com/doc/DT2hyS2ZjY21WQkZt,转载于使用STLINK烧录STM32教程_哔哩哔哩_bilibili

Keil 5使用ST-LINK调试STM32程序_keiluvision5如何用stlink调试-优快云博客

程序烧录不自动运行:

解决STM32下载程序后,程序不能自动运行,要复位才能运行_stm32的bin文件不能自动运行-优快云博客

调试退出时卡死

仿真打了断点,点Debug退出,KEIL死机,提示:Encountered an improper argument-OpenEdv-开源电子网

程序串口printf打印字符串异常,无法接收到数据

创建工程时使用没有修改为AC5编译器导致:

 推挽和开漏

推挽(Push-Pull Output):

输入高电平时,经过反向后,上方的P-MOS管导通,下方的N-MOS关闭,对外输出高电平

输入低电平时,经过反向后,N-MOS管导通,P-MOS关闭,对外输出低电平。

开漏(Open Drain Output):

开漏模式输出时,上方的P-MOS管完全不工作。对于stm32,开漏就是失能了P-MOS,这样,当相应位置1时,引脚实际上是处在了浮空的状态,而通过外接的上拉电阻,将其拉高。

输入低电平,则P-MOS管关闭,N-MOS管导通,使输出接地

输入高电平,则P-MOS管和N-MOS管都关闭,所以引脚既不输出高电平,也不输出低电平,为高阻态。正常使用时必须接上拉电阻


 

它具有“线与”的特性,也就是说,若有很多个开漏模式引脚连接到一起时,只有当所有引脚都输出高阻态,才由上拉电阻提供高电平,此高电平的电压为外部上拉电阻所接所接的电压。若其中一个引脚为低电平,那线路就相当于短路接地,使得整条线路都为低电平,0伏。
在STM32的应用中,推挽输出模式一般应用在输出电平为0和3.3伏而且需要高速切换开关状态的场合。除了必须使用开漏模式的场合,我们都习惯用推挽输出模式。
开漏模式一般应用在I2C、SMBUS通讯等需要“线与”功能的总线电路中,除此之外,还用在电平不匹配的场合,如需要输出5伏的高电平,就可以在外部接一个上拉电阻,上拉电源为5伏,并且把GPIO设置为开漏模式,当输出高阻态时,由上拉电阻和电源向外输出5伏的电平。

CubeMX和Java

windows10关闭java自动更新 (亲试有效)_windows安装java显示update-优快云博客

CubeMX安装后无法联网待解决;

替代方法:直接在官网下载固件包以及升级包,解压后使用升级包替换固件包内的重复文件即可。【经验分享】学习使用HAL库进行STM32软件开发 | 安装STM32cubeMX及STM32F4支持包 - STM32团队 ST意法半导体中文论坛

 CubeMX生成项目:

CubeMX配置好后生成项目,添加第三方文件,编译报错找不到文件或者变量未定义。需要将对应的目录添加到工程里面:

 UART配置失败

配置UART中断时例程与CubeMX生成的代码使用的变量名不一致,导致配置UART后HAL_UART_Receive_IT开启中断失败、触发后重新使能中断失败:

//UART_HandleTypeDef g_uart1_handle;  /* 例程   UART句柄 */

UART_HandleTypeDef huart1;            /* CubeMX UART句柄 */

配置UART错误位置:
static void MX_USART1_UART_Init(void)
{

  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }

    /* 该函数会开启接收中断:标志位UART_IT_RXNE,并且设置接收缓冲以及接收缓冲接收最大数据量 */
    HAL_UART_Receive_IT(&g_uart1_handle, (uint8_t *)g_rx_buffer, RXBUFFERSIZE); 
}



回调函数配置UART错误位置:
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
    if (huart->Instance == USART_UX)                    /* 如果是串口1 */
    {
        数据接收...
        
        //重新打开中断
        HAL_UART_Receive_IT(&huart1, (uint8_t *)g_rx_buffer, RXBUFFERSIZE);
    }
}

 窗口看门狗

可以防止程序运行过快(陷入快速喂狗死循环)或者过慢(卡死、跑飞)

HAL库封装层次

时钟初始化为例(代码由CubeMX生成)

/*主函数调用时钟配置函数*/
int main(void)
{
    ...
    SystemClock_Config();
    ...
}

/*时钟配置函数设置结构体并调用HAL库的RCC配置函数*/
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  ...
  RCC_OscInitStruct.xxx = xxx;     /*配置振荡器结构体*/
  ...
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)    /*调用HAL库函数进行时钟配置*/
  {
    Error_Handler();
  }
}

/*HAL库的RCC配置函数判断合法后调用具体寄存器的配置函数*/
HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef  *RCC_OscInitStruct)
{
  ...
  /* 配置 HSE */
      __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState);
  ...
}

/*寄存器配置*/
#define __HAL_RCC_HSE_CONFIG(__STATE__)                                     \
                    do{                                                     \
                      if ((__STATE__) == RCC_HSE_ON)                        \
                      {                                                     \
                        SET_BIT(RCC->CR, RCC_CR_HSEON);                     \
                      }                                                     \
                       ...                                                  \
                    }while(0U)

ADC配置为例:

中文编码乱码

使用CubeMX生成的代码中打印中文报错:

../Core/Src/main.c(109): warning:  #870-D: invalid multibyte character sequence
  			printf("\r\n杩欐槸鍟?:\r\n");

CubeMX的代码不使用GB2312格式保存,解决方法,在外部使用其他编辑器(如VS code)等打开并修改文件编码

 后重新打开keil工程并编译,即可通过且无警告

位带操作

参考1   参考2

通过硬件方式将指定寄存器(位带区域)的每一位都映射到一个32位的地址空间(别名区域)的对应位上(地址0x2000 0000 的值为0x0000 0000 0000 0001,第0位映射到0x2200 0000中的第0位,即0x xxxx xxxx xxxx xxx1)。通过操作映射后的地址,即可修改源寄存器的对应位

特点:高效,适用于需要频繁修改寄存器位的场景

在映射过程中,虽然每个位有一个映射地址,但是它们并不会真正“浪费”内存。位带操作通常是通过硬件地址映射的方式实现的,不会实际占用额外的内存空间。只是在内存地址空间中映射一个虚拟的、看似“浪费”的地址范围。

//计算别名区域地址
#define BITBAND(addr, bitnum) ((addr & 0xF0000000) + 0x2000000 + ((addr & 0xFFFFF)<<5) + (bitnum<<2))

#define MEM_ADDR(addr)  *((volatile unsigned long *)(addr))
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))

#define GPIOA_ODR_Addr    (GPIOA_BASE + 12) // GPIOA 输出数据寄存器(ODR)
#define PAout(n)   BIT_ADDR(GPIOA_ODR_Addr, n)  // 输出宏

PAout(11) = 1;  // 设置 GPIOA 第 11 位为 1 (高电平)

stm32运行神经网络:

GitHub - Staok/Awesome-Embeded-AI: 收集关于嵌入式领域的机器学习算法实现的进展、相关论文和文章、开发库等,帮助初学者快速了解、学习和入门嵌入式领域的机器学习。CC-BY-NC-SA 4.0。

如何在STM32上部署卷积神经网络(纯C语言搭建)_stm32 tensorflow-优快云博客

在STM32单片机上跑神经网络算法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值