单片机using的功能_单片机 using - CSDN
  • 51单片机 interrupt和 using使用详解

    千次阅读 2017-12-12 20:06:20
    下面是我对interrupt和 using使用详解, 首先看interrupt,这个比较简单,直接看一个外部中断0服务函数的例子 void ext_int0_src() interrupt 0 using 2// { /*外部中断0的服务函数*/ } inter

    注:下文的“BANK”和“工作寄存器组”,这两个名词是一个概念。


    首先推荐一篇文章,点击打开链接

    这篇文章大部分是翻译软件直接翻译的,有些翻译的不通顺的地方、有歧义的地方,直接读读英文原版就清晰了。

    如果链接挂了,自行搜索:关于如何利用Keil C实现51单片机中断功能(interrupt、using关键字的用法


    官方文档里关于using的说明可参阅2个地方,(1)keil软件菜单栏->Help->uVision Heip,打开帮助文件,然后依次展开Ax51 Assembler User Guide -> Control Statement -> Reference -> USING,(2)帮助文件依次展开CX51 Compiler User‘s Guide-> Language Extensions -> Function Declarations -> Register Banks



    下面是我对interrupt和 using使用理解,

    首先看interrupt,这个比较简单,直接看一个外部中断0服务函数的例子

    void ext_int0_src() interrupt 0 using 2//
    {
        /*外部中断0的服务函数*/
    }

    interrupt 0,这里的数字0是外部中断的中断向量号,每一个中断向量都有对应的一个入口地址。如果对中断向量表的概念比较熟悉的话,这里很好理解,不再赘述。


    下面主要看using的使用方法,这个比较复杂,我们从头说起。

        因为51的RAM空间极其有限,keil在编译51的C程序时,C语言函数中的局部变量、形参、返回值、返回地址会优先使用工作寄存器R0~R7(因为工作寄存器读写速度最快),如果这8个字节不够用,keil会为其余的局部变量分配RAM空间,这个空间在编译完成后就固定下来了,假如某个函数中的局部变量a编译后位于RAM的0x5d位置,但是keil也有可能为另一个函数的中的局部变量b分配空间时,把b也分配到RAM的0x5d位置,相当于a和b分时复用同一个RAM空间,这种编译手段也就导致了函数的不可重入特性。51的可重入函数由仿真栈来实现,可参阅本博客的另一篇文章。

          对于STM32等RAM较为充足的单片机来说,keil分配局部变量就不采用这种分时复用RAM的方法了,而是通过栈,具体地说就是,在调用函数前,先把实参添加到工作寄存器(工作寄存器并不是全部用来传参,还有一些用来传递函数的返回值、函数的返回地址等),若工作寄存器满足不了传参需求,那么其余实参将被压栈,这样,在进入函数之后,通过读取工作寄存器和出栈,即可令形参获得实参的值;另外函数中的局部变量一般也先从工作寄存器开始分配空间,若空间不足,会从栈中申请空间。这种编译方法是最常见的,而上一段keil针对51的编译手段比较另类。

        51的工作寄存器R0~R7共有4组(分别是BANK 0、1、2、3),在任何时刻,都只有1个工作组生效!这4个组(BANK)在RAM中的位置分别是[00H, 07H]、[08H, 0FH]、[10H, 17H]、[18H, 1FH],换句话说,RAM中的00H地址、08H地址、10H地址、18H地址,这四个地址的名字都叫R0,那么在汇编程序中我们经常看到类似MOV R0,#07这样的语句,这个#07到底被放到了RAM的哪个地址中去了呢?00H?08H?10H?还是18H?到底是这4个地址中的哪一个,取决于51的PSW寄存器的RS1和RS0两个位,若PSW.RS=2,就意味着第2组工作寄存器生效,R0的地址就是10H。

        上面提到了51不可重入函数的局部变量分时共享同一RAM空间的情况,需要注意的是,未使用的工作寄存器组所在的RAM地址(从00H~1FH共32字节)不会被复用,换句话说,如果我们在程序中没有手动切换工作寄存器组,那么有些寄存器组就在程序的自始至终从不被使用,白白浪费了很多RAM。举个例子,普通函数只使用了BANK 0,且中断函数通过声明using 1只使用了bank 1,那么bank 2和bank3不会被程序的任何地方给用到(唯一的例外:仿真栈指针,下面有讲到);再举个例子,假设整个51程序中都没有使用中断,也即只使用了BANK 0,那么BANK 1、2、3所在的空间在整个程序运行过程中都是闲着的(唯一的例外:仿真栈指针)。

        51在上电后,PSW的RS两个位默认为0,也即51默认使用工作寄存器组BANK 0,在默认状态下,对于普通的C语言函数,其传参、申请局部变量、导出函数的返回值等功能,keil将其翻译成汇编以后,肯定要使用R0~R7;对于51的中断服务函数,它没有形参,也不用返回值,但是一般肯定有局部变量,这时就需要用到R0~R7了;试想,在执行普通函数时,R0~R7已经被使用了,在执行普通函数时,一旦发生中断,而中断函数也需要使用R0~R7,那怎么办?我们最先想到的是,在执行中断服务函数前先把R0~R7入栈(像累加器A、状态PSW等也要入栈这个不用说大家也知道),在中断服务完成后把R0~R7出栈,然后就能恢复现场,回到普通函数中去了,但是这8个Rn不能直接入栈,PUSH R0这样的语句是不允许的,要想R0入栈只能用两句:MOV A R0; PUSH A;这样的后果是,每次工作寄存器入栈都需要2*8=16条汇编语句才能完成,再加上A、B、PSW等寄存器入栈等,相当于每次中断都要消耗大量的时间来出栈入栈,影响程序速度。如何解决这一问题呢?51提供了这样一种机制,切换工作寄存器组,过程如下:

        普通函数的执行过程中正在使用BANK0的R0~R7,执行过程中突然发生了中断,而中断函数也想使用R0~R7,在执行中断服务函数前,我们切换工作寄存器组,切换的具体方法就是直接修改PSW的RS两个比特位,而不必把BANK 0入栈,本文开头的例子中using 2,就是说,在进入外部中断0的服务函数前,先入栈CPU寄存器,再把工作寄存器组由0切换成2,在退出中断服务后,先由BANK2切换回BANK0,并弹出CPU寄存器,由于BANK0和BANK2处在不同的RAM空间,互相不干扰,切换回BANK0之后就把那个普通函数的现场给恢复了。

        还有两个问题点需要说明:

        问题1、对于同一优先级的中断,可以using同一个寄存器组,因为同一优先级的中断不会互相打断,也就是说,例如:我把同一优先级的中断函数都using 2,这些函数也不会冲突地使用R0~R7,他们只会分时复用BANK 2。但是对于不同优先级的中断函数,必须手动设定为让他们使用不同的BANK,因为高优先级的中断会打断低优先级的中断,如果使用相同的BANK,一旦发生中断嵌套,低优先级服务函数正在使用的R0~R7将会被覆盖。这些东西都是说的在用C编程时的情况,如果用的是汇编编程,那我们可以自由的任意压栈出栈CPU寄存器,任意的压栈出栈BANKn,只要程序员自己心里清楚地知道哪些Rn正在被使用,那他就能写出安全的程序。用C编程的话,程序员比较省心,只要使用了using指令,就能轻易地保护R0~R7。当然,在汇编中使用USING也是可以的,也不用压栈出栈BANK,也很省心。

    问题2、如果我们使用了keil为51构造的仿真栈,以大编译模式为例,keil会给仿真栈指针?C_XBP分配一个RAM空间(2个字节),这个空间在哪呢?通过查看map文件(后缀名为.m51)我们发现,若我们的中断函数只使用了BANK 1(普通函数默认已把BANK 0给用了,除非程序员为所有的普通函数都用using 1或2或3来修饰,如果不是闲的蛋疼没人会这么做),这时仿真栈指针?C_XBP将会被分配到BANK 2的R0和R1所在的位置上,也即RAM的10H、11H地址。如果普通函数使用了BANK0,中断函数只使用了using 2,那么?C_XBP将会被分配到BANK 1的R0和R1所在的位置上;如果普通函数使用了BANK0,中断函数使用了BANK1和BANK2,那么?C_XBP将会被分配到BANK 3的R0和R1所在的位置上。


       综上所述,在进入中断服务程序后,要么通过修改PSW切换BANK 号码来保护R0~R7,要么把R0~R7入栈来保护R0~R7。使用using n编写的C语言中断服务函数,keil就给翻译成了PSW切换PSW切换的方式。

    展开全文
  • C语言在8051单片机上的扩展(interrupt、using关键字的用法)直接访问寄存器和端口 定义sfr P0 0x80 sfr P1 0x81 sfr ADCON; 0xDEsbit EA 0x9F 操作ADCON = 0x08;  P1 = 0xFF; io_status = P0 ; EA = 1; 在...

     C语言在8051单片机上的扩展(interrupt、using关键字的用法)

    直接访问寄存器和端口

     定义

    sfr P0 0x80
    sfr P1 0x81
    sfr ADCON; 0xDE

    sbit EA  0x9F


    操作

    ADCON = 0x08;  
    P1 = 0xFF;   

    io_status = P0 ;
    EA = 1;   

            在使用了interrupt 1 关键字之后,会自动生成中断向量

            在 ISR中不能 与其他 “后台循环代码”(the background loop code) 共享局部变量,因为连接器会复用 在RAM中这些变量的位置 ,所以它们会有不同的意义,这取决于当前使用的不同的函数复用变量对RAM有限的51来讲很重要。所以,这些函数希望按照一定的顺序执行 而不被中断。

    void timer0_int(void) interrupt 1 using 2
    {
     unsigned char temp1;
     unsigned char temp2;
     executable C statements;
    }

            “interrupt”声明表向量生成在(8*n+3),这里,n就是interrupt参数后的那个数字这里,在08H的代码区域 生成LJMP timer0_int这样一条指令。

            “using” tells the compiler to switch register banks on entry to an interrupt routine. This “context” switch is the fastest way of

    providing a fresh registerbank for an interrupt routine’s local data and is to be preferred to stacking registers for very time-criticalroutines. Note that interrupts of the same priority can share a register bank, since there is no risk that they will interrupt each other.

            “using” 告诉编译器 在进入51danpi中断处理器 去切换寄存器的bank。这个”contet”切换是为中断处理程序的局部变量提供一个新鲜的寄存器bank最快的方式。对时序要求严格的程序,是首选的stack寄存器(保存寄存器到stack)方式。

            注意:同样优先级别的中断可以共享寄存器bank,因为他们每次将中断没有危险。

            If a USING 1 is added to the timer1 interrupt function prototype, the pushing of registers is replaced by a simple MOV to PSW to switch registerbanks. Unfortunately, while the interrupt entry is speeded up, the direct register addressing used on entry to sys_interp fails. This is because C51 has not yet been told that the registerbank has been changed. If no working registers are used and no other function is called, the optimizer eliminiates teh code to switch register banks.

           如果在timer1的中断函数原型中使用using 1, 寄存器的pushing将被MOV to PSW切换寄存器bank 所替换。

           不幸的是,当一个中断入口被加速时。用在入口的 直接寄存器寻址将失败。这是因为 C51没有告诉 寄存器bank已经改变。如果不工作的寄存器将被使用,如果没有其他函数被调用,优化器…..

            Logically, with an interrupt routine, parameters cannot be passed to it or returned. When the interrupt occurs, compiler-inserted code is run which pushes the accumulator, B,DPTR and the PSW (program status word) onto the stack. Finally, on exiting the interrupt routine, the items previously stored on the stack are restored and the closing “}” causes a RETI to be used rather than a normal RET.

            逻辑上,一个中断服务程序,不能传递参数进去,也不可返回值。当中断发生时,编译器插入的代码被运行,它将累加器,B,DPTR和PSW(程序状态字)入栈。最后,在退出中断程序时,预先存储在栈中 被恢复。最后的”}”结束符号将插入RETI到中断程序的最后,为了用 Keil C语言创建一个中断服务程序(ISR),利用 interrupt 关键词和正确的中断号声明一个static void函数。Keil C编译器自动生成中断向量,以及中断程序的进口、出口代码。Interrupt 函数属性标志着该函数为ISR。可用using属性指定ISR使用哪一个寄存器区,这是可选的。有效的寄存器区范围为1到3。

    中断源的矢量位置

    中断源               Keil中断编号           矢量地址
    最高优先级                 6                     0x0033
    外部中断0                 0                     0x0003
    定时器0溢出               1                     0x000B
    外部中断1                 2                     0x0013
    定时器1溢出               3                     0x001B
    串口                           4                     0x0023
    定时器2溢出               5                     0x002B
    DMA                           7                     0x003B
    硬件断点                    8                     0x0043
    JTAG                         9                     0x004B
    软件断点                   10                     0x0053

    监视定时器               12                     0x0063

    1.函数在调用前定义与在调用后定义产生的代码是有很大差别的(特别是在优化级别大于3级时)。(本人也不太清楚为什么,大概因为在调用前定义则调用函数已经知道被调用函数对寄存器的使用情况,则可对函数本身进行优化;而在调用后进行定义则函数不知被调用函数对寄存器的使用情况,它默认被调用函数对寄存器(ACC、 B、 DPH、 DPL、 PSW、 R0、 R1、 R2、 R3、R 4、 R5、, R6、 R7)都已经改变,因此不在这些寄存器中存入有效的数据)

    2.函数调用函数时除在堆栈中存入返回地址之外,不在堆栈中保存其它任何寄存器。(ACC、 B、 DPH、 DPL、 PSW、 R0、 R1、 R2、 R3、R 4、 R5、, R6、 R7)的内容。(除非被调用函数使用了using特性)

    3.中断函数是一个例外,它会计算自身及它所调用的函数对寄存器(ACC、 B、 DPH、 DPL、 PSW、 R0、 R1、 R2、 R3、R 4、 R5、, R6、 R7)的改变,并保存相应它认为被改变了的寄存器。

    4.使用C写程序时,尽量少使用using n (n=0,1,2,3)特性。(这个特性在本人使用的过程中存在一些问题,不知算不算是一个小bug)

            默认keil c51中的函数使用的是0寄存器组,当中断函数使用using n时,n = 1,2,3或许是对的,但n=0时,程序就已经存在了bug(只有中断函数及其所调用的函数并没有改变R0 —- R7的值时,这个bug不会表现出来)

            一个结论是,在中断函数中如果使用了using n,则中断不再保存R0—-R7的值。由此可以推论出,一个高优先级的中断函数及一个低优先级的中断函数同时使用了using n,(n = 0,1,2,3)当n相同时,这个存在的bug 是多么的隐蔽。(这恰是使人想象不到的)

            使用不同寄存器组的函数(特殊情况外)不能相互调用”using”关键字告诉编译器切换register bank

            如果中断程序不重要,using关键字能忽略。如果一个函数被从中断程序调用,而此中断强制使用using,当编译一个被调用的函数时,编译器必须告诉它
    1)在函数前 必须用伪指令

    #pragma NOAREGS

    在进入函数

    #pragma RESTORE
    或者
    #pragmas AREGS

    这样就不会使用 “绝对地址定位”

    2)#pragma REGISTERBANK(n)

    用这个指定告诉当前使用的bank

    用NOAREGS指令 移除 MOV R7,AR7

    中断服务例程

    void timer0_int(void) interrupt 1 using 1

     unsigned char temp1 ;  
     unsigned char temp2 ;  
    }

    被调用的函数

    #pragma SAVE // Rember current registerbank

    #pragma REGISTERBANK(1)     // Tel C51 base address of current registerbank.
    void func(char x)

    // Called from interrupt routine      
    // with “using1”  
     }

    #pragma RESTORE // Put back to original registerbank


            如果中断服务例程使用了using,被中断服务例程 调用的函数一定要REGISTERBANK(n),一个被ISR调用的函数也可能被后台程序调用为了函数”reentrant(可重入8051 系列MCU的基本结构包括:32 个I/O 口(4 组8 bit 端口);两个16 位定时计数器;全双工串行通信;6 个中断源(2 个外部中断、2 个定时/计数器中断、1 个串口输入/输出中断),两级中断优先级;128 字节内置RAM;独立的 64K 字节可寻址数据和代码区。中断发生后,MCU 转到5个中断入口处之一,然后执行相应的中断服务处理程序。中断程序的入口地址被编译器放在中断向量中,中断向量位于程序代码段的最低地址处,注意这里的串口输入/输出中断共用一个中断向量。8051的中断向量表如下:
    中断源 中断向量
    —————————
    上电复位          0000H
    外部中断0        0003H
    定时器0 溢出   000BH
    外部中断1        0013H
    定时器1 溢出   001BH
    串行口中断       0023H
    定时器2 溢出    002BH

            interrupt 和 using 都是C5 的关键字。C51中断过程通过使用interrupt关键字和中断号(0 到 31)来实现。中断号指明编译器中断程序的入口地址中断序号对应着8051中断使能寄存器IE 中的使能位,对应关系如下:
    IE寄存器 C51中的 8051的
    的使能位 中断号 中断源
    ——————————–
    IE.0 0 外部中断0
    IE.1 1 定时器0 溢出
    IE.2 2 外部中断1
    IE.3 3 定时器1 溢出
    IE.4 4 串口中断
    IE.5 5 定时器2 溢出

            有了这一声明,编译器不需理会寄存器组参数的使用和对累加器A、状态寄存器、寄存器B、数据指针和默认的寄存器的保护。只要在中断程序中用到,编译器会把它们压栈,在中断程序结束时将他们出栈。C51 支持所有 5 个 8051 标准中断从 0 到 4 和在 8051 系列(增强型)中多达 27 个中断源。
            using 关键字用来指定中断服务程序使用的寄存器组。用法是:using 后跟一个0 到3 的数,对应着 4 组工作寄存器。一旦指定工作寄存器组,默认的工作寄存器组就不会被压栈,这将节省 32 个处理周期,因为入栈和出栈都需要 2 个处理周期。这一做法的缺点是所有调用中断的过程都必须使用指定的同一个寄存器组,否则参数传递会发生错误。因此对于using,在使用中需灵活取舍。

    展开全文
  • void INT0()interrupt 0 using 1 {.... ..... } interrupt 0 指明是外部中断0; interrupt 1 指明是定时器中断0; interrupt 2 指明是外部中断1; interrupt 3 指明是定时器中断1; interrupt 4 指明是...
    void INT0()interrupt 0 using 1
    {....
    .....
    }
    interrupt 0  指明是外部中断0;
    interrupt 1  指明是定时器中断0; 
    interrupt 2  指明是外部中断1;
    interrupt 3  指明是定时器中断1;
    interrupt 4  指明是串行口中断;
    
    using 0 是第0组寄存器;
    using 1 是第1组寄存器;
    using 2 是第2组寄存器;
    using 3 是第3组寄存器;
    
    51单片机内的寄存器是R0--R7(不是R0-R3)
    
    R0-R7在数据存储器里的实际地址是由特殊功能寄存器PSW里的RS1、RS0位决定的。
    
    using 0时设置 RS1=0,RS0 =0,用第0组寄存器,R0--R7的在数据存储区里的实际地址是00H-07H。R0(00H)....R7(07H)
    
    using 1时设置 RS1=0,RS0 =1,用第1组寄存器,R0--R7的在数据存储区里的实际地址是00H-07H。R0(08H)....R7(0FH)
    
    using 2时设置 RS1=1,RS0 =0,用第2组寄存器,R0--R7的在数据存储区里的实际地址是08H-0FH。R0(10H)....R7(17H)
    
    using 3时设置 RS1=1,RS0 =1,用第3组寄存器,R0--R7的在数据存储区里的实际地址是00H-07H。R0(18H)....R7(1FH)

    转载于:https://www.cnblogs.com/xianghang123/archive/2011/02/24/1963699.html

    展开全文
  • void INT0()interrupt 0 using 1 {.... ..... } interrupt 0 指明是外部中断0; interrupt 1 指明是定时器中断0; interrupt 2 指明是外部中断1; interrupt 3 指明是定时器中断1; interrupt 4 指明是...
    【引自http://www.cnblogs.com/xianghang123/archive/2011/02/24/1963699.html】
    
    void INT0()interrupt 0 using 1
    {....
    .....
    }
    interrupt 0  指明是外部中断0;
    interrupt 1  指明是定时器中断0; 
    interrupt 2  指明是外部中断1;
    interrupt 3  指明是定时器中断1;
    interrupt 4  指明是串行口中断;
    
    using 0 是第0组寄存器;
    using 1 是第1组寄存器;
    using 2 是第2组寄存器;
    using 3 是第3组寄存器;
    
    51单片机内的寄存器是R0--R7(不是R0-R3)
    
    R0-R7在数据存储器里的实际地址是由特殊功能寄存器PSW里的RS1、RS0位决定的。
    
    using 0时设置 RS1=0,RS0 =0,用第0组寄存器,R0--R7的在数据存储区里的实际地址是00H-07H。R0(00H)....R7(07H)
    
    using 1时设置 RS1=0,RS0 =1,用第1组寄存器,R0--R7的在数据存储区里的实际地址是00H-07H。R0(08H)....R7(0FH)
    
    using 2时设置 RS1=1,RS0 =0,用第2组寄存器,R0--R7的在数据存储区里的实际地址是08H-0FH。R0(10H)....R7(17H)
    
    using 3时设置 RS1=1,RS0 =1,用第3组寄存器,R0--R7的在数据存储区里的实际地址是00H-07H。R0(18H)....R7(1FH)
    展开全文
  • 关于单片机using使用

    千次阅读 2009-06-28 22:45:00
    C51的中断函数的格式为:void FuncIr(void) interrupt x [using y]以下是梦游的一些分析: 一、中断函数是一个特殊的函数,没有参数,也没有返回值;但是程序中允不允许使用return呢?答案是允许的,不过只能用...
  • 51在上电后,PSW的RS两个位默认为0,也即51默认使用工作寄存器组BANK 0,在默认状态下,对于普通的C语言函数,其传参、申请局部变量、导出函数的返回值等功能,keil将其翻译成汇编以后,肯定要使用R0~R7;...
  • 51单片机中断细节的一些问题。 interrupt0:外部中断0interrupt1:定时器中断0interrupt2:外部中断interrupt3:定时器中断1interrupt4:串口 using 0 是第0组寄存器; using 1 是第1组寄存器; using 2 是第2组寄存器...
  • C语言在8051单片机上的扩展(interrupt、using关键字的用法) 直接访问寄存器和端口  定义 sfr P0 0x80 sfr P1 0x81 sfr ADCON; 0xDE sbit EA 0x9F 操作 ADCON = 0x08;  P1 = 0xFF;  io_status = ...
  • 51单片机串口通讯详解

    千次阅读 2019-11-04 22:26:31
    无论是作为调试工具,打印出调试信息,还是对功能模块进行通信,串口是每个单片机开发人员最常用的单片机外设。 由于大部分51单片机不支持在线调试功能,所以串口作为一种有效的调试功能,所以在51单片机程序开发时...
  • 51单片机DHT11温湿度检测手机蓝牙APP显示设计

    万次阅读 多人点赞 2019-05-27 20:56:05
    今天给大家介绍的是一个温湿度检测设计,基于51单片机、蓝牙模块、温湿度传感器、Android APP完成。首先先展示一下设计好的实物,接下来将从系统方案、硬件设计、软件设计这三个方面来阐述。 1.系统方案 先...
  • 1、在程序开始处,声明程序中用到的命名空间,...using System; // 声明了程序中用到的一个命名空间 System using io = System.IO; // 给命名空间 System.IO 定义了一个别名,叫io namespace ConsoleApplication1
  • 单片机 中断

    千次阅读 多人点赞 2018-05-31 15:08:05
    单片机 中断一、简述 中断,即CPU在正常执行程序的过程中,遇到外部/内部的紧急事件需要处理,暂时中断(中止)当前程序的执行,而转去为事件服务,待服务完毕,再返回到暂停处(断点)继续执行原来的程序。...
  • 相信喜欢单片机的朋友都用过STC的单片机,用过STC单片机的朋友都有这种感受:实惠、易用、功能强大!就是每次下载都要冷启动特别恶心,相信很多朋友的开发板上的电源键都按烂了。  其实STC单片机可以不用免掉电下载...
  • 基于51单片机的智能晾衣架系统设计

    万次阅读 2019-03-23 00:02:09
    1.功能介绍 设计基于51单片机的智能晾衣架。主要功能如下: (1)控制晾衣架的升降。 (2)具有限位开关功能。 (3)具有无线遥控功能。 (4)能够指示运行状态。 (5)具有智能模式,可以根据环境光线控制晾衣架的...
  • 基于51单片机的RFID RC522智能钱包

    千次阅读 2018-12-06 23:04:11
    基于51单片机的RFID RC522智能钱包,这个程序主要演示的是RFID RC522智能钱包中的设置及扣款功能,相信会扣款那么充值也就改一个数字的事,具体的功能要自己根据实际情况进行编写,下面是代码: #include "reg...
  • 单片机超轻量级操作系统

    万次阅读 2017-01-10 18:54:18
    在写完面向对象的单片机编程,就特别想在单片机编程引入一个多线程多任务的编程,把这个思想引入单片机。后发现如下好文,后面再把它封装成类的话,就更方便使用了,我觉得这将会使很多只有操作系统能做的工作,普通...
  • 在 使用STC8H1K的高级PWM的正交编码器计数方式 实验中,开始对于基于STC8H1K28单片机的高级PWM功能对于正交编码信号进行计数解调的过程中,通过对于STC8H1K28单片机的数据手册相关内容阅读,并进行实验,最终没有...
1 2 3 4 5 ... 20
收藏数 2,401
精华内容 960
关键字:

单片机using的功能