历史上的今天
返回首页

历史上的今天

今天是:2025年01月29日(星期三)

2019年01月29日 | STM32基础设计(3)---中断串口通信

2019-01-29 来源:eefocus

本文介绍,通过中断方式运用STM32串口USART1。


首先,总结全文,设计步骤主要如下:


1,初始化GPIO


2,初始化USART1


3,初始化NVIC(嵌套向量中断控制器)


4,编写中断服务函数


5,编写主函数


详细步骤如下:


1,初始化GPIO

void IO_Init()

{

GPIO_InitTypeDef Uart_A;

GPIO_InitTypeDef led;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC| RCC_APB2Periph_AFIO,ENABLE);

GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable|GPIO_Remap_SWJ_JTAGDisable,ENABLE);

led.GPIO_Pin = GPIO_Pin_13;//博主开发板上的LED灯接的GPIOC的13引脚

led.GPIO_Mode = GPIO_Mode_Out_PP;

led.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOC,&led);

Uart_A.GPIO_Pin = GPIO_Pin_9;

Uart_A.GPIO_Speed = GPIO_Speed_50MHz;

Uart_A.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_Init(GPIOA,&Uart_A);

Uart_A.GPIO_Pin = GPIO_Pin_10;

Uart_A.GPIO_Speed = GPIO_Speed_50MHz;

Uart_A.GPIO_Mode = GPIO_Mode_IN_FLOATING; 

GPIO_Init(GPIOA,&Uart_A);

}

以上代码不在详细介绍,前参看STM32基础设计(1)---点亮LED灯、SEM32基础设计(2)---查询串口通信


2,初始化USART1

void Usart1_Init()

{

USART_InitTypeDef Uart;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

Uart.USART_BaudRate = 115200;

Uart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

Uart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

Uart.USART_Parity = USART_Parity_No;

Uart.USART_StopBits = USART_StopBits_1;

Uart.USART_WordLength = USART_WordLength_8b;

USART_Init(USART1,&Uart);

USART_Cmd(USART1,ENABLE);

USART_ClearFlag(USART1,USART_FLAG_TC); 

}

以上代码不在详细介绍,具体请参看STM32基础设计(2)---查询串口通信


3,初始化NVIC

首先,让我们来了解库函数中的NVIC结构体:


typedef struct

{//指明那个中断通道

  uint8_t NVIC_IRQChannel;                    /*!< Specifies the IRQ channel to be enabled or disabled.

                                                   This parameter can be a value of @ref IRQn_Type 

                                                   (For the complete STM32 Devices IRQ Channels list, please

                                                    refer to stm32f10x.h file) */

//抢占优先级

  uint8_t NVIC_IRQChannelPreemptionPriority;  /*!< Specifies the pre-emption priority for the IRQ channel

                                                   specified in NVIC_IRQChannel. This parameter can be a value

                                                   between 0 and 15 as described in the table @ref NVIC_Priority_Table */

//子优先级

  uint8_t NVIC_IRQChannelSubPriority;         /*!< Specifies the subpriority level for the IRQ channel specified

                                                   in NVIC_IRQChannel. This parameter can be a value

                                                   between 0 and 15 as described in the table @ref NVIC_Priority_Table */

//中断通道使能

  FunctionalState NVIC_IRQChannelCmd;         /*!< Specifies whether the IRQ channel defined in NVIC_IRQChannel

                                                   will be enabled or disabled. 

                                                   This parameter can be set either to ENABLE or DISABLE */   

} NVIC_InitTypeDef;

了解了这个结构体后,就可以在初始化函数中定义这个变量了


NVIC_InitTypeDef nvic;

另外在NVIC初始化中还设置优先级分组(哪怕只有一个中断也要分组,这是规定)。具体使用这个库函数:


void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)

{

  /* Check the parameters */

  assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));

  

  /* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */

  SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;

}

关于优先级分组此处不再赘述,请大家参考这位博主的博客:


http://blog.csdn.net/DLUTXIE/article/details/7059184?locationNum=4&fps=1


接下来,设置结构体中变量的值:


nvic.NVIC_IRQChannelPreemptionPriority = 1;//抢占优先级

nvic.NVIC_IRQChannelSubPriority = 0;//子优先级

nvic.NVIC_IRQChannel = USART1_IRQn;//中断通道

nvic.NVIC_IRQChannelCmd = ENABLE;//通道使能

NVIC_Init(&nvic);//NVIC寄存器初始化

