工程链接:https://gitee.com/zh5mku_admin/p4_-uart1.git 前言 从串口开始,发现STM32CubeMx生成的工程,竟然需要对代码进行大概,而且生成的代码不知什么哪一步的问题,上位机发送数据后,始终无法进入到中断服务函数,下位机能发不能收,找了一下网上的,这个地方竟然还是一个坑,我了个去,一度郁闷… 暴脾气上来之后,找了找原子大神的资料,发现从STM32F4开始都有HAL库的资料,捞下来,链接: https://pan.baidu.com/s/1lTam-Cl_8XxMPjay7x7MDQ 提取码:hstk 再结合STM32STM32CubeMx生成的工程代码,两者直接结合魔改,基于STM32STM32CubeMx生成的LED工程,利用原子F4 HAL库的写法的写法,既然原子没出F103的HAL库,那就自己改一套适用F103的工程,不就万事大吉,管他CubeMx有多少坑,绕过去不就得了,何必去踩下去再爬起来,弄得一身脏…。
- 魔改第一步,增加文件夹
看了一下CubeMx生成的LED工程文件目录树,发现基本上不需要改,不过CMSIS下面应该有一些用不到,暂时先不管,后面好好研究研究,在工程根目录下增加一个”HARDWARE“的文件夹,就可以开始魔改了
2. 魔改GPIO控制方式 在main.h里面添加下列代码,可以直接实现像51类似的GPIO控制功能,位带操作。
#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+20)
#define GPIOB_ODR_Addr (GPIOB_BASE+20)
#define GPIOC_ODR_Addr (GPIOC_BASE+20)
#define GPIOD_ODR_Addr (GPIOD_BASE+20)
#define GPIOE_ODR_Addr (GPIOE_BASE+20)
#define GPIOF_ODR_Addr (GPIOF_BASE+20)
#define GPIOG_ODR_Addr (GPIOG_BASE+20)
#define GPIOH_ODR_Addr (GPIOH_BASE+20)
#define GPIOI_ODR_Addr (GPIOI_BASE+20)
#define GPIOJ_ODR_ADDr (GPIOJ_BASE+20)
#define GPIOK_ODR_ADDr (GPIOK_BASE+20)
#define GPIOA_IDR_Addr (GPIOA_BASE+16)
#define GPIOB_IDR_Addr (GPIOB_BASE+16)
#define GPIOC_IDR_Addr (GPIOC_BASE+16)
#define GPIOD_IDR_Addr (GPIOD_BASE+16)
#define GPIOE_IDR_Addr (GPIOE_BASE+16)
#define GPIOF_IDR_Addr (GPIOF_BASE+16)
#define GPIOG_IDR_Addr (GPIOG_BASE+16)
#define GPIOH_IDR_Addr (GPIOH_BASE+16)
#define GPIOI_IDR_Addr (GPIOI_BASE+16)
#define GPIOJ_IDR_Addr (GPIOJ_BASE+16)
#define GPIOK_IDR_Addr (GPIOK_BASE+16)
#define PAout(n) BIT_ADDR(GPIOA_ODR_Addr,n)
#define PAin(n) BIT_ADDR(GPIOA_IDR_Addr,n)
#define PBout(n) BIT_ADDR(GPIOB_ODR_Addr,n)
#define PBin(n) BIT_ADDR(GPIOB_IDR_Addr,n)
#define PCout(n) BIT_ADDR(GPIOC_ODR_Addr,n)
#define PCin(n) BIT_ADDR(GPIOC_IDR_Addr,n)
#define PDout(n) BIT_ADDR(GPIOD_ODR_Addr,n)
#define PDin(n) BIT_ADDR(GPIOD_IDR_Addr,n)
#define PEout(n) BIT_ADDR(GPIOE_ODR_Addr,n)
#define PEin(n) BIT_ADDR(GPIOE_IDR_Addr,n)
#define PFout(n) BIT_ADDR(GPIOF_ODR_Addr,n)
#define PFin(n) BIT_ADDR(GPIOF_IDR_Addr,n)
#define PGout(n) BIT_ADDR(GPIOG_ODR_Addr,n)
#define PGin(n) BIT_ADDR(GPIOG_IDR_Addr,n)
#define PHout(n) BIT_ADDR(GPIOH_ODR_Addr,n)
#define PHin(n) BIT_ADDR(GPIOH_IDR_Addr,n)
#define PIout(n) BIT_ADDR(GPIOI_ODR_Addr,n)
#define PIin(n) BIT_ADDR(GPIOI_IDR_Addr,n)
#define PJout(n) BIT_ADDR(GPIOJ_ODR_Addr,n)
#define PJin(n) BIT_ADDR(GPIOJ_IDR_Addr,n)
#define PKout(n) BIT_ADDR(GPIOK_ODR_Addr,n)
#define PKin(n) BIT_ADDR(GPIOK_IDR_Addr,n)
- 魔改UART配置
UART1的中断服务函数和回调函数,魔改于F4的写法,不过需要先将#include "stm32f1xx_it.c"中的void USART1_IRQHandler(void)函数和内容注释或者删掉,UART配置具体代码如下,
#include "HAL_UART1.h"
#if 1
#pragma import(__use_no_semihosting)
struct __FILE
{
int handle;
};
FILE __stdout;
void _sys_exit(int x)
{
x = x;
}
int fputc(int ch, FILE *f)
{
while((USART1->SR&0X40)==0);
USART1->DR = (uint8_t) ch;
return ch;
}
#endif
#if EN_USART1_RX
uint8_t USART_RX_BUF[USART_REC_LEN];
uint16_t USART_RX_STA=0;
uint8_t aRxBuffer[RXBUFFERSIZE];
UART_HandleTypeDef UART1_Handler;
void HAL_UART1_INIT(uint32_t bound)
{
UART1_Handler.Instance=USART1;
UART1_Handler.Init.BaudRate=bound;
UART1_Handler.Init.WordLength=UART_WORDLENGTH_8B;
UART1_Handler.Init.StopBits=UART_STOPBITS_1;
UART1_Handler.Init.Parity=UART_PARITY_NONE;
UART1_Handler.Init.HwFlowCtl=UART_HWCONTROL_NONE;
UART1_Handler.Init.Mode=UART_MODE_TX_RX;
HAL_UART_Init(&UART1_Handler);
HAL_UART_Receive_IT(&UART1_Handler, (uint8_t *)aRxBuffer, RXBUFFERSIZE);
}
void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
GPIO_InitTypeDef GPIO_Initure;
if(huart->Instance==USART1)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_USART1_CLK_ENABLE();
GPIO_Initure.Pin=GPIO_PIN_9;
GPIO_Initure.Mode=GPIO_MODE_AF_PP;
GPIO_Initure.Speed=GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
GPIO_Initure.Pin=GPIO_PIN_10;
GPIO_Initure.Mode = GPIO_MODE_INPUT;
GPIO_Initure.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
#if EN_USART1_RX
HAL_NVIC_EnableIRQ(USART1_IRQn);
HAL_NVIC_SetPriority(USART1_IRQn,1,3);
#endif
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance==USART1)
{
if((USART_RX_STA&0x8000)==0)
{
if(USART_RX_STA&0x4000)
{
if(aRxBuffer[0]!=0x0a)USART_RX_STA=0;
else USART_RX_STA|=0x8000;
}
else
{
if(aRxBuffer[0]==0x0d)USART_RX_STA|=0x4000;
else
{
USART_RX_BUF[USART_RX_STA&0X3FFF]=aRxBuffer[0] ;
USART_RX_STA++;
if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;
}
}
}
}
}
void USART1_IRQHandler(void)
{
uint32_t timeout=0;
HAL_UART_IRQHandler(&UART1_Handler);
timeout=0;
while (HAL_UART_GetState(&UART1_Handler) != HAL_UART_STATE_READY)
{
timeout++;
if(timeout>HAL_MAX_DELAY) break;
}
timeout=0;
while(HAL_UART_Receive_IT(&UART1_Handler, (uint8_t *)aRxBuffer, RXBUFFERSIZE) != HAL_OK)
{
timeout++;
if(timeout>HAL_MAX_DELAY) break;
}
#if SYSTEM_SUPPORT_OS
OSIntExit();
#endif
}
#endif
#ifndef _HAL_UART1_H
#define _HAL_UART1_H
#include "stm32f1xx_hal.h"
#include "stdio.h"
#define USART_REC_LEN 200
#define EN_USART1_RX 1
extern uint8_t USART_RX_BUF[USART_REC_LEN];
extern uint16_t USART_RX_STA;
extern UART_HandleTypeDef UART1_Handler;
#define RXBUFFERSIZE 1
extern uint8_t aRxBuffer[RXBUFFERSIZE];
void HAL_UART1_INIT(uint32_t bound);
#endif
- 编写main函数
具体代码如下
int main(void)
{
uint8_t len;
uint16_t times=0;
HAL_Init();
SystemClock_Config();
HAL_LED_Init();
HAL_UART1_INIT(115200);
while (1)
{
if(USART_RX_STA&0x8000)
{
len=USART_RX_STA&0x3fff;
printf("\r\n您发送的消息为:\r\n");
HAL_UART_Transmit(&UART1_Handler,(uint8_t*)USART_RX_BUF,len,1000);
while(__HAL_UART_GET_FLAG(&UART1_Handler,UART_FLAG_TC)!=SET);
printf("\r\n\r\n");
USART_RX_STA=0;
}else
{
times++;
if(times%5000==0)
{
times = 0;
}
if(times%200==0)printf("请输入数据,以回车键结束\r\n");
if(times%30==0)LED2=!LED2;
HAL_Delay(10);
}
}
}
|