STM32的串口空闲中断及接受数据

源程序:

IO口定义:

void GPIO_ConfiguraTIon(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

/* 第1步:打开GPIO和USART部件的时钟 */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

/* 第2步:将USART Tx的GPIO配置为推挽复用模式 */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);

/* 第3步:将USART Rx的GPIO配置为浮空输入模式

由于CPU复位后,GPIO缺省都是浮空输入模式,因此下面这个步骤不是必须的

但是,我还是建议加上便于阅读,并且防止其它地方修改了这个口线的设置参数

*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA, &GPIO_InitStructure);

/* 第1步:打开GPIO和USART2部件的时钟 */

//RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);

/* 第2步:将USART2 Tx的GPIO配置为推挽复用模式 */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOA, &GPIO_InitStructure);

/* 第3步:将USART2 Rx的GPIO配置为浮空输入模式

由于CPU复位后,GPIO缺省都是浮空输入模式,因此下面这个步骤不是必须的

但是,我还是建议加上便于阅读,并且防止其它地方修改了这个口线的设置参数

*/

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA, &GPIO_InitStructure);

/* 第3步已经做了,因此这步可以不做

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

*/

GPIO_Init(GPIOA, &GPIO_InitStructure);

}

串口初始化:

void USART_Configuration(void)

{

USART_InitTypeDef USART_InitStructure;

/* 第4步:配置USART参数

- BaudRate = 115200 baud

- Word Length = 8 Bits

- One Stop Bit

- No parity

- Hardware flow control disabled (RTS and CTS signals)

- Receive and transmit enabled

*/

USART_InitStructure.USART_BaudRate = 19200;

USART_InitStructure.USART_WordLength = USART_WordLength_8b;

USART_InitStructure.USART_StopBits = USART_StopBits_1;

USART_InitStructure.USART_Parity = USART_Parity_No;

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

USART_Init(USART1, &USART_InitStructure);

//配置USART1空闲中断

USART_ITConfig(USART1, USART_IT_IDLE , ENABLE);

/* 第5步:使能 USART, 配置完毕 */

USART_Cmd(USART1, ENABLE);

/* CPU的小缺陷:串口配置好,如果直接Send,则第1个字节发送不出去

如下语句解决第1个字节无法正确发送出去的问题 */

USART_ClearFlag(USART1, USART_FLAG_TC); /* 清发送完成标志,Transmission Complete flag */

USART_InitStructure.USART_BaudRate = 9600;

USART_InitStructure.USART_WordLength = USART_WordLength_8b;

USART_InitStructure.USART_StopBits = USART_StopBits_1;

USART_InitStructure.USART_Parity = USART_Parity_No;

USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

USART_Init(USART2, &USART_InitStructure);

//配置USART2空闲中断

USART_ITConfig(USART2, USART_IT_IDLE , ENABLE);

USART_Cmd(USART2, ENABLE);

/* CPU的小缺陷:串口配置好,如果直接Send,则第1个字节发送不出去

如下语句解决第1个字节无法正确发送出去的问题 */

USART_ClearFlag(USART2, USART_FLAG_TC); /* 清发送外城标志,Transmission Complete flag */

}

DMA配置:

void DMA_Configuration(void)

{

DMA_InitTypeDef DMA_InitStructure;

/* DMA clock enable */

RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //开启DMA1外设时钟

/* DMA1 Channel4 (triggered by USART1 Tx event) Config */

DMA_DeInit(DMA1_Channel4);

DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40013804;

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART1_SEND_DATA;

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;

DMA_InitStructure.DMA_BufferSize = 512;

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //循环模式

DMA_InitStructure.DMA_Priority = DMA_Priority_High;

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

DMA_Init(DMA1_Channel4, &DMA_InitStructure);

DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE);

DMA_ITConfig(DMA1_Channel4, DMA_IT_TE, ENABLE);

/* Enable USART1 DMA TX request */

USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);

DMA_Cmd(DMA1_Channel4, DISABLE);

/* DMA1 Channel5 (triggered by USART2 Tx event) Config */

DMA_DeInit(DMA1_Channel7);

DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004404;

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_SEND_DATA;

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;

DMA_InitStructure.DMA_BufferSize = 512;

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

DMA_InitStructure.DMA_Priority = DMA_Priority_High;

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

DMA_Init(DMA1_Channel7, &DMA_InitStructure);

DMA_ITConfig(DMA1_Channel7, DMA_IT_TC, ENABLE);

DMA_ITConfig(DMA1_Channel7, DMA_IT_TE, ENABLE);

/* Enable USART1 DMA TX request */

USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);

DMA_Cmd(DMA1_Channel7, DISABLE);

