8-bit Knowledge Base

    Publish
     
      • Using Port Match

        BrianL | 12/358/2015 | 02:21 PM

        Port Match is a versatile feature included on most Silicon Labs 8-bit MCUs (C8051 and EFM8). This feature allows an interrupt to be generated any time a GPIO pin input level does not match an expected value (which is why it's sometimes referred to as Port Mismatch). On parts with sleep mode, this function can also wake the device, allowing for low-power applications that are sensitive to GPIO changes.

         

        General Operation:

        Port Match is enabled for a particular pin by setting its respective bit in its PnMASK register. For example, to enable port match on P0.0, you would write the following instruction:

         

        P0MASK |= 0x01;

        Additionally, Port Match will not work if the pin is in analog mode, so its respective PnMDIN bit must be set as well to enable the pin's input drivers.

         

         

        P0MDIN |= 0x01;

         

        Once enabled, an interrupt is generated whenever the pin's respective Pn bit and PnMAT bit do not match. For example, if P0 reads 0x01 and P0MAT reads 0x00, an interrupt would be generated due to P0.0 not matching.

         

        Thus, to set P0.0 to interrupt if P0.0 reads 0, the following instruction would be used:

         

        P0MAT |= 0x01;

         

        Interrupt Operation:

        In order to generate an interrupt, the Port Match interrupt and global interrupts should be enabled.

         

        Note: an interrupt will be continually generated as long as there is a port mismatch. If a mismatch event still exists after the ISR exits, the ISR will be immediately called again.

         

        In general, the most useful way to use Port Match is to use a particular trick so that interrupts are only generated on pin edges, rather than continually on one pin level. This can easily be accomplished by assigning the PnMAT register to its relative Pn register value. This removes the mismatch event. For example, an ISR that interrupts only on the edges (both rising and falling) of any enabled Port Match pins would look like the following:

         

        void PMATCH_ISR(void) interrupt PMATCH_IRQn
        {
        	P0MAT = P0;
        	P1MAT = P1;
        }

        Since the value of P0 may change during the ISR, it is recommended to sample it at the beginning of the ISR, then use the sample to determine the behavior of the rest of the ISR, like so:

         

        void PMATCH_ISR(void) interrupt PMATCH_IRQn
        {
                uint8_t P0_sample = P0;
                uint8_t P1_sample = P1;
        	P0MAT = P0_sample;
        	P1MAT = P1_sample;
        }

         

         

         

        Determining Interrupt Cause:

        If multiple pins are enabled for Port Match, it is still relatively simple to determine which pin or pins caused the port match interrupt. Similarly, it is easy to tell whether a rising or falling edge on this pin was the cause.

         

        To determine the pin, merely XOR the PnMAT register with the Pn value.

         

        uint8_t P0_matchPin;
        ...
        P0_matchPin = P0MAT ^ P0_sample;

        To determine the edge, look at this pin's bit in its respective match register. If the match register reads 0 for this bit, then a mismatch will occur when the pin level is 1. This means that the pin transitioned from 0 to 1, or that this was a rising edge. If the match bit is 1, a falling edge occurred on this pin:

         

         

         

        bit edge;
        ...
        edge = (P0MAT & P0_matchPin) == 0;

        In this case, edge being 1 would indicate a rising edge, 0 for a falling edge. 

         

         

        Wake-up Source:

        On devices with a sleep-mode function (C8051F9xx, EFM8SBxx), Port Match events can also wake the device up from sleep mode. In this case, it is not necessary to generate an interrupt, so Port Match interrupts and global interrupts may be left disabled. Only the appropriate PnMAT and PnMASK bits must be set, and Port Match should be enabled as a wakeup source.

         

        An example project for the EFM8BB1 demonstrating Port Match on all available pins and determining which pin/edge caused the event has been attached to this article.

      • Wake-On-LAN Solution

        Stephen | 12/358/2015 | 02:18 PM

        Question

        I found this webpage about your Wake on LAN solution:

        http://www.silabs.com/products/mcu/pages/wake-on-lan.aspx

         

        Is this product available?

        Answer

        This solution is implemented in firmware that runs on Silicon Labs C8051F340 or C8051T622 microcontrollers. Attached is the Wake-On-Lan firmware source code.


        The documentation for the microcontrollers themselves, as well as development kits, can be found here:

        http://www.silabs.com/products/mcu/8-bit/c8051f32x-f34x/Pages/c8051f32x-f34x.aspx

        https://www.silabs.com/products/mcu/8-bit/c8051t62x-t32x/Pages/c8051t62x-t32x.aspx


      • Generate hex file with Raisonance 8051 tools

        Stephen | 12/358/2015 | 02:18 PM

        Question

        I am using the Raisonance 8051 tools to build my project using the Silicon Labs 8-bit IDE. How do I generate a hex file?

        Answer

        The Raisonance 8051 tools build an OMF file. To generate a hex file from the OMF file, obtain the Raisonance's OMF-to-HEX translator (OMF2HEX.exe):

        http://support.raisonance.com/content/can-i-translate-omf-files-hex-or-bin-format

         

        In the Silicon Labs IDE, click on Project > Target Build Configuration > check the Generate hex file option.


        The "generation executable" (program that creates the hex file) should be OMF2HEX.exe from Raisonance.

      • Firmware Version in Kit Manager

        Stephen | 12/358/2015 | 02:17 PM

        Question

        In the Simplicity Studio Kit Manager, I see a "Firmware Version". What is this Kit Firmware?

        Answer

        On every EFM8 and EFM32 kit, there is a Segger J-Link debugger. The Kit Firmware is the debugger firmware, which is updated to address debugger-related bug fixes.

         

        If your kit has old kit/debugger firmware, you will be notified when opening Kit Manager in Simplicity Studio. Upgrading to the newest kit/debugger firmware is always recommended.

         

        kit_firmware.png

         

      • Comparator Input Leakage

        Stephen | 12/358/2015 | 02:16 PM

        Question

        What is the comparator input leakage current?

        Answer

        A comparator input is a pin configured in analog mode. In analog mode, the pin's weak pull is disabled, and its leakage current is specified in the Port I/O DC Electrical Characteristics section of the datasheet, and not in the Comparator Electrical Characteristics section.

         

        For example, the C8051T60x leakage current is max +/- 1 µA (Table 8.3 of the revision 1.2 datasheet).

      • STARTUP.A51是什么文件,如何使用?

        Shaolin | 12/357/2015 | 10:48 PM

                STARTUP.A51是 Keil C51 的项目中的初始化文件。里面包含了中断向量表和变量初始化代码。此文件为可选文件,如果项目中没有此文件将使用编译器中的默认配置。在Simplicity Studio中建立项目时会自动添加此文件。在旧的8比特 IDE中如果想添加此文件可以到如下路径复制一份到项目中:
                        C:\Keil\C51\LIB\STARTUP.A51

         

                不同的MCU上XRAM大小不同,可以在此文件中修改XRAM的大小以实现初始化。

        ; <o> XDATASTART: XDATA memory start address <0x0-0xFFFF> 
        ; <i> The absolute start address of XDATA memory
        XDATASTART EQU 0 

         
                如果系统中定义变量比较多,尺寸比较大,那么初始化时间比较久可能导致看门狗复位,所以可以在初始化函数执行之前关闭看门狗,比如看门狗在PCA模块的设备上可以使用如下代码:

        PCA0MD DATA 0D9H
        CSEG AT 0
        ?C_STARTUP: LJMP STARTUP1
        RSEG ?C_C51STARTUP
        STARTUP1:
        ANL PCA0MD, #0BFH

        而看门狗为独立模块的处理器比如C8051F85x/F86x, EFM8(除 EFM8SB1/SB2/UB2外)上使用如下代码:

         

        STARTUP1: MOV 097H,#0DEH
                  MOV 097H,#0ADH


                附件中的文件是STARTUP.A51的例子。相关参考文章:

                         芯片不停重启,代码无法执行至main()函数。

      • Keil C51中如何在特定地址定义变量、常量?

        Shaolin | 12/357/2015 | 10:47 PM

        可以通过在C语言、汇编语言定义变量时指定地址。也可以通过连接器参数中控制变量、常量的地址。需要注意的是在C语言中定义变量/常量不能同时指定地址和初值。如果在C语言中定义了初值,则需要在连接器选项中指定地址。
        具体的方法参见附件。

      • 烧录程序时如何锁定Flash?

        Shaolin | 12/357/2015 | 10:46 PM

                锁定Flash可以通过烧录工具进行,在烧录工具上选择锁定,这样烧录完毕之后Flash将会被锁定。还有另外的一个锁定Flash的方法就是在lock byte写入特定的值,可以在源代码中加入也可以直接修改hex文件。如下是锁定Flash的例子。
                1. 修改 Hex 文件在文件结束符之前加入一行用来锁定Flash

                新加入02FDFE00000003可以锁定 F02x MCU,例子如下:

        ...
        ...User code...
        ...
        :02FDFE00000003
        :00000001FF
        其中
        02 表示包含2个字节数据
        FDFE 表示起始地址
        00 表示记录类型(普通数据)
        0000 待写入的值
        03 校验和(下面链接中的intel hex文件规范中有解释如何计算)
        00000001FF 文件结束符


        附件中的两个文件一个是 F32x 的例子,一个是 F02x 的例子。

                2. 可以在项目中添加一个常量定义,将这个常量定义到lock byte所在地址,编译器即会在hex文件中生成对应的数据。锁定变量位置的方式参见如下文章:

               Locating a variable in code space (Keil BL51 Linker)

         

        相关链接及软件

        Silicon Laboratories IDE 及Flash编程工具(Flash Programming Utilities):

        https://www.silabs.com/products/mcu/Pages/SoftwareDownloads.aspx

        Intel HEX 文件格式:
        http://www.keil.com/support/docs/1584.htm
        http://www.8052.com/tutintel.phtml

        Flash相关的知识库文章:

        Updating Locked FLASH
        Locating a variable in code space (Keil BL51 Linker)
        Copying firmware from one MCU to another
        Locking Code Memory
      • Keil C51 编译的时候 Large Mode 、Compact Mode 与 Small Mode 区别有哪些?

        Shaolin | 12/357/2015 | 10:45 PM

                Large ModeCompact ModeSmall Mode 是Keil编译时的不同模式,通过传递给编译器的参数来实现,RAM分配和代码编译模式可以分别独立选择三种中的一种。
                Small Mode
                        代码调用、跳转时使用的指令CALL/JMP被编译为ACALL/AJMP,这样就限制代码的整体尺寸不超过2K bytes
                        局部变量被分配在DATA内存中,参数传递也通过DATA内存进行。
                Compact Mode
                        代码调用、跳转时使用的指令CALL/JMP被编译为LCALL/AJMP,这样就限制代码整体尺寸不超过64K bytes,单个函数尺寸不超过2K bytes.
                        局部变量被分配在PDATA内存中,参数传递也通过PDATA内存进行。
                Large Mode
                        代码调用、跳转时使用的指令CALL/JMP被编译为LCALL/AJMP,这样就限制代码整体尺寸不超过64K bytes,单个函数尺寸不超过2K bytes.
                        局部变量被分配在XDATA内存中,参数传递也通过XDATA内存进行。
                参见Keil官方帮助文档:
                                http://www.keil.com/support/man/docs/c51/c51_le_memmodels.htm
                                http://www.keil.com/support/man/docs/c51/c51_le_memtypes.htm
                                http://bubuko.com/infodetail-715474.html

      • C8051Fxxx / EFM8 可以使用哪些编译器?

        Shaolin | 12/357/2015 | 10:45 PM

                C8051Fxxx / EFM8 体系支持标准的C51编译器生成的代码。Keil C51、IAR、SDCC、Raisonace、Tasking、Hi-Tech等。 如果要使用某些型号上的特殊功能则需要特定编译器的支持, 比如在C8051F12x上的有一个硬件乘/累加模块MAC0,此模块非C51的标准模块。编译器在处理乘/累加语句时通常会调用库函数使用C51的8位A、B寄存器进行乘法和加法运算来实现,效率比较低。Keil C51支持可以将乘/累加的C语言代码转换为调用F12x的MAC0模块的指令。

         

                我们与Keil公司达成协议免费为用户提供C51编译器,只需注册即可免费使用。可以通过如下方式之一获取:

                1. 独立版本:

                在如下页面下载并按照AN014的说明进行安装。
                http://www.silabs.com/products/mcu/Pages/8-bit-microcontroller-software.aspx#keil-pk51
                2. 安装Simplicity Studio

                Simplicity Studio中包含了C51编译器。通过Help->Licensing菜单可以注册。