assembly, atmel 8515

Thread Starter

nice_song

Joined Mar 11, 2008
6
dear all,
i'm a new at programming AT8515 assembly language, right now, im stuying it by myself. I use AVR studio simulator tool for my programs.
I need help programming the UART. I think i need some sample programs for UART programming so i can move on in my programming..

who can help me in this?
hope you will reply.
thanks!
 

hgmjr

Joined Jan 28, 2005
9,029
Take a look at this webpage www.avrbeginners.net. There is a section on setting up the UART in an AVR device. It is written in assembly language but the register initialization will be the same in either case.

There is actually a pretty good example of initializing the USART in the ATMEGA8515's datasheet on page 141.

hgmjr
 

Thread Starter

nice_song

Joined Mar 11, 2008
6
hi!

i'm using assembly language..

..one particular problem i have is that i have to send the positions of the switch and display the received positions of the switch on the hyperterm programs in windows and on the other STK500 LED when connected together through their serial ports. I use port A for my switches and port C for my leds..

thanks for the reply.
 

hgmjr

Joined Jan 28, 2005
9,029
hi!

i'm using assembly language..

..one particular problem i have is that i have to send the positions of the switch and display the received positions of the switch on the hyperterm programs in windows and on the other STK500 LED when connected together through their serial ports. I use port A for my switches and port C for my leds..

thanks for the reply.
What assistance do you need at this point? Have you sorted out the UART initialization difficulty you mentioned you were having?

hgmjr
 

Thread Starter

nice_song

Joined Mar 11, 2008
6
yup.. i have sorted out the UART initialization already.
thanks for the link!

i'm currently integrating things...
i might need some help later.. please keep posted.:)

thanks so much..
 

Thread Starter

nice_song

Joined Mar 11, 2008
6
hi!

i got this program code from a friend,
the problem with this program is whenever i try in with the board,
the output on the screen (windows hyper term) appears to be more than one number (eg. when i press the push button for the 1, what appears in the screen is 1111111111111111111111111111, something like that).. it could have a problem with the delay, but i don't know where specifically i could place the delay.. or rather, how to do it..:(

by the way i now use the AT90S8515, STK500.. if you have the board, u can try it...
 

Attachments

hgmjr

Joined Jan 28, 2005
9,029
hi!

i got this program code from a friend,
the problem with this program is whenever i try in with the board,
the output on the screen (windows hyper term) appears to be more than one number (eg. when i press the push button for the 1, what appears in the screen is 1111111111111111111111111111, something like that).. it could have a problem with the delay, but i don't know where specifically i could place the delay.. or rather, how to do it..:(

by the way i now use the AT90S8515, STK500.. if you have the board, u can try it...
Rich (BB code):
;-------------STK500 UART Program ---------------;
;  Program Description:                          ;
;     This program reads the push button and     ;
;     sends the position of the pressed          ;
;     pushbutton to the PC through the serial    ;
;     port. The values are displayed using       ;
;     Hyperterm program in Windows               ;
;-------------STK500 UART Program ---------------;
.include "8515def.inc"
.def temp =r16
.def temp2=r17
.def ch   =r18
;---- Start of Program----;
.CSEG     ; code segment
Vector:
     rjmp Reset             ;Program Reset:1
     rjmp VECInt0           ;External IRQ 0:2
     rjmp VECInt1           ;External IRQ 1:3
     rjmp VECTmr1_Capt      ;Timer/Ctr 1 Capture Event:4
     rjmp VECTmr1_CompA     ;Timer/Ctr 1 Compare Match A:5
     rjmp VECTmr1_CompB     ;Timer/Ctr 1 Compare Match B:6
     rjmp VECTmr1_Ovf       ;Timer/Ctr 1 Overflow:7
     rjmp VECTmr0_Ovf       ;Timer/Ctr 0 Overflow:8
     rjmp VECSPI_STC        ;Serial Transfer Complete:9
     rjmp VECUART_RX        ;UART, RX Complete:10
     rjmp VECUART_UDRE      ;UART, Data Register Empty:11
     rjmp VECUART_TX        ;UART, TX Complete:12
     rjmp VECAna_Comp       ;Analog Comparator:13
 
Reset:
     rjmp Init
VECInt0:
     reti
VECInt1:
     reti
VECTmr1_Capt:
     reti
VECTmr1_CompA:
     reti
