单片机

Holtek着眼于中高阶应用市场,宣布新推出HT32F49365/HT32F49395高性能32-bit单片机。采用高效能Arm® Cortex®-M4核心,提供单精度浮点运算单元(FPU),支持所有Arm®单精度数据处理指令和数据类型,内置完整DSP指令和内存保护单元(MPU),增强数值运算效能与应用安全性。高集成度与高运算效能并提供多种节能模式,可满足各种应用场景,例如智能家居、工业控制、嵌入式系统、电机控制等。

1.jpg

HT32F49365/HT32F49395系列最高运行速度可达240MHz,工作电压范围为2.6V~3.6V,符合-40℃~105℃工业温度范围。Flash容量为256KB/1024KB,SRAM容量最高为224KB,可支持外部SPI Flash扩展 (最高16 MBytes寻址能力),并提供耐受5V电压输入的GPIO。丰富的外围资源包括:12-bit 2 Msps ADC ×3,12-bit DAC ×2,16-bit通用定时器 ×8,32-bit通用定时器 ×2,高级控制定时器 ×2,I²C ×3,SPI/I²S ×4,SDIO ×2,USART/UART ×8,USB FS ×1和CAN ×2。提供封装48QFN、48/64/100LQFP,依据封装类型GPIO引脚可达37~80个。

HT32F49365/HT32F49395系列支持业界主流Keil MDK及IAR EWARM开发环境,并提供硬件开发工具包、周边驱动函数库(Firmware Library)及应用范例等,操作系统支持FreeRTOS及RT-Thread OS。

来源:Holtek

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

围观 28

GD32F30x 和 GD32F403 系列硬件为参考。

一. 硬件设计 

1.电源

1.png




2.png

3.png

2.复位

4.png


注意:

1. 内部上拉电阻40kΩ,建议外部上拉电阻建议10kΩ,以使得电压干扰不会导致芯片工作异常;

2. 若考虑静电等影响,可在NRST管脚处放置ESD保护二极管;

3. 尽管MCU内部有硬件POR电路,仍推荐外部加NRST复位阻容电路;

4. 如果MCU启动异常(由于电压波动等),可适当增加NRST对地电容值,拉长MCU复位完成时间,避开上电异常时序区。

3.时钟

GD32F30x/GD32F403系列内部有完备的时钟系统,可以根据不同的应用场合,选择合适的时钟源,时钟主要特征:

4-32MHz外部高速晶体振荡器(HXTAL);

8MHz内部高速RC振荡器(IRC8M);

32.768KHz外部低速晶体振荡器(LXTAL);

48 MHz内部高速RC振荡器(IRC48M);

40kHz内部低速RC振荡器(IRC40K);

PLL时钟源可选HXTAL、IRC8M或IRC48M;

HXTAL时钟可监控;

时钟树如下:

5.png







6.png

7.png

8.png

9.png

4.启动配置

GD32F30x/GD32F403系列提供三种启动方式,可以通过BOOT0和BOOT1来进行相关的配置。

用户可以配置BOOT0和BOOT1,进行上电复位或系统复位,从而确定启动选项。电路设计时,运行用户程序,BOOT0不能悬空,建议通过一个10kΩ电阻到GND;运行System Memory进行程序更新,需要将BOOT0接高,BOOT1接低,更新完成后,再将BOOT0接低上电才能运行用户程序;SRAM执行程序多用于调试状态下。

嵌入式的 Bootloader 存放在系统存储空间,用于对 FLASH 存储器进行重新编程。在GD32F305xx/ GD32F307xx/ GD32F403xx设备中,Bootloader可以通过USART0 (PA9 and PA10),USART1 (PD5 and PD6),USBFS (PA9, PA11 and PA12)和外界交互。在GD32F303xx(Flash<512kB)设备中,Bootloader可以通过USART0 (PA9 and PA10) 和外界交互, 在GD32F303xx(Flash>512kB)设备中,Bootloader可以通过USART0 (PA9 and PA10) USART1 (PA2 and PA3)和外界交互。




10.png

11.png

5.下载调试

GD32F30x/GD32F403系列内核支持JTAG调试接口和SWD接口。JTAG接口标准为20针接口,其中5根信号接口,SWD接口标准为5针接口,其中2根信号接口。

注意:复位后,调试相关端口为输入PU/PD模式,其中:

PA15:JTDI为上拉模式;

PA14:JTCK / SWCLK为下拉模式;

PA13:JTMS / SWDIO为上拉模式;

PB4:NJTRST为上拉模式;

PB3:JTDO为浮空模式。

12.png





13.png

14.png

15.png

有以下几种方式可以提高SWD下载调试通信的可靠性,增强下载调试的抗干扰能力。

1. 缩短SWD两个信号线长度,最好15cm以内;

2. 将SWD两根线和GND线编个麻花,缠在一起;

3. 在SWD两根信号线对地各并几十pF小电容;

4. SWD两根信号线任意IO串入100Ω~1KΩ电阻。

6.典型外设

ubs外设电路

16.png




17.png

18.png

二. PCB Layout

1.电源去耦电容

GD32F30x/GD32F403系列电源有VDD、VDDA、VREF+和VBAT四个供电脚,100nF去耦电容采用陶瓷即可,且需要保证位置尽可能地靠近电源引脚。电源走线要尽量使得经过电容后再到达MCU电源引脚,建议可通过靠近电容PAD处打Via的形式Layout。

19.png


2.时钟电路

GD32F30x/GD32F403系列时钟有HXTAL和LXTAL,要求时钟电路(包括晶体或晶振及电容等)靠近MCU时钟引脚放置,且尽量时钟走线由GND包裹起来。

20.png


注意:

1. 晶体尽量靠近MCU时钟Pin,匹配电容等尽量靠近晶体;

2. 整个电路尽量与MCU在同层,走线尽量不要穿层;

3. 时钟电路PCB区域尽量禁空,不走任何与时钟无关走线;

4. 大功率、强干扰风险器件及高速走线尽量远离时钟晶体电路;

5. 时钟线进行包地处理,以起到屏蔽效果。

3.复位电路

21.png


注意:复位电路阻容等尽可能地靠近MCU NRST引脚,且NRST走线尽量远离强干扰风险器件及高速走线等,条件允许的话,最好将NRST走线做包地处理,以起到更好的屏蔽效果。

4.USB 电路

USB模块有DM、DP两根差分信号线,建议PCB走线要求做特性阻抗90ohm,差分走线严格按照等长等距规则来走,且尽量使走线最短,如果两条差分线不等长,可在终端用蛇形线补偿短线。

由于阻抗匹配考虑,串联匹配电阻建议50Ω左右即可。当USB终端接口离MCU较远的时候,需要适当增大该串联电阻值。

