您的位置:首页 > 汽车 > 时评 > STM3学习记录

STM3学习记录

2025/4/26 23:02:40 来源:https://blog.csdn.net/qq_44106838/article/details/142066806  浏览:    关键词:STM3学习记录

一、串口
1.串口定义,将串口相关寄存器的首地址强制转化为串口结构体,方便通过结果体访问串口的寄存器

#define     __IO    volatile             /*!< Defines 'read / write' permissions */
typedef struct
{__IO uint32_t SR;         /*!< USART Status register,                   Address offset: 0x00 */__IO uint32_t DR;         /*!< USART Data register,                     Address offset: 0x04 */__IO uint32_t BRR;        /*!< USART Baud rate register,                Address offset: 0x08 */__IO uint32_t CR1;        /*!< USART Control register 1,                Address offset: 0x0C */__IO uint32_t CR2;        /*!< USART Control register 2,                Address offset: 0x10 */__IO uint32_t CR3;        /*!< USART Control register 3,                Address offset: 0x14 */__IO uint32_t GTPR;       /*!< USART Guard time and prescaler register, Address offset: 0x18 */
} USART_TypeDef;#define PERIPH_BASE           0x40000000UL /*!< Peripheral base address in the alias region */
#define APB1PERIPH_BASE       PERIPH_BASE
#define USART3_BASE           (APB1PERIPH_BASE + 0x00004800UL)
#define USART3              ((USART_TypeDef *)USART3_BASE)

2.若有奇偶校验位 16比特数据传输

/* In case of 9bits/No Parity transfer, pTxData needs to be handled as a uint16_t pointer */
if ((husart->Init.WordLength == USART_WORDLENGTH_9B) && (husart->Init.Parity == USART_PARITY_NONE))
{ptxdata8bits  = NULL;ptxdata16bits = (const uint16_t *) pTxData;
}
else
{ptxdata8bits  = pTxData;ptxdata16bits = NULL;
}

3.采样频率是波特率的16倍,起始位将采样位置定位到一位的中间
4.串口有一个字节的缓冲
现象:
串口助手连续发送received@abc
打印数据为:

9 received@
10 areceived@
10 areceived@
10 areceived@
10 areceived@

解释:
从框图得知(只看接收部分结构):
数据先进入接收移位寄存器,再进入接受数据寄存器
串口助手第一次发送received@abc,程序读取到@停止,即读到received@后停止,但是a进入串口接收移位寄存器,等接收数据寄存器读空,接收移位寄存器数据将移入接收数据寄存器,因此第二次读取数据时,从接收数据寄存器读取到的是字符’a’,后续读取received@,也就是说,第二次开始,读取的是areceived@。
在这里插入图片描述

  while (1){rec_len = get_usart_line(rx_buf, rx_max_size, 500000);rx_buf[rec_len] = '\0';if(rec_len > 0) {char str[100];rec_len = snprintf(str, sizeof(str) / sizeof(str[0]), "%d %s\r\n", rec_len, rx_buf);HAL_UART_Transmit_DMA(&huart6, (uint8_t *)str, rec_len);// HAL_UART_Transmit_DMA(&huart6, rx_buf, rec_len);len = rec_len;}rx_buf[0] = 0;/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}int get_usart_line(uint8_t *rx, int rx_max_size, int timeout) {int t = 0, i;uint8_t rx_buf = 0;for(i = 0; rx_buf != '@' && t < timeout && i < rx_max_size; t++) {if(HAL_UART_Receive(&huart6, &rx_buf, 1, 0) == HAL_OK) {// if(HAL_UART_Receive_DMA(&huart6, &rx_buf, 1) == HAL_OK) {rx[i++] = rx_buf;}}return t >= timeout ? -1 : i;
}

二、定时器
1.允许定时器中断

HAL_TIM_Base_Start_IT(&htim2);

2.重写定时器回调函数
函数原型:

/*** @brief  Period elapsed callback in non-blocking mode* @param  htim TIM handle* @retval None*/
__weak void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{/* Prevent unused argument(s) compilation warning */UNUSED(htim);/* NOTE : This function should not be modified, when the callback is needed,the HAL_TIM_PeriodElapsedCallback could be implemented in the user file*/
}

重写:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{if(htim->Instance == TIM2) {static int cnt = 0;if(cnt < 500) led_on();else if(cnt < 1000) led_off();else cnt = 0;cnt++;}
}

三、DMA
STM32 DMA结构图
1.触发方式
硬件触发:UART、ADC、IIC等外设设备
软件触发:M2M置1,内部触发,尽快连续触发传输计数器,快速转运数据,不能喝自动重装一起使用,否则会无限转运。
2.开关控制
当没有开启自动重装,计数器清零时需要先关闭DMA,重新填充初值,再开启DMA,注意必须先关闭
3.DMA通道
每个通道连接的外设不同,必须选择对应外设的通道才能转运,例如STM32F427IIH DMA+UART6 RX必须选择DMA2通道1或通道2 TX必须选择通道DMA2的通道6或7。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com