Cortex-M0

上海东软载波微电子有限公司长期深耕于工业控制和白色家电等行业,并致力提供高可靠性、高性价比的芯片产品。消防产业持续变革,智慧消防产品日趋规范。我司面向消防应用的芯片产品系列不断延伸,可以覆盖主要的通用消防前装市场,已广泛应用于消防设备中的智能控制与人机交互等应用,涵盖早期预警、火灾报警、应急疏散、自动灭火等多系统。

燃气安全无小事,燃气报警器在检测到气体泄漏后发出报警并切断燃气阀,范防于未“燃”。燃气报警器通过高精度传感器检测周围环境气体,产生电信号给到MCU,当达到报警值时提醒用户。除了基本的甲烷浓度检测功能外,一些联网型报警器还具备其他功能,如通过WiFi、Cat-1或NB-IoT和后台服务器基于物联网协议进行通信,上报工作状态、故障自检等。我司32位Cortex-M0内核芯片ES8P5068可满足新国标《GB 15322.2-2019 可燃气体探测器 第2部分:家用可燃气体探测器》燃气报警器对MCU的参数需求。包括:

FLASH高达64KB,4KB RAM    

  • 满足物联网协议等丰富功能的燃气报警器对FALSH和RAM的容量要求。

  • 轻松存储新国标要求的700多条报警记录。

集成独立供电的RTC功能            

  • 电池供电与市电供电切换无需添加外围辅助电路。

  • 保证燃气报警器在运输或其它掉电场景下电池能工作更长时间。

  • 满足新国标要求的报警时间记录及低功耗应用,待机情况下功耗低至0.3μA@2.5V。

UART端口极性可配置               

  • 多达3路UART,除国标要求的读取接口外,可与WiFi、Cat-1或NB-IoT等通信模块通信实现无线远程通信。另外还可预留一路调试接口。

其它                                        

  • 多达15路ADC通道,采集多路模拟信号。

  • 2.2~5.5V宽电压工作范围,兼容3.3V和5V电源系统。

1.png

家庭燃气报警器应用示例

来源:东软载波微电子

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

围观 14

澎湃微S038系列创造新的Cortex-M0 MCU主频记录

澎湃微电子日前宣布,澎湃微的S038系列Cortex-M0 MCU创造了新的工作时钟主频记录,以200M的CPU主时钟工作频率,大幅超越全球已知Cortex-M0 MCU,全球主流厂商的Cortex-M0 MCU时钟主频通常在48M~72M,少数公司提供96M的产品。

1.jpg

NEW PAI NEW LIFE.当程序在S038的SRAM里运行,并且CPU主时钟设置为200M时,其CoreMark能够达到380分,已经达到或超过目前国际大厂Cortex-M4 MCU的工作性能。这样的性能指标,把Cortex-M0 MCU的计算能力提高到一个全新的水平,颠覆了Cortex-M0 MCU在工程师心中的原有印象,使传统的Cortex-M0 CPU焕发了全新的面貌。
Arm传统的、为MCU打造的Cortex-M系列CPU主要有:Cortex-M0, Cortex-M3, Cortex-M4。其中Cortex-M0是一款入门级32位CPU,最大特点是低功耗的设计,因其具有良好的性价比,从而广受欢迎。长期以来,Cortex-M0的市场主要覆盖计算要求不高的应用领域。随着其计算性能的显著提升,将使Cortex-M0 MCU向部分计算性能要求高的场景拓展,比如电机应用。Cortex-M0 MCU也能更好地适应智能化的电子发展趋势,大幅扩展其应用的覆盖面。Cortex-M0 MCU将从传统的控制,成为有计算能力的嵌入式系统核心。

2.jpg

澎湃微作为国产32位MCU的新势力,以锐意进取的精神,依托其先进的技术,在55nm这个相对传统的工艺上,实现了时钟频率的突破。此成果的公布,不仅是澎湃微实力的体现,也充分说明,国产MCU并不只是国际大厂的追随者,也有能力在个别方向上开始全球领先。国产MCU在自身持续努力,在庞大市场和众多合作伙伴的支持下,前景无限!

关于澎湃

澎湃微电子是一家以32位MCU为主营方向的集成电路设计公司(fabless),公司在上海设有研发中心,在深圳设有销售中心,总部设立在厦门。公司产品除了通用型MCU(32位/8位)之外,还有24位高精度ADC等模拟芯片。产品市场涵盖工业控制、消费电子、物联网、医疗健康、BLDC电机控制、小家电等领域。

公司拥有一支完整、经验丰富的国内MCU团队,核心合伙人均在MCU领域有20年以上经验,中层骨干均有10年以上经验。公司技术团队拥有完整的数字、模拟、全流程设计能力,以及丰富的工控领域MCU设计、量产经验,成功量产过高品质、高可靠的工控MCU等相关产品。

围观 86

相关文章:

敏矽微电子Cortex-M0学习笔记01——芯片简介

敏矽微电子Cortex-M0学习笔记02——Cortex-M0开发环境的建立及调试

敏矽微电子Cortex-M0学习笔记03——时钟系统设计例程

敏矽微电子Cortex-M0学习笔记04——GPIO详解及应用实例

敏矽微电子Cortex-M0学习笔记05——端口外部中断实例

敏矽微电子Cortex-M0学习笔记06——段式LCD液晶实例

敏矽微电子Cortex-M0学习笔记07——串口通信详解

1、ME32F030基本定时器简介

ME32F030内置 4 个基本功能的 16 位定时器/计数器。 定时器/计数器工作时钟由 SYSAHBCLKDIV 寄存器控制。关闭 SYSAHBCLKDIV 寄存器中定时器/计数器的时钟供给可节省系统功耗。主要功能如下:

• 可预置分频的 16 位定时器/计数器

• 1 个 16 位匹配寄存器:

–可产生中断

–停止定时器

–对定时器复位

16 位基本型定时器/计数器模块框图如下图所示:

1.png


图1 基本定时器结构图

为了便于理解,可以将基本定时器框图分为4个功能单元。

①:预分频计数单元,由PRESCALE COUNTER (PC) 和 PRESCALE REGISTER (PR)组成,预分频计数器(PC)会在每个 PCLK 时钟上递增计数。达到设定的预分频值后,定时器计数器就会加1,而预分频值就是由PR寄存器决定的。

②:定时器计数单元,由TIMER COUNTER (TC) 和 TIMER CONTROL REGISTER (TCR)组成,定时器控制寄存器TCR决定计数器TC是否启用。预分频计数器(PC)溢出后,定时器计数器(TC)加1,达到设定的匹配值MR0之后可以根据设置产生中断等行为。

③:定时器匹配单元:该单元只有一个MATCH REGISTER0(MR0),它决定着定时器计数器TC的匹配值。

④:定时器控制单元,由MATCH CONTROL REGISTER (MCR) 和 INTERRUPT REGISTER (IR)组成,二者共同作用,控制着定时器的主要功能和参数。

2、ME32F030基本定时器寄存器

在简介中,我们介绍了基本定时器的模块框图,其实每个功能模块都有对应的寄存器来实现其功能。基本定时器的寄存器列表如图所示:

2.png


2-1 中断寄存器

中断寄存器包含用于匹配中断的位。如果有中断产生, IR 中的相应位为高电平。否则,该位为低电平。向对应的 IR 位写逻 辑 1 会使中断复位。写 0 无效。

2-2 定时器控制寄存器

定时器控制寄存器用于控制计数器/定时器的操作。它主要控制着计数器的使能和复位,具体的操作如图所示:

3.png


图3 控制寄存器

2-3 定时器计数寄存器

当预分频器计数器达到其 PC 数值时, 16 位定时器计数器会递增计数。如果 TC 在到达计数器上限之前没有复位,它将一直 计数到 0x0000 FFFF 然后翻转到 0x0000 0000。该事件不会产生中断,如果需要,可使用匹配寄存器检测溢出。

2-4 预分频寄存器

16 位预分频寄存器指定预分频计数器的最大值。当预分频计数器计数到此值后,会从0开始重新计数。

2-5 预分频计数寄存器

16 位预分频计数器用某个常量来控制 PCLK 的分频,再使其输入到定时器计数器。它所控制的是定时器分辨率与最大时间之间的关系,从而能防止定时器溢流。预分频计数器会在每个 PCLK 时钟上递增计数。当预分频计数器的计数达到预分频寄存器中存储的值时,定时器计数器将递增计数,并且在下一个 PCLK 时钟上对预分频计数器复位。这将使得 TC 当 PR = 0 时在每个 PCLK 上递增计数,当 PR = 1 时,在每 2 个 PCLK 上递增计数,依次类推。.

2-6 匹配控制寄存器

匹配控制寄存器用于控制当其中一个匹配寄存器的值与定时器计数器的值匹配时应执行的操作。功能如下所示。

位0:决定着计数器TC与匹配值相等后,中断是否使能。

位1:MR0与TC匹配时,决定TC是否复位。如果选择复位,TC则会清0重新计数,这样就会形成一个固定时间的计数周期。

位2:MR0与TC匹配时,决定TC是否停止。如果置1选择使能,TC则不再会计数。这样就是个单次周期的计数了。如果想要周期性循环计数,那么就需要置0(默认)禁止。

4.png


图4 匹配控制寄存器

2-7 匹配寄存器

匹配寄存器的值会不断地与定时器计数器值进行比较。当两个值相等时,自动触发相应操作。这些操作包括产生中断、复位定时器计数器或停止定时器。所有操作均由 MCR 寄存器中的设置控制。

3、基本定时器驱动函数

在例程LIB->common->Drivers->Source文件夹内有timer.c文件,这个就是提供的定时器库程序,里面除了基本定时器的驱动函数,还包括高级定时器、PWM输出等功能函数,本章节先对基本定时器的函数进行讲解。

3-1 基本定时器初始化

ct:要初始化的定时器模块,可选TIM0、TIM1、TIM2、TIM3。