22.png


注意:

1. 布局时摆放合理,以缩短差分走线距离;

2. 优先绘制差分线,一对差分线上尽量不要超过两对过孔,且需要对称放置;

3. 对称平行走线,保证两根线紧密耦合,避免90°、弧形或45°走线方式;

4. 差分走线上所接阻容、EMC等器件,或测试点,也要做到对称原则。

对于USB HS模块,MCU与外部HS PHY之间的数据线与信号控制线也尽量走短,需要用蛇形线做等长处理,注意事项如下:

1. 布局时摆放合理,USB HS-PHY芯片与MCU之间尽量紧凑;

2. 布线时,以信号线中最长的一根线长度为目标,将其他信号线通过蛇形走线补偿即可。

5.BGA 走线

GD32F403x 系列中包含 BGA100 的封装,对应的型号为 GD32F403VxH6,该芯片走线和其它 BGA 芯片类似,先对各个球型焊盘进行扇出,再进行布线操作。对于 0.5 mm Pitch 的 BGA封装,若将 BGA 焊盘大小设置为 0.25/0.35,过孔距焊盘以及线宽线距为 3 mil 时,可以使用Dog bone 型扇出,扇出后如图 3-5. BGA100 封装的扇出方式所示,过孔距焊盘距离为 4.5mil;但此种布线对 PCB 制造商工艺要求较高,需与 PCB 制造商沟通后再进行布线,若制造商工艺达不到要求,可对此 BGA 封装打盘中孔以及盲埋孔

23.png



参考:

https://gd32mcu.com/cn/download/10?kw=

来源: 嵌入式学习与实践

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

围观 132

CW32的LVD低电压检测器适用于监测VDDA电源电压或外部引脚输入电压,当被监测电压与LVD阈值的比较结果满足触发的条件时,LVD将会产生中断或者复位信号,通常用来处理一些紧急任务。LVD产生的中断或复位标志,只能通过软件程序清零,并且只有当中断或复位标志被清零后,在再次达到触发条件时,LVD才能再次产生中断或复位信号。在本文中以CW32L083系列为例,介绍LVD的基本功能和使用例程。

LVD的基本功能介绍:

1、4路监测电压源

VDDA电源电压,PA00引脚输入,PB00引脚输入,PB11引脚输入

2、16阶阈值电压,范围2.02V-3.76V

3、3种触发条件,可以组合使用

电平触发:电压低于阈值

下降沿触发:电压跌落到阈值以下的下降沿

上升沿触发:电压回升到阈值以上的上升沿

4、可触发产生中断或复位信号,二者不能同时产生

5、8阶滤波可配置

6、支持迟滞功能

7、支持低功耗模式下运行,中断唤醒MCU

1.png

通过LVD的控制寄存器LVD_CR0的SOURCE位域来选择LVD模块监控的电压(VDDA电源/ PA00引脚/PB00引脚/PB11引脚),在监测外部引脚电压时,需将对应的GPIO端口配置为模拟输入模式(GPIOx_ANALOG.PINy = 1)。

LVD的比较结果可以从PA01/PA08/PC12/PE02/PF02脚输出,在此之前,需将对应的GPIO口配置为数字输出模式,同时选择端口位LVDOUT复用功能。

LVD 内置的电压比较器具有迟滞功能,只有当被监测电压高于或低于阈值电压达到 20mV 时,比较器输出信号才会发生翻转,可避免当 LVD 的监测电压在阈值电压附近时,电压比较器的输出结果发生频繁翻转,增强系统抗干扰能力。具体波形如下图所示:

2.png

LVD的阈值电压根据LVD控制寄存器LVD_CR0的VTH位控制。

3.png

LVD支持数字滤波功能,可以增强系统的鲁棒性(系统在一定的参数抖动下,维持起某些性能的特性),可以将LVD电压比较的输出结果信号进行数字滤波,小于滤波宽度的信号被滤除,不会被触发中断或复位,如下图所示,图中两处噪音或其他信号就被滤除了。

4.png

通过设置控制寄存器LVD_CR1的FLTEN位域,可以使能数字滤波模块,当将该位设置为1的时候,会使能数字滤波模块。

通过设置控制寄存器 LVD_CR1 的 FLTCLK 位域可以选择数字滤波的时钟:

• FLTCLK 位为 1,选择 HSIOSC 作为滤波时钟 

• FLTCLK 位为 0,选择内置 RC 振荡器时钟作为滤波时钟,其频率约 150kHz

控制寄存器 LVD_CR1 的 FLTTIME 位域用于选择数字滤波的时钟个数,如下表所示:

5.png

从 LVD 状态寄存器 LVD_SR 的 FLTV 位域,可以读出经 LVD 数字滤波后的信号电平;当 GPIO 的功能复用为 LVD_OUT 时,数字滤波后的信号就可以从 GPIO 输出,以方便观察测量。

LVD 支持在低功耗模式下工作,中断输出可将芯片从低功耗模式下唤醒。当被监测电压与 LVD 阈值的比较结果满足触发条件时,可产生中断或复位信号。产生中断还是复位信号由控制寄存器 LVD_CR0 的 ACTION 位域控制:

 • ACTION 为 1,LVD 触发产生复位 #define LVD_Action_Reset  ((uint32_t)0x00000002)

 • ACTION 为 0,LVD 触发产生中断 #define LVD_Action_Irq   ((uint32_t)0x00000000)

LVD可以通过设置控制寄存器 LVD_CR0 的 IE 位域为 1,使能 LVD 中断,满足触发条件时将产生 LVD 中断,中断标志位 LVD_SR.INTF 会被硬件置 1,用户可以向 INTF 位写 0,清除中断标志。设置控制寄存器 LVD_CR1 的 LEVEL、FALL、RISE 位域,可选择不同的中断或复位触发方式,三者可组合使用:

• LEVEL 为 1,被监测电压低于阈值时触发中断或产生复位 

• FALL 为 1,被监测电压跌落到阈值以下的下降沿触发中断或产生复位 

• RISE 为 1,被监测电压回升到阈值以上的上升沿触发中断或产生复位

LVD使用例程介绍:

根据上述内容,可以配置一个关于CW32L083的电压监测例程,LVD的输入通道设置为PA00,输出端口为PA08,门限电压为2.02V,利用LVD的中断实现当LVD输入通道电压低于或者高于门限电压时刻(利用上升沿和下降沿),PC03输出电平翻转一次。

