STM32串口状态机(仿时序逻辑)
Posted whulaolao
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STM32串口状态机(仿时序逻辑)相关的知识,希望对你有一定的参考价值。
在此,首先感谢CSDN的无痕幽雨,他的博客给了我很大的启发,贴上他博客的网址:https://blog.csdn.net/wuhenyouyuyouyu/article/details/52585835
我的学习总是断断续续的,学了半年STM32后又转去做FPGA,学了一年FPGA后又回来用STM32,以前对单片机的概念是用来做些简单的事情,最重要的是能够配置好寄存器驱动外设,但是现在拿起来做机械臂的控制时,我立马懵掉了,机械臂这么多个姿态,要想自动抓取那么动作必然是跟随一定流程的,特殊的动作,如果简单的驱动外设很明显无法完成这个艰巨的任务,除此以外,要想接收PYNQ串口发来的指令,这些指令能够告诉我的STM32什么时候开始抓,目标转向角是多少,目标位置是多少,等等。我们以前做仪器常用的是SPI,通过先写地址再写数据的方式非常容易修改寄存器变量,可是串口,就只能自己制造协议了,根据队友的提醒以及做FPGA的知识,我采用了状态机的写法(C语言版),最终实现了这个自定义的串口协议,并且让自己的C水平提高了一些。
废话不多说了,本次要写的代码流程图如下所示:
当然了,这个是我比赛串口的流程图,最终我整理出来的代码是重新写的,因此赋值有所不同。
对于嵌入式来说,外设的驱动是基本功,在这里我驱动了UART1来编写我的协议,并驱动了RGB灯进行验证, 在这里直接贴出我的驱动代码:
<LED.h>
#ifndef INC_LED_H_ #define INC_LED_H_ #include "stm32f10x.h" #include "stm32f10x_conf.h" #define LED_Pin_Port GPIOB #define LED_Green_Pin GPIO_Pin_0 #define LED_Blue_Pin GPIO_Pin_1 #define LED_Red_Pin GPIO_Pin_5 #define LED_Green_ON GPIO_ResetBits(LED_Pin_Port,LED_Green_Pin) #define LED_Green_OFF GPIO_SetBits(LED_Pin_Port,LED_Green_Pin) #define LED_Blue_ON GPIO_ResetBits(LED_Pin_Port,LED_Blue_Pin) #define LED_Blue_OFF GPIO_SetBits(LED_Pin_Port,LED_Blue_Pin) #define LED_Red_ON GPIO_ResetBits(LED_Pin_Port,LED_Red_Pin) #define LED_Red_OFF GPIO_SetBits(LED_Pin_Port,LED_Red_Pin) void LED_Init(void); #endif /* INC_LED_H_ */
<LED.c>
#include "LED.h" void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE); GPIO_InitStructure.GPIO_Pin = LED_Green_Pin; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(LED_Pin_Port,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LED_Blue_Pin; GPIO_Init(LED_Pin_Port,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = LED_Red_Pin; GPIO_Init(LED_Pin_Port,&GPIO_InitStructure); }
<uart.h>
#ifndef INC_UART_H_ #define INC_UART_H_ #include "stm32f10x.h" #include "stm32f10x_conf.h" void Uart1_Init(void); void Uart1_SendByte(u8 Data); u8 Uart1_ReceiveByte(void); void Uart1_SendString(char *str); #endif /* INC_UART_H_ */
<uart.c>
#include "uart.h" void Uart1_Init(void) { GPIO_InitTypeDef Uart_GPIO_InitStructure; USART_InitTypeDef Uart1_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA,ENABLE); Uart_GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; Uart_GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; Uart_GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&Uart_GPIO_InitStructure); Uart_GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; Uart_GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; Uart_GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA,&Uart_GPIO_InitStructure); Uart1_InitStructure.USART_BaudRate = 115200; Uart1_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; Uart1_InitStructure.USART_Mode = USART_Mode_Rx|USART_Mode_Tx; Uart1_InitStructure.USART_Parity = USART_Parity_No; Uart1_InitStructure.USART_StopBits = USART_StopBits_1; Uart1_InitStructure.USART_WordLength = USART_WordLength_8b; USART_Init(USART1,&Uart1_InitStructure); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_Init(&NVIC_InitStructure); USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); USART_Cmd(USART1,ENABLE); } void Uart1_SendByte(u8 Data) { USART_SendData(USART1,Data); while(USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET); } void Uart1_SendString(char *str) { while((*str)!=‘