ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 14.06.2025

Просмотров: 3142

Скачиваний: 0

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

140 10 AVR Development Board

The CODE segment starts with the interrupt vector area. In this example, only two vectors are used: the reset vector, and the vector for the interrupt for timer0 overflow. The reset vector directs the program to the initialization sequence, and the timer0 overflow vector contains a jump instruction to the associated interrupt service routine, isr_t0_ov.

INIT.ASM contains the initialization sequence, which starts by loading the stack pointer SP with the last address of the internal RAM (Ramend), then calls the initialization routines for timer0, and I/O port B.

After the initialization sequence, the program enables the interrupts, loads the software timer s_timer0 with a constant (time_s_timer0), which defines the time between the moments when port B changes its status, then enters the main loop.

This software timer is the key element of the program. Basically, s_timer0 is an 8-bit RAM variable defined in MAP.ASM, and decremented every 10 milliseconds by the interrupt service routine for timer0 overflow. If the timer is loaded with the value N, it will reach zero after a time T = N × 10 ms.

In this example, N is the constant time_s_timer, defined in MAP.ASM with the value 50, which gives a total time of 500 ms between the moments when port B is toggled. When the software timer expires, port B changes its status, then the timer is reloaded, and the program continues in an endless loop.

The resource-specific routines are placed outside the main loop in the modules TIMER.ASM and IO.ASM. TIMER.ASM contains the initialization sequence for timer0, organized as a subroutine init_timer0, and the interrupt service routine that implements the software timer.

Here is the listing of TIMER.ASM:

init_timer0:

ldi tmp1,prescaler_constant out tccr0,tmp1

ldi tmp1,ft_div mov rint,tmp1 out tcnt0,tmp1 ldi tmp1,$01 out timsk,tmp1 ret

This routine chooses the division factor for the prescaler, and the number of clocks before overflow, then enables the interrupt for timer0 overflow.

isr_t0_ov:

out

tcnt0,rint

in

rsav,sreg

push

tmp1

rcall

soft_timer

pop

tmp1

out

sreg,rsav

ret

10.4 The Software

141

Note how this routine saves and restores the CPU status. The register rint (an alias for r1) is preloaded with the number of clocks before tcnt0 overflows, so that tcnt0 can be reloaded as fast as possible.

soft_timer:

lds tmp1,s_timer0 tst tmp1

breq sft1 dec tmp1

sts s_timer0,tmp1

sft1:

lds tmp1,s_timer1 tst tmp1

breq ex_sft dec tmp1

sts s_timer1,tmp1

ex_sft:

ret

The routine soft_timer implements two independent software timers, s_timer0 and s_timer1. In principle, the number of distinct timers that can be implemented using this technique is limited only by the time required to execute the interrupt service routine. If a larger number of software timers is required, use the technique described in Chap. 9 for HC11 to reduce the execution time of the interrupt service routine.

Step 6. Adding a New Task to an Existing Application

The structure of the software described in the previous paragraph can be used for almost any application. Adding a new task to an existing application involves the following steps:

1.Modify MAP.ASM to define more variables if needed.

2.Write a new software module if a new resource is required. It is recommended to keep all the routines associated with specific resources in separate files (e.g. TIMER.ASM, IO.ASM, UART.ASM, ADC.ASM, etc.)

3.Modify the main program so that it includes calls to subroutines that actually execute the new task.

In the following example, the program reports the status of port B as a string of two ASCII digits, followed by CR+LF, over the asynchronous serial communication line, when the ASCII code for ‘?’ is received on the serial line. Note that port B is toggled every 500 ms, as described in the previous example.

The UART initialization routine and the communication routines are placed in a separate file UART.ASM, invoked in the main module using the “.include” directive. A separate file, LIB.ASM, is used for miscellaneous library routines – in this case hex-to-ASCII conversion routines used to prepare data for serial communication.


142 10 AVR Development Board

Here is the listing of the main module UARTMAIN.ASM:

.include ‘‘8535def.inc’’

.include ‘‘map.asm’’

.cseg

.org 0

reset:

rjmp init

.org 9 vector_t0_ov:

rjmp isr_t0_ov

init:

.include ‘‘init.asm’’ sei

ldi

tmp1,time_s_timer0

sts

s_timer0,tmp1

main_loop:

rcall

get_uart

brcc

main0

cpi

tmp1,’?’

brne

main0

rcall

send

main0:

lds

tmp1,s_timer0

tst

tmp1

brne

main_loop

ldi

tmp1,time_s_timer0

sts

s_timer0,tmp1