/* DMA1 Channel5 (triggered by USART1 Rx event) Config */

DMA_DeInit(DMA1_Channel5);

DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40013804;

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART1_RECEIVE_DATA;

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

DMA_InitStructure.DMA_BufferSize = 512;

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

DMA_InitStructure.DMA_Priority = DMA_Priority_High;

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

DMA_Init(DMA1_Channel5, &DMA_InitStructure);

DMA_ITConfig(DMA1_Channel5, DMA_IT_TC, ENABLE);

DMA_ITConfig(DMA1_Channel5, DMA_IT_TE, ENABLE);

/* Enable USART1 DMA RX request */

USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);

DMA_Cmd(DMA1_Channel5, ENABLE);

/* DMA1 Channel6 (triggered by USART1 Rx event) Config */

DMA_DeInit(DMA1_Channel6);

DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40004404;

DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)USART2_RECEIVE_DATA;

DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

DMA_InitStructure.DMA_BufferSize = 512;

DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;

DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

DMA_Init(DMA1_Channel6, &DMA_InitStructure);

DMA_ITConfig(DMA1_Channel6, DMA_IT_TC, ENABLE);

DMA_ITConfig(DMA1_Channel6, DMA_IT_TE, ENABLE);

/* Enable USART2 DMA RX request */

USART_DMACmd(USART2, USART_DMAReq_Rx, ENABLE);

DMA_Cmd(DMA1_Channel6, ENABLE);

}

中断优先级配置:

void NVIC_Configuration(void)

{

NVIC_InitTypeDef NVIC_InitStructure;

/* Configure one bit for preemption priority */

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

/* Enable the USART1 Interrupt */

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

/* Enable the USART2 Interrupt */

NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

//Enable DMA Channel4 Interrupt

NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

//Enable DMA Channel7 Interrupt

NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel7_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

/*Enable DMA Channel5 Interrupt */

NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel5_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

/*Enable DMA Channel6 Interrupt */

NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel6_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

数组定义,含义如题名:

u8 USART1_SEND_DATA[512];

u8 USART2_SEND_DATA[512];

u8 USART1_RECEIVE_DATA[512];

u8 USART2_RECEIVE_DATA[512];

u8 USART1_TX_Finish=1; // USART1发送完成标志量

u8 USART2_TX_Finish=1; // USART2发送完成标志量

USART1中断服务函数

void USART1_IRQHandler(void)

{

u16 DATA_LEN;

u16 i;

if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) //如果为空闲总线中断

{

DMA_Cmd(DMA1_Channel5, DISABLE); //关闭DMA,防止处理其间有数据

//USART_RX_STA = USART1-》SR; //先读SR,然后读DR才能清除

//USART_RX_STA = USART1-》DR;

DATA_LEN=512-DMA_GetCurrDataCounter(DMA1_Channel5);

if(DATA_LEN 》 0)

{

while(USART1_TX_Finish==0) //等待数据传输完成才下一次

{

;

}

//将数据送DMA存储地址

for(i=0;iTA_LEN;i )

{

USART1_SEND_DATA=USART1_RECEIVE_DATA;

}

//USART用DMA传输替代查询方式发送,克服被高优先级中断而产生丢帧现象。

DMA_Cmd(DMA1_Channel4, DISABLE); //改变datasize前先要禁止通道工作

DMA1_Channel4-》CNDTR=DATA_LEN; //DMA1,传输数据量

USART1_TX_Finish=0; //DMA传输开始标志量

DMA_Cmd(DMA1_Channel4, ENABLE);

}

//DMA_Cmd(DMA1_Channel5, DISABLE); //关闭DMA,防止处理其间有数据

DMA_ClearFlag(DMA1_FLAG_GL5 | DMA1_FLAG_TC5 | DMA1_FLAG_TE5 | DMA1_FLAG_HT5);//清标志

DMA1_Channel5-》CNDTR = 512; //重装填

DMA_Cmd(DMA1_Channel5, ENABLE); //处理完,重开DMA

//读SR后读DR清除Idle

i = USART1-》SR;

i = USART1-》DR;

}

if(USART_GetITStatus(USART1, USART_IT_PE | USART_IT_FE | USART_IT_NE) != RESET) //出错

{

USART_ClearITPendingBit(USART1, USART_IT_PE | USART_IT_FE | USART_IT_NE);

}

USART_ClearITPendingBit(USART1, USART_IT_TC);

USART_ClearITPendingBit(USART1, USART_IT_IDLE);

}

USART2中断服务函数

void USART2_IRQHandler(void)