void LVD_PortInit(void) 
{ 
    GPIO_InitTypeDef GPIO_InitStructure = {0}; 
    
    //打开GPIOA时钟 
    __RCC_GPIOA_CLK_ENABLE(); 
    
    //将PA08设置为LVD比较结果输出 
    GPIO_InitStructure.Pins = GPIO_PIN_8; 
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; 
    GPIO_Init(CW_GPIOA, &GPIO_InitStructure); 
    
    //将PA08复用为LVD比较结果输出     
    PA08_AFx_LVDOUT();
     //将PA00设置为LVD的输入口 
    PA00_ANALOG_ENABLE(); 
} 

int main(void) 
{ 
    LVD_InitTypeDef LVD_InitStruct = {0}; 
    
    //LED初始化 
    LED_Init(); 
    
    //配置测试IO口 
    LVD_PortInit(); 
    
    LVD_InitStruct.LVD_Action = LVD_Action_Irq;  //配置中断功能 
    LVD_InitStruct.LVD_Source = LVD_Source_PA00; //配置LVD输入口为PA00 
    LVD_InitStruct.LVD_Threshold = LVD_Threshold_2p02V; //配置LVD基准电压为2.02v 
    LVD_InitStruct.LVD_FilterEn = LVD_Filter_Enable;//LVD滤波模块开启 
    LVD_InitStruct.LVD_FilterClk = LVD_FilterClk_RC150K;//LVD滤波时钟为150KHz 
    LVD_InitStruct.LVD_FilterTime = LVD_FilterTime_4095Clk; 
    LVD_Init(&LVD_InitStruct);
    
    LVD_TrigConfig(LVD_TRIG_FALL | LVD_TRIG_RISE, ENABLE);//LVD中断为上升沿和下降沿触发 
    LVD_EnableIrq(LVD_INT_PRIORITY); 
    LVD_ClearIrq(); 
    FirmwareDelay(4800); 
    LVD_Enable(); //LVD使能 
    
    while (1) 
    { 
        if (gFlagIrq) 
        { 
            PC03_TOG(); 
            gFlagIrq = FALSE; 
        } 
    } 
} 

/** 
* @brief LED I/O初始化 
* 
*/ 
void LED_Init(void) 
{ 
    GPIO_InitTypeDef GPIO_InitStructure = {0};
    
    //打开GPIOC时钟 
    REGBITS_SET(CW_SYSCTRL->AHBEN, SYSCTRL_AHBEN_GPIOC_Msk); 
    
    /* Configure the GPIO_LED pin */ 
    GPIO_InitStructure.Pins = GPIO_PIN_2 | GPIO_PIN_3; 
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; 
    GPIO_Init(CW_GPIOC, &GPIO_InitStructure); 
    
    //LEDs are off. 
    PC02_SETLOW(); 
    PC03_SETLOW(); 
} 

//LVD中断服务函数 
void LVD_IRQHandler(void) 
{ 
    LVD_ClearIrq();      //清除中断标志 
    gFlagIrq = TRUE;     //将gFlagIrq赋值为TURE 
}

根据上述例程可以得到在PA00的输入电压值低于2.02v或高于2.02v的瞬间时刻,LVD会产生中断,PC03的输出电平会产生翻转,可利用CW32L083的开发板和一根杜邦线,将PA00和DVCC连接,在连接上的时刻以及拔掉杜邦线的时刻,LED1的状态会发生翻转。

来源:武汉芯源半导体

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

围观 199

程序架构重要性

很多人尤其是初学者在写代码的时候往往都是想一点写一点,最开始没有一个整体的规划,导致后面代码越写越乱,bug不断。

最终代码跑起来看似没有问题(有可能也真的没有问题),但是系统的可扩展性很差,添加一个功能的时候会浪费大量的时间,甚至导致整个代码的崩溃。

所以,在一个项目开始的时候多花一些时间在代码的架构设计上是十分有必要的。代码架构确定好了之后你会发现敲代码的时候会特别快,并且在后期调试的时候也不会像无头苍蝇一样胡乱找问题。当然,调试也是一门技术。

在学习实时操作系统的过程中,发现实时操作系统框架与个人的业务代码之间的耦合性就非常低,都是只需要将业务代码通过一定的接口函数注册好后就交给操作系统托管了,十分方便。

但是操作系统的调度过于复杂,这里就使用操作系统的思维方式来重构这个时间片轮询框架。实现该框架的完全解耦,用户只需要包含头文件,并且在使用过程中不需要改动已经写好的库文件。

Demo

首先来个demo,该demo是使用电脑开两个线程:一个线程模拟单片机的定时器中断产生时间片轮询个时钟,另一个线程则模拟主函数中一直运行的时间片轮询调度程序。

#include <thread>
#include <stdio.h>
#include <windows.h>
#include "timeslice.h"

// 创建5个任务对象
TimesilceTaskObj task_1, task_2, task_3, task_4, task_5;

// 具体的任务函数
void task1_hdl()
{        
    printf(">> task 1 is running ...\n");
}

void task2_hdl()
{    
    printf(">> task 2 is running ...\n");
}

void task3_hdl()
{    
    printf(">> task 3 is running ...\n");
}

void task4_hdl()
{    
    printf(">> task 4 is running ...\n");
}

void task5_hdl()
{    
    printf(">> task 5 is running ...\n");
}

// 初始化任务对象,并且将任务添加到时间片轮询调度中
void task_init()
{    
    timeslice_task_init(&task_1, task1_hdl, 1, 10);    
    timeslice_task_init(&task_2, task2_hdl, 2, 20);    
    timeslice_task_init(&task_3, task3_hdl, 3, 30);    
    timeslice_task_init(&task_4, task4_hdl, 4, 40);    
    timeslice_task_init(&task_5, task5_hdl, 5, 50);    
    timeslice_task_add(&task_1);    
    timeslice_task_add(&task_2);    
    timeslice_task_add(&task_3);    
    timeslice_task_add(&task_4);    
    timeslice_task_add(&task_5);
}

// 开两个线程模拟在单片机上的运行过程
void timeslice_exec_thread()
{    
    while (true)    
    {        
        timeslice_exec();    
    }
}

void timeslice_tick_thread()
{    
    while (true)    
    {        
        timeslice_tick();        
        Sleep(10);    
    }
}

int main()
{    
    task_init();
    
   printf(">> task num: %d\n", timeslice_get_task_num());    
   printf(">> task len: %d\n", timeslice_get_task_timeslice_len(&task_3));
   
   timeslice_task_del(&task_2);    
   printf(">> delet task 2\n");    
   printf(">> task 2 is exist: %d\n", timeslice_task_isexist(&task_2));
    
   printf(">> task num: %d\n", timeslice_get_task_num());    
   timeslice_task_del(&task_5);    printf(">> delet task 5\n");
   printf(">> task num: %d\n", timeslice_get_task_num());    
   printf(">> task 3 is exist: %d\n", timeslice_task_isexist(&task_3));   
   
   timeslice_task_add(&task_2);    printf(">> add task 2\n");    
   printf(">> task 2 is exist: %d\n", timeslice_task_isexist(&task_2));
    
   timeslice_task_add(&task_5);    printf(">> add task 5\n");   
   printf(">> task num: %d\n", timeslice_get_task_num());
    
   printf("\n\n========timeslice running===========\n");
    
   std::thread thread_1(timeslice_exec_thread);    
   std::thread thread_2(timeslice_tick_thread);
    
   thread_1.join();    
   thread_2.join();

   return 0;
}

