单片机

波形发生器应用相对广泛,对于波形发生器,想必大家有所了解。为增进大家对波形发生器的了解,本文将对如何基于单片机设计DAC0832波形发生器加以介绍。

基于单片机设计DAC0832波形发生器"

波形发生器是一种常用的信号源,广泛的应用于电子电路、自动控制系统和教学实验等领域,是现代测试领域内应用最为广泛的通用仪器之一。在研制、生产、测试和维修各种电子元件、部件以及整机设备时,都需要有信号源。由它产生不同频率不同波形的电压、电流信号并加到被测器件或设备上,用其他仪器观察。

测量被测仪器的输出响应,以分析确定它们的性能参数。信号发生器是电子测量领域中最基本、应用最为广泛的一类电子仪器。它可以产生多种波形信号,如方波、锯齿波、三角波等,因而广泛应用于通信、雷达、导航、宇航等领域

以多种波形发生器为对象,选择单片机、独立按键及D/A转换器,设计相应的电路构成多种波形发生器。

一、功能要求

1.有4个功能键,分别用来选择输出:三角波、锯齿波、梯形拨、方波。

2.按下某个功能键,进入中断,在中断程序中查询、确定是哪个功能键,并输出对应的波形。

3.显示器2位,显示功能号01、02、03、04,代表输出三角波、锯齿波、梯形拨、方波。

二、设计任务

1、 完成单片机最小系统电路设计。

2、 完成按键电路设计。

3、 完成D/A转换及接口电路的设计。

4、 完成显示电路的设计。

电路图如下:(proteus 仿真通过)

“基于单片机设计DAC0832波形发生器"

其一仿真图:

“基于单片机设计DAC0832波形发生器"

三、源程序

ORG 0000H

START:LJMP MAIN

ORG 0003H ;外部中断入口

LJMP INSER ;转到中断服务程序

ORG 0030H

MAIN:MOV DPTR,#7FFFH ;DAC0832地址

SETB EX0 ;允许中断

SETB IT0 ;负边沿触发方式

SETB EA ;开中断

HERE:JB 20H.0,ST ;锯齿波处理

JB 20H.1,TRI ;三角波处理

JB 20H.2,SQ ;方波处理

JB 20H.3,TXB ;梯形波处理

SJMP HERE ;等待中断

INSER:JNB P1.0, LL1 ;中断服务程序,查询按键

SJMP L1

LL1:MOV 20H,#00H SETB 20H.0 ;设置锯齿波标志

SJMP RT

L1:JNB P1.2, LL2

SJMP L2

LL2:MOV 20H,#00H

SETB 20H.1 ;设三角梯波标志

SJMP RT

L2:JNB P1.4, LL3

SJMP L3

LL3:MOV 20H,#00H

SETB 20H.2 ;设置方波标志

SJMP RT

L3:JNB P1.6, LL4

SJMP RT

LL4:MOV 20H,#00H

SETB 20H.3 ;设置梯形波标志

RT:RETI ;中断返回

ST:CLR

P1.1 ;锯齿波

CLR P1.3 SETB P1.5

CLR P1.7

MOV A,#00H

LOOPP:MOVX @DPTR,A ;启动D/A转换

INC A

JB 20H.0,LOOPP ;连续输出波形

LJMP HERE

TRI:CLR P1.1 ;三角波

CLR P1.3

CLR P1.5

SETB P1.7

MOV A,#00H

UP:MOVX @DPTR,A ;启动D/A转换

INC A ;上升沿

CJNE A,#0FFH,UP

DOWN:MOVX @DPTR,A ;启动D/A转换

DEC A ;下降沿

CJNE A,#00H,DOWN

JB 20H.1, UP ;连续输出波形

LJMP HERE

SQ:CLR P1.1 ;方波

SETB P1.3

CLR P1.5

CLR P1.7

MOV A,#00H

MOVX @DPTR,A ;DAC输出低电平

ACALL DELAY ;延时1

MOV A,#0FFH

MOVX @DPTR,A ;DAC输出高电平

ACALL DELAY ;延时2

JB 20H.2, SQ ;连续输出波形

LJMP HERE

TXB:CLR P1.1 ;梯形波

CLR P1.3

SETB P1.5

SETB P1.7

MOV A,#00H

MOVX @DPTR,A

ACALL DELAY

LOOP:MOVX @DPTR,A

INC A

CJNE A,#0FFH,LOOP

ACALL DELAY

MOVX @DPTR,A

LOOP1:DEC A

MOVX @DPTR,A

CJNE A,#00H,LOOP1

MOVX @DPTR,A

ACALL DELAY

JB 20H.3,LOOP

DELAY:MOV R4,#0FH ;延时子程序

LOOP11:MOV R5,#10H

LOOP22:NOP

NOP

NOP

DJNZ R5,LOOP22

DJNZ R4,LOOP11

RET

END

通过本文,希望大家对上述介绍的波形发生器相关内容具备一定的了解。

来源:网络
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:
cathy@eetrend.com)。

围观 28

经典的AT89C51单片机,其内部只有128字节RAM(内存),同样经典的MSP430F149也只有2K的RAM空间。

即使现在用的比较多的STM32F1系列,其最大的RAM也不到100K。

很多小伙伴就有这样的疑问:现在固态硬盘都以 T 为单位了,手机电脑内存都是8G、甚至32G了,为什么单片机RAM连1M都不到?

今天就来讲讲关于RAM以及单片机内存少的几点内容。
(备注:本文说的单片机,指MCU,微控制器)

关于RAM

RAM:Random Access Memory,随机存取存储器,也是大家所说的内存。