VECTmr1_CompB:
     reti
VECTmr1_Ovf:
     reti
VECTmr0_Ovf:
     reti
VECSPI_STC:
     reti
VECUART_RX:
     reti
VECUART_UDRE:
     reti
VECUART_TX:
     reti
VECAna_Comp:
     reti
 
Init:
     ldi temp,high(RAMEND)     ;set stack ptr
     out SPH,temp
     ldi temp,low(RAMEND)
     out SPL,temp
     ldi temp,0x80             ;enable global interrupt
     out SREG,temp
     ldi temp,0x00             ;disable external interrupts
     out GIMSK,temp
     out TIMSK,temp            ;disable timer interrupts
     out TCCR0,temp            ;Disable Timer0
     out TCCR1B,temp           ;disable Timer1
     out DDRA,temp             ;set portA as input
     ldi temp,0xff
     out DDRB,temp             ;set PortB as output
     out PORTB,temp            ;clear LEDs
 
UART_init:
     ldi temp,0x16             ;set 9600 baud rate
     out UBRR,temp
     ldi temp,0x18             ;disable RX/TX interrupt, 8-bit
     out UCR,temp
 
Main:
      rcall getkey
      out PORTB,temp
      out UDR,ch                ;send to serial port
loop:
      sbis USR,0x05             ;check if sent (UDRE is bit 5 instead of bit 6...)
      rjmp loop
      rjmp Main
getkey:                         ;check if button pressed
      sbis PINA,0x00
      rjmp k0
      sbis PINA,0x01
      rjmp k1
      sbis PINA,0x02
      rjmp k2
      sbis PINA,0x03
      rjmp k3
      sbis PINA,0x04
      rjmp k4
      sbis PINA,0x05
      rjmp k5
      sbis PINA,0x06
      rjmp k6
      sbis PINA,0x07
      rjmp k7
      rjmp getkey
 
k0: ldi ch,'0'
      ret 
k1: ldi ch,'1'
      ret
k2: ldi ch,'2'
      ret
k3: ldi ch,'3'
      ret
k4: ldi ch,'4'
      ret
k5: ldi ch,'5'
      ret
k6: ldi ch,'6'
      ret
k7: ldi ch,'7'
      ret
I imported your code into AVRSTUDIO4 and simulated it. The main thing I see is that in the loop used to test the "UART Data Register Empty" flag, the bit tested should be bit-5 rather than bit-6. (See my code insert above for the actual line involved.)

See if that change fixes your problem. If not let me know and I will see if there is something else amiss.

Good Luck,
hgmjr
 

Thread Starter

nice_song

Joined Mar 11, 2008
6
thanks for that..

i'm surprised with my simple mistake, but honestly i don't really understand why the UDRE should be just a 5-bit..??..
 

hgmjr

Joined Jan 28, 2005
9,029
thanks for that..

i'm surprised with my simple mistake, but honestly i don't really understand why the UDRE should be just a 5-bit..??..
I did not mean to infer that it is a 5 bit value. The UDRE flag occupies the bit-5 position in the control register for the UART in the AVR device you are programming.

hgmjr

keywords: atmega8515, AVR, AVRSTUDIO4, assembly language
 

hgmjr

Joined Jan 28, 2005
9,029
Rich (BB code):
;-------------STK500 UART Program ---------------;
;  Program Description:                          ;
;     This program reads the push button and     ;
;     sends the position of the pressed          ;
;     pushbutton to the PC through the serial    ;
;     port. The values are displayed using       ;
;     Hyperterm program in Windows               ;
;-------------STK500 UART Program ---------------;
 
.nolist
.include "8515def.inc"
.list
 
.def temp             = r16
.def temp2            = r17
.def ch               = r18
.def switch_state = r19
.def any_switch     = r20
.def sw_temp        = r21
 
;---- Start of Program----;
 
.CSEG                    ; code segment
 
.org    0
 
Reset:
    rjmp    Init
VECInt0:
    reti
VECInt1:
    reti
VECTmr1_Capt:
    reti
VECTmr1_CompA:
    reti
VECTmr1_CompB:
    reti
VECTmr1_Ovf:
    reti
VECTmr0_Ovf:
    reti
VECSPI_STC:
    reti
VECUART_RX:
    reti
VECUART_UDRE:
    reti
VECUART_TX:
    reti
VECAna_Comp:
    reti
 