4,编写中断服务函数

先贴代码,在解释


void USART1_IRQHandler(void)//注意,这个函数名必须这样写,否则进不了USART1中断。详见库函数中的  IRQn_Type 结构体

{

char temp= '0';

if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == SET)//判断是否接收到数据

{

temp = USART1->DR;//如果接收到数据,就将其读出,这样才可将RXNE寄存器清除

if(temp == 'G')//如果接收到G  则关灯

{

GPIOC->BRR = GPIO_Pin_13;

}else if(temp == 'K')//开灯

{

GPIOC->BSRR = GPIO_Pin_13;

}

}

if(USART_GetFlagStatus(USART1,USART_FLAG_TXE) && temp != '0')//如果发送寄存器为空,即可以发送数据

{

USART1->DR = temp;将接收到的数据再发送回去

while(!USART_GetFlagStatus(USART1,USART_FLAG_TC));等待数据发送完毕

}

}

5,编写主函数

老规矩,先贴代码再解释:


int main()

{

IO_Init();

Usart1_Init();

Nvic_Init();

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//这里是打开串口的接收中断,以便在USART1收到数据时,进入中断函数。这里特别提一下,现在不用打开发送中断,只有在准备发送数据时才应打开,否则会直接进入中断函数。

GPIOC->BSRR = GPIO_Pin_13;

while(1){}

}

额。。。突然发现没什么好解释的。


中断串口通信介绍到此完毕。


本文完整代码如下:


#include

#define uint unsigned int

#define uchar unsigned char

void delay(uint n)

{

int i,j;

for(i=0;i

for(j=0;j<8500;j++);

}

 

void IO_Init()

{

GPIO_InitTypeDef Uart_A;

GPIO_InitTypeDef led;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOC| RCC_APB2Periph_AFIO,ENABLE);

GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable|GPIO_Remap_SWJ_JTAGDisable,ENABLE);

led.GPIO_Pin = GPIO_Pin_13;

led.GPIO_Mode = GPIO_Mode_Out_PP;

led.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_Init(GPIOC,&led);

Uart_A.GPIO_Pin = GPIO_Pin_9;

Uart_A.GPIO_Speed = GPIO_Speed_50MHz;

Uart_A.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_Init(GPIOA,&Uart_A);

Uart_A.GPIO_Pin = GPIO_Pin_10;

Uart_A.GPIO_Speed = GPIO_Speed_50MHz;

Uart_A.GPIO_Mode = GPIO_Mode_IN_FLOATING; //page 110

GPIO_Init(GPIOA,&Uart_A);

}

void Usart1_Init()

{

USART_InitTypeDef Uart;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

Uart.USART_BaudRate = 115200;

Uart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

Uart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

Uart.USART_Parity = USART_Parity_No;

Uart.USART_StopBits = USART_StopBits_1;

Uart.USART_WordLength = USART_WordLength_8b;

USART_Init(USART1,&Uart);

USART_Cmd(USART1,ENABLE);

USART_ClearFlag(USART1,USART_FLAG_TC); //page 540

}

void Nvic_Init()

{

NVIC_InitTypeDef nvic;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

nvic.NVIC_IRQChannelPreemptionPriority = 1;

nvic.NVIC_IRQChannelSubPriority = 0;

nvic.NVIC_IRQChannel = USART1_IRQn;

nvic.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&nvic);

}

 

int main()

{

IO_Init();

Usart1_Init();

Nvic_Init();

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);

GPIOC->BSRR = GPIO_Pin_13;

while(1){}

}

 

void USART1_IRQHandler(void)

{

char temp= '0';

if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == SET)

{

temp = USART1->DR;

if(temp == 'G')

{

GPIOC->BRR = GPIO_Pin_13;

}else if(temp == 'K')

{

GPIOC->BSRR = GPIO_Pin_13;

}

}

if(USART_GetFlagStatus(USART1,USART_FLAG_TXE) && temp != '0')

{

USART1->DR = temp;

while(!USART_GetFlagStatus(USART1,USART_FLAG_TC));

}

}



推荐阅读

史海拾趣

ADLINK公司的发展小趣事