运行结果如下:

1.jpg

由以上例子可见,这个框架使用十分方便,甚至可以完全不知道其原理,仅仅通过几个简单的接口就可以迅速创建任务并加入到时间片轮询的框架中,十分好用。

时间片轮询架构

其实该部分主要使用了面向对象的思维,使用结构体作为对象,并使用结构体指针作为参数传递,这样作可以节省资源,并且有着极高的运行效率。

其中最难的部分是侵入式链表的使用,这种链表在一些操作系统内核中使用十分广泛,这里是参考RT-Thread实时操作系统中的侵入式链表实现。

h文件:

#ifndef _TIMESLICE_H
#define _TIMESLICE_H

#include "./list.h"

typedef enum 
{    
    TASK_STOP,    
    TASK_RUN
} IsTaskRun;

typedef struct timesilce
{    
    unsigned int id;    
    void (*task_hdl)(void);    
    IsTaskRun is_run;    
    unsigned int timer;    
    unsigned int timeslice_len;    
    ListObj timeslice_task_list;
} TimesilceTaskObj;

void timeslice_exec(void);
void timeslice_tick(void);
void timeslice_task_init(TimesilceTaskObj* obj, void (*task_hdl)(void), unsigned int id, unsigned int timeslice_len);
void timeslice_task_add(TimesilceTaskObj* obj);
void timeslice_task_del(TimesilceTaskObj* obj);
unsigned int timeslice_get_task_timeslice_len(TimesilceTaskObj* obj);
unsigned int timeslice_get_task_num(void);
unsigned char timeslice_task_isexist(TimesilceTaskObj* obj);

#endifc文件:
#include "./timeslice.h"

static LIST_HEAD(timeslice_task_list);

void timeslice_exec()
{    
    ListObj* node;    
    TimesilceTaskObj* task;
   
   list_for_each(node, &timeslice_task_list)    
   {
        
        task = list_entry(node, TimesilceTaskObj, timeslice_task_list);        
        if (task->is_run == TASK_RUN)        
        {            
            task->task_hdl();            
            task->is_run = TASK_STOP;        
        }    
    }
}

void timeslice_tick()
{    
    ListObj* node;    
    TimesilceTaskObj* task;
   
   list_for_each(node, &timeslice_task_list)    
   {        
       task = list_entry(node, TimesilceTaskObj, timeslice_task_list);        
       if (task->timer != 0)        
       {            
           task->timer--;            
           if (task->timer == 0)            
           {                
               task->is_run = TASK_RUN;                
               task->timer = task->timeslice_len;            
           }        
       }    
   }
}

unsigned int timeslice_get_task_num()
{    
    return list_len(&timeslice_task_list);
}

void timeslice_task_init(TimesilceTaskObj* obj, void (*task_hdl)(void), unsigned int id, unsigned int timeslice_len)
{    
    obj->id = id;    
    obj->is_run = TASK_STOP;    
    obj->task_hdl = task_hdl;    
    obj->timer = timeslice_len;    
    obj->timeslice_len = timeslice_len;
}

void timeslice_task_add(TimesilceTaskObj* obj)
{    
    list_insert_before(&timeslice_task_list, &obj->timeslice_task_list);
}

void timeslice_task_del(TimesilceTaskObj* obj)
{    
    if (timeslice_task_isexist(obj))        
        list_remove(&obj->timeslice_task_list);    
    else        
        return;
}

unsigned char timeslice_task_isexist(TimesilceTaskObj* obj)
{    
    unsigned char isexist = 0;    
    ListObj* node;    
    TimesilceTaskObj* task;
    
   list_for_each(node, &timeslice_task_list)    
   {        
       task = list_entry(node, TimesilceTaskObj, timeslice_task_list);        
       if (obj->id == task->id)            
           isexist = 1;    
   }
    
   return isexist;
}

unsigned int timeslice_get_task_timeslice_len(TimesilceTaskObj* obj)
{    
    return obj->timeslice_len;
}

底层侵入式双向链表

该链表是linux内核中使用十分广泛,也十分经典,其原理具体可以参考文章:

https://www.cnblogs.com/skywang12345/p/3562146.html

h文件:

#ifndef _LIST_H
#define _LIST_H    
#define offset_of(type, member)             (unsigned long) &((type*)0)->member
#define container_of(ptr, type, member)     ((type *)((char *)(ptr) - offset_of(type, member)))

typedef struct list_structure
{    
    struct list_structure* next;    
    struct list_structure* prev;
} ListObj;

#define LIST_HEAD_INIT(name)    {&(name), &(name)}
#define LIST_HEAD(name)         ListObj name = LIST_HEAD_INIT(name)

void list_init(ListObj* list);
void list_insert_after(ListObj* list, ListObj* node);
void list_insert_before(ListObj* list, ListObj* node);
void list_remove(ListObj* node);
int list_isempty(const ListObj* list);
unsigned int list_len(const ListObj* list);

#define list_entry(node, type, member) \    
    container_of(node, type, member)
    
#define list_for_each(pos, head) \    
    for (pos = (head)->next; pos != (head); pos = pos->next)

#define list_for_each_safe(pos, n, head) \  
    for (pos = (head)->next, n = pos->next; pos != (head); \    
        pos = n, n = pos->next)
        
#endif

c文件:

#include "list.h"

void list_init(ListObj* list)
{    
    list->next = list->prev = list;
}

void list_insert_after(ListObj* list, ListObj* node)
{    
    list->next->prev = node;    
    node->next = list->next;
   
   list->next = node;    
   node->prev = list;
}

void list_insert_before(ListObj* list, ListObj* node)
{    
    list->prev->next = node;    
    node->prev = list->prev;
    
   list->prev = node;    
   node->next = list;
}

void list_remove(ListObj* node)
{    
    node->next->prev = node->prev;    
    node->prev->next = node->next;
   
   node->next = node->prev = node;
}

int list_isempty(const ListObj* list)
{    
    return list->next == list;
}

unsigned int list_len(const ListObj* list)
{    
    unsigned int len = 0;    
    const ListObj* p = list;    
    while (p->next != list)    
    {        
        p = p->next;        
        len++;    
    }
    
    return len;
}