Init:
    ldi    temp,high(RAMEND)    ;set stack ptr
    out    SPH,temp
    ldi    temp,low(RAMEND)
    out    SPL,temp
 
    ldi    temp,0x80        ;enable global interrupt
    out    SREG,temp
 
    ldi    temp,0x00        ;disable external interrupts
    out    GIMSK,temp
    out    TIMSK,temp        ;disable timer interrupts
 
    out    TCCR0,temp        ;Disable Timer0
    out    TCCR1B,temp        ;disable Timer1
 
    out    DDRA,temp        ;set portA as input
    ldi    temp,0xff
    out    DDRB,temp        ;set PortB as output
    out    PORTB,temp        ;clear LEDs
 
 
UART_init:
    ldi    temp,0x16        ;set 9600 baud rate
    out    UBRR,temp
    ldi    temp,0x18        ;disable RX/TX interrupt, 8-bit
    out    UCR,temp
 
    ldi    switch_state,0
 
Main:
 
    ; Set up a state-machine...
 
 
    cpi    switch_state,0x00
    breq    state0    
    cpi    switch_state,0x01
    breq    state1
    cpi    switch_state,0x02
    breq    state2
    cpi    switch_state,0x03
    breq    state3
 
continue:
 
    ; Do useful stuff here between key presses and key processing....
 
 
 
    rjmp main
 
 
state0:    ; Idle state here for any key pressed...
    in        sw_temp,PINA
    cpi    sw_temp,0xff
    breq    idle_s0
    ldi    switch_state,0x01    ; Bump state...    
    rjmp    continue
idle_s0:
    rjmp    continue
 
state1:    ; Process the key and transmit it...
    rcall    getkey
    out    PORTB,temp
    out    UDR,ch            ;send to serial port
    ldi    switch_state,0x02    ; Bump state....
    rjmp    continue
 
state2:    ; Wait here for send complete...
    sbis    USR,0x05        ;check if sent
    rjmp  continue
    ldi    switch_state,0x03    ; Bump state...
    rjmp     continue
 
state3:    ; Wait here for all switches to release...
    in        sw_temp,PINA
    cpi    sw_temp,0xff
    brne    idle_s3
    cbi    $0b,0x05
    ldi    switch_state,0x00 ; Return to looking for switch...
    rjmp    continue
idle_s3:        
    rjmp    continue
 
 
 
getkey:                    ;check if button pressed
    sbis    PINA,0x00
    rjmp    k0
    sbis    PINA,0x01
    rjmp    k1
    sbis    PINA,0x02
    rjmp    k2
    sbis    PINA,0x03
    rjmp    k3
    sbis    PINA,0x04
    rjmp    k4
    sbis    PINA,0x05
    rjmp    k5
    sbis    PINA,0x06
    rjmp    k6
    sbis    PINA,0x07
    rjmp    k7
    rjmp    getkey
 
k0:    ldi    ch,'0'
    ret    
k1:    ldi    ch,'1'
    ret
k2:    ldi    ch,'2'
    ret
k3:    ldi    ch,'3'
    ret
k4:    ldi    ch,'4'
    ret
k5:    ldi    ch,'5'
    ret
k6:    ldi    ch,'6'
    ret
k7:    ldi    ch,'7'
    ret
Here is a modification to your original program in which I have added a state-machine with four states. By taking the state-machine approach, it is possible to handle those cases in which you "fat-finger" the switch. The state machine forces you to release the current pressed switch before you can press the next switch. This should result in one and only one character per switch depression.

It can no doubt be improved upon with features like switch debouncing and some additional bells and whistles. It can however serve as an example of one possible implementation of a state machine written in AVR assembler.

hgmjr
 

Thread Starter

nice_song

Joined Mar 11, 2008
6
that's so cool!! it will help me a lot! thanks!

what if i'll use two stk500 boards and i connect them together through serial ports.. one will be a receiver and the other will be a transmitter..

when the switch/push button is pressed on the transmitter, the corresponding LED should light on the receiver..

what will be the modified program for this? (from the one you've sent) for the receiver and transmitter?

thanks again!
 

hgmjr

Joined Jan 28, 2005
9,029
How about you take a stab at implementing the two programs and then post your efforts here. I will be more than happy to assist in debugging your code.

The example of a state machine I have provided should give you a boiler-plate for you to use in such a program.

hgmjr
 
Top