tickpersecond:预分频系数。

 void TIM0_Init(TIM0_Type *ct, uint32_t tickpersecond)
{
if (ct == TIM0)
{
SYSCON->SYSAHBCLKCTRL_b.TIM0_CLK=1;//使能定时器时钟
SYSCON->PRESETCTRL_b.TIM0_RST_N=0; //复位定时器
SYSCON->PRESETCTRL_b.TIM0_RST_N=1;
}

else if (ct == TIM1)
{

SYSCON->SYSAHBCLKCTRL_b.TIM1_CLK=1;

SYSCON->PRESETCTRL_b.TIM1_RST_N=0;

SYSCON->PRESETCTRL_b.TIM1_RST_N=1;
}

else if (ct == TIM2)
{
SYSCON->SYSAHBCLKCTRL_b.TIM2_CLK=1;

SYSCON->PRESETCTRL_b.TIM2_RST_N=0;

SYSCON->PRESETCTRL_b.TIM2_RST_N=1;
}

else if (ct == TIM3)
{

SYSCON->SYSAHBCLKCTRL_b.TIM3_CLK=1;

SYSCON->PRESETCTRL_b.TIM3_RST_N=0;

SYSCON->PRESETCTRL_b.TIM3_RST_N=1;

} else return;

//设置预分频系数
if (tickpersecond>SystemCoreClock)
tickpersecond=SystemCoreClock;
ct->PR_b.PRVAL=SystemCoreClock/tickpersecond-1;
return;
}

3-2 设置匹配寄存器

这个函数用于设置定时器的匹配值,以及达到匹配值之后的行为。

Ct:要设置的定时器模块,可选TIM0、TIM1、TIM2、TIM3。

Ticks:要写入的计数器匹配值。

Action: 触发中断 TIM_MATCH_TRIGGER_INT

复位计数器 TIM_MATCH_RESET_COUNTER

停止计数器 TIM_MATCH_STOP_COUNTER

void TIM0_ConfigMatch(TIM0_Type *ct, uint16_t ticks, uint8_t action)
{
ct->MR0_b.MATCH=ticks-1;
ct->MCR=action;
return;
}

3-3 设置预分频计数器值

void TIM0_SetTimerCounter(TIM0_Type *ct, uint16_t tick)
{
ct->PC_b.PCVAL=tick;
return;
}

3-4 复位预分频计数器值

void TIM0_ResetTimerCounter(TIM0_Type *ct)
{
ct->PC_b.PCVAL=0;
return;
}

来源:敏矽MCU

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

围观 51

相关文章:

敏矽微电子Cortex-M0学习笔记01——芯片简介

敏矽微电子Cortex-M0学习笔记02——Cortex-M0开发环境的建立及调试

敏矽微电子Cortex-M0学习笔记03——时钟系统设计例程

敏矽微电子Cortex-M0学习笔记04——GPIO详解及应用实例

敏矽微电子Cortex-M0学习笔记05——端口外部中断实例

敏矽微电子Cortex-M0学习笔记06——段式LCD液晶实例

1、UART串口简介

在单片机应用开发中,串口可以说是最常用的外设之一了。

串口最重要的功能就是能够让单片机和外部设备进行数据交互。例如在我们学习敏矽微电子的cortex m0时,可以将开发板与电脑相连,通过串口调试助手来调试程序、观察程序运行结果。还有很多其他的串口模块,比如蓝牙、 NBIOT、GPRS、4G 等模组,都是使用的串口来进行驱动的,因此掌握串口是嵌入式工程师必备的技能。

接下来我们就来学习如何驱动ME32F030上的串口。

在正式学习之前,我们先对UART串口的通信格式做一个了解。UART的全称是:通用异步收发传输器(Universal Asynchronous Receiver/Transmitter)。串行传输数据是按照字节为单位进行移位传输的,因此通信速度较低。但其拥有线路简单、通信距离远的优点,使用两条线即可实现双向通信,一条用于发送,一条用于接收。因此在工业应用中受到广泛应用。其通信格式也十分简单,如下图所示:

1.png

图1 UART数据格式

空闲位:数据线在空闲状态的时候保持高电平,表示没有数据传输。

起始位:当要传输数据的时候,数据线会被拉低,表示开始数据传输。

数据位:数据位就是实际要传输的数据,一般都是按照字节传输数据的,即一次传输8 位数据的。一般都是低位在前,高位在后。当然也有相反的传输协议,但平时很少会遇到。

奇偶校验位:这是对数据中“1”的位数进行奇偶校验用的,可以根据需求进行选择。

停止位:数据传输完成标志位,停止位的位数可以选择 1 位、1.5 位或 2 位高电平,一般都选择 1 位停止位。

波特率:波特率就是 UART 数据传输的速率,也就是每秒传输的数据位数,一般选择 9600、19200、115200 等。

随着电脑日新月异的升级换代,现在很多电脑都不带传统的COM口,USB接口开始广泛应用。所以就有了USB转串口芯片来解决这个难题,常用的U转串芯片有CH340、PL2303 等。通过这些芯片就可以实现串口 TTL 转 USB。

ME32F030开发板使用的是PL2303 芯片来完成串口和电脑之间的连接,只需要一条USB 线即可。在使用前需要注意两件事:第一,先下载并安装PL2303的驱动程序。第二,检查开发板的USB跳线帽是否接到COM、USB这边。正确的接法如下:

2.png

图2 跳线连接

2、UART驱动寄存器

ME32F030 提供2个 UART 外设:UART0,UART1。串行接口都支持红外传输(IrDA)协议功能。时钟都受 SYSAHBCLKCTRL 寄存器控制。同时每个 UART 有独立的时钟分频器来产生波特率,并使之不受系统时钟和PCLK影响。UART对应的管脚映射图如下:

3.png

图3 UART管脚映射

看完管脚的映射关系,接下来就列出与UART相关的寄存器组,随后会挨个进行讲解。

4.png

图4 UART寄存器

2-1 UART接收/发送缓冲寄存器

UART 接收/发送缓冲寄存器包含着 UART 接收到/将发送的字节,接收到的数据和待发送的串口数据都在该寄存器中。

2-2 UART状态寄存器

该寄存器用于提供 UART 接收发送缓存器的状态。大致可以归类为以下几种状态:

发送状态:发送FIFO空、发送FIFO半满、发送FIFO满。

接收状态:接收FIFO空、接收FIFO半满、接收FIFO满。

奇偶校验状态:没有奇偶校验错误,或检测到奇偶错误,写1来清除错误标志。

接收缓存器溢出状态 :用来表明缓存器是否溢出。

2-3 UART控制寄存器

接下来就要着重讲解下UART控制寄存器了。0-5位属于基本的接收、发送中断使位,这里不再累述。

BIT6:奇偶校验中断使能,使能该中断后,当接收到的数据发生奇偶校验错误后,会产生中断通知串口接收发生错误。

BIT7:接收溢出中断使能,使能该中断后,当接收到的数据超出FIFO容量就会产生中断。通知及时取出数据或者清空FIFO。

BIT8:奇偶校验方式选择位,0为偶校验,1为奇校验。这里注意,这只是选择了奇偶校验的方式,但是并不会生效,是否启动校验还需要下面介绍的寄存器。

BIT9:奇偶校验使能位,只有当该位置1才会使能奇偶校验,具体的校验方式由刚才介绍的奇偶校验方式选择位来决定。

BIT10:IRDA传输协议使能位,置1使能。

BIT22:RX接收使能,置1使能。

BIT23:TX发送使能,置1使能。

5.png

6.png

图5 UART控制寄存器

2-4 UART中断状态寄存器

既然刚才在介绍UART控制寄存器的时候,介绍了不少中断使能控制。肯定就会有相应的中断状态的管理。UART中断状态寄存器从低位开始依次管理着:①、发送结束中断状态,②、接收完成中断状态,③、发送FIFO满中断,④、接收FIFO满中断,⑤、发送FIFO半满中断,⑥、接收FIFO半满中断,⑦、奇偶校验错误中断,⑧、接收溢出中断。

2-5 UART 波特率分频器寄存器

UART 波特率分频器寄存器 (BAUDDIV) 用于时钟分频从而产生相应的波特率。该寄存器可读写。该分频器的时钟源是由UARTnCLKDIV 控制 UART 的波特率源时钟(SCLK)。

7.png

图6 UART 波特率分频器寄存器

波特率分频值计算公式:

BAUDDIV = SCLK / UART BAUDRATE

2-6 UART TX/RX FIFO 数据清除寄存器

操作该寄存器可以快速对TX/RX FIFO进行数据清空。

8.png

图7 UART TX/RX FIFO 数据清除寄存器

3、UART驱动函数

在例程LIB->common->Drivers->Source文件夹内有uart.c文件,这个就是提供的UART驱动文件,里面包含了一些基本的驱动函数,使用起来十分方便。下面会对每个函数进行讲解。

3-1 UART初始化

在每段源代码的后面,笔者对其进行一下注释,方便大家快速掌握和使用这个函数。这个函数的4个参数的意义如下:

uart:要使能的UART模块,可选UART0、UART1。

baudrate:要设置的串口的波特率。

parityoption:奇偶校验位,可选UART_EVEN_PARITY(奇校验)、 UART_ODD_PARITY(偶校验)、 UART_RX_NO_INT(无校验)。