rcall

toggle

rjmp

main_loop

,include ‘‘timer.asm’’

.include ‘‘uart.asm’’

.include ‘‘io.asm’’

.include ‘‘lib.asm’’

Note the two new subroutine calls included in the main loop: get_uart, and send. Get_uart checks if a character is available in the receiver’s data register, reads the character in tmp1, and sets the carry bit to inform the main program. When no

character is available, get_uart returns carry = 0.

get_uart:

clc

sbis

usr,rxc

;check rxc status bit

ret

in

tmp1,udr

;get character received

sec

;set carry

ret

;and return


10.4 The Software

143

Send prepares and sends over the communication line a string comprising two ASCII digits corresponding to the hexadecimal value of each nibble of port B, plus CR and LF.

send:

rcall

hex_asc

;convert tmp1 to ASCII

rcall

put_uartw

;send tmp1

mov

tmp1,tmp2

;next character in tmp2

rcall

put_uartw

;send next character

ldi

tmp1,$0D

;CR

rcall

put_uartw

ldi

tmp1,$0A

;LF

rcall

put_uartw

ret

Put_uartw waits for the status bit UDRE to be set, then writes the content of tmp1 to UDR. It does not check for valid ASCII characters before sending.

put_uartw:

sbis

usr,udre

;check if

TX

;register

empty

rjmp

put_uartw

;wait

until ready to send

out

udr,tmp1

;send

the byte

ret

144 10 AVR Development Board

10.5 Exercises

SX 10.1

Use two software timers to make the upper and lower nibble of port B toggle at different time intervals.

Solution

The two software timers s_timer0 and s_timer1 described in the previous paragraphs must be loaded with different constants to obtain different time intervals for toggling the lines of port B. Here is how LEDMAIN.ASM should be modified for this:

init:

.include ‘‘init.asm’’

sei

ldi

tmp1,time_s_timer0

sts

s_timer0,tmp1

;start s_timer0

ldi

tmp1,time_s_timer1

sts

s_timer1,tmp1

;start s_timer1

main_loop:

lds

tmp1,s_timer0

tst

tmp1

brne

main1

ldi

tmp1,time_s_timer0 ;restart s_timer0

sts

s_timer0,tmp1

rcall

toggle1

;act on port

main1:

lds

tmp1,s_timer1

;check s_timer1

tst

tmp1

brne

main_loop

ldi

tmp1,time_s_timer1 ;restart s_timer1

sts

s_timer1,tmp1

rcall

toggle2

;act on port

rjmp

main_loop

Each of the subroutines toggle1 and toggle2 must affect only one nibble of port B, leaving the other nibble unchanged:

toggle1:

in

tmp1,portb

;read port

mov

tmp2,tmp1

;save it to tmp2

andi

tmp2,$0F

;mask lower nibble

com

tmp1

andi

tmp1,$F0

;mask upper nibble

or

tmp1,tmp2

;recompose

out

portb,tmp1

;write new value

ret

;to the port


11

8051 Development Board

11.1 In this Chapter

This chapter contains the description of a simple development board for the study of the 8051 family of microcontrollers.. Unlike the development boards dedicated to the HC11 and AVR families, presented in the previous chapters, this project allows the user to load and execute programs in an external RAM area, addressed to be visible both in the program memory and data memory address space.

11.2 Hardware

The schematic of the board is presented in Fig. 11.1, 11.2, and 11.3. Figure 11.1 shows the microcontroller IC10, the bus demultiplexer IC7, the RS232 interface IC12, the RESET and clock circuits, and the ISP connector SV1.

Note the presence of the two NAND gates IC6C and IC6D, which implement the logic function AND between the signals RD\ (Read) and PSEN\ (Program Store Enable), both active LOW, and generate the signal RDPSEN. RDPSEN is active LOW when either RD\ or PSEN\ is LOW. Connecting this signal to the RD\ input of an external RAM circuit allows the use of this RAM to store program as well as data.

The microcontroller can be any of 8032, 8051, 8052, AT89C51, AT89C52, etc. in a DIP40 package. The input EA\ (External Access) of the MCU is connected to the jumper JP1 to allow the use of the internal ROM, if this is available. Connect the jumper so that EA\ = 1 to use the internal ROM. When the external ROM is used, EA\ must be connected to GND.

The clock circuit comprises the crystal Q1 (14.74 MHz) and the capacitors C6, C7 (22 pF). C5 (10 µF) and R4 (10 K) implement the RESET circuit. The pushbutton S1 is provided to allow manual reset of the circuit.