{

u16 DATA_LEN;

u16 i;

if(USART_GetITStatus(USART2, USART_IT_IDLE) != RESET) //如果为空闲总线中断

{

DMA_Cmd(DMA1_Channel6, DISABLE); //关闭DMA,防止处理其间有数据

//USART_RX_STA = USART1-》SR; //先读SR,然后读DR才能清除

//USART_RX_STA = USART1-》DR;

DATA_LEN=512-DMA_GetCurrDataCounter(DMA1_Channel6);

if(DATA_LEN 》 0)

{

while(USART2_TX_Finish==0) //等待数据完成才下一次

{

;

}

//将数据送DMA存储地址

for(i=0;iTA_LEN;i )

{

USART2_SEND_DATA=USART2_RECEIVE_DATA;

}

//USART用DMA传输替代查询方式发送,克服被高优先级中断而产生丢帧现象。

DMA_Cmd(DMA1_Channel7, DISABLE); //改变datasize前先要禁止通道工作

DMA1_Channel7-》CNDTR=DATA_LEN; //DMA1,传输数据量

USART2_TX_Finish=0; //DMA传输开始标志量

DMA_Cmd(DMA1_Channel7, ENABLE);

}

//DMA_Cmd(DMA1_Channel5, DISABLE); //关闭DMA,防止处理其间有数据

DMA_ClearFlag(DMA1_FLAG_GL6 | DMA1_FLAG_TC6 | DMA1_FLAG_TE6 | DMA1_FLAG_HT6);//清标志

DMA1_Channel6-》CNDTR = 512; //重装填

DMA_Cmd(DMA1_Channel6, ENABLE); //处理完,重开DMA

//读SR后读DR清除Idle

i = USART2-》SR;

i = USART2-》DR;

}

if(USART_GetITStatus(USART2, USART_IT_PE | USART_IT_FE | USART_IT_NE) != RESET) //出错

{

USART_ClearITPendingBit(USART2, USART_IT_PE | USART_IT_FE | USART_IT_NE);

}

USART_ClearITPendingBit(USART2, USART_IT_TC);

USART_ClearITPendingBit(USART2, USART_IT_IDLE);

}

DMA1_Channel5中断服务函数

void DMA1_Channel5_IRQHandler(void)

{

DMA_ClearITPendingBit(DMA1_IT_TC5);

DMA_ClearITPendingBit(DMA1_IT_TE5);

DMA_Cmd(DMA1_Channel5, DISABLE); //关闭DMA,防止处理其间有数据

DMA1_Channel5-》CNDTR = 580; //重装填

DMA_Cmd(DMA1_Channel5, ENABLE); //处理完,重开DMA

}

DMA1_Channel6中断服务函数

void DMA1_Channel6_IRQHandler(void)

{

DMA_ClearITPendingBit(DMA1_IT_TC6);

DMA_ClearITPendingBit(DMA1_IT_TE6);

DMA_Cmd(DMA1_Channel6, DISABLE); //关闭DMA,防止处理其间有数据

DMA1_Channel6-》CNDTR = 580; //重装填

DMA_Cmd(DMA1_Channel6, ENABLE); //处理完,重开DMA

}

DMA1_Channel4中断服务函数

//USART1使用DMA发数据中断服务程序

void DMA1_Channel4_IRQHandler(void)

{

DMA_ClearITPendingBit(DMA1_IT_TC4);

DMA_ClearITPendingBit(DMA1_IT_TE4);

DMA_Cmd(DMA1_Channel4, DISABLE); //关闭DMA

USART1_TX_Finish=1; //置DMA传输完成

}

DMA1_Channel7中断服务函数

//USART2使用DMA发数据中断服务程序

void DMA1_Channel7_IRQHandler(void)

{

DMA_ClearITPendingBit(DMA1_IT_TC7);

DMA_ClearITPendingBit(DMA1_IT_TE7);

DMA_Cmd(DMA1_Channel7, DISABLE);//关闭DMA

USART2_TX_Finish=1;//置DMA传输完成

}

原文地址:https://www.cnblogs.com/yilangUAV/p/12641607.html

时间: 2024-10-02 06:55:01

STM32的串口空闲中断及接受数据的相关文章

关于STM32串口空闲中断的问题

1.空闲中断是接受数据后出现一个byte的高电平(空闲)状态,就会触发空闲中断.并不是空闲就会一直中断 2.关于第二点有要铺垫的三个情况,datasheet中 "当一空闲帧被检测到时,其处理步骤和接收到普通数据帧一样,但如果IDLEIE位被设置将产生一个中断" "空闲符号被视为完全由'1'组成的一个完整的数据帧,后面跟着包含了数据的下一帧的开始位'1'的位数也包括了停止位的位数” 空闲符号的配图后面跟这一个低电平.有人理解为只有收到下一个数据的起始位才会触发中断,这样理解是不