rxinttriggerlevel:接收中断触发条件。

    void UART_Open(UART0_Type *uart, uint32_t baudrate, uint8_t parityoption, uint8_t rxinttriggerlevel)
{
uint32_t volatile delays;  

if (uart==UART0)
{

//初始化时关闭UART0 IRQ
NVIC_DisableIRQ(UART0_IRQn);

//使能 UART0 时钟
SYSCON->SYSAHBCLKCTRL_b.UART0_CLK=1; //enable UART0 PCLK
SYSCON->UART0CLKDIV_b.DIV = 0x1;      /* divided by 1 */

//复位 UART0
SYSCON->PRESETCTRL_b.UART0_RST_N=0;
SYSCON->PRESETCTRL_b.UART0_RST_N=1;
}
  else if (uart==UART1)
{
//初始化时关闭UART1 IRQ
NVIC_DisableIRQ(UART1_IRQn);

//使能 UART1 时钟
SYSCON->SYSAHBCLKCTRL_b.UART1_CLK=1; //enable UART1 PCLK
SYSCON->UART1CLKDIV_b.DIV = 0x1;      /* divided by 1 */

//复位 UART1
SYSCON->PRESETCTRL_b.UART1_RST_N=0;
SYSCON->PRESETCTRL_b.UART1_RST_N=1;
}
  else return ;

  //设置波特率
  uart->BAUDDIV_b.BAUDDIV = MainClock/baudrate;

//设置奇偶校验
if (parityoption==UART_ODD_PARITY)
uart->CTRL_b.PARISEL=1;

if (parityoption!=UART_NO_PARITY)
uart->CTRL_b.PARIEN=1;

//设置中断触发条件
if (rxinttriggerlevel==UART_RX_NOT_EMPTY)
uart->CTRL_b.RXNEIE=1;

if (rxinttriggerlevel==UART_RX_HALF_FULL)
uart->CTRL_b.RXHLFIE=1;

if (rxinttriggerlevel==UART_RX_FULL)
uart->CTRL_b.RXFIE=1;

//使能发送和接收功能
  uart->CTRL_b.TXEN=1;
uart->CTRL_b.RXEN=1;

//插入延时
SYS_DelaymS(1);

//清空 FIFO
uart->FIFOCLR=0xFF;
  return;
}

3-2 UART关闭

这段函数用来关闭UART0或者UART1,只需要传入需要关闭的串口即可。

    void UART_Close(UART0_Type *uart)
{
if (uart==UART0)
{
//关闭UART0_IRQ
NVIC_DisableIRQ(UART0_IRQn);

//关闭UART0时钟
SYSCON->SYSAHBCLKCTRL_b.UART0_CLK=0;

}else if (uart==UART1)
{

//关闭UART1_IRQ
NVIC_DisableIRQ(UART1_IRQn);

//关闭UART1时钟
SYSCON->SYSAHBCLKCTRL_b.UART1_CLK=0;
}
  else return ;

//关闭相应UART的中断,并清除中断标志
UART_DisableInt(uart);
UART_ClearIntFlag(uart);
return;
}

3-3 UART读取单个字节

这段函数的作用是UART读取单个字节的数据。

    uint8_t UART_ByteRead(UART0_Type *uart, uint8_t *data)
{
if (uart->STATE_b.RXNE)
{
*data=uart->DATA;
return 0;
}
  else
return 1;
}

3-4 UART连续读取多个字节

UART连续读取串口数据,直到读取到指定长度的数据。

    void UART_Read(UART0_Type *uart, uint8_t * rxbuf, uint8_t *readbytes)
{
uint8_t temp=0;

//get all data
while ((uart->STATE_b.RXNE)&&((*readbytes)--))
{
*rxbuf++=uart->DATA;
temp++;
}

//return number of read
*readbytes=temp;
return;
}

3-5 UART发送单个字节

这段函数的作用是UART发送单个字节的数据。

     uint8_t UART_ByteWrite(UART0_Type *uart, uint8_t data)
{
if (uart->STATE_b.TXF)
return 1;

uart->DATA=data;
return 0;
}

3-6 UART连续发送多个字节

UART连续发送串口数据,直到发送完指定长度的数据。

    void UART_Send(UART0_Type *uart, uint8_t * txbuf, uint32_t sendbytes)
{
while (sendbytes--)
{
while (uart->STATE_b.TXF);
uart->DATA=*txbuf++;
}
return;
}

3-7 UART发送字符串

UART发送一段字符串数据,只需要将要发送的字符串数据首地址传入即可。

    void UART_PutString (UART0_Type *uart, uint8_t * str)
{
while (!(* str=='\0'))
{
while (uart->STATE_b.TXF);
uart->DATA=*str++;
}
return;
}

3-8 UART使能中断

有两个参数项,第一个是选择需要使能的UART,第二个选择触发中断的条件。

    void UART_EnableInt(UART0_Type *uart, uint32_t intcon)
{
uart->CTRL |= intcon;
return;
}

3-9 UART关闭中断

调用该函数后,所有的串口的中断触发条件都将关闭。

    void UART_DisableInt(UART0_Type *uart)
{
uart->CTRL &= 0xFFFFFF00;
return;
}

4、串口中断例程

介绍完UART常用的驱动函数,接下来用个小例程来演示下UART的驱动。测试程序的功能是:通过串口助手发送一个字节的数据到单片机,单片机收到该数据后,将该数据通过单片机的串口发送到串口助手。

程序设计思路

首先是对UART0端口的初始化,将IO口复用为串口UART0的TX、RX功能。

随后将UART0初始化为波特率115200,无奇偶校验,接收非空触发中断。

下一步就是使能UART0的中断,中断触发条件为接收FIFO非空。

最后使能UART0_IRQn中断服务子程序。

测试程序的代码如下:

int main(void)
{
//UART0 端口初始化
PA_2_INIT(PA_2_TX0);
PA_3_INIT(PA_3_RX0);

//UART0 寄存器初始化
UART_Open(UART0,115200,UART_NO_PARITY,UART_RX_NOT_EMPTY);
UART_EnableInt(UART0,UART_RX_NOT_EMPTY);
NVIC_EnableIRQ(UART0_IRQn);
while(1)
{
}
}

//UART0 中断服务子程序
void UART0_IRQHandler(void)
{
uint8_t cdata; 

//判断中断状态位
if (UART0->INTSTATUS_b.RXNEINT )
{
cdata = UART0->DATA; //将接收到的数据返回
UART0->DATA=cdata;
}

//清除中断状态
UART0->INTSTATUS = 0x0F;
}

程序调试

编写完程序,首先要在编译环境下进行编译、连接。没有错误后(最好连警告也没有)。就可以实际连接到电路板进行程序调试运行了。

在实验前需要先确定U转串所使用的的串口号,通过windows的设备管理器中的端口(COM和LPT)查看我们的串口,比如本例中是COM7。

9.png

图8 串口端口号选择

接下来打开串口上位机工具,本例使用的是“大傻串口工具”。按照程序中设置的串口参数配置好串口。端口选择COM7,波特率115200,数据位8位,无奇偶校验,1位停止位。最后点击打开串口即可。打开后如图所示:

10.png

图9 串口配置

上位机环境配置好之后,接下里就可以下载并仿真程序了。首先我们在UART0_IRQ中断子程序中位置打上断点。随后全速运行程序。

11.png

图10 仿真界面

然后我们在上位机发送一个数据进行测试,例如发送一个字节0x11。这时候单片机便会进入串口中断服务程序,并且停止在断点处。这时候我们听过watch窗口看到接收的数据,就是0x11。

12.png

图11 数据发送

继续单步运行并退出中断服务程序,这时候我们再去看上位机,发现收到了单片机返回的数据。

13.png

图12 数据接收

来源:敏矽MCU

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

围观 124

相关文章:

敏矽微电子Cortex-M0学习笔记01——芯片简介

敏矽微电子Cortex-M0学习笔记02——Cortex-M0开发环境的建立及调试

敏矽微电子Cortex-M0学习笔记03——时钟系统设计例程

敏矽微电子Cortex-M0学习笔记04——GPIO详解及应用实例

敏矽微电子Cortex-M0学习笔记05——端口外部中断实例

1、LCD显示驱动概述

在上一章节GPIO中断的学习中,我们通过LCD液晶来显示中断的发生次数,很直观的知道了程序的运行情况,但这也只是LCD的一个小应用。在以后的学习和开发中,LCD作为显示单元,会愈发显示出它的重要性。那么接下来就开始介绍ME32F030的LCD驱动。学习前先对其做个简单的概述。

ME32F030的LCD 显示驱动通过自动地创建交流段和公共电压信号来直接驱动 LCD。它可以支持静态,1/2,1/3,1/4,1/5 和 1/6 占空比 的 LCD 面板。.最多可以支持 6 个公共电压端和 16 个段组合(共计 96)的 LCD 显示面板。

主要特征有:

• 多达 96 个点(6x16)

• 可配置公共电压信号(Common) 0-5

• 可配置段电压信号(Segment) 0-16

• 支持静态,1/2 偏压和 1/3 偏压电压

• 六种显示模式:静态,1/2 占空比,1/3 占空比,1/4 占空比,1/5 占空比或 1/6 占空比

• 可配置的帧频率

• 在数字模式下,支持 8 个 7 段 LED

其对应的复用管脚映射图如下:

1.png

图1 LCD寄存器0

2、LCD驱动寄存器

液晶显示的驱动还是比较饶的,因此肯定会有专门的LCD驱动寄存器,来辅助完成LCD液晶的驱动工作。ME32F030的LCD液晶驱动寄存器总览如图所示:

2.png

图2 LCD寄存器0

2-1 LCD控制寄存器0

查看LCD控制寄存器的列表,获知LCD驱动是支持 LCD 输出和 LED 输出两种工作模式的。因此要根据自己的实际情况使能相应的功能。这里需要注意的是,在 LED 模式下,LEDINV位决定着共阴极/共阳极显示,一定要根据实际电路进行选择。

3.png3-1.png

图3 LCD寄存器0

2-2 LCD控制寄存器1

在使能了相应的驱动工作方式后,就需要对控制模式以及输出参数进行设置。有LCD显示占空比选择、偏压选择、扫描周期频率需要配置。

4.png

图4 LCD控制寄存器1

2-3 数据映射寄存器

需要让LCD显示期望的数据时,只要向数据映射寄存器0~3写入相应的值即可。随后就会按预先设定自动输出到相应的 LCD 管脚上。

2-4 LCD驱动使能控制器0

该寄存器决定着LCD COM0~5的输出控制,相应的BIT位置1来使能对应的COM。

