1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

Help with code modification

Discussion in 'AVR' started by Electrode074, Feb 27, 2017.

  1. Electrode074

    Electrode074 New Member

    Joined:
    Feb 27, 2017
    Messages:
    7
    Likes:
    0
    Hello,
    I am working on a Larson scanner using an LED bar graph display in a prop build for a buddy. I have been an electronics hobbyist for decades now. I know my circuits, components and schematics, I'm just not a coder. I bread boarded the display using an ATTiny13A using code provided for public use on a blog site (the author is no longer monitoring his blog), loaded the code using a USB AVR programmer and it works great. There are just extra patterns in the code that I would like to eliminate as they are not needed. Also the code is set up for 12 LEDs and I would like to just use 10 as that is what is needed for the bar graph. I'm new here so I'm not sure if it ok to post the code from the ASM file.
     
  2. atferrari

    atferrari Well-Known Member

    Joined:
    Oct 8, 2003
    Messages:
    2,814
    Likes:
    121
    Location:
    Buenos Aires - Argentina
    Do not eliminate. It is just to feel better?

    Not sure about those 10 instead 12 you mention. Could you elaborate?

    The bargraph, what does it display, actually? Is there any numeric calculation for that?
     
  3. Les Jones

    Les Jones Well-Known Member

    Joined:
    May 15, 2015
    Messages:
    1,452
    Likes:
    189
    Location:
    Lancashire UK
    ONLINE
    This is how to use code tags. I have inserted it as a picture so they will not be interpreted.

    Screen Shot 02-27-17 at 10.38 PM.PNG
    This is an example of using code tags
    Code (text):

    ;
    /*
     * Shutdown timer    (Shutdown_timer03)  (To shut off a light after a preset period and also if the battery voltage is too low.)
     *
     *  Created: 03/09/2015
     *   Author: Les
     *  Version 2 being modified by adding low battery warning light
     */
     ;   using ATTINY13
    ; Fuse bit settings
     ; Low           0x62   (0x6A is also OK)
     ; High        0xFF
     ; Extended    0xFF
     ; Lock           0xFF


     ;
    ;

    ;Use internal clock at 9.6 Mhz   (Default value) and divide by 8 by setting CKDIV8 fuse bit (These are the default setting on a new chip.)
    ; 9.6 Mhz/8 = 1.2 Mhz
    ;(So Instruction time = 833.3 nS)

    ; So for 50 uS delay requires 50/0.8333 = 60 instructions

    ; Burst needs to be 5 mS long. This will be 50 cycles of 10 Khz

    ;
    ;**************************************************************************
    .nolist
    .include   <tn13def.inc>   ; ATtiny 13
    .list
    .listmac

    ;***************************************************************************
    ;*
    ;* Global Register Variables
    ;*
    ;***************************************************************************
    ; Note register number is in decimal

    .def   N200mS       = r17   ;Number of 200 mS
    .def   Seconds       = r18   ;Number of seconds
    .def   Minutes       = r19   ;Number of minutes
    .def   count_L       = r22   ;Used for time delay
    .def   Flags       = r23   ;Bit 0 used for battery low warning flag



    .equ   Shutdown_volts   = 0xA4   ;battery voltage shutdown value. (164 decimal. Divide battery voltage using a 4.7K resistor to ground and a 10 K resistor to the )
    ;                                                                (collector ofthe power switching transistor. This gives a ratio of 0.32. So for a cut off voltage )
    ;                                                                (of 10.0 we need to detect 3.2 volts This is 256 x 3.2/5 = 164 )
    .equ   Battery_Low   = 0xB4   ;Battery voltage low warning level. (Set to come on at 11.0 volts so this will be 1.0 * 0.32 = 3.52 volts at ADC input
    ;                                   (This will be a count of 256 * 3.52/5 = 180 = 0xB4 )
    ;
    .equ   Shutdown_minutes = 5   ;Time to shutdown in minutes.
    ;
    ;
    ;******************************** INTERRUPT VECTORS ***********************
    .CSEG
    .ORG   00
           rjmp   reset
           reti
           reti
           rjmp    TC_overflow   ;Timer/Counter Overflow
           reti
           reti   ;   rjmp   timer1_OVF
           reti
           reti
           reti
           reti
    ;
    ;******************************* RESET *************************************
    ;  
    ; Initialise the stack-pointer  
    reset:
                   ldi   R16,low(RAMEND)
                   out   SPL,R16


               
       

               
    ; initialize PORTB
    ;   Bit 0   Input    (pin 5)       (Input will be low when button is pressed.
    ;   Bit 1   Input
    ;   Bit 2   Input   ADC input (Pin 7)
    ;   Bit 3   Output  (Pin 2)   (Drive to low battery warning LED High for LED on)
    ;   Bit 4   Output   (Pin 3)   (Drive to power control tansistor base.)
    ;   Bit 5   Input

                       ldi   R16,0x18   ; Bits 3 and 4 as outputs.
                       out   DDRB,R16   ;
                       ldi   R16,0x10
                       out   PORTB,R16   ; PORTB Bit 3 low, bit 4 high


    ; initialize Flags
                       ldi Flags,0x00



    ;Initialize ADC

                       ldi R16,0x84           ;Enable ,  Prescale value 16,  No auto triggering
                       out ADCSRA,R16

                       ldi   R16,0b00000000
                       out   ADCSRB,R16

                       ldi R16,0x21   ;Select AD1 (pin 7) input, Select VCC as analogue reference. ADLAR (Left justify result)
                       out ADMUX,R16


                       ldi R16,0x04   ;Set PB2 as analoge input
                       out DIDR0,R16


    ;Initialize timer / counter


                       ldi R16,0x00           ;Normal operation
                       Out TCCR0A,R16

                       ldi R16,0x05           ;  Prescale value 1024 (Inc counter every 0.8333 uS x 1024 = 853.3 uS  (1171.88 hZ)
                       Out TCCR0B,R16           ; Counter will overflow every 218.445 mS  (4,58 hZ)  
                                               ; Counting to 234 would give 199.7 mS  ( 256 - 234 = 22 = 0x16)

                       ldi R16,0x02           ;TOIE0 (Bit1) : Timer/Counter0 Overflow Interrupt Enable
                       Out TIMSK0,R16

    ;Init time counters
                       ldi N200mS,0x05
                       ldi Seconds,0x00
                       ldi Minutes,0x00

    ;Wait for button to be released  (Wait for input to go high

    Wait_Button_High:
                       sbis PINB,0
                       rjmp Wait_Button_High

                       bset 7       ;Enable global interrupst.

                       rjmp main


    ;Timer/Counter Overflow interrupt handler.
    TC_overflow:

                       ldi R20,0x16       ;Preset timer so interrupt occures every 199.7 mS
                       out   TCNT0,R20

                       dec   N200mS ;200mS
                       breq TC01
                       RETI
    TC01:
                       ldi N200mS,0x05


    Inc_Sec:          

                       SBRS Flags, 0
                       CBI PORTB,0x03       ;Clear battery low warning LED
                       SBRS Flags,0       ;Bat_Warning   ;Skip if battery warning bit is set
                       RJMP Inc_S2

                       in R20,PORTB
                       ldi R21,0x08       ;Bits 3
                       eor R20,R21           ; Toggle bit 3 (Pin 2) (Every second)
                       out PORTB,R20




    Inc_S2:
                       ldi R20,0x3C       ;60 decimal

                       inc   Seconds           ;Increment seconds counter
                       cpse Seconds,R20
                       rjmp TC_End
                       CLR Seconds

    Inc_Min:
                       ldi R20,0x3C       ;60 decimal

                       inc   Minutes           ;Increment minute counter
                       cpse Minutes,R20
                       rjmp TC_End
                       CLR Minutes

    TC_End:
                       RETI


    ;       ------------------------------------- End of interrupt handlers --------------------------------------




    ;
    ;                    Main program code
    ;
    Main:
               nop
               nop
               ldi R20,Shutdown_minutes
               cpse Minutes,R20               ;Is it time to shutdown ?
               rjmp Not_Time
               cbi PORTB,4                       ;Clear PORTB bit 4
               rjmp End_Loop



    Not_Time:
               nop
               nop
               nop
    ;           rjmp Main   ; Just loop waiting for interrupt


    ;Read ADC input value
                       ldi R16,0x84           ;Enable ,  Prescale value 16,  No auto triggering
                       out ADCSRA,R16

                       ldi R16,0x21   ;Select AD1 input (pin 7) Select VCC as analogue reference, ADLAR (Left justify result)
                       out ADMUX,R16

                       sbi   ADCSRA,ADSC      ; Start ADC conversion
                       nop
    Wait_ADC_Ready:
                       sbic  ADCSRA,ADSC      ; Wait_ADC_Ready:
                       rjmp  Wait_ADC_Ready
                       in R20,ADCL           ;Read ADC result L  (Value not used but need to read this register befor high byte.)
                       in R20,ADCH           ;Read ADC result H

    ;Test for battery warning level
                       CBR Flags,0x01 ;Bat_Warning           ;Clear battery warning flag

                       CLC               ;Clear carry flag
                       SBCI R20,Battery_Low
                       BRBC 0x00,Test_Shutdown       ;Branch if carry bit is clear
                       SBR Flags,0x01 ;Bat_Warning           ;Set battery warning flag bit


    ;Test for battery shutdown level
    Test_Shutdown:
                       in R20,ADCH           ;Read ADC result H again
                       CLC               ;Clear carry flag
                       SBCI R20,Shutdown_volts
                       BRBS 0x00,Bat_Low           ;Branch if carry bit is set
                       RJMP Bat_OK

    Bat_Low:
                       CBI PORTB,0x04           ; Shutdown

    End_loop:
                       NOP
                       RJMP End_loop           ; Loop until power removed.



    Bat_OK:


    Test_button:                           ;If button pressed input will be low.
                       sbic   PINB,0

                       rjmp Main   ; Just loop waiting for interrupt

    ;Now wait 100 mS and recheck that button is pressed. (De bounce switch contacts)
                       rcall Delay_100ms
                       sbic   PINB,0  
                       rjmp Main
                       cbi PORTB,4                       ;Clear PORTB bit 4
                       rjmp End_Loop








    ;Test_button:
                       sbis   PINB,0
                       rjmp   Test_button   ;Loop until button pressed

    ;Now wait 100 mS and recheck that button is pressed. (De bounce switch contacts)
                       rcall Delay_100ms
                       sbis   PINB,0  
                       rjmp   Test_button   ;Loop until button is pressed


    Button_open_loop:
                       sbic   PINB,0   ;
                       rjmp   Button_open_loop; loop until pedal released








    ;Subroutines.
    ;
    ;
    ;                               ----------------------------------------------
    ; Instruction cycle time is 0.83333 uS

    ; Delay 1mS  Rcall to get here takes 3 instruction cycles. ret instruction takes 4 instruction cycles, ldi takes 1 instruction cycle (total 8)

    ; For 1 mS (1000 uS) we need 1000/0.83333 = 1200 instructions  so need additional 1192 instructions    5 cycles in loop.


    Delay_1_mS:
                       ldi    count_L,0xEE   ;Decimal 238  0xEE (Once round the loop is 5 instructions)
    D_1mS_Loop:
                       dec   count_L       ; Count_L is R22  (1 cycle)
                       nop               ;(1 cycle)
                       nop               ;(1 cycle)
                       brne    D_1mS_Loop   ;If not zero  (2 cycles while looping, 1 on exit)
                       ret





    Delay_100ms:
                       ldi R21,0x64   ;100 decimal
    Del_100ms_Loop:
                       rcall Delay_1_mS
                       dec R21
                       brne Del_100ms_Loop
                       ret

    ;                               -------------End of subroutines --------------
    ;
     
    Les.
     
    • Like Like x 1
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. Electrode074

    Electrode074 New Member

    Joined:
    Feb 27, 2017
    Messages:
    7
    Likes:
    0

    atferrari, I need to get rid of unused code, only need the bargraph to use one function of the code. Circuit wise, I can get by with using all 12 segments instead of 10, I can work around that with little to no issue. This is a 10 segment LED bargraph running a larson scanner (knight rider style). I am only using 3 components for the prop as space is a major issue. Parts; 10 segment LED bargraph, ATTiny13A and a 10K pot to vary the speed, once the correct speed is obtained, will replace pot with a fixed resistor.

    This is the code from the asm file. From what I can tell from the code, all I need is mode, 0 as this is the effect my buddy is going for. I don't need the rest of the LED pattern functions. I wanted to trim mode1, mode2 & mode3 from the code, but am unsure how to so without affecting mode, 0 operation.

    Code (text):

    /*********************************************************
                                                         
     CharlieScanner

     Software to generate a Larson scanner pattern on 12 LEDs
     Charlieplexing is used in order to control the LEDs with
     only 4 IO ports. One port reads in a voltage. The
     software then changes speed accordingly.

     Uses internal RC-Osc at 9.6 MHz/8
     Fuses should be set to default

     Written by Thomas Frey    http://tomscircuits.blogspot.com/

     $Date:$

    *********************************************************/

    ; defines

    #define tmp        R16
    #define    tmp2        R17
    #define duration    R18
    #define LED        R19
    #define adc_result    R20
    #define mode        R21


    #include "tn13def.inc"

    .MACRO LEDon
        ldi    LED, @0
        rcall    setled
    .ENDMACRO


    .cseg


    /*********************************************************

     Interrupt vectors

    *********************************************************/
    .org 0    rjmp reset
             


    .org    INT0addr         rjmp reset        ;External Interrupt0
    .org    PCI0addr       rjmp reset        ;Pin Change Interrupt0
    .org    OVF0addr     rjmp reset        ;Overflow0 Interrupt
    .org    ERDYaddr         rjmp reset        ;EEPROM write complete
    .org    ACIaddr        rjmp reset        ;Analog Comparator Interrupt
    .org    OC0Aaddr    rjmp reset        ;Timer/Counter0 Compare Match A    
    .org    OC0Baddr    rjmp reset        ;Timer/Counter0 Compare Match B    
    .org    WDTaddr            rjmp reset        ;Watchdog Timeout
    .org    ADCCaddr         rjmp reset        ;ADC Conversion Complete Handle






    /*********************************************************

     Initialisation

    *********************************************************/
    reset:

    ; set stack pointer
        ldi    tmp, LOW(RAMEND)
        out    SPL, tmp


    ; set clock to 1,2 MHz
       
        ldi    tmp, 0b10000000
        out    CLKPR, tmp

        ldi    tmp, 0b00000011        ; Divide by 8
        out    CLKPR, tmp


    ; init ADC

        ldi    tmp, (1<<ADLAR)|(1<<MUX1)    ; Use ADC in 8bit mode, PB4; Vcc is reference
        out    ADMUX, tmp

        ldi    tmp, (1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADEN)    ; Slow conversion, ADC on
        out    ADCSRA, tmp

        rjmp    main

    ; init registers
        ldi    mode, 0



    /*********************************************************

     Main loop

    *********************************************************/

    main:

        cpi    mode,0
        brne    mode1

        LEDon 1
        LEDon 2
        LEDon 3
        LEDon 4
        LEDon 5
        LEDon 6
        LEDon 7
        LEDon 8
        LEDon 9
        LEDon 10
        LEDon 11
        LEDon 12

        LEDon 11  
        LEDon 10
        LEDon 9
        LEDon 8
        LEDon 7
        LEDon 6
        LEDon 5
        LEDon 4
        LEDon 3
        LEDon 2

        rjmp    main

    mode1:

        cpi    mode, 1
        brne    mode2

        LEDon 1
        LEDon 2
        LEDon 3
        LEDon 4
        LEDon 5
        LEDon 6
        LEDon 7
        LEDon 8
        LEDon 9
        LEDon 10
        LEDon 11
        LEDon 12

        rjmp    main

    mode2:
        cpi    mode, 2
        brne    mode3

        LEDon 1
        LEDon 12

        LEDon 2
        LEDon 11

        LEDon 3
        LEDon 10

        LEDon 4
        LEDon 9

        LEDon 5
        LEDon 8

        LEDon 6
        LEDon 7

        LEDon 7
        LEDon 6

        LEDon 8
        LEDon 5

        LEDon 9
        LEDon 4

        LEDon 10
        LEDon 3

        LEDon 11
        LEDon 2

        LEDon 12
        LEDon 1


        rjmp    main

    mode3:

        LEDon 1
        LEDon 2
        LEDon 1
        LEDon 3
        LEDon 2
        LEDon 4
        LEDon 3
        LEDon 5
        LEDon 4
        LEDon 6
        LEDon 5
        LEDon 7
        LEDon 6
        LEDon 8
        LEDon 7
        LEDon 9
        LEDon 8
        LEDon 10
        LEDon 9
        LEDon 11
        LEDon 10
        LEDon 12
        LEDon 11
        LEDon 12


        rjmp    main


    /*********************************************************

        Sub routine:    wait

        Function:    Generates a pause, depending on ADC
                input

        Parameter: none / duration - lenght of the pause
       
    *********************************************************/

    wait:
        sbi     ADCSRA, ADSC        ; start ADC conversion
       
    wait_adc:
        sbic    ADCSRA, ADSC        ; wait for the ADC to finish
        rjmp    wait_adc

        in    adc_result, ADCH

        tst    adc_result
        brne    wait_cont        ; not minimum? -> go on
       
                        ; else: change mode
        inc    mode
        andi    mode, 0b00000011    ; wrap around (four modes only)

    wait_endmode:
        sbi     ADCSRA, ADSC        ; start ADC conversion
       
    wait_adc2:
        sbic    ADCSRA, ADSC        ; wait for the ADC to finish
        rjmp    wait_adc2

        in    adc_result, ADCH

        tst    adc_result
        breq    wait_endmode

    wait_cont:
        mov    duration, adc_result
        inc    duration

        ldi    tmp, 0
       
    timer_loop:

        dec    tmp
        brne    timer_loop

        dec    duration
        brne    timer_loop

        ret



    /*********************************************************

        Sub routine:    setled

        Function:    switches one LED on and waits

        Parameter:    LED - which LED to activate
                0 means none
       
    *********************************************************/


    setled:

        rcall    setport

        ldi    tmp, 250
        rcall    wait

        ret


    /*********************************************************

        Sub routine:    setport

        Function:    switches one LED on

        Parameter:    LED - which LED to activate
                0 means none
       
    *********************************************************/

    setport:

        clr    tmp

        ldi    ZL, LOW(translation*2)
        ldi    ZH, HIGH(translation*2)

        lsl    LED            ; LED * 2 - for LPM instruction

        add    ZL, LED
        adc    ZH, tmp

        lpm    tmp, Z+
        out    DDRB, tmp

        lpm    tmp, Z
        out    PORTB, tmp

        ret


    translation:
        .db    0b00000000, 0b00000000

        .db    0b00000011, 0b00000001
        .db    0b00000101, 0b00000001
        .db    0b00001001, 0b00000001

        .db    0b00000011, 0b00000010
        .db    0b00000110, 0b00000010
        .db    0b00001010, 0b00000010

        .db    0b00000101, 0b00000100
        .db    0b00000110, 0b00000100
        .db    0b00001100, 0b00000100

        .db    0b00001001, 0b00001000
        .db    0b00001010, 0b00001000
        .db    0b00001100, 0b00001000

     
     
  6. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,084
    Likes:
    326
    Location:
    Brisbane Australia
    Remove the first two lines after main and all the code from mode0: to the comments above the subroutine wait.

    Mike.
    Edit, so your main loop looks like this,
    Code (text):

    /*********************************************************

     Main loop

    *********************************************************/

    main:
        LEDon 1
        LEDon 2
        LEDon 3
        LEDon 4
        LEDon 5
        LEDon 6
        LEDon 7
        LEDon 8
        LEDon 9
        LEDon 10
        LEDon 11
        LEDon 12

        LEDon 11  
        LEDon 10
        LEDon 9
        LEDon 8
        LEDon 7
        LEDon 6
        LEDon 5
        LEDon 4
        LEDon 3
        LEDon 2
        rjmp    main

    /*********************************************************

        Sub routine:    wait

        Function:    Generates a pause, depending on ADC
                input

        Parameter: none / duration - lenght of the pause
       
    *********************************************************/
     
    • Thanks Thanks x 1
  7. Electrode074

    Electrode074 New Member

    Joined:
    Feb 27, 2017
    Messages:
    7
    Likes:
    0
    Thank you Mike! I appreciate you taking the time and effort to look it over. Will give a go after work this evening and compile it to hex. I will let you know how it goes, again, much thanks!
     
  8. Electrode074

    Electrode074 New Member

    Joined:
    Feb 27, 2017
    Messages:
    7
    Likes:
    0
    So with Mike's help I got the code changed. I'm using Atmel Studio 6.2 to try and compile the ASM file. Did a bit of research on how to use AS. What I can't find is when I start a project, do I need to use GCC C executable or static library project or the GCC C++ version(s). I've tried both executable and static library can get the code to build but get an error with #include "tn13def.inc" saying no such file or directory. I see the tn13def.inc file is in the include folder for Atmel Studio so I figure it may be a syntax issue with the include? Any help would be greatly appreciated.
     
  9. Les Jones

    Les Jones Well-Known Member

    Joined:
    May 15, 2015
    Messages:
    1,452
    Likes:
    189
    Location:
    Lancashire UK
    ONLINE
    You are not compiling "C" code. When you start a new project there should be an option to use Atmel AVR assembler. Select that option.

    Les.
     
    • Thanks Thanks x 1
  10. Electrode074

    Electrode074 New Member

    Joined:
    Feb 27, 2017
    Messages:
    7
    Likes:
    0
    Thank you for your help Les, I appreciate your time!
     
  11. Electrode074

    Electrode074 New Member

    Joined:
    Feb 27, 2017
    Messages:
    7
    Likes:
    0
    Again, I wish to thank you Mike & Les for lending a hand. I really appreciate your help. Got everything working like it should. Couldn't have done so without your generosity. If you ever need help with anything on the electronic side of things, please let me know, I would like to return the favor.
     
  12. Les Jones

    Les Jones Well-Known Member

    Joined:
    May 15, 2015
    Messages:
    1,452
    Likes:
    189
    Location:
    Lancashire UK
    ONLINE
    I'm pleased that everyting is now working. It was a pleasure helping. We get too many posts where the OP does not give any information about the problem and the thread has many posts before we know what the question really is.

    Les.
     
    • Like Like x 1
  13. Electrode074

    Electrode074 New Member

    Joined:
    Feb 27, 2017
    Messages:
    7
    Likes:
    0
    Hey Guys just wanted to share the results from your help.
     

Share This Page