到此,一个全新的,完全解耦的,十分方便易用时间片轮询框架完成。

来源:小麦大叔

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

围观 84

就8051 MCU(单片机)而言,烧录器的种类繁多,兹此我们为您介绍烧录工具的”在线升级”。过去有普通烧写器,这个工具大多用并口烧录,使用引脚较多。以笙泉科技的8051 MCU为例:MPC82系列、MPC89系列几乎为20或20多个引脚。这些带来诸多不便,假如程序有BUG,软件需要升级等,就会很麻烦,得要先把IC从系统上卸下来,然后烧录新的程序,最后再焊回去,……於是痛苦就这么产生了。

基于解决上述的痛点,方便的ISP和ICP方式应运而生。

方式1: ISP(在系统编程)

所谓的ISP即在系统编程: In-System Programming, 缩写为ISP), 参见下图之范例:

1.png

这样,使用者可以在系统上预留3个点:VCC、DTA(P3.1)、GND,通过笙泉专利默认的应用程序软件重新配置在线升级,由于烧录接口减少,第一段所述之痛苦也可逐步减轻。

2.png

8051 ISP烧录器(TH079)特色:

  • USB即插即用

  • 支持联机及脱机二种烧录模式

  • 支持滚动码烧录,此滚动码可当序列号或唯一ID号使用

  • 可设置最大烧录次数限制

  • 自动软件在线更新

  • 3线传输模式,接口简单好连接

3.png

虽然以ISP方式,其使用的接口少(VCC, P3.1, GND) ,但它必须在IC内先植入ISP CODE,也就是说必须用掉部分程序空间,且只能修改部分硬件选项。

方式2: 专业再升级-ICP(在电路编程)

1)  ICP (在电路编程)为一种电路,具有5线烧录模式,完全可代替前述的ISP方式之在线烧录工具,这个在笙泉科技的对应规格书上都有强烈建议,常搭配采用的仿真、烧录工具包括有OCD_ICE和M-Link。

4.png

2) ICP (在电路编程)特色:

  • 无须在目标芯片上预编程一个引导程序

  • 专用串行接口: 不占用 IO口

  • 目标芯片无须在运行状态: 仅需电源

  • 便携、独立的工作,而无须主机的干预

采ICP方式的普通烧写器,其关键是只要用到5个接口,一般来讲4个就足够 ( OCD_SCL, VDD, OCD_SDA, GND )。亦即该烧写器通过ICP方式(电路)来实现在线升级/下载更新程序的功能。

最后归纳: 在您设计的系统中,一定要预留ICP的接口(4个点 OCD_SCL, VDD, OCD_SDA, GND ),为您的产品保驾护航,从此前述之”痛苦”将消失,轻松实现在线升级更新。

来源:megawin笙泉科技

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

围观 98

作者: Bill Hawkins、 Zhang Feng、 Xavier Bignalet(Microchip Technology Inc.)

简介

在许多熟悉的系统中,通常需要对消耗品组件进行身份验证。例如,打印机墨盒、车辆中的电池、化妆品盒和送药设备中的药物等。本文档探讨了在现有设计中包含Microchip的CryptoAuthentication™系列ATSHA204A安全元件以实现对消耗品进行安全身份验证的优势。请参见图1。

1.png

图1:安全身份验证的雾化器框图

在本示例中,我们将从Microchip的AN2265“Vibrating Mesh Nebulizer Reference Design”(DS00002265) 开始,其中介绍了振动式网孔雾化器及其如何使用Microchip独立于内核的外设实现。本文档介绍了如何更新雾化器参考设计以包含可拆卸振动网和药盒的安全身份验证来增强设计。

雾化器参考设计具有用于固定振动网(将随时间逐渐磨损)和供应药物(一种耗材供应)的可拆卸药盒。这种储存药物的可拆卸药盒会极大地影响设备的性能。

出于以下几个原因,制造商可能希望保护这些药盒应用不受第三方供应商的影响:

  • 客户对设备的质量和功能的印象在很大程度上受药盒内物质的影响。当更换的第三方药盒不满足制造商的标准,并且提供的性能低于客户的预期时,制造商而不是第三方药盒厂商会接收到投诉。

  • 尤其是在医疗行业中,允许不受控地访问设备可能会导致制造商因用药剂量错误、药物受到污染甚至是消耗品药盒中的药物出错而承担责任。

  • 另一个原因是为了保护收入来源。典型的业务模式包括消耗品销售将提供支撑公司主要收入来源的预期。如果第三方可以在同一个市场上销售,那么制造商的收入会降低,而这部分收入本应补偿基本单元和研发(Research and development,R&D)的成本。

本文档介绍了对雾化器进行的安全增强,包括对可拆卸 药盒进行身份验证和跟踪其使用情况,并且可能限制药 盒的使用以避免出现硬件磨损、未授权重填和重用旧药 盒等问题。 

引入ATSHA204A

雾化器的药盒中使用ATSHA204A芯片向基本单元对药盒进行身份验证。ATSHA204A具有用于使能身份验证的多种功能,例如SHA-256哈希算法、安全EEPROM、惟一序列号、高质量随机数发生器和I 2C接口或单线接口。

SHA-256加密引擎

ATSHA204A在硬件中集成了SHA-256哈希算法。该哈希函数使用输入流(质询)并产生256位(32字节)输出(响应)。哈希函数的两个主要特性如下:

• 无法从哈希输出重新生成输入流。

• 无法改变输入流并获得相同的哈希输出。

ATSHA204A将使用主机单片机提供的质询字符串生成哈希密钥。单片机还可以使用该质询字符串和密钥来执行哈希函数。如果哈希输出与主机单片机预期的输出一致,则证明ATSHA204A器件知道相同的密钥。

安全EEPROM/密钥存储

ATSHA204A具有512字节的EEPROM,按十六个32字节槽排列。其中任何一个槽都可以配置为要在哈希函数中使用的密钥值。当配置ATSHA204A时,槽中的值可以受到写保护、读保护、用其他槽作为密钥进行加密或者保留为可读/可写的EEPROM存储单元。提供物理防篡改和边信道保护,以防止有人解密和探测器件芯片来读取存储器。

惟一序列号

保证每个ATSHA204A都有惟一的72位(9字节)序列号,从而允许制造商通过连接的ATSHA204A惟一识别任何器件。

高质量随机数发生器

ATSHA204A具有基于噪声源的高质量随机数发生器。这可以用来生成将只使用一次的惟一质询,并防止攻击设备记录质询和响应以在主机上回放来冒充有效器件。

I2C/单线接口