5.png

图5 LCD使能寄存器0

2-5 LCD驱动使能控制器1

该寄存器决定着LCD Segment0~16的输出控制,相应的BIT位置1来使能对应的 Segment。

6.png

图6 LCD使能寄存器1

3、LCD驱动函数

在例程LIB->common->Drivers->Source文件夹内有lcd.c文件,这个就是提供的LCD驱动文件,里面包含了一些基本的驱动函数,使用起来十分方便。下面会对每个函数进行讲解。

3-1 LCD初始化

在每段源代码的后面,笔者对其进行一下注释,方便大家快速掌握和使用这个函数。这个函数的4个参数的意义如下:

Mode:LCD的输出模式,可选LCD_MODE、LED_MODE。

Duty:显示占空比,可选DUTY_1 ~ DUTY_8.

Biasanod:LCD输出模式下代表偏置电压,可选LCD_BIAS_3(1/3偏压)、LCD_BIAS_2(1/2偏压)。LED输出模式下代表共正极/共负极选择。

Finhz:COM扫描周期频率,手册推荐80-100Hz。

    void LCD_Init (uint8_t mode,uint8_t duty, uint8_t biasanode, uint8_t finhz)
{
SYSCON->SYSAHBCLKCTRL_b.LCD_CLK=1;  //LCD时钟使能
SYSCON->PRESETCTRL_b.LCD_RST_N=0;   //LCD复位操作
SYSCON->PRESETCTRL_b.LCD_RST_N=1;
//disable output

LCD->LCDOUTEN0=0;  //LCD COM口初始化(禁止输出)
LCD->LCDOUTEN1=0;  //LCD SEG口初始化(禁止输出)
//set duty

LCD->LCDCTRL1_b.DUTY=duty;  //LCD 显示占空比
if ((finhz>0)&&(duty>0))
LCD->LCDCTRL1_b.FREQDIV=SystemCoreClock/(duty*finhz); //LCD COM扫描周期频率

if (mode==LCD_MODE)
{
SYSCON->PDRUNCFG_b.LCD_PD=0;     //LCD 电压发生器上电
LCD->LCDCTRL1_b.BIAS=biasanode;  //偏置电压选择
LCD->LCDCTRL0_b.LCDEN=1;         //选择为 LCD输出模式
LCD->LCDCTRL0_b.LEDEN=0;         
}
  else if (mode==LED_MODE)
{
SYSCON->PDRUNCFG_b.LCD_PD=1;     //LCD 电压发生器掉电
LCD->LCDCTRL0_b.LEDINV=biasanode;//LED共正极/共负极选择
LCD->LCDCTRL0_b.LEDEN=1;         //选择为 LED输出模式
LCD->LCDCTRL0_b.LCDEN=0;
}
return;
}

3-2 LCD输出使能

这段函数控制着LCD的COM端口和SEGMEN端口的输出使能,可以根据实际需求来进行配置。比如开发板使用了COM0~COM3,SEG0~SEG7。因此comchannel参数的低4位都是置1的,即输入参数应该为0xF。同理,segchannel的低8位都是置1的,即输入参数应该为0xFF。

    void LCD_EnableOutput(uint8_t comchannel, uint16_t segchannel)
{
LCD->LCDOUTEN0_b.LCDCOMEN=comchannel;
LCD->LCDOUTEN1_b.LCDSEGEN=segchannel;
return;
}

3-3 LCD功能关闭

这段函数的作用是关闭LCD外设功能,通过LCD电压发生器,并且关闭其时钟。

    void LCD_Deinit(void)
{
SYSCON->PDRUNCFG_b.LCD_PD=1;       //LCD 电压发生器掉电
SYSCON->SYSAHBCLKCTRL_b.LCD_CLK=0; //LCD 时钟关闭
return;
}

3-4 LCD全显

这段函数的功能是数据映射寄存器全部置位,从而全部显示。

    void LCD_LightFullScreen(void)
{
LCD->MEMMAP0=0xFFFFFFFF;
LCD->MEMMAP1=0xFFFFFFFF;
LCD->MEMMAP2=0xFFFFFFFF;
LCD->MEMMAP3=0xFFFFFFFF;
return;
}

3-5 LCD清屏

这段函数的功能是数据映射寄存器全部清0,从而快速清屏。

    void LCD_ClearScreen(void)
{
LCD->MEMMAP0=0;
LCD->MEMMAP1=0;
LCD->MEMMAP2=0;
LCD->MEMMAP3=0;
return;
}

4、端口中断例程

介绍完LCD常用的驱动函数,接下来用个小例程来演示LCD的驱动。测试程序的代码如下:

    void lcd_PortInit(void)
{
//initial LCD pin
PB_2_INIT  (PB_2_LCD_COM0  );//LCD_COM0:PB_2
PB_10_INIT (PB_10_LCD_COM1 );//LCD_COM1:PB_10
PB_11_INIT (PB_11_LCD_COM2 );//LCD_COM2:PB_11
PB_6_INIT  (PB_6_LCD_COM3  );//LCD_COM3:PB_6 

PB_12_INIT (PB_12_LCD_SEG0 );//LCD_SEG0:PB_12
PB_13_INIT (PB_13_LCD_SEG1 );//LCD_SEG1:PB_13
PB_14_INIT (PB_14_LCD_SEG2 );//LCD_SEG2:PB_14
PB_15_INIT (PB_15_LCD_SEG3 );//LCD_SEG3:PB_15
PA_8_INIT  (PA_8_LCD_SEG4  );//LCD_SEG4:PA_8
PA_9_INIT  (PA_9_LCD_SEG5  );//LCD_SEG5:PA_9
PA_10_INIT (PA_10_LCD_SEG6 );//LCD_SEG6:PA_10
PA_11_INIT (PA_11_LCD_SEG7 );//LCD_SEG7:PA_11
} 

int main(void)
{
uint32_t number = 0;
uint32_t lcd[10]={0xD07,0x500,0xB05,0xF01,0x702,0xE03,0xE07,0x501,0xF07,0x703};//0~9 LCD真值表

lcd_PortInit();//LCD端口初始化
LCD_Init(LCD_MODE, DUTY_4, LCD_BIAS_3, 100);//LCD 驱动初始化
LCD_EnableOutput(0xF, 0xFF);//使能LCD输出

while(1)
{
LCD->MEMMAP0 = (lcd[number]<<16)|lcd[number];
LCD->MEMMAP1 = (lcd[number]<<16)|lcd[number];
if (number++==11)
number=0;
SYS_DelaymS(1000);
}
}

程序第一步先执行lcd_PortInit函数来复用LCD端口。端口复用完成后就是LCD_Init函数,这个在前面讲解过。我们选择的是LCD输出模式,1/4占空比输出,1/3偏压,100Hz的COM刷新率。完成初始化的配置后,就可以使能LCD的输出了。

测试用的显示程序是让液晶在0~9之间不停的循环显示。效果图如下:

全0显示:

7.png

图7 LCD显示全0

全9显示:

8.png

图8 LCD显示全9

来源:敏矽MCU

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

围观 36

相关文章:

敏矽微电子Cortex-M0学习笔记01——芯片简介

敏矽微电子Cortex-M0学习笔记02——Cortex-M0开发环境的建立及调试

敏矽微电子Cortex-M0学习笔记03——时钟系统设计例程

敏矽微电子Cortex-M0学习笔记04——GPIO详解及应用实例

1、目的

本篇学习笔记我们主要来了解ME32F030的中断系统,首先通过对ME32F030终端系统和中断控制存器进行学习,最后通过实际的GPIO端口中断实例掌握中断函数的编程实现来加深掌握ME32F030中断系统的编程方法。

2、ME32F030中断概述

中断是单片机系统重要的组成部分,使单片机能够快速的对事件请求做出响应。ME32F030靠内部的嵌套向量中断控制器(NVIC)来进行中断的调度,它是 Cortex™-M0 内核的一部分。它可以让 CPU 以最短的时间对中断作出反应。主要的特征有:

• 较短的中断响应延迟.

• 处理系统异常和外设中断.

• 支持 32 个中断向量.

• 四种可编程的中断响应优先级别.

• 产生软件中断.

• 可配置的不可屏蔽中断源会有详细的说明。

3、ME32F030嵌套向量中断控制器(NVIC)

嵌套向量中断控制器(NVIC)负责着整个MCU的中断管理,除了管理我们常用的外设中断源,还包括非屏蔽中断源的管理。具体管理的中断源及其中断序号,其实在CMSDK_CM0.h中定义好了,通过程序定义对具体管理的中断源一目了然,定义的内容如下图所示。

1.png

中断源

ME32F030的中断系统是由一系列的NVIC寄存器组成的,这些寄存器可用于中断 IRQ0~IRQ31, 包括中断使能,等待和优先级等操作。如果中断被允许,并且相应中断挂起被设置,NVIC 将会根据中断优先级触发中断。反之,中断被禁止,中断源只会改变中断挂起状态,而 NVIC 不会对中断源信号采取任何动作,不论任何中断优先级。具体的NVIC寄存器组如表格所示:

2.png

NVIC寄存器列表

2-1 中断允许寄存器

中断允许寄存器(ISER)用于使能中断设置,同时可返回当前允许中断设置。需要注意的是,对该寄存器写0是无效的,是不能禁止中断的。要禁止中断,就需要下面介绍的中断禁止寄存器。

2-2 中断禁止寄存器

有使能中断的设置,相应的就会有禁止中断设置,这就是中断禁止寄存器的作用。对寄存器进行写1操作,就可以禁止中断设置。。需要注意的是,对该寄存器写0是无效的。对寄存器进行读操作,同返回当前禁止中断设置。

2-3 中断挂起寄存器

当有中断事件发生时,中断挂起寄存器(ISPR)中对应的中断位就会置位 。此时读取寄存器就可以判断具体的中断源。同时我们也可以向寄存器的中断位写1,来强制中断进入挂起状态。

