这次讲讲利用串口收发中断来进行串口通讯。STM32 上为每个串口分配了一个中断。也就是说无论是发送完成还是收到数据或是数据溢出都产生同一个中断。程序需在中断处理函数中读取状态寄存器(USART_SR)来判断当前的是什么中断。下面的中断映像图给出了这些中断源是如何汇合成最终的中断信号的。图中也给出了如何控制每一个单独的中断源是否起作用。
另外,Cortex-M3 内核中还有个NVIC,可以控制这里的中断信号是否触发中断处理函数的执行,还有这些外部中断的级别。关于NVIC 可以参考《ARM CortexM3 权威指南》,里面讲解的非常详细。
简单的说,为了开启中断,我们需要如下的代码:
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //开启接收中断
USART_ITConfig(USART1, USART_IT_TXE, ENABLE); // 开启发送中断
这里多说一句,串口的发送中断有两个,分别是:
l发送数据寄存器空中断(TXE)
l发送完成中断(TC)
一般来说我们会使用发送数据寄存器空中断,用这个中断发送的效率会高一些。
中断处理函数的框架如下,如果检测到错误就清除错误,收到数了就处理。发完当前数据了就发下一个。
void USART1_IRQHandler(void)
{
unsigned int data;
if(USART1->SR & 0x0F)
{
// See if we have some kind of error, Clear interrupt
data = USART1->DR;
}
else if(USART1->SR & USART_FLAG_RXNE) //Receive Data Reg Full Flag
{
data = USART1->DR;
// 对收到的数据进行处理,或者干些其他的事
}
else if(USART1->SR & USART_FLAG_TXE)
{
{ // 可以发送数据了,如果没有数据需要发送,就在这里关闭发送中断
USART1->DR = something; // Yes, Send character
}
}
}
下面给一个利用环形缓冲区的串口驱动程序。
#ifndef _COM_BUFFERED_H_
#define _COM_BUFFERED_H_
#define COM1 0
#define COM2 1
#define COM_RX_BUF_SIZE 64 /* Number of characters in Rx ring buffer */
#define COM_TX_BUF_SIZE 64 /* Number of characters in Tx ring buffer */
#define COM_NO_ERR 0 /* Function call was successful */
#define COM_BAD_CH 1 /* Invalid communications port channel */
#define COM_RX_EMPTY 2 /* Rx buffer is empty, no character available */
#define COM_TX_FULL 3 /* Tx buffer is full, could not deposit character */
#define COM_TX_EMPTY 4 /* If the Tx buffer is empty. */
/************************************************************
* function : COMGetCharB
* parameter: char port, port can be COM1 / COM2
* parameter: char* err is a pointer to where an error code will be placed:
* *err is set to COM_NO_ERR if a character is available
* *err is set to COM_RX_EMPTY if the Rx buffer is empty
* *err is set to COM_BAD_CH if you have specified an invalid channel
* return : char
* usage : This function is called by your application to obtain a character from the communications
* channel.
* changelog:
*************************************************************/
unsigned char COMGetCharB (unsigned char ch, unsigned char *err);
/************************************************************
* function : COMPutCharB
* parameter: char port, port can be COM1 / COM2
* return : COMM_NO_ERR if the function was successful (the buffer was not full)
* COMM_TX_FULL if the buffer was full
* COMM_BAD_CH if you have specified an incorrect channel
* usage : This function is called by your application to send a character on the communications
* channel. The character to send is first inserted into the Tx buffer and will be sent by
* the Tx ISR. If this is the first character placed into the buffer, the Tx ISR will be
* enabled. If the Tx buffer is full, the character will not be sent (i.e. it will be lost)
* changelog:
*************************************************************/
unsigned char COMPutCharB (unsigned char port, unsigned char c);
/************************************************************
* function : COMBufferInit
* parameter:
* return :
* usage : This function is called by your application to initialize the communications module. You
* must call this function before calling any other functions.
* changelog:
*************************************************************/
void COMBufferInit (void);
/************************************************************
* function : COMBufferIsEmpty
* parameter: char port, port can be COM1 / COM2
* return : char
* usage : This function is called by your application to see
* if any character is available from the communications channel.
* If at least one character is available, the function returns
* FALSE(0) otherwise, the function returns TRUE(1).
* changelog:
*************************************************************/
unsigned char COMBufferIsEmpty (unsigned char port);
/************************************************************
* function : COMBufferIsFull
* parameter: char port, port can be COM1 / COM2
* return : char
* usage : This function is called by your application to see if any more characters can be placed
* in the Tx buffer. In other words, this function check to see if the Tx buffer is full.
* If the buffer is full, the function returns TRUE otherwise, the function returns FALSE.
* changelog:
*************************************************************/
unsigned char COMBufferIsFull (unsigned char port);
#endif
[cpp] view plain copy
/*
* file: com_buffered.c
* author: Li Yuan
* platform: STM32F107
* date: 2013-5-5
* version: 0.0.1
* description: UART Ring Buffer
**/
#include "stm32f10x_usart.h"
#include "com_buffered.h"
#define OS_ENTER_CRITICAL() __set_PRIMASK(1)
#define OS_EXIT_CRITICAL() __set_PRIMASK(0)
/**
* Enables Transmiter interrupt.
**/
static void COMEnableTxInt(unsigned char port)
{
static USART_TypeDef* map[2] = {USART1, USART2};
USART_ITConfig(map[port], USART_IT_TXE, ENABLE);
}
/*
*********************************************************************************************************
上一篇:stm32 TIM8和TIM3初始化相互有影响
下一篇:STM32 下载程序时,往flash固定位置写数据配置
推荐阅读最新更新时间:2024-11-17 15:35
设计资源 培训 开发板 精华推荐
- 为 NT3H1101 设计的外接天线
- 【浙江理工电赛】MC34063升压模块(H题)
- 用于 MC9S08JM60 8 位 HCS08 MCU 的 3PHASELV-KIT、3 相 BLDC/PMSM 低压电机控制驱动器,用于开发 BLDC/PMSM 电机控制应用
- ZSR800GTA 8 伏可调正电压调节器的典型应用
- LT8494EUF 锂离子电池至 12V、650kHz 低静态电流升压的典型应用电路
- EVAL6206PD,基于 L6506 PWM 电流控制器的评估板
- ZXLD1366 具有内部开关的高精度 1A、60V LED 驱动器的典型应用
- 2.33GHz SDARS 低噪声放大器应用中的 BFP740F 超低噪声射频晶体管
- HV9910DB6,用于 OSRAM OSTAR 的简单恒流 LED 驱动器演示板
- 使用 Analog Devices 的 AD9144BCPZ 的参考设计
- 2024年Automechanika Shanghai海量同期活动刷新历届记录,汇聚行业智慧,共谋未来发展
- 企业文化分享 如何培养稀缺的硅IP专业人员?SmartDV开启的个人成长与团队协作之旅
- 恩智浦发布首个超宽带无线电池管理系统解决方案
- 北交大本科生探秘泰克先进半导体开放实验室,亲历前沿高科技魅力
- 新帅上任:杜德森博士(Dr. Torsten Derr)将于2025年1月1日出任肖特集团首席执行官
- 边缘 AI 如何提升日常体验
- 苹果要首发!台积电宣布2nm已准备就绪
- AMD有望用上全新芯片堆叠技术:延迟大幅减少、性能显著提升
- 宁德时代发布10月战报
- 2024年10月电池行业:增长势头不减!