1、首先想要stm32收到我发送的内容,就需要建立一个东西来保存
所以说 我先定义了一个 RxPacket[100]的全局变量
2、串口发送是通过中断来进行的,所以说我们需要配置IO口,配置中断(当然最重要的串口配置也不能少)
我是看开发手册上的,用的USART1所以说使用的是PA9和PA10,
然后就是io口、串口的配置和串口中断通道优先级配置,如下
3、中断函数的代码写的方式
3.1、首先我们先要确定hex的包头和包尾和每一步的状态,(注意,我是用的@做包头,\r和\n换行做的包尾)
所以说 我们先定义一个状态变量,作为目前是什么状态,包头、数据还是包尾
3.2、然后我们就判断USART1的缓冲区有没有数据,代码如下:
假如有,欧克,我们进入下一步,
先把数据接收了,放在一个变量里面,我们把他记作RxData代码如下
3.3、好,我们现在就来判断状态,先看是不是状态0,是的话就是包头开始,判断RxData是不是@,是的话就进入下一个阶段
3.4、状态1了,那就是要接收数据了,我们需要用一个变量来该边数组的下标,进行后移保存,同时判断是不是到包尾了,代码如下
3.5、如果到包尾了,进行下一个状态,给有效数组的后一个赋给“\0",同时改变状态还原到状态0,继续后面的接收,( 里面的Serial_RxFlag 是全局变量,会在主函数待会说。)
3.6 、好,这就接收到了一个串口发送的数据包了,最后再清除一下串口缓冲区的内容
4、主函数的代码
初始化,先判断RxFlag的标志位,来对发送的数据进行匹配,实现代码逻辑
例如,实现一个点灯
5,全部代码
5.1串口的代码
char Serial_RxPacket[100]; //"@MSG\r\n"
uint8_t Serial_RxFlag;
void Serial_Init(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); //开启串口
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //开启gpio口
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//上拉输入
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;//波特率9600
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无流控制模式。
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//接受和发送模式
USART_InitStructure.USART_Parity = USART_Parity_No;//无校验位
USART_InitStructure.USART_StopBits = USART_StopBits_1;//1个停止位
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//8字节
USART_Init(USART1, &USART_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//串口接收中断使能
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//中断优先级
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//中断
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//通道使能
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
USART_Cmd(USART1, ENABLE);//串口使能
}
5.2中断的代码
void USART1_IRQHandler(void)
{
static uint8_t RxState = 0;
static uint8_t pRxPacket = 0;
if (USART_GetITStatus(USART1, USART_IT_RXNE) == SET)
{
uint8_t RxData = USART_ReceiveData(USART1);
if (RxState == 0)
{
if (RxData == '@' && Serial_RxFlag == 0)
{
RxState = 1;
pRxPacket = 0;
}
}
else if (RxState == 1)
{
if (RxData == '\r')
{
RxState = 2;
}
else
{
Serial_RxPacket[pRxPacket] = RxData;
pRxPacket ++;
}
}
else if (RxState == 2)
{
if (RxData == '\n')
{
RxState = 0;
Serial_RxPacket[pRxPacket] = '\0';
Serial_RxFlag = 1;
}
}
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
}
5.3 主函数的代码
int main(void)
{
OLED_Init();
LED_Init();
Serial_Init();
OLED_ShowString(1, 1, "TxPacket");
OLED_ShowString(3, 1, "RxPacket");
while (1)
{
if (Serial_RxFlag == 1)
{
if (strcmp(Serial_RxPacket, "LED_ON") == 0)
{
LED1_ON();
Serial_SendString("LED_ON_OK\r\n");
OLED_ShowString(2, 1, " ");
OLED_ShowString(2, 1, "LED_ON_OK");
}
Serial_RxFlag = 0;
}
}
}