“单片机中RAM少,有哪几点原因?"

RAM是一种易失性存储器,也就是说断电就会丢失存储数据。

RAM有一些常见特点:

  • 随机存取

  • 易失性

  • 对静电敏感

  • 访问速度块

  • ······

随着需求的提高,技术的进步,RAM又发展了像SRAM、DRAM、SDRAM等多种类型的RAM存储器,这里可以参看一下文章:SRAM、DRAM、SDRAM的区别

“单片机中RAM少,有哪几点原因?"

相对于Flash、硬盘等非易失性存储器而言,RAM具有更快的读写速度,因此RAM广泛用于各种单片机、嵌入式、计算机系统中。

但RAM也存在一些“不足”,导致在很多场合,RAM的容量都相对比较小。

RAM容量小的几点原因

RAM相对Flash、硬盘而言,要做到足够大容量,其成本相对Flash要多的多。

1.RAM工艺更复杂

RAM要求速度更快,电流又不能太大,为了能尽量满足和平衡更高要求,就需要使用更特殊和更先进的半导体电容技术。

“单片机中RAM少,有哪几点原因?"

2.更大的硅面积

因为RAM的工艺更复杂,其占用硅面积相对更大。

大家应该都知道芯片的制造过程,目前芯片主要使用硅这种材料制作芯片(当前,现在也发明了更先进的材料),占用硅面积更大,意味着单个芯片成本更贵,相信这个原理大家都懂。

“单片机中RAM少,有哪几点原因?"

通过认识wafer、die、cell它们的关系你就能大概理解芯片其实是“批量”生成的。

3.功耗原因

单片机通常要求功耗不能太多,特别是低功耗的单片机,在待机模式下,要求nA级别的电路。

为了满足低功耗,单片机中RAM,通常是静态RAM(SRAM)。

这里要扩展一下与SRAM对应的DRAM(动态RAM),顾名思义,动态RAM就是需要定时给电容补充漏掉的电荷,也就是需要定时刷新,DRAM需要驱动电路,功耗相对SRAM自然更大。

4.单片机大容量RAM需求不大

大家都知道,使用单片机开发的项目,通常都是裸机,或者RTOS,一般不会用到大型软件,特别是早期的时候(早期少数对RAM有需求的项目,一般通过外扩RAM的方式)。

所以,早期很多项目对单片机RAM容量要求不高,甚至有很大一部分RAM都没有用到。

当然,随着UI、AI、物联网的快速发展,现在对单片机RAM的需求也在不断增加,很多新出的单片机RAM容量也在不断增加,比如256K,甚至512K了。

5.其他

除了以上说的几点,还有像寿命、稳定性、兼容性等也是间接影响RAM大小的因素。

来源:strongerHuang
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 75

刚开始学单片机的你,是不是会因用程序把LED点亮而感到高兴,会因用程序把数码管点亮而感到高兴。这是好事,这也是想继续学习下去的动力。

但是到了与数据相关的实验时,却感觉很难有所进步。有时候,把驱动写好了,下载到单片机后,一点反应都没有,可是又不知道问题出在哪里,数据通信又不像LED那样可以用万用表测出到底有没有电。

这是学习单片机和STM32的一道坎。又或者说,这是一条河,阻拦着你的去路的河,有一条河你会怎么办?过去的方法很多,但是笔者觉得较快的方法就是借助原有工具渡过去。过去之后你会发现河的那边是一个不一样的世界。

那这个原有的工具是什么呢?那就是"串口通信"。

串口通信介绍

串口通信是指外设和计算机间,通过数据信号线 、地线、控制线等,按位进行传输数据的一种通讯方式......这种太过理论了,看似懂了,但又不懂。还是用我笔者自己的话来说吧。

串口通信就是可以把程序在单片机或者STM32芯片中运行的结果发送到电脑的一种通信方式。如何使用串口通讯,你需要知道的几个重要的知识点:

  • 1.波特率。(数据传输的速度,两个设备在通信时的速度要设置成一样,否则会出现乱码)。

  • 2.硬件连接。串口通信是一种异步通信,一般都是TX->RX,RX->TX。

  • 3.停止位。

  • 4.奇偶校验。

  • 5.硬件数据流。

3、4、5,这几项一般不需要改变,所以在这就不用多说了。

串口作用

串口能用来做什么事情?

学过C语言的人都知道,程序开发需要不断调试不断验证。很多的语言编程软件都有很完整的程序调试功能。使用起来很方便。而我们的开发虽然也是用C语言,但我们的程序最终运行的环境不是在我们的开平台而是在真正的硬件系统中运行。这时想要查看程序的运行过程或者结果就不像编程软件那么方便了。

想要解决这个问题,我们这时就可以借助串口通信来把我们需要知道的结果又或者是程序运行的关键步骤发送到电脑上,我们就知道程序在硬件系统中运行是否出现问题。51单片机可以用串口来调试,STM32可以用串口来调试。高级一点的LINUX开发板也是使用串口来调试。

学会串口通信能做什么

当你学会串口通信时,你可以开始玩WIFI模块、GSM模块、蓝牙模块、GPS模块、以及各种使用串口通信的传感器等等。有能力你还可以编写上位机软件通过串口通信来控制设备。

串口通信需要什么

如果你只有STM32核心板,那么你还需要一个串口转USB模块和一个串口数据接收软件还有几根杜邦线就可以了。如果你的是比较完整的一款开发板的话,一般都已经带有串口转USB模块,这样使用起来就更简单了。聪明的你是不是发现还缺少了点什么,对。没错因为还缺少了最重要的程序。想要使用串口通信当然还需要写串口通信的程序。下面就教你如何去用,而不是写。

