#include "stm32f1xx_hal.h"
/**
* 按钮点灯
*/
void ledTest(){
// 开启GPIOA时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_DISABLE(); // 禁用GPIOB时钟
__HAL_RCC_GPIOC_CLK_DISABLE(); // 禁用GPIOC时钟
__HAL_RCC_GPIOD_CLK_DISABLE(); // 禁用GPIOD时钟
__HAL_RCC_GPIOE_CLK_DISABLE(); // 禁用GPIOE时钟
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_6; // 选择GPIOA的第6个引脚
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // 设置为输入
GPIO_InitStruct.Pull = GPIO_NOPULL; // 下拉模式
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 初始化GPIOA的第6个引脚
GPIO_InitTypeDef GPIO_InitStruct5 = {0};
GPIO_InitStruct5.Pin = GPIO_PIN_5; // 选择GPIOA的第5个引脚
GPIO_InitStruct5.Mode = GPIO_MODE_OUTPUT_PP; // 设置为推挽输出模式
GPIO_InitStruct5.Speed = GPIO_SPEED_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct5); // 初始化GPIOA的第5个引脚
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET); // 默认不亮
// 主循环
while(1) {
GPIO_PinState pin6Status = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_6); // 读取GPIOA的第6个引脚状态
if (pin6Status == GPIO_PIN_RESET) {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
} else {
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
}
}
}
int main(void) {
// 初始化串口引脚
// 打开GPIOA时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
// 初始化PA9引脚,这是USART1的TX引脚
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_9; // STM32F103的PA9引脚是USART1的TX引脚
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; // 复用推挽输出模式,具体的模式选择来自数据手册,全双工还是半双工都是这个模式
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; // 高速
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 初始化GPIOA的第9个引脚
// 初始化PA10引脚,这是USART1的RX引脚
GPIO_InitTypeDef GPIO_InitStruct10 = {0};
GPIO_InitStruct10.Pin = GPIO_PIN_10; // STM32F103的PA10引脚是USART1的RX引脚
GPIO_InitStruct10.Mode = GPIO_MODE_INPUT; // 输入模式
GPIO_InitStruct10.Pull = GPIO_PULLUP; // 上拉模式,上拉或者浮空都可以,由于串口通信引脚的空闲状态是高电平,所以这里选择上拉比较好
GPIO_InitStruct10.Speed = GPIO_SPEED_FREQ_HIGH; // 高速
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct10); // 初始化GPIOA的第10个引脚
// 初始化USART
// // 开启AFIO时钟
// __HAL_RCC_AFIO_CLK_ENABLE(); // 启用AFIO时钟
// // 重映射UASRT1
// __HAL_AFIO_REMAP_USART1_ENABLE(); // 启用USART1的重映射功能,重映射为(TX/PB6, RX/PB7)
// 打开USART1时钟
__HAL_RCC_USART1_CLK_ENABLE();
// 配置串口
USART_HandleTypeDef huart1;
huart1.Instance = USART1; // 选择USART1
huart1.Init.BaudRate = 115200; // 设置波特率为115200(瑞莎的TTL-USB默认是1.5M)
huart1.Init.WordLength = USART_WORDLENGTH_8B; // 8位数据位
huart1.Init.StopBits = USART_STOPBITS_1; // 1位停止位
huart1.Init.Parity = USART_PARITY_NONE; // 无奇偶校验
huart1.Init.Mode = USART_MODE_TX_RX; // 发送和接收模式
// 使能USART
__HAL_USART_ENABLE(&huart1); // 启用USART1,打开总开关
// 初始化USART
HAL_USART_Init(&huart1);
while(1){
// 发送数据
const char *message = "Hello, USART!\r\n";
while (*message)
{
while (!(huart1.Instance->SR & USART_SR_TXE)); // 等待发送缓冲区空,放置数据被覆盖
// 或者用宏来写
// while (__HAL_USART_GET_FLAG(&huart1, USART_SR_TXE) == RESET);
huart1.Instance->DR = (*message++ & 0xFF); // 发送数据
// 或者用HAL的接口()用接口就不用循环了,其实可以一次发送完
// HAL_USART_Transmit(&huart1, (uint8_t *)message, 1, HAL_MAX_DELAY);
}
while(!(huart1.Instance->SR & USART_SR_TC)); // 等待发送完成,准确来说是发送数据寄存器和移位寄存器都是空,才判定发送完成
// 同理或者用宏来写
// while (__HAL_USART_GET_FLAG(&huart1, USART_SR_TC) == RESET);
// 读取数据
char buffer[1024]; // 创建一个缓冲区来存储接收到的数据
uint16_t index = 0;
while (index < sizeof(buffer) - 1) // 保留一个字节给null结尾
{
while (!(huart1.Instance->SR & USART_SR_RXNE)); // 等待接收数据寄存器非空,也就是有东西写
// 或者用宏来写
// while (__HAL_USART_GET_FLAG(&huart1, USART_SR_RXNE) == RESET);
char c = huart1.Instance->DR & 0xFF; // 读取接收到的数据
if (c == '\n') break; // 如果接收到换行符,结束接收
buffer[index++] = c; // 存储到缓冲区
}
buffer[index] = '\0'; // 确保字符串以null结尾
// HAL_USART_Transmit(&huart1, (uint8_t *)message, strlen(message), HAL_MAX_DELAY);
// 接收数据
// uint8_t buffer[100];
// HAL_StatusTypeDef status = HAL_USART_Receive(&huart1, buffer, sizeof(buffer) - 1, HAL_MAX_DELAY);
// if (status == HAL_OK) {
// buffer[sizeof(buffer) - 1] = '\0'; // 确保字符串以null结尾
// // 处理接收到的数据
// HAL_USART_Transmit(&huart1, buffer, strlen((char *)buffer), HAL_MAX_DELAY);
// }
}
}Loading
stm32-bluepill
stm32-bluepill