ATSHA204A提供I2C接口或单线接口,允许药盒在接口中具有最少的触点。经过身份验证的雾化器使用单线接口,这种接口采用具有三个大型焊盘的芯片封装。ATSHA204A芯片采用可粘到药盒上的设计,主机只提供滑动触点来连接到药盒(就像电池连接器一样),这样药盒就无需电路板或配对连接器。

如何使用ATSHA204A进行身份验证?

安全雾化器演示是单芯片系统设计。PIC16F1718运行整个操作,包括使用ATSHA204A进行身份验证所需的质询/响应。请参见图2

2.png

图2:ATSHA204A身份验证框图

PIC16具有16个存储在存储器中的质询/响应对。每次使用器件时,都会对药盒进行身份验证。当用户按下按钮来启动雾化器时,PIC16主机会向药盒上的ATSHA204A发送32字节质询。然后,ATSHA204A使用密钥对质询进行哈希运算,并将值返回到PIC16。返回的值与预期的响应进行比较,如果匹配,则允许雾化器运行。如果不匹配,雾化器的红色LED指示灯会点亮几秒钟,然后再熄灭。雾化器通过使用自由运行定时器中的低4位从16个质询中进行选择,但具体数量无法预测。

由于PIC16存储有限数量的质询/响应对,这就意味着克隆器件只需处理几个用例即可破坏该系统的安全性。为了防止出现这种情况,可以为每个PIC16主机编程惟一的质询/响应对,这样一来,通过这种方式创建的克隆器件便无法在任何其他器件上工作。

身份验证方法可保护配件/一次性用品,但无法防止克隆主机(在新系统中复制质询/响应对)。要实现更高级别的安全性,需要在主机MCU旁边添加独立安全元件(ATSHA204A)。请参见图3。该主机ATSHA204A会为药盒ATSHA204A产生随机质询,并提供响应以与来自药盒ATSHA204A的响应进行比较。此外,密钥派生实现将进一步提高解决方案的稳健性。

3.png

图3:对称身份验证

作为ATSHA204A的替代产品,ATSHA206A是外形受限应用的理想解决方案,在此类应用中,由于药盒尺寸受限而无法容纳任何PCB,因此只能采用2引脚封装。2引脚ATSHA206A或3引脚ATSHA204A可以塑封到一次性药盒中。ATSHA206A的内部添加了集成电容,可在电源引脚上提供寄生电源能力。本质上,数据和电源共用同一个引脚。

限制药盒的使用

经过身份验证的雾化器保存每个药盒的使用计数。此数据可用于限制药盒的使用。有多种机制可实现此功能。ATSHA204A器件包含EEPROM和SRAM两个存储器块。EEPROM分为三个区域:数据区域、配置区域和 一次性编程(One-Time-Programmable,OTP)区域。

数据区域分为16个通用存储器槽。EEPROM数据区域中的任何槽都可用于存储密钥。

配置区域中有128位分配为LastKeyUse,可用于限制存储在Slot 15中的密钥编号15的使用。每次使用Slot15作为密钥时,这128位都会清零。没有复位机制。在 使用128次之后,将永久禁止Slot/Key 15。因此,每个药盒的使用计数可以限制为128次或更少。

此外,还有512位的OTP存储器可用于存储只读数据或单向熔丝型消耗记录信息。在消耗模式下配置时,这些位可以写入0,但不能写回1。因此,在OTP存储器为全零之前,可以将0移入OTP存储器512次。在OTP存 储器为全零之后,可以禁止使用药盒。

如果药盒的使用次数小于这些值(Slot 15为128次, OTP为512次),则可以将其中一些位预编程为零,以便根据需要提供所需的次数。

关于安全增强功能的深入探讨

存储在主机MCU、ATSHA204A或公司计算机系统中的机密信息密钥必须受到绝对保护。如果密钥泄露,则安全功能将不再起作用,产品也很容易遭到克隆。

Microchip的一些32位单片机具有稳健的安全性,能够提供可信执行环境(Trusted Execution Environment,TEE)、加密加速器、安全引导和安全自举程序等。例如,图4显示了一个SAM L11作为配件身份验证应用中 (其中SAM L11增加了稳健性)的主机MCU正在托管TEE,即从MCU到安全元件的CryptoAuthlib API调用。TEE将Cryptoauthlib API回调会离开的关键代码与系统的其余部分隔离,并避免固件更改。

4.png

图4:一次性药盒身份验证

存储在ATSHA204A中的一次性药盒的密钥不会遭到窥探。ATSHA204A只是Microchip提供的其中一种安全芯片。Microchip还提供其他使用公钥加密(用于网络身份验证)的芯片来防止单一密钥泄露。每个芯片都有自己的密钥,其真实性由证书确定,该证书提供了器件到根证书颁发机构的可追溯性。这些芯片的说明超出了本文档的范围,可通过Microchip网站上的安全设计中心查看更多信息,网址如下:https://www.microchip.com/design-centers/security-ics

附录A:警告、限制和免责声明

医疗参考设计和演示仅用作评估和开发目的。如果将Microchip器件用于生命维持和/或生命安全应用,一切风险由买方自负。买方同意在由此引发任何一切损害、索赔、诉讼或费用时,会维护和保障Microchip免于承担法律责任。

附录B:参考资料

 • AN2265,“Vibrating Mesh Nebulizer Reference Design”(DS00002265),Bill Hawkins和 Zhang Feng,Microchip Technology Inc.

- AN2265 位于 Microchip 产品页面,网址为https://www.microchip.com/en-us/solutions/medical/drug-delivery-devices/nebulizer

• ATSHA206A一次性药盒安全身份验证

- 请参见ATSHA206A产品页面,网址为https://www.microchip.com/en-us/product/ATSHA206A

来源:Microchip 工程师社区

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

围观 169

近年来,新能源汽车快速发展和普及,但随之而来的“续航焦虑”也困扰着广大车主。于是,可随身携带、只要有标准插座就能为“爱车”充电的便携式充电枪进入消费者视野。

模式二便携式充电枪作为即插即用型充电设备,结构简洁、操作简单,不受充电场地限制,满足电动车主随时充电的应用诉求。此外,模式二便携式充电盒在使用过程中性能稳定,相比模式一无保护式充电,模式二充电安全有保障。

1.png

图为:思皓新能源车的便携充电枪

思皓创建于2018年4月24日,此品牌为安徽江淮汽车集团股份有限公司与大众汽车集团(中国)合资成立的大众汽车(安徽)有限公司(原名江淮大众汽车有限公司)发布全新品牌。同时也是大众旗下子品牌之一。

通过拆解思皓新能源车的便携充电枪,我们发现武汉芯源半导体的CW32F030C8T6在其作为核心主控芯片。

2.png

3.png