串口实验

在做一个实验时,最好把这个实验分割成几个关键的步骤,这样做的好处就是可以清晰的知道自己需要做什么,以及做完了哪些。还有哪些还没做。下面笔者把串口实验分成几个关键的步骤:

1)串口通信使用到的GPIO引脚配置

STM32F103系列的芯片一般都有三个串口以上,用来调试使用的串口一般都是使用USART1。其他的串口配置都是一样的。

下面这段就是串口配置的程序:

GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//使能USART1,GPIOA时钟

//USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
//USART1_RX GPIOA.10初始化

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10 

串口使用的的GPIO口是PA9和PA10,所以只需配置这两个IO口的输入输出模式就可以了。

2)串口主要参数设置(直接看程序)

USART_InitTypeDef USART_InitStructure;
//USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;
//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
//数据格式,8位
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); 
//初始化串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//开启串口接受中断

串口参数配置无法就是配置串口的波特率、数据格式、停止位、奇偶校验、硬件流、收发模式。除了波特率需要改变其他的参数都不需要管。直接复制拿来用。

3)串口中断配置

串口如果使用中断接收,那么就需要配置串口的中断参数,配置项无法就是配置那个的中断源和中断的优先级。

NVIC_InitTypeDef NVIC_InitStructure;
//Usart1 NVIC 配置

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;//子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能
NVIC_Init(&NVIC_InitStructure);//根据指定的参数初始化VIC寄存器

4)串口使能

就是你需要什么时候开始使用串口功能,就是一句原有的函数。

USART_Cmd(USART1, ENABLE); //使能串口1 

5)编写串口中断处理函数

使用库函数开发,所有的中断函数都是已经存在的,只是中断函数里面没有处理任何事情而已。中断函数如下:

void USART1_IRQHandler(void)
{
//这里是编写中断处理的内容,但是一般会先判断相关的标准才算完整
}

完整的串口中断函数:

void USART1_IRQHandler(void)
{
int Res=0; //定义一个变量用来接收串口数据集
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断(接收到的数据必须是0x0d 0x0a结尾)
  {
  Res =USART_ReceiveData(USART1);//读取接收到的数据
  USART_SendData(USART1,Res ); //把接收到的数据通过串口1发送出去
  }
}

串口数据的接收和发送的函数都是库函数提供的,想用时只需找到它直接拿来用就可以了。

以上就完成了一个最简单的串口实验。把程序编译烧写到STM32然后用串口转USB模块连接到电脑,使用串口数据接收软件SSCOM或其他的数据接收软件设置好波特率,打开串口,正常的话,那发送什么到STM32那就会收到什么。这样就算完成了。

这次就说到这了,如果有开发板的配套例程可以先使用,用多了,慢慢就理解了。这篇文章主要想说明串口的重要性。用串口来调试真的方便很多。

来源:网络
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:
cathy@eetrend.com)。

围观 97

本文从现代电子系统的可靠性出发,详细论述了单片机应用系统的可靠性特点。提出了芯片选择、电源设计、PCB制作、噪声失敏控制、程序失控回复等集合硬件系统的可靠性设计技术和软件系统的可靠性设计技术的解决方法。可供单片机应用系统的开发人员借鉴与参考。

单片机应用系统的设计包括功能性设计、可靠性设计和产品化设计。其中,功能性是基础,可靠性是保障,产品化是前途。因此,从事单片机应用系统开发工作的设计人员必须掌握可靠性设计。

一、可靠性与可靠性设计

1.现代电子系统的可靠性

现代电子系统具有如下特点:嵌入式的计算机系统.智能化的体系结构;以计算机为核心的柔性硬件基础,由软件实现系统的功能;硬件系统有微电子技术的有力支持。单片机应用系统是当前最典型、最广泛的现代电子系统。现代电子系统的可靠性表现为,在规定条件下,系统准确无误运行的能力.突出了可靠性的软件和运行中的失误概率。

可靠性设计则是在产品开发过程中,保证运行可靠的全部设计手段,甚至包括了产品出厂后软件升级中的可靠性设计。由于软件的介入,可靠性问题除了二值可靠性的“失效”外.出现了除了“正常”与“失效”以外介于其间的诸如“出错”、“失误”、“不稳定”的多值可靠性问题。

“单片机应用系统的可靠性特点"

2.单片机应用系统的可靠性特点

(1)系统运行状态的可靠性特点单片机应用系统普遍采用CMOS器件,因此,经常的运行状态有静态运行与动态运行之分。静态运行是指单片机在休闲或掉电方式下的工作状态。此时,单片机指令停止运行。外围电路被关断或电源被关断,系统中只有值守电路在工作。

因此,静态运行下的系统不存在软件的可靠性问题,其可靠性主要表现在值守电路的抗干扰能力、系统中器件的静态参数余度,如直流特性参数余度、工作电压、工作稳定以及接插件的可靠性等。动态运行是指单片机应用系统工作在程序运行状态。此时的可靠性主要是软件运行的可靠性问题.表现在动态参数余度,如逻辑电平噪声容限、时钟误差、时序误差等。

(2)固化软件运行环境与可靠性单片机应用系统中,CPU运行的是事先固化在单片机的程序存储器的软件.用户无法更改和输入新的程序。这就避免r外来计算机病毒的侵袭,其可靠性表现在固化软件本身的可靠性和程序存储器数据保护的可靠性。