2-4 清除中断挂起寄存器

当MCU响应了中断请求,并且执行完对应的中断子程序后,MCU便会返回断点处继续运行。但在返回前需要通过清除中断挂起寄存器(ICPR),来清除对应的中断挂起,这样当次的中断流程算是完整结束。

2-5 中断优先级寄存器

如同我们做事情有轻重缓急之分,单片机对中断的处理也有“轻重缓急”。具体就是靠8组中断优先级寄存器IPR0~7来实现。每组寄存器对应4个中断源的优先级。这样刚好决定了中断0~中断31的优先级。

每一组的中断优先级寄存器IPRn的每个字节最高两位决定优先级,因此有0~3共4个优先级可以选择,越低的值表示优先级越高,当优先级更高的中断发生时,高优先级的中断会打断低优先级中断。如果是同优先级中断,则并不会打断当前中断,而是依次响应中断。中断优先级寄存器IPRn如图所示:

3.png

这里介绍个快速的方法来计算中断 M 的 IPR 寄存器号:

• 计算对应的 IPR 寄存器号, N, N = M / 4

• 计算 IPR 寄存器内的字节偏移量 M % 4, 其中:

– 字节偏移量 0 对应寄存器的位 7:0

– 字节偏移量 1 对应寄存器的位 15:8

– 字节偏移量 2 对应寄存器的位 23:16

– 字节偏移量 3 对应寄存器的位 31:24

4、ME32F030端口中断例程

本篇中我们首先讲解了ME32F030的GPIO中断系统,然后又介绍了嵌套向量中断控制器(NVIC)的原理。

最后,我们还是要通过具体的实例来把我们学到的理论知识应用到实际的例子中。我们将两者结合起来做个小实验,测试程序的代码如下:

    unsigned int uiCnt = 0;//端口反转次数

int main(void)
{
	PA->DIR_b.DIR0 = 1;       //PA_0 设置为输出口

	PA->IS_b.ISENSE0 = 0;    //PA_0 设置为沿触发

	PA->IBE_b.IBE0 = 1;       //PA_0 上升沿和下降沿都触发中断

	PA->IC_b.CLR0 =1 ;        //PA_0 中断标志位清除

	PA->IE_b.MASK0 = 1;      //PA_0 中断使能
 
	PB->DIR_b.DIR9=1;        //PB_9 设置为输出口

NVIC_EnableIRQ(PA_IRQn); //使能PA_IRQ中断

lcd_init();                 //LCD液晶初始化
 
while (1)
{

	uiCnt++;               //端口反转次数加1

	PA->NOT_b.NOT0=1;    //PA_0 输出取反

	SYS_DelaymS(500);

	if(uiCnt == 20)           //当反转20次时
		{
			PA->IE_b.MASK0 = 0;  //PA_0 中断关闭
		}
  }
}

//PA_IRQ中断子程序
void PA_IRQHandler(void)  
{
PB->NOT_b.NOT9=1;    //PB_9(LED灯)输出取反

  PA->IC_b.CLR0 =1 ;     //清除PA_0中断位

//LCD显示中断发生的次数
  LCD->MEMMAP1 = lcd[uiCnt/10] | (lcd[uiCnt%10]<<16);
}

测试程序是通过PA_0端口输出反转,来产生下降沿和上升沿。但同时它的端口中断功能是被使能的,因此可以通过输出电平来“触发”自己的中断。在中断服务子程序中,LED小灯端口输出取反来进行点亮和熄灭,同时加入了LCD段码液晶来显示中断发生的次数。在程序全速运行的过程中,当端口输出反转20次之后,会关闭端口的中断功能。接下来下载并仿真例程来进行说明。

程序下载并仿真后,先在程序这两处打上断点。然后用快捷键F5全速运行,程序首先会运行到第78行处的断点,这时端口还没有进行输出反转。接下来用快捷键F10单步运行观察。

4.png

仿真1

F10单步运行后,发现程序已经跳转到了PA_IRQ中断服务子程序中,继续F10单步运行并观察执行每一步的现象,直到把中断服务子程序走完。

5.png

仿真2

中断服务子程序内的代码全部运行后的效果如图所示,首先LED小灯的端口输出取反,把LED小灯给点亮后(下次再进中断会输出取反熄灭,依次往复)。LCD段码液晶显示01,这说明发生了1次中断。

6.png

仿真结果

通过单步仿真我们清楚了中断发生后的处理流程,接下来就可以把之前打的两个断点取消掉,然后在83行的位置打上一个断点,随后F5全速运行程序,等待程序停到断点处。在等待的过程中,LED小灯保持闪烁,LCD段码液晶上的数字一直在自加。当程序停到断点处后,LCD段码液晶显示为20。继续单步运行后,端口PA_0的中断功能就被关闭了。

7.png

仿真3

关闭中断后,再次全速运行程序。我们发现小灯不再闪烁了,段码液晶显示的数字也不再自加。这是因为我们已经把端口中断关闭掉了,虽然uiCnt还在自加。但是已经进不了中断子程序去更新显示。因此依旧停留显示在20。我们不妨把uiCnt添加到Watch窗口中来看一下,添加方法如图所示。双击ucCnt变量名,选中后右键选择“Add uiCnt to”,“Watch 1”,这样就添加到Watch1窗口中了。

8.png

仿真4

通过Watch1窗口看到端口已经反转37次了,但LCD液晶已经停留在20。这也说明中断确实被关闭了,因此液晶一直没能更新显示。

9.png

仿真5

10.png

仿真结果2

来源:敏矽MCU

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

围观 39

相关文章:

敏矽微电子Cortex-M0学习笔记01——芯片简介

敏矽微电子Cortex-M0学习笔记02——Cortex-M0开发环境的建立及调试

敏矽微电子Cortex-M0学习笔记03——时钟系统设计例程

前面我们已经对敏矽微电子的基于cortex m0内核的ME32F030R8T6的基本功能做了介绍,然后详细讲解了开发环境MDK的安装,pack包的安装,工程的建立及程序的仿真,紧接着讲解了ME32F030R8T6的时钟系统。

如果说前面都是基础知识介绍和理论讲解,那么从本篇开始,我们不但会有理论介绍,还会结合敏矽微电子提供的ME32F030R8T6开发板进行实例验证,让大家看到实例运行的结果。

1、敏矽微电子Cortex-M0学习笔记04-GPIO详解及实例

首先我们对ME32F030R8T6芯片的I/O端口做一个大致的了解。

1.1. ME32F030R8T6的GPIO 概述

ME32F030R8T6提供多达 57个 GPIO 管脚。主要的特点有:

• 数字管脚可以用软件定义为输入或输出

• 管脚读写可以被屏蔽

• 多个管脚的置位、清零位用一条指令实现

• 管脚的输出取反

• 每一个管脚可作为外部中断信号

• 可编程的中断触发条件及中断优先级

• 所有GPIO管脚在复位后被配置成带上拉电阻的输入管脚

MCU的端口除了灵活易用的特点之外,其外设功能也十分强大。管脚功能由IO控制寄存器配置,除电源管脚,其余管脚均可复用。

系统复位后,管脚功能将被设置成默认值。

GPIO可以复用的功能如下:LED/LCD 驱动、触摸按键、ADC、定时器6输出、定时器7输出、PWM输出、UART0、UART1、SPI、I2C。

在使用端口复用功能时,通过 I/O 配置寄存器IOCON对端口进行功能设置,每个引脚对应的复用功能,请参照官方数据手册的详细说明。

1.2. ME32F030R8T6的GPIO 寄存器详解

对于使用过单片机开发产品的人来说,功能繁多、名称各异的寄存器应该是最重要也是最令人头疼的地方,但是没办法,想要开发出功能稳定、性能可靠的产品,就必须来硬着头皮查看各个寄存器的功能和配置方法。

当然,对于ME32F030R8T6来说,官方推出了库函数,利用这些库函数可以不必关心具体的寄存器就能编写出合适的程序。但是对于想要深入了解的话,还是要看看寄存器的。

1.2.1. GPIO功能配置寄存器

MCU有一系列的GPIO 控制寄存器来实现对I/O口的灵活控制。

首先我们对 I/O 配置寄存器IOCON做一个介绍,因为它决定着I/O端口的功能选择和电气特性。所以需要拿出来单独进行介绍,该寄存器的每一位的功能如下:

1.png

2.png

①、管脚功能:

IOCON 寄存器中的 FUNC 位可设为 GPIO (FUNC = 000) 或外设功能。如果将管脚配置为 GPIO 管脚,则 DIR 寄存器决定管脚是配置为输入还是输出。对于任何外设功能,会根据管脚的功能自动控制管脚方向。GPIO 的 DIR 寄存器此时对外设功能无效。

②、管脚模式:

IOCON 寄存器的 MODE 位允许为每个管脚使能或禁止片内上拉电阻。默认情况下,所有管脚的上拉电阻都被使能。

③、管脚驱动

对于每个正常驱动管脚,可以选择两种电流的输出驱动,即低电流模式和高电流模式。用户可以根据自己的实际需求进行选择。

④、开漏模式

所有数字 I/O 管脚都可为开漏模式。但是请注意,该模式并不是真正的开漏模式。输入上拉至不能超过VDD。

⑤、模式功能

I/O 管脚可以配置为模拟功能,作为模拟信号的输出和输入管脚,例如复用为AD口的时候,可以作为检测电压的模拟信号输入口。

⑤、电压转换速率模式

在作用AD转换口的时候,可以设置端口转换速率为快速模式或慢速模式,默认为快速模式。相对于快速模式,慢速模式转满时间会变长,随之电流功耗也增大,但时精度会更加精确,根据应用场景和自身需求,选择适合的模式。

1.2.2. GPIO控制寄存器总览

MCU所有的GPIO被分布到4个端口: PA,、PB、PC、PD。每个端口都拥有自己独立的控制寄存器去管理 GPIO 的功能。下面的表列出了所有的寄存器以供参考。接下来会对每个寄存器做出详解。