ADLINK 是一家全球领先的嵌入式计算解决方案提供商,以下是该公司发展的五个相关故事:

  1. 公司创立与初期发展: ADLINK 成立于1995年,总部位于台湾新北市。公司专注于为工业自动化、通讯、医疗保健、交通运输等领域提供高性能的嵌入式计算和连接解决方案。在创立初期,ADLINK 主要专注于硬件产品的开发和销售,如嵌入式计算板卡、模块、工业计算机等。

  2. 技术创新与产品扩展: 随着市场需求的不断变化和技术的发展,ADLINK 不断进行技术创新,积极拓展产品线。除了传统的嵌入式计算硬件产品外,公司还推出了嵌入式操作系统、软件工具和解决方案等,以满足客户在物联网、人工智能、工业4.0 等领域的需求。

  3. 全球业务布局与国际化发展: ADLINK 在全球范围内建立了广泛的销售网络和服务体系,拥有多个全球研发和生产基地,并在美国、欧洲、亚洲等地设有分支机构和办事处。通过与全球领先企业的合作和市场拓展,ADLINK 的产品和解决方案已经覆盖了全球100多个国家和地区。

  4. 合作伙伴关系与客户案例: ADLINK 与世界各地的行业领先企业建立了紧密的合作伙伴关系,共同开发创新性的解决方案,应用于工业自动化、智能交通、医疗保健等领域。例如,公司与德国西门子、美国英特尔等知名企业合作,在工业物联网、边缘计算等领域取得了一系列成功案例。

  5. 未来展望与持续发展: 面对快速变化的市场环境和日益激烈的竞争,ADLINK 将继续致力于技术创新和产品研发,不断提升解决方案的质量和性能,以满足客户日益增长的需求。公司将继续秉承“创新、合作、可靠”的核心价值观,努力成为全球领先的嵌入式计算和连接解决方案提供商。

Acme Electric Corporation公司的发展小趣事

Acme Electric Corporation是一家专注于生产变压器和电源设备的公司。以下是该公司发展的五个相关故事:

  1. 公司成立和初期发展: Acme Electric Corporation成立于1958年,总部位于美国威斯康星州。公司最初是一家小规模的家庭企业,致力于生产各种类型的变压器和电源设备,主要用于工业、商业和农业应用。

  2. 技术创新和产品扩展: 随着市场需求的增长和技术进步,Acme Electric Corporation不断进行技术创新,并扩展了产品线。公司推出了一系列高性能、高效率的变压器和电源设备,包括控制变压器、隔离变压器、电源逆变器等,满足不同客户的需求。

  3. 市场拓展和客户合作: Acme Electric Corporation积极开拓国内外市场,并与各行各业的客户建立了合作关系。公司的产品被广泛应用于制造业、电力行业、建筑业等领域,为客户提供稳定可靠的电源解决方案。同时,Acme Electric Corporation与客户密切合作,根据客户的需求定制产品,提供个性化的服务。

  4. 质量控制和生产管理: Acme Electric Corporation注重产品质量和生产管理,采用先进的生产设备和严格的质量控制体系,确保产品的稳定性和可靠性。公司拥有一支专业的研发团队和生产团队,不断改进工艺流程,提升产品质量和生产效率。

  5. 未来发展展望: Acme Electric Corporation将继续致力于变压器和电源设备领域的研发和生产,不断推出更先进、更可靠的产品和解决方案,以满足客户在各个领域的需求。公司将加强国际市场拓展,提升自身在全球市场的竞争力,为行业的发展做出更大的贡献。

ABLIC公司的发展小趣事

2020年4月,ABLIC成为MinebeaMitsumi集团的一员。这一合作对于ABLIC来说具有重要意义。MinebeaMitsumi集团作为一家在电子元器件领域具有强大实力的企业,为ABLIC提供了更广阔的发展空间和资源支持。通过融入MinebeaMitsumi集团的“八矛战略”,ABLIC的模拟半导体业务得到了进一步提升,其在集团内部的地位也愈发重要。

AVG [AVG Semiconductors(HITEK)]公司的发展小趣事

在电子行业的发展过程中,AVG也面临着各种挑战和危机。例如,随着全球贸易保护主义的抬头和原材料价格的波动,公司的生产成本不断上升;同时,新技术的不断涌现和市场竞争的加剧也给公司带来了不小的压力。然而,AVG始终保持着冷静和清醒的头脑,积极应对各种挑战和危机。公司通过优化生产流程、提高生产效率、加强成本控制等措施,降低了生产成本;同时,加大研发投入,推出具有竞争力的新产品,以应对市场竞争的挑战。这些举措使得AVG在困境中保持了稳健的发展态势。

Empro Technology Corp公司的发展小趣事