(3)时空边界性问题与可靠性时空边界性问题普遍存在于单片机应用系统中.如单片机应用系统中采用二位十进制数代替四位公元纪年的定时时钟系统。在跨越2000年时就会形成数据处理失误;采用有限写入次数的程序存储器。在超过写入次数的运行操作时会出现数据错误;程序存储器保存数据也有一定的年限,超过此年限也会出现数据错误。其它诸如计数容量.数据溢出,参数超边界应用都会带来可靠性问题。因此.必须采取时空边界性问题的可靠性防范措施。

3.本质可靠性与可靠性控制本质可靠性是只考虑系统功能要求的软、硬件可靠性设计,是可靠性设计的基础。如采用CMOS电路代替7rrL电路提高噪声容限,增加系统抗干扰能力:采用高可靠性的软硬件开发平台实现产品开发;按照电磁兼容规范设计可靠的PCB等。常用的可靠性控制设计有:噪声失敏控制,时空边界管理,系统自检与自修复,出错后的安全性包容等。

二、硬件系统的可靠性设计

硬件系统的可靠性是系统本质可靠性和可靠性控制的基础。

1.硬件系统总体方案的可靠性设计硬件系统总体方案的可靠性设计内容包括:

(1)采用硬件平台的系统设计方法

单片机应用系统的硬件平台都是由相近似的应用系统基本电路组成,只适用于某一领域中的硬件系统设计。基于硬件平台设计的应用系统有基本的可靠性保证。一个良好的硬件平台应具备:标准化、系列化、规范化设计的电路系统;柔性特性的基本应用系统体系结构;丰富的软件支持;可靠性测试记录。

(2)最大的系统集成

最大的系统集成可以最大限度简化系统构成,有助于减少系统硬件失误概率。最大的系统集成应具备:依靠器件解决的思想;单片机选择实现系统的最大包容;0EM的支持。

2.器件选择的可靠性设计

单片机芯片的选择要满足系统集成的最大化要求;优选CMOS器件:为简化电路设计尽可能采用串行传输总线器件代替并行总线扩展的器件;选择保证可靠性的专用器件,如采用电源监控类器件、信号线路故障保护器、ESD(静电干扰)保护器、能实现电源短路保护的自聚合开关等。

三、软件系统的可靠性设计

在单片机应用系统可靠性设计中,软件设计最主要的任务是保证在过程空间中。应用程序按照给定的顺序有序运行。在高可靠性的硬件系统基础上。软件设计的可靠性保障了最少的软件错误以及在软件出错后仍能保证系统正常运行或安全运行。

1.本质可靠性的软件设计

软件的本质可靠性是指不依靠软件附加.最大限度减少自身错误及缺陷,并且要有足够的时序余度。

单片机系统在CPU的控制下实现分时操作.程序完全依靠时序调度、切换控制。程序运行的可控不仅要求时序准确,而且要有足够的时序余度。

第一,系统复位时序。多个器件复位的时序要求是主要问题。应保证MCU对外围可编程器件的初始化在该器件复位后进行。软件设计时,可以在系统上电复位后,MCU延迟片刻,确保外围器件复位后,再对其初始化。

第二,外围器件工作时序。对外围器件的工作时序必须分析清楚,MCU的操作必须保证时序信号的衔接控制和时序信号的时序余度。

第三,应用系统的状态转换时序。应用系统中的状态转换有MCU运行状态转换、外围器件运行状态转换和电源系统供电状态转换等。在程序设计中.必须考虑状态转换时过渡期对程序运行的影响,精心设计时序控制。通常。MCU本身的状态转换,都有自动监视、自动运行管理功能,程序设计只需按MCU数据手册及指令系统的操作要求进行即可。对于有较长过渡期的外围状态转换,可采取足够的延时或设置提前转换状态的办法。

第四,总线时序。单片机应用系统中有并行总线和串行总线,这些总线在规范化操作时,其时序数据通信协议保证。在虚拟总线方式时,虚拟总线运行的可靠性在于时序的准确模拟。并行总线要保证读、写操作指令运行下的读写时序:同步串行总线要保证时钟线控制下的同步时序;串行异步时序则要考虑波特率对数据传送的影响。

四、结束语

单片机应用系统的可靠性设计涉及硬件系统的抗干扰设计和软件系统的抗干扰设计,采取的措施多而复杂。实际应用时,应根据设计条件与目标要求,制定应用系统的可靠性等级,合理采用硬性可靠性措施。充分利用软件的可靠性设计,提高系统的抗干扰能力。

来源:玩转单片机与嵌入式
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 92

很多人说单片机性能太弱,那你了解这个性能是如何得出来的吗?

概述

我们经常听见某手机发布会,安兔兔跑分多少多少,其实这个跑分就是体现手机性能的一个指标。

我们使用STM32开发产品,选择MCU时,一般会综合考虑MCU各方面性能。

对于MCU来说,一个重要指标是功耗,还有一个重要指标就是性能。

当我们进入ST官方微控制器网页,就会发现ST将MCU划分为不同层次,如下图:

https://www.st.com/en/microcontrollers.html

“单片机性能测试基准CoreMark是什么?"

从上面层次关系,大致可以了解ST 各MCU的功耗和性能。

STM32 CoreMark跑分

STM32家族的32位微控制器基于ARM Cortex®-M处理器设计,为用户提供新的自由度。

产品集高性能、实时性、数字信号处理、低功耗、低压运行、互联性于一体,保持充分的集成化和易用性。

根据性能划分,STM32各系列MCU划分为如下图几大类产品。具体可以参看官网信息。

https://www.st.com/en/microcontrollers/stm32-32-bit-arm-cortex-mcus.html

