【学习笔记 三】循环队列在stm32 USART应用

	在学习笔记(二)中,聊到循环队列(https://blog.csdn.net/qq_31983073/article/details/133066935?spm=1001.2014.3001.5501),那么这一章就说一说循环队列在stm32中的应用,主要是结合串口的发送与接收的实现。

1.1数据类型

下面展示一些 内联代码片

// A code block
var foo = 'bar';
// 串口发送的数据类型
typedef{
	ring_queue_u8_t st_tx_queue;
	ring_queue_u8_t st_rx_queue;
	void (*fv_transmit_intterupt_enable)(uint8_t );
}usart_comm_t;

waiting

1.2 USART发送

1.2.1 USART放入缓存

/*
    \brief:放入缓存
    \param[in]:
        \args:pst_queue -结构体指针ring_queue_u8_t
        \args:pu8_buf -发送数据指针
        \args:u16_len -发送数据长度
    \return:(uint8_t)
        \1:放入缓存失败
        \0:发送缓存成功
*/
uint8_t u8_usart_transmit(ring_queue_u8_t *pst_queue ,uint8_t *pu8_buf ,uint16_t u16_len)
{
	for(int i = 0 ;i < u16_len ; i++ )
	{
		uint8_t res = u8_ring_queue_input(pst_queue , pu8_buf[i] ) ;
		if( res ==  1 )//入队失败
		{
			printf("buffer is too small");//初始化数组太小,更改pst_queue->u8_buf大小
			return 1 ;
		}
	}
	pst_queue->fv_transmit_intterupt_enable(1);
	return 0 ;
}

1.2.2 USART中断发送


/*
    \brief:中断串口发送处理
    \param[in]:
        \args:pst_queue -结构体指针ring_queue_u8_t
        \args:usartx -串口号
    \return:(uint8_t)
        \1:发送缓存失败
        \0:发送缓存成功
*/
void v_usart_tx_isr(USART_TypeDef* usartx ,ring_queue_u8_t *pst_queue )
{
//	USART_TypeDef* usartx = USART1;
	/*发送中断*/
	if(USART_GetITStatus(usartx , USART_IT_TXE) != RESET)
	 {  
	 	//1:出队失败(队列空)
        //0:出队成功
        uint8_t value = 0 ;
		uint8_t res = u8_ring_queue_output(pst_queue , &value );
		if( res == 0 )//0:出队成功
		{
			USART_SendData(usartx , value );//关闭发送中断
		}
		else//发送数据完成
		{   
			//USART_ITConfig(usartx , USART_IT_TXE, DISABLE); //关闭发送中断
			pst_queue->fv_transmit_intterupt_enable(0);
		}   
	 }
}

1.3 USART接收

1.3.1 USART在中断接收

/*
    \brief:中断串口接收处理
    \param[in]:
        \args:pst_queue -结构体指针ring_queue_u8_t
        \args:usartx -串口号
    \return:none
*/
void v_usart_rx_isr(USART_TypeDef* usartx ,ring_queue_u8_t *pst_queue )
{
	/*接收中断*/
	if(USART_GetITStatus( usartx , USART_IT_RXNE) != RESET)
	{   
		/* Read one byte from the receive data register */
		uint8_t value= USART_ReceiveData( usartx );

		uint8_t res = u8_ring_queue_input( pst_queue ,  value ) ;
		if( res == 1 )//出队失败
		{
			printf("buffer is too small");//初始化数组太小,更改pst_queue->u8_buf大小
		}
	}
}

1.3.2 USART接收到数据解析


//数据解析代码,用户自己实现
void v_data_analysis_handler( uint8_t value )
{

}
/*
    \brief:接收数据出队处理
    \param[in]:
        \args:pst_queue -结构体指针ring_queue_u8_t
    \return:none
*/
void v_usart_rx_data_handler( ring_queue_u8_t *pst_queue )
{
	uint8_t value = 0 ;
	uint8_t res = u8_ring_queue_output(pst_queue , &value );
	if( res == 0 )//0:出队成功
	{
		//单个数据出队解析
		v_data_analysis_handler( value );
	}
	else//发送数据完成
	{   

	}
}

1.3.3 串口通信结构体初始化

#define TX_BUF_SIZE		(300)	//发送缓存
#define RX_BUF_SIZE		(300)	//接收缓存

uint8_t u8_tx_buf[TX_BUF_SIZE];
uint8_t u8_rx_buf[RX_BUF_SIZE];

void v_usart_transmit_interrupt_enable(uint8_t value);

usart_comm_t st_usart_comm = 
{
	.st_tx_queue =
	{
	    .u8_buf = u8_tx_buf,	/* 存放数据数组指针 */
	    .u16_len = TX_BUF_SIZE ,	/* 队列长度 */
	    .u16_front = 0 , /* 队列头索引(写) */
	    .u16_rear = 0 ,	/* 队列尾索引(读) */
	},
	.st_rx_queue=
	{
	    .u8_buf = u8_rx_buf ,	/* 存放数据数组指针 */
	    .u16_len = RX_BUF_SIZE ,	/* 队列长度 */
	    .u16_front = 0 , /* 队列头索引(写) */
	    .u16_rear = 0 ,	/* 队列尾索引(读) */
	},
	.fv_transmit_intterupt_enable = v_usart_transmit_interrupt_enable ,
};
//串口发送使能回调
void v_usart_transmit_interrupt_enable(uint8_t value)
{
	USART_ITConfig(USART1, USART_IT_TXE, value/* ENABLE */);  //打开发送中断,这句是关键
}

1.4 主函数实现

 
#include "stm32f10x.h"


//串口中断服务函数
void USART1_IRQHandler(void)
{
	//接收中断处理
	v_usart_rx_isr(USART1 ,&st_usart_comm.st_rx_queue );
	//发送中断处理
	v_usart_tx_isr(USART1 ,&st_usart_comm.st_tx_queue );
}
/* 主函数 */

//进入debug模式,在view中找到watch1,在watch1中,添加tx_flg变量,
//把值由0置为1,即可发送数据
uint8_t tx_flg = 0 ;

void main()
{
	//发送数据标志
	
	//发送数据
	uint8_t tx_buf[10] = {1,2,3,4,5,6,7,8,9,10};
	//串口初始化
	v_usart_init(115200);
	
	while(1)
	{
		if( tx_flg == 1 )
		{
			tx_flg = 0 ;
			u8_usart_transmit( &st_usart_comm.st_tx_queue , tx_buf , 10 );
		}
		v_usart_rx_data_handler( &st_usart_comm.st_rx_queue );
		
	}
}
Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