为了保持技术领先地位,Empro Technology Corp不断加大研发投入,在多个技术领域取得了重大突破。公司申请了一系列专利,涵盖了芯片设计、制造工艺、应用技术等多个方面。这些专利的积累不仅保护了公司的技术成果,也为公司的长期发展奠定了坚实的基础。

承兴(CX)公司的发展小趣事

经过多年的努力和发展,承兴公司已经成为一家具有全球影响力的电子企业。除了在中国市场保持领先地位外,承兴还积极拓展海外市场,并在美国、新加坡等地设立了分公司和研发中心。通过与全球合作伙伴的紧密合作和资源共享,承兴不断提升其全球竞争力,并努力实现国际化的发展目标。

请注意,由于承兴(CX)公司的具体发展历程和细节可能因时间和市场变化而有所不同,以上故事仅为虚构示例,旨在展示承兴公司在电子行业中的发展脉络和关键事件。

问答坊 | AI 解惑

昂宝电子推出CCFL控制器IC系列,适用于汽车液晶显示器

继成功推出一系列Green model AC-DC PWM电源控制IC后,昂宝电子目前又推出一系列CCFL控制器IC,可广泛用于LCD监视器、LCD-TV、笔记本电脑以及工业设备、汽车、手持设备中的液晶显示器。 目前昂宝电子所推出CCFL控制器IC产品包括:OB3316/OB3316 ...…

查看全部问答>

uC_GUI在MCS51系列单片机系统上移植的仿真实现

本文介绍了uC/GUI 的组织结构, PROTEUS 仿真环境, 以及在PROTEUS 仿真环境下实现uC/GUI 移植到MCS51 系列单片机P89C51RD2 的过程; 并且对移植过程中涉及到的修正C51 调用树和代码优化等问题进行了简明阐述。…

查看全部问答>

一个LED的N种玩法(五)----WatchDog Timer

一个LED的N种玩法(五)--WatchDog Timer Author: chenzhufly Email: chenzhufly@126.com 2010-05-02 一.WatchDog Timer 概述 看门狗的目的是当进入错误状态一定时间后复位微控制器。当看门狗使能时,如果用户没有在一定时间内喂狗(看门狗定时 ...…

查看全部问答>

关于Quartus中仿真的问题

是这样的,写了verilog的一个小程序,编译成功了,然后创建bdf文件以后,再编译,就出错。 报错是:    Error: Can\'t compile duplicate declarations of entity \"sig\" into library \"work\" Error: Instance could be entity \" ...…

查看全部问答>

wince 6.0 OAL层初始化LOGO显示问题~

eboot显示一个 logo, 但进去系统的中间黑屏,我想继续在 oal中显示 logo, 去掉lcd初始化函数调用, 可看 OEMInit 函数,没见 初始化LCD部分代码, OEMInit 上下文周围也没找到 初始LCD有关的函数. 麻烦给个提示,谢谢 平台是 PXA270+WINCE6.0…

查看全部问答>

推荐ARM开发板

现在急需推荐一款ARM开发板,要求: 可以做触摸屏;操作系统WinCE——可以自己修改源码;应用于大型系统集成;处理数据采集系统;抗干扰能力强;数据运算速度快;扩展口多。哪位大侠给推荐一下,谢谢:)…

查看全部问答>

WINCE EBOOT应该怎么弄啊(我实在没分给)?

我现在正在弄EBOOT启动(用网络下载NK.BIN), 有几个问题想请教一下,希望各位帮帮忙,多谢 1.PB中本来有提供eboot.bin,我需要再重新编译吗? 2.Target ->ConnectivityOptions里面应该怎么设? 3.除了这两个地方,还有哪里需要注意的. 感激!(我没分了 ...…

查看全部问答>

台达VFD-P 11KW的"CFF"故障,还是没搞定!

请教台达VFD-P系列11KW的\"CFF\"故障    一台达VFD-P系列11KW变频器,驱动一惯量较大的负载(外接有BRAKE单元),以前正常,现在出现\"CFF\"故障.    \"CFF\"的意义是:“变频器有异常输出现象.输出接地(接地电流大于额定电流的50%以上时),功率模组 ...…

查看全部问答>

为什么STR710的PLL1有输入限制?如果超过了有什么影响吗?

                                 我的有源晶振是16MHz的,2分频后,输入PLL1,然后倍频16倍,再2分频,输出64MHz给MCLK,相关实验都做过了,没有什 ...…

查看全部问答>