“单片机性能测试基准CoreMark是什么?"

在嵌入式处理器领域最为知名和常见测试CPU性能的就是:Dhrystone 和 CoreMark。

1、CoreMark是用来衡量嵌入式系统中中心处理单元(CPU,或叫做微控制器MCU)性能的标准。

2、DMIPS:Dhrystone Million Instructions executed Per Second。用来计算同一秒内系统的处理能力,它的单位以百万来计算,也就是(MIPS)。主要用于测整数计算能力。

CoreMark跑分如何得来?

CoreMark是用来衡量CPU性能的标准。该标准于2009年由EEMBC组织的Shay Gla-On提出,并且试图将其发展成为工业标准,从而代替陈旧的Dhrystone标准。

与Dhrystone一样,CoreMark小巧,便携,易于理解,免费,并且显示单个数字基准分数。与Dhrystone不同,CoreMark具有特定的运行和报告规则,旨在避免Dhrystone的问题。

CoreMark跑分是通过运行C语言代码得出来的分数。主要包含如下的运算法则:列举(寻找并排序),数学矩阵操作(普通矩阵运算)和状态机(用来确定输入流中是否包含有效数字),最后还包括CRC(循环冗余校验)。

也就是说CoreMark是使用一套用C语言编辑的测试代码,我们通过运行这套代码就能测试你MCU的性能。

CoreMark测试代码

这里我们可以参考CoreMark官网信息,地址:
https://www.eembc.org/coremark/index.php

“单片机性能测试基准CoreMark是什么?"

这里包含CoreMark相关说明、源代码下载、移植说明等。源代码位于Github,地址:

https://github.com/eembc/coremark

“单片机性能测试基准CoreMark是什么?"

源码docs目录下包含与源码相关的很多说明,感兴趣可以下载来测试一下你MCU跑分多少。

其实,这里也有多种型号STM32的CoreMark跑分和测试结果:

“单片机性能测试基准CoreMark是什么?"

“单片机性能测试基准CoreMark是什么?"

STM32有些板子出厂就自带CoreMark测试程序,比如我这边手上有一个块STM32F429I-Discovery的板子,就自带性能测试代码。

“单片机性能测试基准CoreMark是什么?"

移植的过程,我这里就不教大家了,官方提供一些例程,网上也有很多教程,感兴趣的小伙伴可以试着移植测试一下。

来源: strongerHuang
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 711

虽然这个问题对于电子老白来说不值一提,不过对于初学单片机的朋友,问这个问题的人实在是太多了……

既然是初学者,还得简单介绍一下继电器是个什么东西。

“(这是我手头上的一个继电器)"
(这是我手头上的一个继电器)

继电器就是个开关,这个开关是由它内部的线圈控制的,给它的线圈通电,继电器就吸合,开关就动作了。

有些人还会问什么是线圈?看下图:

“初学者要看!为什么单片机不能直接驱动继电器和电磁阀?"

1脚和2脚就线圈的两个引脚,3脚和5脚现在是通的,3脚和2脚是不通的。如果你给1脚和2脚通电,你就会听到继电器一声响,然后3脚和4脚就通了。

比如你要控制一条线的通断,就可以把这条线故意搞断以后,一端接到3脚,一端接到4脚,然后通过给线圈通电和断电,就可以控制这条线的通断了。

线圈1脚和2脚加多大电压?

这个问题,需要看你用的继电器的正面,比如我现在这个,你可以看到是05VDC,所以你可以给这个继电器的线圈通5V电,继电器就会吸合。

线圈电压怎么加?

终于说到正题了。

你可以直接用两只手拿上5V和GND两条线直接通到继电器线圈的两个引脚,就会听到响声了。

那用单片机怎么给他加电压?我们知道,单片机引脚就可以输出5V,是不是直接用单片机引脚连接继电器线圈,就可以了呢?

答案当然不是的。

为什么呢?

万变不离其宗,还是欧姆定律。

你用万用表量一下继电器线圈的电阻。

“初学者要看!为什么单片机不能直接驱动继电器和电磁阀?"

比如我这个继电器线圈的电阻,大概是71.7欧姆,加5V电压的话,电流就是5除以71.7约等于0.07A,就是70mA。记住,我们单片机的普通引脚最大输出10mA电流,大电流的引脚最大输出20mA电流(这点可参照单片机的datasheet)。

看到了吧,虽然是5V,但是输出电流能力有限,达不到驱动继电器的电流,所以无法直接驱动继电器。

这时候就需要想办法。比如用三极管S8050驱动。

电路图如下。

“初学者要看!为什么单片机不能直接驱动继电器和电磁阀?"

看S8050的datasheet,S8050是一个NPN管,ICE最大允许电流是500mA,远远大于70mA,所以用S8050驱动继电器绝对是没有问题的。

看上图,ICE也就是从C流到E的电流,就是和继电器线圈一条线的电流。NPN三极管,在这里就是个开关,单片机引脚输出5V高电平,ICE就导通继电器就会吸合;单片机引脚输出0V低电平,ICE就截止,继电器就不吸合。

同理,电磁阀也是一种电阻很小功率很大的负载,也需要按照上述欧姆定律的方法,选择合适的驱动元件。

来源:科技老顽童
版权归原作者所有,如有侵权,请联系删除。

围观 65

基本数字逻辑门电路

不管是数字电路,还是C语言,我们都会经常遇到逻辑运算和逻辑电路。