The latch SN74HC573 (IC7), controlled by the signal ALE (Address Latch Enable), is used to demultiplex the external data bus, by storing the lower half (A0–A&) of the address bus.

146

11

8051 Development Board

C10

IC12

1 C1+

C11

VCC

3 C1-

V+ 2

C9

V-

6

GND

4 C2+

C8

SV2 2

TX

5 C2-

14

1

11

T1IN T1OUT

3

4

5

6

12 R1OUT R1IN 13

7

8

J1

9

10

8051

MAX232

15

16 WR\

LSP 4

P35-T1 P36-WR

IC6D

IC6C

14

6

13

P34-T0

17 RD\

12

11

9

8 RDPSEN

3

12

P33-INT1 P37-RD

5

11

P32-INT0

PSEN

29 PSEN 13

10

GND

SV1

P31-TXD

10

74HC00

DATA BUS

10

9

MISO

P30-RXD

ALE

30 ALE

8

7

SCK

8

IC7

6

5

LD

P17

39 D0

19 A0

4

3

7

P00-AD0

D0 2

1D

1Q

2

1

MOSI

6

P16

38 D1

D1 3

18 A1

MRST

5

P15

P01-AD1

37 D2

D2 4

2D

2Q

17 A2

4

P14

P02-AD2

36 D3

D3 5

3D

3Q

16 A3

VCC

LSP 7

3

P13

P03-AD3

35 D4

D4 6

4D

4Q

15 A4

2

P12

P04-AD4

34 D5

D5 7

5D

5Q

14 A5

R4

2

1

P11

P05-AD5

33 D6

D6 8

6D

6Q

13 A6

1

P10

P06-AD6

32 D7

D7 9

7D

7Q

12 A7

RST

9

RST

P07-AD7

8D

8Q

ALE 11

JP2

C

VCC

31

EA

21 A8

20

P20-A8

1

0C

LOW ADDRESS BUS

GND

22 A9

C5

40

P21-A9

23 A10

74HC573

S1

18

VCC

P22-A10

24 A11

GND

XTAL2

P23-A11

25 A12

C6

P24-A12

26 A13

Q1

P25-A13

27 A14

P26-A14

28 A15

19

XTAL1

P27-A15

HIGH ADDRESS BUS

JP1

GND C7

IC10

Fig. 11.1. MCU, bus demultiplexer, RESET, clock, and RS232

The ISP (In System Programming) connector SV1 has been included to allow the use of microcontrollers like AT89LS51, AT89S52 that are provided with this feature. In this case, the jumper JP2 must be connected to bring the signal RST to SV1 pin 5.

The memory circuits and the address decoder are presented in Fig. 11.2. IC5 (AT28C64) is an 8-kilobytes EEPROM, having the chip select input CS\ connected to the signal CS0000, generated by the address decoder IC9 (7445), and the output enable input OE driven by the signal PSEN, generated by the MCU.

LOW ADDRESS BUS

DATA BUS

IC5

A0 10

11 D0

IC2

6264

A0

I/O0

A0 10

A1

9

A1

I/O1

12 D1

A0

I/O0

11 D0

A2

8

A2

I/O2

13 D2

A1

9

A1

I/O1

12 D1

A3

7

A3

I/O3

15 D3

A2

8

A2

I/O2

13 D2

A4

6

A4

I/O4

16 D4

A3

7

A3

I/O3

15 D3

A5

5

A5

I/O5

17 D5

A4

6

A4

I/O4

16 D4

A6

4

A6

I/O6

18 D6

A5

5

A5

I/O5

17 D5

A7

3

A7

I/O7

19 D7

A6

4

A6

I/O6

18 D6

A8 25

A8

A7

3

A7

I/O7

19 D7

A9 24

A9

A8 25

A8

D0

VCC

A10 21

A10

A9 24

A9

A11 23

A11

A10 21

A10

D1

A12

2

A12

A11 23

A11

D2

R6

CS0000 20

CE\

A12

2

A12

D3

CS2000 20

CE\

D4

PSEN 22

OE\

D5

VCC

27

WE\

RDPSEN 22

OE\

D6

AT28C64

WR\

27

WE\

D7

VCC

A13 15

A

O0

1

CS0000

A14 14

B

O1

2

CS2000

R3

A15 13

C

O2

3

CS4000

HIGH ADDRESS BUS

12

D

O3

4

CS6000

O4

5

CS8000

GND

O5

6

CSA000

O6

7

CSC000

O7

9

CSE000

IC9

7445

Fig. 11.2. External memory and address decoder