作为充电枪的核心部件,不仅要求充电安全可靠,而且还需要适应从东北极寒到三亚酷热的各种使用环境,这对MCU要求极高,这说明武汉芯源半导体的CW32F030C8T6单片机已得到一线主机厂的认可。

武汉芯源半导体的CW32F030C8T6,支持-40~105℃的超宽温度范围,也有已公开HBM ESD 8KV、EFT 4KV等测试结果,全部ESD和Latch Up指标达到国际标准最高等级,可以确保充电枪安全稳定的工作。

CW32F030C8T6在充电枪中的应用框图

4.png

CW32F030C8T6特色及优势点‍

√ARM Cortex-M0+ 32位内核;

√12位高精度ADC;

√105℃耐温,适用多种工业/汽车应用

√支持DeepSleep模式,节省功耗;

√8KV ESD,4KV EFT抗干扰,从容应对EMC;

√3路UART,调试更方便

有关芯片购买事宜,请咨询武汉芯源半导体的销售和官方代理商。更多MCU详细信息,请访问武汉芯源半导体官方网站:https://www.whxy.com

来源:武汉芯源半导体

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

围观 27

平时我们写程序,通常都会备注软件版本,那么,怎么在单片机中保存版本信息呢?

方法其实有很多,但基本原理都是在指定存储区域(Flash)中写入软件版本信息。

实现方法

下面就分享一个最常用,也是最基础的小技巧:在Keil MDK环境下,通过软件代码,直接映射到并存储到Flash指定地址。

包含:软件版本、编译日期、编译时间,代码如下:

#define VERINFO_ADDR_BASE   (0x0800FF00) //存放FLASH的地址
const char Software_Ver[] __attribute__((at(VERINFO_ADDR_BASE + 0x00)))  = "Software: 1.0.0";
const char Compiler_Date[] __attribute__((at(VERINFO_ADDR_BASE + 0x40))) = "Date: "__DATE__;
const char Compiler_Time[] __attribute__((at(VERINFO_ADDR_BASE + 0x60))) = "Time: "__TIME__;

这个代码大家能看懂么? 

原理很简单,也有类似其他写入Flash地址的方法(这里暂不讲述)。 这里面包含几个重要知识点,下面给大家描述一下。

关键词__attribute__

attribute,翻译为“属性”,在C语言中,是一个关键字,语法格式为:

__attribute__ ((attribute-list))

__attribute__ 可以设置函数属性(Function Attribute )、变量属性(Variable Attribute )和类型属性(Type Attribute )。

这部分内容,大家可以不用深入理解,知道这么用即可。要深入理解,网上也有很多学习资源。

C语言标准定义

在代码中:

const char Compiler_Date[] __attribute__((at(VERINFO_ADDR_BASE + 0x40))) = "Date: "__DATE__;
const char Compiler_Time[] __attribute__((at(VERINFO_ADDR_BASE + 0x60))) = "Time: "__TIME__;

你会看到__DATE__ 和 __TIME__表示的日期和时间。 

其实,这两个是C语言特殊的标准定义。

__DATE__:编译时刻的日期字符串 如“Apr 13 2021”

__TIME__:编译时刻的时间字符串  如”20:00:00“

除了这两个,其实还有很多类似的标准定义,比如:

__FILE__ :正在编译文件的文件名

__LINE__ :正在编译文件的行号

__STDC__:判断该文件是不是标准C程序

这部分内容,可以参看我的文章:C语言几种特殊标准定义和用法

总是编译版本文件

在Keil MDK中,默认情况下,源文件不修改,只编译一次。

因此,为了编译版本、日期和时间正确,需要进行设置:总是编译。

如下设置:

1.png

固件大小

生成的Hex文件会对没有使用的Falsh用0x00进行填充,比如:

2.png

填充0x00之后,这个hex就相对很大,因此,有两种方法减少hex固件大小。

1.存放FLASH的地址,要设置在合适的位置,如果代码量只有1K,你这只在偏移50K地址,这样偏移太多。

#define VERINFO_ADDR_BASE   (0x0800FF00) //存放FLASH的地址

2.网上还有一个方法,修改“ROM大小”:

3.png

该小之后,发现真的把0x00去掉了:

4.png

这两种方法,其实有一定风险的,如果代码量不断增加,可能会出现问题。所以,大家要主要设置Flash地址。

这里其实也有一个关于Hex文件格式的内容,推荐阅读文章:轻松理解bin、hex、axf和elf文件格式

来源:strongerHuang

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

围观 74

一、波特率介绍

波特率表示单位时间内传送的码元符号的个数,它是对符号传输速率的一种度量,它用单位时间内载波调制状态改变的次数来表示,即指一个单位时间内传输符号的个数(Baud,单位符号:Bd)。

CW32L083 内部集成 6 个通用异步收发器 (UART),支持异步全双工、同步半双工和单线半双工模式,支持硬件数据流控和多机通信;可编程数据帧结构,可以通过小数波特率发生器提供宽范围的波特率选择。UART 控制器工作在双时钟域下,允许在深度休眠模式下进行数据的接收,接收完成中断可以唤醒 MCU 回到运行模式。

波特率发生器框图如下:

1.png

二、波特率设置

1.同步半双工模式下

波特率计算公式:BaudRate = UCLK / 12

其中,UCLK 是 UART 的传输时钟,其来源可以是 PCLK、LSE 或 LSI,通过控制寄存器 UARTx_CR2 的 SOURCE 位域来选择。

2.异步模式下

UART 的接收和发送波特率是相同的,由同一个波特率发生器产生。波特率发生器支持 16 倍采样、8 倍采样、4 倍采样和专用采样这 4 种采样模式,具体的采样模式通过控制寄存器 UARTx_CR1 的 OVER 位域来选择。UCLK是 UART的传输时钟,其来源可以是 PCLK、LSE或 LSI,具体来源通过 UARTx_CR2.SOURCE来选择。BRRI(UARTx_BRRI[15:0]),是波特率计数器的整数部分,可设置范围为 1 ~ 65535。BRRF(UARTx_BRRF[3:0]),是波特率计数器的小数部分,可设置范围为 0 ~ 15。

OVER = 00,设置 16 倍采样,波特率计算公式:BaudRate = UCLK / ( 16×BRRI + BRRF )

OVER = 01,设置 8 倍采样,波特率计算公式:BaudRate = UCLK / ( 8×BRRI )

OVER = 10,设置 4 倍采样,波特率计算公式:BaudRate = UCLK / ( 4×BRRI )

OVER = 11,设置专用采样,波特率计算公式:BaudRate = ( 256×UCLK ) / BRRI

专用采样仅适合传输时钟源为 LSE 或者 LSI 时,进行 2400bps、4800bps 或 9600bps 波特率下的 UART 通信。