首先,在“逻辑”这个概念范畴内,存在真和假这两个逻辑值,而将其对应到数字电路或C语言中,就变成了“非0值”和“0值”这两个值,即逻辑上的“假”就是数字电路或C语言中的“0”这个值,而逻辑“真”就是其它一切“非0值”。

然后,来具体分析一下几个主要的逻辑运算符。假定有2个字节变量:A和B,二者进行某种逻辑运算后的结果为F。以下逻辑运算符都是按照变量整体值进行运算的,通常就叫做逻辑运算符:

  • &&: 逻辑与,F = A && B,当A、B的值都为真(即非0值,下同)时,其运算结果F为真(具体数值为1,下同);当A、B值任意一个为假(即0,下同)时,结果F为假(具体数值为0,下同)。

  • ||:逻辑或,F = A || B,当A、B值任意一个为真时,其运算结果F为真;当A、B值都为假时,结果F为假。

  • ! :逻辑非,F = !A,当A值为假时,其运算结果F为真;当A值为真时,结果F为假。

以下逻辑运算符都是按照变量内的每一个位来进行运算的,通常就叫做位运算符:

  • & :按位与,F = A & B,将A、B两个字节中的每一位都进行与运算,再将得到的每一位结果组合为总结果F,例如A = 0b11001100,B = 0b11110000,则结果F就等于0b11000000。

  • | :按位或,F = A | B,将A、B两个字节中的每一位都进行或运算,再将得到的每一位结果组合为总结果F,例如A = 0b11001100,B = 0b11110000,则结果F就等于0b11111100。

  • ~ :按位取反,F = ~A,将A字节内的每一位进行非运算(就是取反),再将得到的每一位结果组合为总结果F,例如,A = 0b11001100,则结果F就等于0b00110011;这个运算符我们在前面的流水灯实验里已经用过了,现在再回头看一眼,是不是清楚多了。

  • ^ :按位异或,F = A ^ B,异或的意思是,如果运算双方的值不同(即相异)则结果为真,双方值相同则结果为假。在C语言里没有按变量整体值进行的异或运算,所以我们仅以按位异或为例,F = A ^ B,A = 0b11001100,B = 0b11110000,则结果F就等于0b00111100。

要看资料或芯片手册的时候,会经常遇到一些电路符号,表1就是数字电路中的常用符号,知道这些符号有利于我们理解器件的逻辑结构,尤其重点认识以下表中的“国外流行图形符号”。在这里我们先简单看一下,后边遇到了知道到这里查阅就可以了。

“表1
表1 数字逻辑门电路

定时器

定时器是单片机的重点中的重点,但不是难点,大家一定要完全理解并且熟练掌握定时器的应用。

  • 时钟周期:时钟周期T是时序中最小的时间单位具体计算的方法就是1/时钟源,如果大家用的晶振是11.0592M,那么对于这个单片机系统来说,时钟周期=1/11059200秒。

  • 机器周期:我们的单片机完成一个操作的最短时间。机器周期主要针对汇编语言而言,在汇编语言下程序的每一条语句执行所使用的时间都是机器周期的整数倍,而且语句占用的时间是可以计算出来的,而C语言一条语句的时间是不可计算的。51单片机系列,在其标准架构下一个机器周期是12个时钟周期,也就是12/11059200秒。现在有不少增强型的51单片机,其速度都比较快,有的1个机器周期等于4个时钟周期,有的1个机器周期就等于1个时钟周期,也就是说大体上其速度可以达到标准51架构的3倍或12倍。

这两个概念了解即可,下边就来重头戏,定时器和计数器。定时器和计数器是单片机内部的同一个模块,通过配置SFR(特殊功能寄存器)可以实现两种不同的功能,大多数情况下是使用定时器功能,计数器功能大家自己了解下即可。

顾名思义,定时器就是用来进行定时的。定时器内部有一个寄存器,让它开始计数后,这个寄存器的值每经过一个机器周期就会加1一次,因此,可以把机器周期理解为定时器的计数周期。秒表每经过一秒,数字加1,而这个定时器就是每过一个机器周期的时间,也就是12/11059200秒,数字加1。

还有一个特别注意的地方,就是秒表是加到60后,秒就自动变成0了,这种情况在单片机和计算机里称之为溢出。那定时器加到多少才会溢出呢?定时器有几种模式,假如是16位的定时器,也就是2个字节,最大值就是65535,那么加到65535后,再加1就算溢出,如果有其他位数的话,道理是一样的,对于51单片机来说,溢出后,这个值会直接变成0。从某一个初值,经过计算确定的时间后溢出,这个过程就是其定时的含义。

定时器的寄存器描述

标准的51里边只有定时器0和定时器1这两个定时器,现在很多单片机也有多个定时器的,在这里先讲定时器0和1。前边提到过,对于单片机的每一个功能模块,都是由他的SFR,也就是特殊功能寄存器来控制。

而和定时器有关的特殊功能寄存器,有以下几个,大家不需要去记忆这些寄存器的名字和作用,你只要大概知道就行,用的时候,随时可以查手册,找到每个寄存器的名字和每个寄存器所起到的作用。

“表2
表2 定时值存储寄存器

表2中的寄存器,是存储计数器的计数值的,两个字节的用于定时器1,两个字节用于定时器0。

“表3
表3 TCON--定时器/计数器控制寄存器的位分配(地址:88H)

表3中有TF1、TR1、TF0、TR0这4位需要理解清楚。两位定时器1的,两位定时器0的,只解释定时器1的,定时器0的同理。先看TR1,当我们程序中写TR1 = 1以后,定时器值就会每经过一个机器周期加1,当程序中写TR1 = 0以后,定时器值就会保持不变化。TF1,这个是一个标志位,它的作用是告诉定时器溢出了。

