历史上的今天
返回首页

历史上的今天

今天是:2025年03月03日(星期一)

正在发生

2020年03月03日 | 【STM库应用】stm32 之 USART

2020-03-03 来源:eefocus

STM库是官方提供的,其已经做好了底层驱动的配置,用起来是相当简单的;我们只需要了解其每个函数的功能,已经每个函数所使用流程即可!


整个框架就是下面这幅图,我们只需在顶层做调用即可,跟现在做app的差不多!

注:摘自野火,希望大哥不要说我盗版


刚刚开始拿道库,一看这么多函数,感觉有点棘手,无从下手;多亏stm官方也针对该库提供了一个应用手册,画了两天时间进行了探索和实践,发现了一点比较方便的诀窍。


在此给大家分享分享,我们就拿今天的USART来说吧!


至于建工程,网上以及教程里面是非常多的,我也就不多说了!


任意一个外设都对应一个ppp.c和ppp.h文件,所以我们其实也不是无章可循的!同时,stm库他有一套自己的缩写定义,我们必须记住,不过这个很好记!

同时他的函数命名也有一定的规则:


名为PPP_Init的函数,其功能是根据PPP_InitTypeDef中指定的参数,初始化外设PPP,例如  TIM_Init. 


名为PPP_DeInit的函数,其功能为复位外设PPP的所有寄存器至缺省值,例如  TIM_DeInit. 

名为PPP_StructInit的函数,其功能为通过设置PPP_InitTypeDef 结构中的各种参数来定义外设的功能,例如:USART_StructInit

名为PPP_Cmd的函数,其功能为使能或者失能外设PPP,例如:  SPI_Cmd. 

名为PPP_ITConfig的函数,其功能为使能或者失能来自外设PPP某中断源,例如:  RCC_ITConfig. 

名为PPP_DMAConfig的函数,其功能为使能或者失能外设PPP的DMA接口,例如:TIM1_DMAConfig. 

用以配置外设功能的函数,总是以字符串“Config”结尾,例如GPIO_PinRemapConfig. 

名为PPP_GetFlagStatus的函数,其功能为检查外设PPP某标志位被设置与否,例如:I2C_GetFlagStatus. 

名为PPP_ClearFlag的函数,其功能为清除外设PPP标志位,例如:I2C_ClearFlag. 

名为PPP_GetITStatus的函数,其功能为判断来自外设PPP的中断发生与否,例如:I2C_GetITStatus. 

名为PPP_ClearITPendingBit 的函数 , 其功能 为 清除外 设PPP 中断待处理标志位,例如:I2C_ClearITPendingBit. 


这些在官方给的库说明里面都有,我只是特别说明下,有助于我么了解!


我们经常用的不多,如:PPP_Init,PPP_Cmd,PPP_ITConfig,PPP_DMAConfig,PPP_GetFlagStatus,PPP_ClearFlag


同时我们需要熟悉的结构体:PPP_InitTypeDef等


上面指出的都是常用的,不多6个函数,1个结构体,相信大家应该能很快记住,我比较笨,记了两天才记的还不是很清!


下面我们先把USART1d的代码附上去!


void usart_config()

{

USART_InitTypeDef usart;

NVIC_InitTypeDef nvic;

RCC->APB2ENR |= 1<<2;

RCC->APB2ENR |= 1<<14;

GPIOA->CRH &= ~(0xff<<4);

GPIOA->CRH |= 0x8b<<4;

usart.USART_BaudRate = 9600;

usart.USART_Parity = USART_Parity_No;

usart.USART_StopBits = USART_StopBits_1;

usart.USART_WordLength = USART_WordLength_8b;

usart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

usart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

USART_Init(USART1,&usart);

USART_Cmd(USART1,ENABLE);

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

nvic.NVIC_IRQChannel = USART1_IRQn;

nvic.NVIC_IRQChannelCmd = ENABLE;

nvic.NVIC_IRQChannelPreemptionPriority = 0x0f;

nvic.NVIC_IRQChannelSubPriority = 0x0f;

NVIC_Init(&nvic);

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);

}


怎么说呢,我是比较懒的!所以我比喜欢别人那种命名变量的方式,我以前是做linux的,我喜欢linux那套命名模式!

另外,我建议大家在做开发的时候用Keil4.0以上的版本,为啥呢?下面正式我想说的


我们在声明一个结构体变量的时候,我们不知道结构题里面每个变量的名字,怎么办?找吗?很麻烦是吧?


如果我们用了mdk4.0以上的版本,他会自动匹配

可能有的人用过了,会说我多余,呵呵但是对那些没有用过的人很有用,比如李想老师!呵呵,开个玩笑


这样我们就不用一个一个输入了!但是后面的变量赋值怎么办?其实这些变量赋值都在ppp.h里面定义好了,我大致看了下ppp.h内容不是很多,所以很容易就找到,我有一个方法就是查找!


比如我们要找USART_Mode所对应的赋值:

切换到stm32f10x_usart.h,直接在上面输入USART_Mode,按下Enter键,就找到了,那么我就直接把这个定义赋值过去,好了!


有人说我函数名记不住,那么我们还是在stm32f10x_usart.h直接一下子拉到最下面!是不是看到了所有的函数?

如果你细心看我代码的话,你会发现,我对GPIO的初始化没有用结构图,我发现直接配置管脚的话很方便,代码不多,我4行能解决他十几行的代码!


RCC->APB2ENR |= 1<<2;

RCC->APB2ENR |= 1<<14;

GPIOA->CRH &= ~(0xff<<4);

GPIOA->CRH |= 0x8b<<4;


这样就把整个配置完了!有的人说我能记住吗?这么多位!我只想呵呵!不信你自己对着寄存器看下


比如输入模式:后两位一定是00b,输出模式一定是其他三种!在输出中00,01为通用,10,11为复用,偶数为推挽,奇数为开漏,好记吧?


在输入中,有三种模式,浮空就是复位的时候,还有模拟输入,还有上拉下拉输入!


我今天想写中断函数,怎么办?记不住啊,我想既然是中断函数,他一定在启动代码里面有定义,直接切换到startup_stm32f10x.md.s里面,直接搜索Handler


找到所有中断函数的定义:

有了这些基本思想,我们在写程序的时候方便多了,这次完成串口的配置就用了半个小时!我只能说库用着好方便!


/*******************************************************************************

  * @file    obj/main.c 

  * @author  ieczw

  * @version V1.0.1

  * @date    24-11-2013

  *******************************************************************************/  

 

/* Includes ------------------------------------------------------------------*/

#include "stm32f10x.h"

#include "stdio.h"

#include "stm32f10x_conf.h"

void usart_config(void);

void led_init(void);

void msleep(u16 timeout);

void rs232_send_byte(u8 byte);

u16  systick = 0;

int main(void)

{

u8 ascii = 0;

SysTick_Config(72000); //Config DiDa = 1ms

  /* Add your application code here */

usart_config();

led_init();

  /* Infinite loop */

GPIOC->BRR |= 0xff<<8;

msleep(1000);

GPIOC->BSRR |= 0xff<<8;

  while (1)

  {

rs232_send_byte(ascii++);

msleep(1000);

  }

}

 

void led_init()

{

RCC->APB2ENR |= 3<<4;

GPIOC->CRH = 0x33333333;

GPIOD->CRL &= ~(0xf<<2);

GPIOD->CRL |= 3<<2;

GPIOD->ODR &= ~(1<<2);

GPIOC->ODR |= 0xff<<8;

}

void usart_config()

{

USART_InitTypeDef usart;

NVIC_InitTypeDef nvic;

RCC->APB2ENR |= 1<<2;

RCC->APB2ENR |= 1<<14;

GPIOA->CRH &= ~(0xff<<4);

GPIOA->CRH |= 0x8b<<4;

usart.USART_BaudRate = 9600;

usart.USART_Parity = USART_Parity_No;

usart.USART_StopBits = USART_StopBits_1;

usart.USART_WordLength = USART_WordLength_8b;

usart.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;

usart.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

USART_Init(USART1,&usart);

USART_Cmd(USART1,ENABLE);

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

nvic.NVIC_IRQChannel = USART1_IRQn;

nvic.NVIC_IRQChannelCmd = ENABLE;

nvic.NVIC_IRQChannelPreemptionPriority = 0x0f;

nvic.NVIC_IRQChannelSubPriority = 0x0f;

NVIC_Init(&nvic);

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);

}

void rs232_send_byte(u8 byte)

{

USART_SendData(USART1,byte);

while(RESET == USART_GetFlagStatus(USART1,USART_FLAG_TXE));

}

void USART1_IRQHandler(void)

{

static u8 flag = 0;

flag = ~flag;

if(flag)

GPIOC->BRR |= 0xff<<8;

else

GPIOC->BSRR |= 0xff<<8;

if(USART1->SR&(1<<5))

{

USART1->DR = USART1->DR;

while(0 == (USART1->SR&(1<<6)));

}

}

void msleep(u16 timeout)

{

systick = timeout;

while(systick);

}

推荐阅读

史海拾趣

EA Elektro-Automatik公司的发展小趣事

EA Elektro-Automatik深知持续创新是企业发展的重要动力。因此,公司始终将创新作为企业文化的核心价值观之一。公司鼓励员工积极提出创新想法和解决方案,并为他们提供充分的支持和资源。此外,EA Elektro-Automatik还积极参与各类科研项目和行业标准的制定工作,推动整个行业的创新和发展。这种企业文化不仅为公司带来了更多的机会和挑战,也为企业的长期发展奠定了坚实的基础。

以上是关于EA Elektro-Automatik公司在电子行业发展的5个相关故事。这些故事展示了公司从创立到成为全球知名电子测量品牌的发展历程和取得的成就。