3.png

4.png

1.2.3. GPIO屏蔽寄存器

GPIO屏蔽寄存器可屏蔽下列寄存器的读和写操作:PIN、OUT、SET、CLR和 NOT,相当于给这些寄存器上了个“锁”,只有当MASK寄存器相应的BIT位被置 0,被屏蔽的寄存器才能进行读和写操作。该寄存器上电后默认为0,即不进行GPIO屏蔽。当配置1启动屏蔽功能后,对处于输出功能的端口进行任何写操作都无效,不会改变其当前的输出状态。对处于输入功能的端口进行读操作,无论此时端口处于何种电平,都会返回0.

1.2.4. GPIO管脚值寄存器

对配置为数字功能的端口,对该寄存器进行读操作将返回管脚的当前逻辑值,不管该管脚是配置为输入还是输出,也不管它是配置为 GPIO 还是任何其它适用的备用数字功能,都可以直接进行读取。但也有例外,在以下两种情况中, PIN 寄存器中读出的管脚值无效:①、如果选择了管脚的模拟功能(如适用),则不能读取管脚状态,例如将管脚选作 ADC 输入会断开管脚的数字功能。②、该引脚被GPIO屏蔽寄存器MASK给屏蔽了。

1.2.5. GPIO管脚输出寄存器

在没有被GPIO屏蔽寄存器MASK屏蔽的情况下,向该寄存器写0或1将在相应端口管脚产生低电平或高电平。但是对于所有其他配置(输入、非GPIO功能),OUT 寄存器位的值对管脚输出电平无效。读取该寄存器将返回 GPIO 输出寄存器的内容,不管数字管脚配置和方向如何。

通过SET、CLR和NOT寄存器可以对OUT 寄存器执行写操作,允许按位对单个端口管脚进行置位、清除、取反操作。以此来控制OUT 寄存器的输出内容。

1.2.6. GPIO管脚输出置位寄存器

在没有被GPIO屏蔽寄存器MASK屏蔽,端口DIR为输出方向且端口功能为数字GPIO功能的情况下,写1会将相应端口管脚设为高电平。写0对GPIO输出电平无效。另外该寄存器为只写寄存器,对其进行读操作是无效的。

1.2.7. GPIO管脚输出清除寄存器

在没有被GPIO屏蔽寄存器MASK屏蔽,端口DIR为输出方向且端口功能为数字GPIO功能的情况下,写1会将相应端口管脚设为低电平。写0对GPIO输出电平无效。另外该寄存器为只写寄存器,对其进行读操作是无效的。

1.2.8. GPIO管脚输出取反寄存器

在没有被GPIO屏蔽寄存器MASK屏蔽,端口DIR为输出方向且端口功能为数字GPIO功能的情况下,写1会将相应端口的输出状态进行反转。写0对GPIO输出电平无效。另外该寄存器为只写寄存器,对其进行读操作是无效的。

1.2.9. GPIO数据方向寄存器

在使用数字GPIO前,首先要确定的就是端口的数据方向。向该寄存器写1会将端口设置为输出模式,写0设置为输入模式。上电后端口默认为输入状态。

1.2.10. GPIO中断感应寄存器

在文章开头的介绍中,我们就说过MCU的每一个管脚是可以作为外部中断信号。因此会有一系列与之对应的中断管理寄存器,来对每个端口的中断进行管理。这就是接下来要介绍的中断寄存器。在使用端口中断前,需要明确需要触发中断的条件。向中断感应寄存器ISENSEx写入1,端口中断的触发方式为电平中断。向寄存器写入0,端口中断的触发方式为沿中断触发,具体需要什么样的沿来触发,这个还需要下面的中断配置寄存器来设置。

1.2.11. GPIO中断配置寄存器

紧接上文,在明确使用端口触发方式为沿中断触发后,我们通过中断配置寄存器IBEx来选择沿触发条件。向寄存器写入1,管脚的上升沿和下降沿都触发中断。向寄存器写入0,管脚只能由上升沿或下降沿中的一种来触发中断,具体由哪种来触发,需要下面的中断事件寄存器IEVx来决定。

1.2.12. GPIO中断事件寄存器

当中断配置寄存器IBEx值为0时,中断事件寄存器就决定着中断触发的条件,向寄存器写1,上升沿触发中断。写入0,则下降沿产生中断。

1.2.13. GPIO中断屏蔽寄存器

在实际的开发过程中,使用到中断功能的端口毕竟是少数,因此MCU在上电后就默认屏蔽了端口的中断功能。如果要开启端口的中断功能,向对应的寄存器位写1即可。

1.2.14. GPIO原始中断状态寄存器

该寄存器的位读出为高时反映了对应管脚上的原始(屏蔽之前)中断状态,表示在触发 IE 之前所有的要求都满足。位读出为0时表示对应的输入管脚还未启动中断。该寄存器为只读。

1.2.15. GPIO中断状态寄存器

该寄存器中的位读为高反映了输入触发中断的状态。读出为低则表示对应的输入管脚没有中断产生,或者中断被屏蔽。读出为高则表示对应的输入管脚有中断产生。该寄存器为只读。

1.2.16. GPIO中断清除寄存器

在中断发生后,程序会进入中断服务子程序。在中断服务子程序中处理完中断程序后,需要向中断清除寄存器CLRx写1来清除中断标志。

1.3. ME32F030R8T6的GPIO 库函数函数

为了便于开发者快速上手,敏矽微电子官方例程中提供了gpio.c文件,其中包含了设置端口方向、读取端口状态、配置端口中断等函数,供开发者直接使用。

1、设置GPIO为输入方向

void GPIO_ConfigPinsAsInput(PA_Type *port, uint16_t pins)

{

    port->DIR &= ~pins;

    return;

}

2、设置GPIO位输出方向

void GPIO_ConfigPinsAsOutput(PA_Type *port, uint16_t pins)

{

    port->DIR|=pins;

    return;

}

3、设置GPIO输出高

void GPIO_SetPin(PA_Type *port, uint16_t pin)

{

    port->SET |= pin;

    return;

}

4、设置GPIO输出低

void GPIO_ResetPin (PA_Type *port, uint16_t pin)

{

    port->CLR |= pin;

    return;

}

5、设置GPIO输出反转

void GPIO_InvertOutPin (PA_Type *port, uint16_t pin)

{

    port->NOT |= pin;

    return;

}

6、读取GPIO某个引脚的输入状态

uint8_t GPIO_GetPinState(PA_Type *port, uint16_t pin)

{

    if (port->PIN & pin)

    return 1;

    else

    return 0;

}

7、读取GPIO整个引脚的输入状态

uint16_t GPIO_GetPortState(PA_Type *port)

{

    return (uint16_t)port->PIN;

}

8、屏蔽GPIO引脚

void GPIO_SetPortMask(PA_Type *port, uint16_t pins)

{

    port->MASK |= pins;

    return;

}

9、使能GPIO引脚

void GPIO_SetPortMask(PA_Type *port, uint16_t pins)

{

    port->MASK |= pins;

    return;

}

10、配置GPIO引脚的中断功能

void GPIO_EnableInt(PA_Type *port, uint16_t pin, uint8_t triggeredge)

{

	port->IS &= ~pin;


        port->IE |= pin;

    	switch(triggeredge)

    	{

    		case RISE_EDGE:
					port->IBE &= ~pin;

					port->IEV |= pin;			break;			case FALL_EDGE:

					port->IBE &= ~pin;

					port->IEV &= ~pin;			break;			case BOTH_EDGE:

					port->IBE |= pin;			break;				default:			break;



    		}

    		return;

}

11、清除GPIO引脚的中断标志

void GPIO_ClrInt(PA_Type *port, uint16_t pins)

{

    	port->IC =pins;

    	return;
}

1.4. ME32F030R8T6的GPIO 开发实例

介绍完GPIO的原理和函数,接下来就用最经典的LED小灯试验来进行示例。

本例使用敏矽微电子专门为ME32F030R8T6提供的库函数编写程序。

实例程序的代码如下:

int main(void

{
	WDT->MOD=0;          //关闭看门狗   

	PB_9_INIT(PB_9_GPIO);          //PB9(LED)设置为GPIO功能

	GPIO_ConfigPinsAsOutput(PB, IO_PIN9);  //PB9(LED)设置为输出方向

	while (1)

	{

		GPIO_InvertOutPin(PB, IO_PIN9);  //PB9(LED)端口输出反转

		SYS_DelaymS(500);                //延时500ms

	}

}

程序下载成功后,先在端口反转这句话处打上一个断点,然后全速运行程序(快捷键F5)。随后程序会停在断点处,

5.png

此时先暂停观察下LED小灯的状态,发现红圈标注的小灯并没有被点亮。

6.png

运行结果1

接下来单步运行程序,观察执行完端口反转这段程序后的状态。这时我们发现小灯已经被点亮了。

7.png


继续单步运行,当再次执行端口反转这段程序后,端口输出就会反转,接下来小灯就会熄灭。最后取消程序中的所有断点,让程序全速运行起来,小灯便开始周期性的闪烁。

来源:敏矽MCU

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

围观 159

相关文章:

敏矽微电子Cortex-M0学习笔记01——芯片简介

敏矽微电子Cortex-M0学习笔记02——Cortex-M0开发环境的建立及调试

1.1. ME32F030R8T6的时钟树

时钟是MCU运行的基础,时钟信号推动单片机内各个部分执行相应的指令。时钟系统就是CPU的脉搏,决定cpu速率,像人的心跳一样 只有有了心跳,人才能做其他的事情,而MCU有了时钟,才能够运行执行指令,才能够做准确、稳定的进行一系列的操作 (例如:串口通信、PWM信号、ADC采样等等),因此时钟的重要性不言而喻。

ME32F030系列 具有非常灵活的时钟控制系统。用户可根据不同应用需求来配置时钟,从而取得最高的性能及优化的能耗管理。下图为 ME32F030R8T6 的时钟系统概要图:

1.png

从图中可以看出,MCU的时钟源有内部高速的IRC_OSC 和 低速的 WDT_OSC 时钟可供选择。

IRC_OSC:它属于高速时钟,可以由内部晶体振荡器控制寄存器(IRCCTRL)配置为 40/48MHz的主频, 缺省值是40MHz 频率,由工厂出厂预设并由引导程序写入。一般作为系统主时钟的时钟源。

WDT_OSC:它属于低速时钟,由看门狗振荡器控制寄存器控制。振荡器包含模拟和数字两部分。振荡器的模拟部分用于产生模拟时钟(Fclkana)。在振荡器数字部分,模拟时钟(Fclkana)输出一个32KHz 频率时钟。然后再被DIVSEL 控制的分频器分频输出到 WDT_CLK,作为看门狗时钟源。

看门狗振荡器输出频率可用下列公式推算:

WDT_CLK = Fclkana/(4 ×DIVSEL) = 8K Hz ~ 250 Hz (标称值)

1.2. ME32F030R8T6时钟源的应用控制

介绍完系统的时钟源,接下来说说时钟源主要运用到了哪些方面。

ME32F030R8T6的外设非常多,但我们实际使用的时候只会用到有限的几个外设,使用任何外设都需要时钟才能启动,但并不是所有的外设都需要系统时钟那么高的频率,为了兼容不同速度的设备,有些高速,有些低速,如果都用高速时钟,势必造成浪费。并且,同一个电路,时钟越快功耗越快,同时抗电磁干扰能力也就越弱,所以较为复杂的MCU都是采用多时钟源的方法来解决这些问题。

WDT_CLK:由看门狗振荡器控制寄存器来选择输入时钟,作为看门狗的工作时钟。

2.png

MAIN_CLK:由MAINCLK_SEL选择输入时钟源,上电默认选择IRC_OSC_CLK作为时钟源,也可以通过置位来选择WDT_OSC_CLK。

3.png

SYSTEM_CLK:由MAINCLK通过AHB 接口时钟分频器寄存器(SYSAHBCLKDIV)分频而来,默认不分频。SYSTEM_CLK时钟供内核、外设和存储器使用。其中外设通过 AHB 接口时钟控制寄存器(SYSAHBCLKCTRL)来控制外设的时钟使能,上电默认外设的时钟都是打开的。

4.png

UART:UART0/1有自己独立的时钟分频器从MAIN_CLK分频后取得UART时钟。

5.png

CLK_OUT:MCU的内部晶振器(IRC_OSC_CLK)、看门狗振荡器(WDT_OSC_CLK),主时钟(MAIN_CLK),系统时钟(SYSTEM_CLK)都可以通过CLK_OUT作为输出时钟。

使用前需要通过 CLKOUT 输出时钟源选择寄存器 (CLKOUTCLKSEL)来确定想要输出的时钟源,再经过 CLKOUT 输出时钟分频器寄存器 (CLKOUTDIV)分频后输出,该寄存器初始值默认为0,即不输出时钟。需要输出的话,设置好分频系数(1-255)便可以输出了。

6.png

7.png

2、ME32F030R8T6的时钟系统函数简介

为了便于开发者快速上手,敏矽微电子为开发者提供了丰富的库函数和开发例程。

借助于库函数,可以不用像普通单片机那样去配置繁多的寄存器,从而加快开发进程。

借助于例程中,可以更深入理解寄存器配置及功能实现。

本例中,我们就借助于敏矽微电子提供的例程来简单介绍它的时钟系统的跨函数。在sys.c文件中,包含了切换系统时钟,配置时钟主频等函数,供开发者直接使用。

1.3. 主频配置函数

①、配置IRC_CLK为40M主频

void SYS_IRCTrimto40M(void){volatile uint32_t i=0xFFFF;if (DIA->IRCTRIM!=0xFFFFFFFF)

{

SYSCON->IRCCTRL=DIA->IRCTRIM;  while(i--==0);

FMC->FLASH_RDCYC =1;

SYSCON->SYSAHBCLKDIV =1;

SystemCoreClockUpdate ();

}return ;

}

②、配置IRC_CLK为48M主频

void SYS_IRCTrimto48M(void){volatile uint32_t i=0xFFFF;if (DIA->IRCTRIM48!=0xFFFFFFFF)

{

SYSCON->IRCCTRL=DIA->IRCTRIM48;while(i--==0);

FMC->FLASH_RDCYC =1;


SYSCON->SYSAHBCLKDIV =1; //core clock to 48M

SystemCoreClockUpdate ();

}

return ;

}

1.4. 时钟源选择函数

③、选择MAIN_CLK的时钟源,可以选择IRC_CLK 或者 WATCHDOG_CLK。

void SYS_SelectMainClkSrc(uint8_t src)


{

 //switch main clk source

 SYSCON->MAINCLKUEN_b.ENA= 1; //disable main clk update

 //switch main clk source to Specifyed source

 if (src==IRC_CLK)
 
 SYSCON->MAINCLKSEL_b.SEL=0;else if (src==WATCHDOG_CLK)

  SYSCON->MAINCLKSEL_b.SEL=2;

 
  SYSCON->MAINCLKUEN_b.ENA=0; //enable main clk update

 SystemCoreClockUpdate ();

 return;

}

④、设置AHB 接口时钟分频器的分频系数,在这里请注意,函数如果检查到当前时钟为IR_CLK且分频系数小于2,这样系统时钟SYSTEM_CLK的主频肯定大于30M, 而FLASH的擦写速度最高支持到30MHz。此时CPU时钟超过Flash的最大读取速度,这就需要插入延迟时钟,延迟时钟由 RDCYC 寄存器控制。

void SYS_SetAHBClkDivider (uint8_t div)

{

 //setup flash access speed if SystemCoreClock is going tomore than 30MHz 

 if ((SYSCON->MAINCLKSEL_b.SEL==0)&&(div<2))  

 FMC->FLASH_RDCYC = 1;                
  
  SYSCON->SYSAHBCLKDIV_b.DIV = div;  //setup ahb clock divider

 SystemCoreClockUpdate ();   //update MainClock and SystemCoreClock

 return;
}

//⑤、设置WDT_CLK的时钟源,可以选择IRC_CLK 或者 WATCHDOG_CLK。

    void SYS_SelectWDTClkSrc(uint8_t src){if (src==IRC_CLK)



    SYSCON->WDTOSCCTRL_b.WDTCLKSRC = 0;

    else if (src==WATCHDOG_CLK)

    SYSCON->WDTOSCCTRL_b.WDTCLKSRC = 1;

 return;

}

//⑥、设置CLK_OUT的时钟源,可以选择IRC_CLK 、SYS_CLK、 WATCHDOG_CLK、MAIN_CLK中的一个。

void SYS_SelectClkOutSrc(uint8_t src)

{switch (src)


{

case IRC_CLK:

src=0;break;case SYS_CLK:

src=1;break;case WATCHDOG_CLK:

src=2;break;case MAIN_CLK:

src=3;break;

 default:return;

    }

    //switch clock

    SYSCON->CLKOUTUEN_b.ENA = 1;

    SYSCON->CLKOUTCLKSEL_b.SEL = src; //select clk out source

    SYSCON->CLKOUTUEN_b.ENA = 0;

     return;

}

//⑦、设置CLK_OUT时钟的输出分频系数。

void SYS_SetClkOutDivider(uint8_t div)

{

SYSCON->CLKOUTDIV_b.DIV = div;

return;}

3、ME32F030R8T6时钟系统例程

上面介绍了sys.c中关于系统时钟的部分函数,下面我们来编写一个关于时钟配置的例程。使大家能够对时钟配置有一个简单的了解。

本例实现的功能是:将AHB 接口时钟进行2分频,IRC时钟切换到48M主频,最后将系统时钟进行分频输出。

int main(void)

{

 SYS_SetAHBClkDivider (2);     // AHB 接口时钟进行2分频

 SYS_IRCTrimto48M(); // IRC时钟切换到48M主频

 SYS_SelectClkOutSrc(SYS_CLK); // 选择SYS_CLK作为OUT_CLK输出时钟 

 SYS_SetClkOutDivider(10); // 对OUT_CLK时钟进行10分频

 SYS_EnableClkOut(); // 使能OUT_CLK输出端口

}

来源:敏矽MCU

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

围观 122

相关文章:敏矽微电子Cortex-M0学习笔记01——芯片简介

本篇先简单介绍MDK的安装流程,然后重点说明如何把敏矽微电的Cortex-M0的PACK包添加到mdk中,这样才能顺利的在MDK环境下开发敏矽微电子Cortex-M0新片。最后用了很大篇幅介绍如何建立工程,工程中各种文件的添加等等。

1、敏矽微电子Cortex-M0的开发环境

敏矽微电子Cortex-M0是基于ARM内核的,所以基于ARM的开发环境都可以用来开发敏矽微电子Cortex-M0的芯片。最常见的两种ARM开发平台是MDK和IAR。我们今天着重介绍MDK环境下如何建立基于敏矽微电子Cortex-M0芯片的项目,以及如何在MDK环境下调试敏矽微电子Cortex-M0芯片。

需要说明的是:MDK软件是需要注册的,强烈建议大家使用正版软件。不过在刚开始学习以及资金有限的情况下,可以使用MDK的评估版本,评估版本的程序容量是32K版本。这个程序容量对于初学来说,是足够用的。

闲话少说,马上开始我们今天的学习之旅。

2、MDK安装

1、首先打开Keil安装包(资料链接中附有MDK 5.28版本安装包),打开后如图1.1所示。

1.png

图1

2、随后点击“Next”,进入后续的安装流程,勾选红圈选项后,点击“Next”下一步。随后会提示MDK的安装路径,强烈建议采用默认路径。如果要自定义安装路径,请保证自定义的安装路径中不要出现任何中文名字!点击“Next”下一步后,输入下姓名、公司、邮箱等信息,随意填写下即可,继续点击“Next”便开始正式安装。期间软件会自动安装仿真器驱动,耐心等待即可。

2.png

3、等到最后出现下面的界面,软件便已安装成功。

3.png

3、MDK注册

1、启动Keil 5,在File选项中选择License Management子选项。

4.png

2、按照提示进行注册即可,请按照官方正版途径注册。

3、如果点击Add LIC提示以下的错误信息,看红色下划线的信息,得知是因为没有在管理员模式下操作,权限不足导致的。这个是Windows管理员模式产生的问题。如果你的注册过程没有此错误提示,可以跳过第7步。解决的办法也很简单,按照步骤4操作即可。

5.png

4、以管理员模式运行Keil 5,鼠标右键Keil 图标,点击“以管理员身份运行”即可。随后重新按照步骤5操作即可。管理员运行方法如图所示:

6.png

5、软件注册完成后,出现“LIC Added Sucessfully”的提示,说明注册成功。

4、安装ME32F030 PACK包

1、KEIL安装完成后,就需要安装芯片支持的PACK包,来让KEIL支持我们的芯片,这里建议安装资料提供的Keil 5版本,因为其对应的PACK包是傻瓜式一键安装,操作十分的方便,找到我们的PACK包双击安装即可。

7.png

2、PACK包安装完成后,我们可以先确认下,看下KEIL是否已经识别并支持我们的芯片,方法如下,首先创建个新工程,选择project->New uVision Project来建立工程。

8.png

3、新建工程时会提示选择芯片类型,从图中看出KEIL已经支持我们的Mesilicon系列芯片。

9.png

5、新建工程

1、选择project->New uVision Project来建立工程。

 10.png

2、选择芯片类型,选择开发板的芯片为Mesilicon->ME32F030 Series->ME32F030C8x6,选择好后,点击“OK”。

11.png

3、出现下面的界面,这个是根据需求自己添加开发组件,不多介绍,直接点取消跳过。

12.png

4、接下来将资料中的Lib2.3 for keil5x例程解压缩出来,其中公用的.c和.h等文件都在common文件夹内,随后开始向工程中添加.c和.h文件。点击如图所示的快捷按钮。

13.png


5、弹出如下界面,在Groups右边有4个按钮,依次为“新建”、“删除”、“上移”、“下移”功能,先选择新建comm、app两个组,你也可以尝试下删除组,把初始自带的Source Group通过红叉按钮删除掉。

14.png

向每个Group中添加.程序c文件。那就先举个简单的例子作为开始,首先我们选中需要添加程序的组,比如我们向app组里添加需要的main.c文件,选中app组后,点击右侧的Files框体下的Add Files,选中要添加的main.c文件。点击Add便完成添加。

15.png

添加成功后的效果如下图所示,右侧的Files中已包含main.c文件,那么想要删除的话,可以在选中文件后,通过点击上方的红叉进行删除。

16.png

依次类推,我们接下来要向comm中添加.c文件。

①、添加core_cm0.c,这个就是我们的单片机的M0内核文件,它在

Lib2.3 for keil 5->common->CoreSupport文件夹中。

17.png

②、添加system_CMSDK.c,它在Lib2.3 for keil 5->common->DeviceSupport->arm->cmsdk文件夹中。

18.png

③、添加startup_CMSDK_CM0.s文件,这个是启动程序文件,它是由汇编语言写成的。是以.s为结尾的文件,所以在添加它的时候需要注意将文件类型选择为All Files才能看见它。

Lib2.3 for keil 5->common->DeviceSupport->arm->cmsdk->Startup->arm文件夹中。

19.png

20.png

④、前面添加都属于单片机的系统文件,接下来就要开始添加我们自己的.c文件了,这个都在Lib2.3 for keil 5->common->Drivers->Source文件夹内。

21.png

⑤、第一次新建工程时可以参照现有的例程,比如以Demo-Touch Me按键触摸试验为模板,尝试建立一下工程。添加自己所需要的文件,如图所示:

22.png

6、添加完成后,关闭Manage Project Items功能栏。返回KEIL主界面后,在左侧的Project工程栏里,可以看到之前添加的所有程序文件。

23.png

7、接下来我们是不是可以编译程序了呢?那不妨先试一下。编译后发现提示很多此类的报错,提示 cannot open source input file "gpio.h": No such file or directory,这是因为我们只添加了.c文件,而需要的头文件路径还没有指定位置。那么接下来就指定头文件路径。

24.png

点击红圈标注的Options快捷按钮,也可以通过快捷键ALT + F7来打开。

25.png

打开后选中C/C++选项卡,在下面可以看到Include Paths栏,这个就是需要指定的头文件路径,点击右边的 。。。按钮来进行添加。

26.png

点击。。。按钮后,通过弹出的对话框来添加头文件路径。同上文讲到的一样,红圈的四个按钮依次为“新建”、“删除”、“上移”、“下移”功能。

27.png

那就新建路径吧,点击新建后会生成一个新的路径框,点击红圈标识的。。。来添加。

28.png

以core_cm0.c文件对应的头文件core_cm0.h为例子,一路进到上文中添加core_cm0.c的文件夹中,进入如图所示的路径后,点击选择文件夹。

29.png

添加完成后,刚才新添加的路径便显示出来了。

30.png

依次类推,再添加以下3个路径。

Lib2.3 for keil 5->common->DeviceSupport->arm->cmsdk

Lib2.3 for keil 5->common->Drivers->Include

Lib2.3 for keil 5->Demo-Touch Me->myapp->include

这里添加的时候要注意,是要选择.h文件所在的那个文件夹,错选成它的上级或下级文件夹,是无法找到需要的头文件的!添加完成后的效果如下。

31.png

这时候我们再去编译一下试试。没有报错也没有警告,说明项目工程顺利建立。

32.png

6、下载与调试

1、程序编译没问题后,接下来就可以下载程序并仿真测试了。在开始前先插上仿真器并连接开发板,打开Options for Target选项卡,选中Debug。这个时候选择仿真器类型(根据实际进行选择,建议买一个U-LINK2仿真器),勾选上Run to main,这样程序下载后直接运行到main函数,否则会先运行startup_CMSDK_M0.s中Reset_Handler程序。虽然这段程序最后也会跳转到我们的main函数,但我们没有必要每次去仿真它。点击Settings查看我们的仿真器配置情况。

33.png

点击Settings后,在Debug子选项中看到下面的信息。则说明仿真器识别正常。

34.png

再点击查看下Flash Download的选项。这时候看到ME20F030单片机的FLash的下载地址和RAM空间地址都已经明确了,这就是为什么前面强烈推荐安装KEIL 5版本,随后打上PACK包,很多设置项都是PACK包整合配置好的,我们直接用就可以了。

35.png

2、仿真选项设置好之后,开始下载程序。点击工具栏上的

 36.png

图标来下载并仿真程序。

 37.png

图标所示的功能也可以下载程序,但是它是不带仿真功能的,这点需要注意!下载成功后会多出下面的工具条。

 38.png

下面我们分别来介绍一下这些仿真调试按钮的功能:

1:复位,点击后程序会从头开始重新运行。

2:全速运行,点击后程序便开始全速运行,运行到断点处会停止,或者使用停着功能。

3:停止,当程序在运行状态下,使用此功能,程序便会停止运行。

4:执行进去,本质是单步运行,如果下一步是要执行的是个函数,那么就行进入到函数 里面,进行单步仿真。

5:段执行,也是单步运行,但不同的是,如果下一步是要执行的是个函数,那么会直接运行整个函数,并不会进入函数内部运行,它是直接以一整段代码为单位进行执行的。

6:执行跳去,当不需要再继续在某个函数里继续单步仿真时,执行此功能,就会直接执行完函数内剩余的代码,随后跳出该函数后会暂停,等待下一步操作。

7:执行到光标处,使用此功能前,先确定想运行到地方,鼠标单击运行的那一行,此时光标便会在这一行显示,这时候再点击此按钮,程序会全速运行,直到在光标处停止。

8:全速运行,此功能是让程序全速运行,除非认为暂停或者遇到断点,否则程序会一直运行。

来源:敏矽MCU

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

围观 391

1.敏矽微电子Cortex-M0学习手记01-芯片简介

1.1. 概述

ME32F030R8T6 的出现为嵌入式的开发带来了极大地便利,ME32F030R8T6 是一款内嵌 ARM Cortex™ M0 核的 32 位微控制器。64Kflash、8K的RAM可以容纳更多的代码,工程师们可以尽情的丰富与完善产品的功能。对于硬件工程师来说,芯片管脚的复用极大的便利了PCB的排版,工程师可以根据走线的需要选择最优的管脚。ME32F030R8T6 管脚功能由 IO 控制寄存器IOCON配置,除电源管脚,其余管脚均可复用。系统复位后,管脚功能将被设置成默认值。

工程师可以通过IOCON寄存器来配置引脚的功能,引脚功能丰富,极大地方便了工程开发。

1.png

1.2. 基本功能

ME32F030R8T6 是一款内嵌 ARM Cortex™ M0 核的 32 位微控制器。

这款控制器具备我们经常使用的一些功能,像检测电压需要用到的ADC,ME32F030R8T6 有多达12个通道的ADC,12位ADC转换,1MHz的转换速率,检测速度与精度相比一般的单片机有了大大的提高。

2.png

存储器分配图

还有常用的UART串口该控制器具备有常用外设和功能,如高速 12 位的 ADC 转换器,UART 串口,SPI 接口,I2C 总线接口,看门狗定时器(WDT),7 个通用计数器/定时器。除此之外,ME32F030R8T6还集成人机界面控制器和马达控制功能,如 LCD 驱动,电容触摸按键,直流无刷电机控制 PWM 模块。

1.3. 应用场景

ME32F030R8T6 适用于家电、厨电、其他消费电子、工业类等场合

3.jpg

来源: 敏矽MCU

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

围观 127

页面

订阅 RSS - Cortex-M0