比如定时器设置成16位的定时器,那么每经过一个机器周期,TL1加1一次,当TL1加到255后,再加1,TL1变成0,TH1会加1一次,如此一直加到TH1和TL1都是255(即TH1和TL1组成的16位整型数为65535)以后,再加1一次,那么就会溢出,TH1和TL1同时都变为0,只要一溢出,TF1马上自动变成1,告诉定时器溢出了,仅仅是提供给一个信号,让知道定时器溢出了,它不会对定时器是否继续运行产生任何影响。

“表4
表4 TCON--定时器/计数器控制寄存器的位描述

注意在表4中的描述中,只要写到硬件置1或者清0的,就是指一旦符合条件,单片机自动完成的动作,只要写软件置1或者清0的,是指用程序去完成这个动作。

“表5
表5 TMOD--定时器方式控制寄存器的位分配(地址:89H)

TCON是“可位寻址”,TMOD是“不可位寻址”。这个地方的意思就是比如TCON有一位TR1,我们可以在程序中直接进行TR1 = 1,这样操作。但是(T1)M1 = 1,这样的操作就是错误的,操作就必须一次操作一个字节,就是必须一次性对TMOD所有位操作,不能对其中某一位单独进行操作。

“表6
表6 TMOD--定时器方式控制寄存器M1/M0工作模式

以上这4种模式的配置,其中模式0是为了兼容老的8048单片机而设的,现在的51几乎不会用到这种模式,而模式3根据应用经验,他的功能模式2完全可以取代,所以基本上也是不用,重点就学习模式1和模式2。

  • 模式1:就是THn和TLn组成了一个16位的定时器,取值范围是0到65535,溢出后,只要不对THn和TLn重新赋值,则从0开始计数。

  • 模式2:的功能是自动装载,就是TLn溢出后,TFn就直接置1了,并且THn的值直接赋给TLn,然后TLn从新赋值的这个数字开始计数,这个功能可以用来产生串口的通信波特率。

理解定时器原理

为了加深大家理解这个定时器原理,来看一下模式1的电路示意图1。

“图1
图1 定时器/计数器模式1示意图

分析一下这个示意图,OSC框表示时钟频率,因为1个机器周期等于12个时钟周期,所以那个d就等于12。下边GATA右边的那个门是一个非门电路,再右侧是一个或门,再往右是一个与门电路。

图上可以看出来,下边部分电路是控制了上边部分,那我们先来看下边是如何控制的,我们以定时器0为例。

  • TR0和下边或门电路的结果要进行与门运算,TR0如果是0的话,与运算完了肯定是0,所以确定如果要让定时器工作,TR0 = 1。

  • 与门结果要想是1,那或门出来的信号必须也得是1才行。在GATE位为1的情况下,经过一个非门变成0,或门电路结果要想是1的话,那INT0即P3.2引脚必须是1的情况下,这个时候定时器才会工作,而INT0引脚是0的情况下,定时器不工作,这就是GATE位的作用。

  • 当GATE位为0的时候,经过一个非门变成1,不管INT0引脚是什么电平,经过或门电路后则肯定是1,定时器就会工作。

  • 要想让定时器工作,就是加1,从图上看有两种方式,第一种方式是那个开关打到上边的箭头,就是C/T = 0的时候,一个机器周期TL就会加1一次,当开关打到下边的箭头,即C/T =1的时候,T0引脚即P3.4引脚来一个脉冲,TL就加1一次,这也就是计数器功能。(INT0引脚是P3.2,INT1引脚是P3.3,T0引脚是P3.4,T1引脚是P3.5。)

定时器程序应用

了解了定时器相关的寄存器,那么我们下面就来做一个定时器的程序,巩固一下我们学到的内容。我们这节课的程序先使用定时器0,在使用定时器的时候,需要以下几个步骤:

1、设置特殊功能寄存器TMOD,配置好工作模式;

2、设置计数寄存器TH0和TL0的初值;

3、设置TCON,通过打开TR0位来让定时器开始计数。

4、判断TCON寄存器的TF0位,监测定时器溢出情况。

写程序之前,要先来学会计算如何用定时器定时时间。以晶振是11.0592M为例讲解,时钟周期就是1/11059200,机器周期就是12/11059200,假如要定时20ms就是0.02秒,要经过x个机器周期得到0.02秒,算一下x*12/11059200 = 0.02,得到x = 18432。

那么现在16位的定时器溢出值是65536,可以这样,先给TH0和TL0一个初值,让他们经过18432个机器周期后刚好溢出,溢出后可以通过检测TF0位得知,就刚好是0.02秒。这个初值y = 65536 - 18432 = 47104,转成16进制就是0xB800,那么就是TH0 = 0xB8,TL0 = 0x00。

那0.02秒已经定时出来了,细心的同学会发现,如果初值直接给一个0x0000,一直到65536溢出,定时器定时值最大也就是71ms左右,那么想定时更长时间怎么办呢?用你小学学过的逻辑,倍数关系就可以解决此问题。

本程序实现的结果是小灯点亮持续一秒,熄灭持续一秒,也就是以0.5HZ的频率进行闪烁。那好了,我们下面就用程序来实现以下这个功能。

#include //包含寄存器的库文件

sbit LED = P0^0;

sbit ADDR0 = P1^0;

sbit ADDR1 = P1^1;

sbit ADDR2 = P1^2;

sbit ADDR3 = P1^3;

sbit ENLED = P1^4;

void main()