UCLK 为 24MHz 波特率设置示例(OVER = 00)

2.png

UCLK 为 32.768kHz 波特率设置示例(OVER = 11)

3.png

3.波特率自动检测 

CW32L083 使用 UART 作为从机进行通信时,可以通过自动波特率检测的方法,自动适应 UART 主机的波特率。可将通用定时器(GTIM)的输入捕获来源配置为 UART 的 RXD 信号,或者将 GTIM 的门控信号配置为 UART 的 RXD 信号,配合使用相关软件算法测量 UART 的波特率,以实现波特率自适应。

三、波特率计数器寄存器定义

1.UARTx_BRRI 波特率计数器整数部分寄存器

Address offset: 0x0C  Reset value: 0x0000 0000

4.png

2.UARTx_BRRF 波特率计数器小数部分寄存器

Address offset: 0x10  Reset value: 0x0000 0000

5.png

四、波特率设置举例

当传输时钟 UCLK 的频率为 24MHz 时,要求配置 BaudRate = 115200 bps,计算 16×BRRI + BRRF = 24000000 / 115200 = 208.33 则: 

BRRI = 208.33 / 16 = 13.02,最接近的整数是:13(0x0D) 

BRRF = 0.02×16 = 0.32,最接近的整数是:0(0x00) 

即需要设置 UARTx_BRRI 为 0x0D,UARTx_BRRF 为 0x00 此时,实际波特率 BaudRate = 115384.62 bps,误差率为 0.16%。

来源:武汉芯源半导体

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

围观 34

导读

本期将为大家介绍一份应用指南,包括RX单片机进入低功耗模式的方法、注意事项和技巧等内容。以及对RX MCU硬件手册中的常见问题提供相应的说明,帮助您更好地了解硬件手册。

RX单片机低功耗模式区分与技巧

由于欧洲ErP指令和最近的能源状况等原因,人们开始关注和着手解决节能问题(如减少待机功耗),并将其作为决定产品价值的一大要素。

当然,人们对于嵌入到产品且耗电较大的单片机也提出了较高的要求,现在应该有很多客户正在通过低功耗模式来解决这一问题。

但您是否也曾为消耗电流的降低未达预期,苦苦思考也不得其解而困扰?

相信在大家正在使用的单片机中,有很多都是通过硬件支持低功耗功能的。RX单片机支持各类低功耗模式,如表1所示,具体取决于用途和规格。

表1 各类低功耗模式和工作状态

1.png

注1:在软件待机期间,SNOOZE模式会暂时恢复外围功能的运行。这样,在保持低功耗状态的同时,外围功能可以间歇运行。

例如,在软件待机模式下,除子时钟以外的振荡器和许多外围模块都会停止工作,从而显著降低功耗。另一方面,由于可运行的外围模块有限,因此用于恢复的中断因素受限,恢复速度也比休眠模式要慢。因此,您需要根据系统需求使用不同的低功耗模式。

此外,要实现低功耗,不仅要充分利用硬件功能,还要考虑软件。在进入低功耗模式之前,需要进行设置,例如关闭不需要的外围功能和降低时钟频率,并需要考虑将各端子设置为何种状态才能降低功耗,比如将上拉端子设置为H输出。

应用指南假设了是这些原因导致的消耗电流无法下降,并阐述了需要注意的要点和技巧。

此外,对于表2中的运行确认设备,还提供了一个示例程序,您可以立即确认每个低功耗模式下的电流消耗。将示例程序下载到您Renesas Starter Kit中搭载的单片机上,运行后就能进入低功耗模式,检查电流消耗情况。对于非Renesas Starter Kit基板和非运行确认设备的单片机,也可以参考本应用指南实现低功耗需求。

表2 各设备支持的模式

2.png

此外,如表3所示,为解除低功耗模式,除了可使用外部端子中断来实现之外,还可以使用实时时钟报警中断的方法,因此本例更加实用。

表3 使用的外围功能和用途

3.png

注1 仅限在基于RTC的软件待机模式下使用

注2 仅限在基于RTC的深度软件待机模式下使用

为了在您的RX单片机上轻松实现低功耗模式,应用于客户系统构建工作,您可点击下方链接查看RX产品家族应用指南。

https://www.renesas.cn/cn/zh/document/apn/rx-family-examples-transitioning-low-power-consumption-modes-rev120

更多资料

瑞萨RX产品家族网页:

https://www.renesas.cn/cn/zh/products/microcontrollers-microprocessors/rx-32-bit-performance-efficiency-mcus

瑞萨电子开发板及套件网页:

https://www.renesas.cn/cn/zh/design-support/boards-kits

硬件手册使用指南

微控制器(即单芯片微型计算机,以下简称“单片机”)硬件手册对于配备有单片机的产品开发来说非常重要,是必须阅读的资料。但事实是,随着单片机功能的复杂化,手册的页数也会大幅增加,内容也会变得复杂。

内容越复杂,关于手册内容的疑问也就越多。另外,对于首次开发单片机的人来说,所有的文字看起来都犹如天书。

我们会继续提高手册自身的可读性,但为了尽可能完善现有手册的可读性,我们根据客户对硬件手册的常见问题,在硬件手册使用指南中补充了相应的阅读方法。

另外,即使是同样的表述,不同公司也会有不同的含义,所以我们希望大家能够通过本硬件手册使用指南理解RX是如何定义的。

本指南重点介绍了硬件手册中最重要的电气特性,特别是最大绝对额定值、建议运行条件和DC特性项目。本资料将进一步对AC规格、各类外围功能以及内容进行完善。

记载内容如下:

4.png

上图是最大绝对额定值的例子。

此处所述的输入电压标记方法等内容,相对来说存在较多的疑问。

例如,“-0.3~VCC + 0.3(最大4.0)”,如果只有这一句话,很难明白其含义是什么。本资料的目的正是针对那些需要具体说明的部分加以补充,以便您能更好地理解。

更快、更准确地了解硬件手册的内容将有助于提高产品开发的时间效率,防止基板开发后才能发现的各种缺陷。

下载不同产品的硬件手册时,即可在下方相关文件处找到本资料。(位于所要下载硬件手册的下方,仿佛助手一样对硬件手册进行补充说明)

5.png

强烈推荐您一并下载阅读,以随时查看,进而确保RX开发周期一切顺利。RX系列产品网页您可识别下方二维码或复制链接在浏览器中打开查看。

https://www.renesas.cn/cn/zh/products/microcontrollers-microprocessors/rx-32-bit-performance-efficiency-mcus/software-tools/useful-information-rx-mcus

来源:瑞萨MCU小百科

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

围观 17

页面

订阅 RSS - 单片机