安普康(AMPCOM)公司的发展小趣事

随着业务的不断发展,安普康开始积极寻求市场拓展和战略合作的机会。公司在香港市场取得了显著的成绩后,决定进一步拓展内地市场。通过设立深圳安普康科技有限公司等分支机构,安普康逐步在内地市场建立了完善的销售网络和服务体系。同时,公司还与多家知名企业建立了长期合作关系,共同开拓市场、分享资源。这些合作不仅提升了安普康的市场地位,也为其未来的发展奠定了坚实的基础。

Henkel公司的发展小趣事

随着业务的不断发展,安普康开始积极寻求市场拓展和战略合作的机会。公司在香港市场取得了显著的成绩后,决定进一步拓展内地市场。通过设立深圳安普康科技有限公司等分支机构,安普康逐步在内地市场建立了完善的销售网络和服务体系。同时,公司还与多家知名企业建立了长期合作关系,共同开拓市场、分享资源。这些合作不仅提升了安普康的市场地位,也为其未来的发展奠定了坚实的基础。

FILTRAN公司的发展小趣事

在电子行业竞争日益激烈的背景下,安普康深知创新是企业发展的核心动力。因此,公司始终将研发投入作为重要战略之一。通过引进先进的生产设备和技术,安普康不断提升产品的品质和性能。同时,公司还积极与国内外知名企业和研究机构合作,共同开展技术研发和创新。这些努力使得安普康在光纤产品、布线产品等领域取得了多项专利,并成功推出了一系列具有市场竞争力的新产品。

驰兴电感(Coilank)公司的发展小趣事

随着电子行业的快速发展,驰兴电感紧跟市场趋势,不断拓展产品应用领域。除了传统的消费电子和通讯领域外,驰兴电感还成功将产品应用于汽车电子、网络通讯、智能家居等新兴领域。这些领域的拓展不仅为公司带来了更广阔的市场空间,也进一步提升了驰兴电感在电子行业中的地位。

Hilscher Gesellschaft für Systemautomation mbH公司的发展小趣事

HVPSI成立于本世纪初,起初是一家小型的技术初创企业,专注于研发高效、可靠的高压电源模块。在创始人及核心团队的带领下,公司迅速在MOV(金属氧化物压敏电阻)模块领域取得了突破。这些模块在电力电子设备中起到了关键的过压保护作用,有效提高了系统的稳定性和安全性。通过不断的技术迭代和产品优化,HVPSI逐渐在行业内树立了技术领先的形象。

问答坊 | AI 解惑

MP3充电器原理与维修

MP3充电器是最易损坏的配件之一。笔者维修多款充电器后发现,它们基本上都是采用开关电源电路,电路结构大同小异。本文以市面上最常见的昕潮TJ-01型充电器为例,简述其工作原理与常见故障检修,电路见图1。工作原理 (1)开关振荡电路市电经D1~D4整 ...…

查看全部问答>

如何控制LCD,BACKLIGHT开关

如题, WINCE 下如何控制LCD和backlight的开关呢,系统有提供相关的API调用吗…

查看全部问答>

MSP430F1611的遗憾

我搞了一片,很好的东西,只是不能超频。给16M的时钟立即死悄悄了。 149给16M的时钟,跑得非常的好。就是内存小了才2K…

查看全部问答>

申请MSP430开发板,介绍好书

MSP430优势不用多说,用来做手持设备是不二选择。 介绍一本关于MSP430的书吧,难得国内务实的一本教材:《MSP430系列单片机系统工程设计与实践》,对大家设计低功耗设备很有帮助。 书内先讲解编程风格,大概描述下关键外设使用。最重要的是后面 ...…

查看全部问答>

紧急求助:MSP430G2553 液晶显示图像的问题

我们最近在用液晶显示特定的波形,但这需要回读,从液晶(ST7920控制器)资料上看到可以读取DDRAM和GDRAM中的数据,但是没有成功, 由于我们用的是绘图方式,所以需要读取GDRAM中的数据,小弟这里有个网上下的程序,但不太清楚具体的含义,并且回 ...…

查看全部问答>

控制直流电机的正转反转和PWM调速直流电机驱动,单片机与L298之间如何用光耦隔离?

控制直流电机的正转反转和PWM调速直流电机驱动,单片机与L298之间如何用光耦隔离?…

查看全部问答>

SBL 串口升级

各位大神好: 最近在做TI cc2540的SBL串口升级,用的是TI协议栈1.40自带的bootloader,工具用的是serial boot tool1.2的版本,用户程序用的是TI协议栈自带的hosttest工程。 升级过程中出现这样的问题:刚把bootloader烧入目标板后,通过boot tool ...…

查看全部问答>

DSPLIB库滤波器参数问题

我用matlab生成的希尔伯特变换器系数,用在DSPLIB的hilb16()函数中,输出的波形都不正确,请问TI有针对该DSPLIB库专门的工具可以生成滤波器系数吗? …

查看全部问答>