微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 一种基于avr的多任务机制

一种基于avr的多任务机制

时间:11-18 来源:互联网 点击:
首先要获得函数的pc地址,并通过获得的函数地址,轻松切换函数数。其目的是减少坠余的代码。比如说对按键扫描的扫描,以达到精简函数代码,提高函数执行效率。

其主要的思想就是利用中断返回的时候改变函数的返回地址,来实现的,当然用指针也可以过得函数地址,以下是用iccavr仿真编译软件和hex文件反汇编软件以及proteus仿真实验,单片机atmega16调试的内容。
首先,我们用C语言编译以一段函数,自定义4个不同的函数,举例:3个发光二极管发光来指示。
如:
#include
#include
unsigned int sp_ZHI=0,SP_init=0;

void LED_1(void)
{ while(1){PORTB=(1

void LED_2(void)
{while(1){PORTB=(1

void LED_3(void)
{ while(1){PORTB=(1

然后再设计一个关函数,
void LED_OFF(void)
{ while(1){PORTB=0;}}

接着是中断初始化及其端口配置,
void INTER_init_0()
{

PORTA = 0xFF;
DDRA = 0xff;
PORTB = 0xff;
DDRB = 0xff;
PORTC = 0xFF;
DDRC = 0x00;
PORTD = 0xFF;
DDRD = 0x00;

MCUCR|=1GICR|=(1GIFR&=~(1

}
中断请求函数

unsigned char k=4;
//外部中断0向量端口
#pragma interrupt_handler int0_isr:iv_INT0
void int0_isr(void)
{

k++;
if(k>=4)
k=0;
SP=sp_ZHI-2;//这个sp_ZHI-2是通过反汇编看出来的,查看一下汇编。
}

//重置堆栈指针,防止堆栈溢出
void SP_INIT(unsigned int a)
{
SP=a;

}

然后我们定义主函数
其主函数的功能:

开机显示为3个发光二极管都发光

通过按键中断切换发光二极管。



void main(void)
{ INTER_init_0();
sp_ZHI=SP;
SP_INIT(sp_ZHI);
SREG|=0x80;//使能全局中断
PORTB = 0;
while(1)
{
switch(k)
{
case 1:LED_1();break;
case 2:LED_2();break;
case 3:LED_3();break;
default :LED_OFF();break;
}
}
}

以下以本C语言函数通过反汇编软件编译出来的汇编程序,
; reassembly of "实验.hex"
; created by ReAVR V3.2.0
; at 2010/02/02 - 22:04:10
; for ICCAVR assembler
;---------------------------------------
; AVR_TYPE=
; FLASH_SIZE=8KB
; SRAM_START=0x60
;---------------------------------------
.area text
;; older iccavr need different setup:
;; .area text (abs,ovr)
;; .org 0x0000
;---------------------------------------
; byte constants:
;
k00 = 0x00 ;
k01 = 0x01 ;
k02 = 0x02 ;
k03 = 0x03 ;
k04 = 0x04 ;
k10 = 0x10 ;
k40 = 0x40 ;@
k5F = 0x5F ; _
k60 = 0x60 ; `
k65 = 0x65 ; e
kAA = 0xAA ; ?
kBF = 0xBF ; ?
kFF = 0xFF ;
;
; io register addresses:
;
p11 = 0x11
p12 = 0x12
p14 = 0x14
p15 = 0x15
p17 = 0x17
p18 = 0x18
p1A = 0x1A
p1B = 0x1B
p35 = 0x35
p3A = 0x3A
p3B = 0x3B
p3D = 0x3D
p3E = 0x3E
p3F = 0x3F
;
; bit numbers:
;
b0 = 0x00
b1 = 0x01
b2 = 0x02
b3 = 0x03
b4 = 0x04
b5 = 0x05
b6 = 0x06
b7 = 0x07
;---------------------------------------
;
L0000:
jmp __start ; L0033
; ----------- jump on last line
jmp L0085
; ----------- jump on last line
.word 0xFFFF ; pc=0x0004(0x0008)
.word 0xFFFF ; pc=0x0005(0x000A)
.word 0xFFFF ; pc=0x0006(0x000C)
.word 0xFFFF ; pc=0x0007(0x000E)
.word 0xFFFF ; pc=0x0008(0x0010)
.word 0xFFFF ; pc=0x0009(0x0012)
.word 0xFFFF ; pc=0x000A(0x0014)
.word 0xFFFF ; pc=0x000B(0x0016)
.word 0xFFFF ; pc=0x000C(0x0018)
.word 0xFFFF ; pc=0x000D(0x001A)
.word 0xFFFF ; pc=0x000E(0x001C)
.word 0xFFFF ; pc=0x000F(0x001E)
.word 0xFFFF ; pc=0x0010(0x0020)
.word 0xFFFF ; pc=0x0011(0x0022)
.word 0xFFFF ; pc=0x0012(0x0024)
.word 0xFFFF ; pc=0x0013(0x0026)
.word 0xFFFF ; pc=0x0014(0x0028)
.word 0xFFFF ; pc=0x0015(0x002A)
.word 0xFFFF ; pc=0x0016(0x002C)
.word 0xFFFF ; pc=0x0017(0x002E)
.word 0xFFFF ; pc=0x0018(0x0030)
.word 0xFFFF ; pc=0x0019(0x0032)
.word 0xFFFF ; pc=0x001A(0x0034)
.word 0xFFFF ; pc=0x001B(0x0036)
.word 0xFFFF ; pc=0x001C(0x0038)
.word 0xFFFF ; pc=0x001D(0x003A)
.word 0xFFFF ; pc=0x001E(0x003C)
.word 0xFFFF ; pc=0x001F(0x003E)
.word 0xFFFF ; pc=0x0020(0x0040)
.word 0xFFFF ; pc=0x0021(0x0042)
.word 0xFFFF ; pc=0x0022(0x0044)
.word 0xFFFF ; pc=0x0023(0x0046)
.word 0xFFFF ; pc=0x0024(0x0048)
.word 0xFFFF ; pc=0x0025(0x004A)
.word 0xFFFF ; pc=0x0026(0x004C)
.word 0xFFFF ; pc=0x0027(0x004E)
.word 0xFFFF ; pc=0x0028(0x0050)
.word 0xFFFF ; pc=0x0029(0x0052)
.word 0xFFFF ; pc=0x002A(0x0054)
.word 0xFFFF ; pc=0x002B(0x0056)
.word 0xFFFF ; pc=0x002C(0x0058)
.word 0xFFFF ; pc=0x002D(0x005A)
.word 0xFFFF ; pc=0x002E(0x005C)
.word 0xFFFF ; pc=0x002F(0x005E)
nop
nop
; --------- this is skippy
sbrs r16,b4
;
__start::
; L0033:
ldi r28,k5F
; --------- last may be skipped
; pc=0x34(0x68)
;
ldi r29,k04
out p3D,r28
out p3E,r29
subi r28,k10
sbci r29,k00
ldi r16,kAA
std Y+o00,r16
clr r0
ldi r30,k65
ldi r31,k00
ldi r17,k00
L003F:
cpi r30,k65
cpc r31,r17
breq L0044
; ----- branch on last line
st Z+,r0
rjmp L003F
; ----------- jump on last line
L0044:
st Z,r16
ldi r30,k60
ldi r31,k00
ldi r26,k60
ldi r27,k00
ldi r17,k00
L004A:
cpi r30,k65
cpc r31,r17
breq L0051
; ----- branch on last line
lpm
adiw r30,k01
st X+,r0
rjmp L004A
; ----------- jump on last line
L0051:
call L00A3
L0053:
rjmp L0053
; ----------- jump on last line
; pc=0x54(0xA8)
;
L0054:
rjmp L0057
; ----------- jump on last line
L0055:
ldi r24,k01
out p18,r24
L0057:
rjmp L0055
; ----------- jump on last line
ret
;----------------------*
; pc=0x59(0xB2)
;
L0059:
rjmp L005C
; ----------- jump on last line
L005A:
ldi r24,k02
out p18,r24
L005C:
rjmp L005A
; ----------- jump on last line
ret
;----------------------*
; pc=0x5E(0xBC)
;
L005E:
rjmp L0061
; ----------- jump on last line
L005F:
ldi r24,k04
out p18,r24
L0061:
rjmp L005F
; ----------- jump on last line
ret
;----------------------*
; pc=0x63(0xC6)
;
L0063:
rjmp L0066
; ----------- jump on last line
L0064:
clr r2
out p18,r2
L0066:
rjmp L0064
; ----------- jump on last line
ret
;----------------------*
; pc=0x68(0xD0)
;
L0068:
sts (p3E+0x20),r17 ; io register
sts (p3D+0x20),r16 ; io register
ret
;----------------------*
; pc=0x6D(0xDA)
;
L006D:
ldi r24,kFF
out p1B,r24
out p1A,r24
out p18,r24
out p17,r24
out p15,r24
clr r2
out p14,r2
out p12,r24
out p11,r2
in r24,p35
ori r24,k02
out p35,r24
in r24,p35
ori r24,k01
out p35,r24
in r24,p3B
ori r24,k40
out p3B,r24
in r24,p3A
andi r24,kBF
out p3A,r24
sei
ret
;----------------------*
; pc=0x85(0x10A)
;
L0085:
st -Y,r2
st -Y,r24
st -Y,r25
in r2,p3F
st -Y,r2
lds r24,D0064
subi r24,kFF
sts D0064,r24
cpi r24,k04
brcs L0094
; ----- branch on last line
clr r2
sts D0064,r2
L0094:
lds r24,D0060
lds r25,D0061
sbiw r24,k02
sts (p3E+0x20),r25 ; io register
sts (p3D+0x20),r24 ; io register
ld r2,Y+
out p3F,r2
ld r25,Y+
ld r24,Y+
ld r2,Y+

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top