利用串口空闲中断接收数据

1 void USART2_IRQHandler(void) 2 { 3 // 使能串口空闲中断 4 USART_ITConfig(USART2, USART_IT_IDLE , ENABLE); 5 6 if(USART_GetITStatus(USART2,USART_IT_RXNE)==SET) 7 { 8 9 rx_buf[cnt]=USART_ReceiveData(USART2); 10 rx_rxbuf[cnt] = rx_buf[cnt] ;//把接收到的数组存到备用的数组当中,

stm32RS485串口通信——中断接收发送数据

功能:通过PC机的串口调试助手发送数据给串口A,串口B接收到串口A发送的数据,再由串口B将接收到的数据返回给PC机的串口调试助手. PC->串口A->串口B->PC. 实验平台:stm32f407 /********************************************************************* 本平台具有六个串口: com1  485 com2 com3  232 需一个管脚控制DTU com4 485 com5  调试串口  TTL com6

STM32串口之空闲中断

NBiot模块一般都是串口接口,使用AT指令集,对接中国移动onenet平台.先用串口助手去测试,流程测试OK之后需要在MCU上重新写一遍. STM32串口 IDLE中断 IDLE其实是空闲的意思.IDLE中断叫空闲中断,不叫帧中断.那么什么叫空闲,怎么定义空闲呢?在实际发送数据的时候,比如一串字符串,我们会采用如下方式发送 void uart1_putc(char dat) { SBUF = dat; while (!TI); TI = 0; } void uart1_puts_n(char

关于STM32空闲中断

有一次做一个东西,为了尽量不占用CPU的处理数据时间,所以就使用DMA接收串口的数据,但是呢问题来了.,,,,,怎么样才能确定接收到了一条完整的数据了,,我们都知道只要打开DMA 那家伙就不停的把接收的数据放到我们指定的地方. 只要接收到一条完整的数据我就该去处理了 关于空闲中断,,,就是说每接收到一条完整的数据就会置位空闲标志位,我们只需要判断空闲标志位是否置一,,就能知道是不是接收到了一条完整的数据 用空闲中断的好处就是,,对于以前我写程序通信都会在数据的后面加上尾,,然后另一个接收的单片机

C#上位机制作之串口接受数据(利用接受事件)

前面设计好了界面,现在就开始写代码了,首先定义一个串口对象.. SerialPort serialport = new SerialPort();//定义串口对象 添加串口扫描函数,扫描出来所有可用串口显示在下拉框中,同时设置接受函数 string[] ArryPort = SerialPort.GetPortNames(); comboBox1.Items.Clear(); for (int i = 0; i < ArryPort.Length; i++) { comboBox1.Items.

STM32的串口采用DMA方式接收数据测试(转)

STM32的串口采用DMA方式接收数据测试 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明.   参考链接:http://www.amobbs.com/forum.PHP?mod=viewthread&tid=5511863&highlight=dma%E6%8E%A5%E6%94%B6   环境: 主机:WINXP 开发环境:MDK4.23 MCU:STM32F103CBT6 说明: 串口可以配置成用DMA的方式接收数据,不过DMA需要定长才

关于STM32 USART(串口)发送数据丢失第一帧的真实原因探索

自我介绍 为什么要写个自我介绍?俗话说,光说不练假把式,光练不说傻把式, 因为本人一直很自负,感觉什么东西都可以很快上手(当然非对口专业知识要求高的技能除外),如果我不把这自负表现出来,感觉会憋出内伤. 本人于2015年毕业于电子科技大学,开始的理想是进入一家国外的游戏公司,但理想很丰满,现实很骨感,给育碧.2k Game.Gameloft.EA都投了简历,但都被无情pass掉了(在此吐槽一下,这些公司真的是想在校园里招本科生吗?明明是研究生的计算机图形学却成了这些公司对本科生的要求).后来毕业

一种STM32的串口控制台的实现(非常实用)

一.背景 曾经玩Linux时非常喜欢这种基于出串口的控制台, 通过简单的串口TX和RX能实现嵌入式硬件的人机交互,非常实用,  那么STM32能否实现通过超级终端与用户互动的构想呢? 答案是肯定的,由于这个UART控制平台就像应用程序套上一层可访问的外科(Shell)故而我将这种基于UART的控制平台简称Shell,构架和效果如下图: 这张图箭头指向的是输入的指令,其余是STM32串口输出的信息,, 可以看到通过这些简单的指令输入我们通过Shell可以做很多事情: 1. 现场设备发生故障,可以通