{

unsigned char counter = 0;

ENLED = 0; ADDR0 = 0; ADDR1 = 1;

ADDR2 = 1; ADDR3 = 1; LED = 1; //74HC138和LED灯初始化部分

TMOD = 0x01; //设置定时器0为模式1

TH0 = 0xB8;

TL0 = 0x00; //定时值初值

TR0 = 1; //打开定时器0

while(1)

{

if(1 == TF0) //判断定时器0是否溢出

{

TF0 = 0;

TH0 = 0xB8; //一旦溢出后,重新赋值

TL0 = 0x00;

counter++;

if(50 == counter) //判断定时器0溢出是否达到50次

{

counter = 0; //counter清0,重新计数

LED = !LED; //LED取反操作,0-->1,1-->0

}

}

}

}

程序都有注释,不难理解,这里要解释一个地方,就是两次if判断。细心的同学会发现,if(1 == TF0)这句,1写前边,因为如果写if(TF0 == 1),作为新手来说,不小心丢掉一个’=’号后,写成if(TF0 = 1),这样实际上在语法上是可以通过的,用的Keil4还会出一个警告说明一下,Keil以前的版本及一些其他软件,可能根本不会出任何错误或者警告提示,但这样产生的Hex文件下载到单片机里边,程序就错了,大家可以改改试试看。

来源:嵌入式ARM
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 52

学习STM32单片机的时候,总是能遇到“堆栈”这个概念。分享本文,希望对你理解堆栈有帮助。

对于了解一点汇编编程的人,就可以知道,堆栈是内存中一段连续的存储区域,用来保存一些临时数据。堆栈操作由PUSH、POP两条指令来完成。而程序内存可以分为几个区:

  • 栈区(stack)

  • 堆区(Heap)

  • 全局区(static)

  • 文字常亮区程序代码区

程序编译之后,全局变量,静态变量已经分配好内存空间,在函数运行时,程序需要为局部变量分配栈空间,当中断来时,也需要将函数指针入栈,保护现场,以便于中断处理完之后再回到之前执行的函数。

栈是从高到低分配,堆是从低到高分配。

普通单片机与STM32单片机中堆栈的区别

普通单片机启动时,不需要用bootloader将代码从ROM搬移到RAM。

但是STM32单片机需要。

这里我们可以先看看单片机程序执行的过程,单片机执行分三个步骤:

  • 取指令

  • 分析指令

  • 执行指令

根据PC的值从程序存储器读出指令,送到指令寄存器。然后分析执行执行。这样单片机就从内部程序存储器去代码指令,从RAM存取相关数据。

RAM取数的速度是远高于ROM的,但是普通单片机因为本身运行频率不高,所以从ROM取指令慢并不影响。

而STM32的CPU运行的频率高,远大于从ROM读写的速度。所以需要用bootloader将代码从ROM搬移到RAM。

使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。

其实堆栈就是单片机中的一些存储单元,这些存储单元被指定保存一些特殊信息,比如地址(保护断点)和数据(保护现场)。

如果非要给他加几个特点的话那就是:

  • 这些存储单元中的内容都是程序执行过程中被中断打断时,事故现场的一些相关参数。如果不保存这些参数,单片机执行完中断函数后就无法回到主程序继续执行了。

  • 这些存储单元的地址被记在了一个叫做堆栈指针(SP)的地方。

结合STM32的开发讲述堆栈

从上面的描述可以看得出来,在代码中是如何占用堆和栈的。可能很多人还是无法理解,这里再结合STM32的开发过程中与堆栈相关的内容来进行讲述。

如何设置STM32的堆栈大小?

在基于MDK的启动文件开始,有一段汇编代码是分配堆栈大小的。

“详解STM32单片机的堆栈"

这里重点知道堆栈数值大小就行。还有一段AREA(区域),表示分配一段堆栈数据段。数值大小可以自己修改,也可以使用STM32CubeMX数值大小配置,如下图所示。

“详解STM32单片机的堆栈"

STM32F1默认设置值0x400,也就是1K大小。

Stack_Size EQU 0x400

函数体内局部变量:

void Fun(void){ char i; int Tmp[256]; //...}

局部变量总共占用了256*4 + 1字节的栈空间。所以,在函数内有较多局部变量时,就需要注意是否超过我们配置的堆栈大小。

函数参数:

void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)

这里要强调一点:传递指针只占4字节,如果传递的是结构体,就会占用结构大小空间。提示:在函数嵌套,递归时,系统仍会占用栈空间。

堆(Heap)的默认设置0x200(512)字节。

Heap_Size EQU 0x200

大部分人应该很少使用malloc来分配堆空间。虽然堆上的数据只要程序员不释放空间就可以一直访问,但是,如果忘记了释放堆内存,那么将会造成内存泄漏,甚至致命的潜在错误。

MDK中RAM占用大小分析

经常在线调试的人,可能会分析一些底层的内容。这里结合MDK-ARM来分析一下RAM占用大小的问题。在MDK编译之后,会有一段RAM大小信息:

“详解STM32单片机的堆栈"

这里4+6=1640,转换成16进制就是0x668,在进行在调试时,会出现:

“详解STM32单片机的堆栈"

这个MSP就是主堆栈指针,一般我们复位之后指向的位置,复位指向的其实是栈顶:

“详解STM32单片机的堆栈"

而MSP指向地址0x20000668是0x20000000偏移0x668而得来。具体哪些地方占用了RAM,可以参看map文件中【Image Symbol Table】处的内容:

“详解STM32单片机的堆栈"

来源:STM32嵌入式开发
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:
cathy@eetrend.com)。

围观 394

页面

订阅 RSS - 单片机