Continue to Site

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.

  • 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.

convertinf Ardunio code to Swordfish basic

Status
Not open for further replies.
from post #15...
Code:
Dim C As Byte
Dim D As Byte
Dim E As Byte
Dim F As Byte
Dim G As Byte
Dim a As Byte
Dim b As Byte
dim Duration as integer // length of time note is played  333ms 1/3 of a second

c=1.91
d = 1.70
e=1.50
f=1.43

duration = 1.91
Since all of these variables are declared 'as byte' or 'as integer', all of the assignment statements will be automatically rounded to an integral type for you... c, d, e, and duration will be set to 2, f will be set to 1

Also, instead of 'as integer' 'as word' would be better since time can't be negative.
 
will try both suggestions.
this is a passive buzzer that is supplied with the super starter kit unio r3 project by elegoo.com
was contemplating trying out the Ardunio sketcj using said buzzer as per the lit instructions and see just how loud the buzzer really is.
The video link I posted, the sound was pretty loud
 
made suggested changes. While testing I asked my wife if she thought it was to loud or ?
She couldn't hear anything. Just as I suspected, she needs hearing aids.
trying to compare the different tones but it just mixes it all together.
Will hack at it after church and breakfast
Code:
{
*****************************************************************************
*  Name    : UNTITLED.BAS                                                   *
*  Author  : [select VIEW...EDITOR OPTIONS]                                 *
*  Notice  : Copyright (c) 2021 [select VIEW...EDITOR OPTIONS]              *
*          : All Rights Reserved                                            *
*  Date    : 7/16/2021                                                      *
*  Version : 1.0                                                            *
*  Notes   :                                                                *
*          :                                                                *
*****************************************************************************
}
Device = 18F43k22
Clock = 8
Config FOSC = INTIO67   'internal oscillator 
//Config MCLRE = off
// some LCD options...


 
#option LCD_DATA = PORTD.4
#option LCD_RS = PORTD.2
#option LCD_EN = PORTD.3
#option DIGITALIO_INIT = true
Include "setdigitalio.bas"
Include "utils.bas"
Include "LCD.bas"
Include "convert.bas"
Include "intosc.bas"
Include "utils.bas"

Const Notes(7) As Word = (262,294,330,349,392,440,494) //notes
Dim Index As Byte                                      //use to count to end of medeloy
Dim Buzzer As PORTB.2                                  //defing buzzer output pin
Dim C As word
Dim D As Word
Dim E As Word
Dim F As Word
Dim G As Word
Dim a As Word
Dim b As Word
Dim Duration As Integer // length of time note is played  333ms 1/3 of a second
Dim x As Byte


C=1.91
D = 1.70
E=1.50
F=1.43

SetAllDigital
While true

Duration = c
Buzzer = 1
DelayMS(Duration)
Toggle(Buzzer)
DelayMS(Duration)

'delayms(2000)
  {
     Duration = d
        Buzzer = 1
        DelayMS(Duration)
        Toggle(Buzzer)
        DelayMS(Duration)

           ' delayms(2000)
     Duration = e
        Buzzer = 1
        DelayMS(Duration)
        Toggle(Buzzer)
        DelayMS(Duration)
  
   }



Wend
 
Here is a port of the arduino Tone library for the 18FxxK22
tone.bas:
Code:
// port of arduino Tone library for swordfish
// (device = 18FxxK22)
module tone

// **WARNING**
// Do NOT connect the pin directly to some sort of audio input... the voltage is considerably
// higher (5V) than standard line level voltages, and can damage sound card inputs, etc.
// If required, use a voltage divider to bring the voltage down
// Also, the output pin cannot directly drive a low-impedance 8/16 ohm speaker.
//

// specify default output pin
#option _TONE_OUTPUT_PIN = PORTC.2

// 88-key piano note frequencies, in Hz
public const NOTE_B0  as word = 31
public const NOTE_C1  as word = 33
public const NOTE_CS1 as word = 35
public const NOTE_D1  as word = 37
public const NOTE_DS1 as word = 39
public const NOTE_E1  as word = 41
public const NOTE_F1  as word = 44
public const NOTE_FS1 as word = 46
public const NOTE_G1  as word = 49
public const NOTE_GS1 as word = 52
public const NOTE_A1  as word = 55
public const NOTE_AS1 as word = 58
public const NOTE_B1  as word = 62
public const NOTE_C2  as word = 65
public const NOTE_CS2 as word = 69
public const NOTE_D2  as word = 73
public const NOTE_DS2 as word = 78
public const NOTE_E2  as word = 82
public const NOTE_F2  as word = 87
public const NOTE_FS2 as word = 93
public const NOTE_G2  as word = 98
public const NOTE_GS2 as word = 104
public const NOTE_A2  as word = 110
public const NOTE_AS2 as word = 117
public const NOTE_B2  as word = 123
public const NOTE_C3  as word = 131
public const NOTE_CS3 as word = 139
public const NOTE_D3  as word = 147
public const NOTE_DS3 as word = 156
public const NOTE_E3  as word = 165
public const NOTE_F3  as word = 175
public const NOTE_FS3 as word = 185
public const NOTE_G3  as word = 196
public const NOTE_GS3 as word = 208
public const NOTE_A3  as word = 220
public const NOTE_AS3 as word = 233
public const NOTE_B3  as word = 247
public const NOTE_C4  as word = 262
public const NOTE_CS4 as word = 277
public const NOTE_D4  as word = 294
public const NOTE_DS4 as word = 311
public const NOTE_E4  as word = 330
public const NOTE_F4  as word = 349
public const NOTE_FS4 as word = 370
public const NOTE_G4  as word = 392
public const NOTE_GS4 as word = 415
public const NOTE_A4  as word = 440
public const NOTE_AS4 as word = 466
public const NOTE_B4  as word = 494
public const NOTE_C5  as word = 523
public const NOTE_CS5 as word = 554
public const NOTE_D5  as word = 587
public const NOTE_DS5 as word = 622
public const NOTE_E5  as word = 659
public const NOTE_F5  as word = 698
public const NOTE_FS5 as word = 740
public const NOTE_G5  as word = 784
public const NOTE_GS5 as word = 831
public const NOTE_A5  as word = 880
public const NOTE_AS5 as word = 932
public const NOTE_B5  as word = 988
public const NOTE_C6  as word = 1047
public const NOTE_CS6 as word = 1109
public const NOTE_D6  as word = 1175
public const NOTE_DS6 as word = 1245
public const NOTE_E6  as word = 1319
public const NOTE_F6  as word = 1397
public const NOTE_FS6 as word = 1480
public const NOTE_G6  as word = 1568
public const NOTE_GS6 as word = 1661
public const NOTE_A6  as word = 1760
public const NOTE_AS6 as word = 1865
public const NOTE_B6  as word = 1976
public const NOTE_C7  as word = 2093
public const NOTE_CS7 as word = 2217
public const NOTE_D7  as word = 2349
public const NOTE_DS7 as word = 2489
public const NOTE_E7  as word = 2637
public const NOTE_F7  as word = 2794
public const NOTE_FS7 as word = 2960
public const NOTE_G7  as word = 3136
public const NOTE_GS7 as word = 3322
public const NOTE_A7  as word = 3520
public const NOTE_AS7 as word = 3729
public const NOTE_B7  as word = 3951
public const NOTE_C8  as word = 4186
public const NOTE_CS8 as word = 4435
public const NOTE_D8  as word = 4699
public const NOTE_DS8 as word = 4978

public const notes() as word =
(
    NOTE_B0,
    NOTE_C1,
    NOTE_CS1,
    NOTE_D1,
    NOTE_DS1,
    NOTE_E1,
    NOTE_F1,
    NOTE_FS1,
    NOTE_G1,
    NOTE_GS1,
    NOTE_A1,
    NOTE_AS1,
    NOTE_B1,
    NOTE_C2,
    NOTE_CS2,
    NOTE_D2,
    NOTE_DS2,
    NOTE_E2,
    NOTE_F2,
    NOTE_FS2,
    NOTE_G2,
    NOTE_GS2,
    NOTE_A2,
    NOTE_AS2,
    NOTE_B2,
    NOTE_C3,
    NOTE_CS3,
    NOTE_D3,
    NOTE_DS3,
    NOTE_E3,
    NOTE_F3,
    NOTE_FS3,
    NOTE_G3,
    NOTE_GS3,
    NOTE_A3,
    NOTE_AS3,
    NOTE_B3,
    NOTE_C4,
    NOTE_CS4,
    NOTE_D4,
    NOTE_DS4,
    NOTE_E4,
    NOTE_F4,
    NOTE_FS4,
    NOTE_G4,
    NOTE_GS4,
    NOTE_A4,
    NOTE_AS4,
    NOTE_B4,
    NOTE_C5,
    NOTE_CS5,
    NOTE_D5,
    NOTE_DS5,
    NOTE_E5,
    NOTE_F5,
    NOTE_FS5,
    NOTE_G5,
    NOTE_GS5,
    NOTE_A5,
    NOTE_AS5,
    NOTE_B5,
    NOTE_C6,
    NOTE_CS6,
    NOTE_D6,
    NOTE_DS6,
    NOTE_E6,
    NOTE_F6,
    NOTE_FS6,
    NOTE_G6,
    NOTE_GS6,
    NOTE_A6,
    NOTE_AS6,
    NOTE_B6,
    NOTE_C7,
    NOTE_CS7,
    NOTE_D7,
    NOTE_DS7,
    NOTE_E7,
    NOTE_F7,
    NOTE_FS7,
    NOTE_G7,
    NOTE_GS7,
    NOTE_A7,
    NOTE_AS7,
    NOTE_B7,
    NOTE_C8,
    NOTE_CS8,
    NOTE_D8,
    NOTE_DS8
)

// for optional icd debugger _trap() support
#if isoption(MPLAB_ICD) and (MPLAB_ICD)
  include "mplabicd.bas"
  #option _TONE_TRAP = true
#endif
#option _TONE_TRAP = false

// CCP requires using instruction cycle (FOSC/4)
const FCYC as longword = (_clock * 1000000) / 4

// sound output pin
dim OUTPUT_PIN as _TONE_OUTPUT_PIN._TONE_OUTPUT_PIN@

// ccp1 interrupt bits (18FxxK22)
dim CCP1IF as PIR1.bits(2),
    CCP1IE as PIE1.bits(2)

// duration 'timer'
// setting duration = -1 --> play until stop() is called
dim tmr_toggle_count as longint = 0

interrupt ccp1_interrupt()
    if (tmr_toggle_count <> 0) then
        toggle(OUTPUT_PIN)      // toggle pin
        if (tmr_toggle_count > 0) then
            tmr_toggle_count = tmr_toggle_count - 1
        endif
    else
        CCP1IE = 0               // disable the interrupt
        OUTPUT_PIN = 0          // keep pin low after stop
    endif
    CCP1IF = 0
end interrupt

// load CCP1 compare value
inline sub load_compare(w as word)
    CCP1IF = 0
    CCPR1H = w.bytes(1)
    CCPR1L = w.bytes(0)
    CCP1IE = 1
end sub

// initialize TMR1 and CCP1 (18FxxK22)
public sub init(enable_intr as boolean = true)
    low(OUTPUT_PIN)

    // TMR1 setup
    T1CON = (%00 << 6) +        // TMR1 clock source is instruction clock (FOSC/4)
            (%00 << 4) +        // prescaler value 1:1
            (%0 << 3) +         // sec osc disabled
            (%0 << 2) +         // ignored
            (%0 << 1) +         // 8-bit rd/wr
            (%0 << 0)           // TMR1 OFF
    TMR1H = 0
    TMR1L = 0

    // CCP1 setup
    CCP1IF = 0
    CCP1IE = 0
    // CCP1 (output on pin RC2)
    CCP1CON = (%0000 << 4) +            // unused
              (%1011 << 0)              // Compare mode: Special Event Trigger (CCPxIF is set, TMRX is reset)
    // assign TMR1 to CCP1 (K22 specific)
    CCPTMRS0.bits(1) = 0                // CCP1 timer select bits: 00 = CCP1 – Capture/Compare modes use Timer1
    CCPTMRS0.bits(0) = 0
   
    if (enable_intr) then
        enable(ccp1_interrupt)
    endif
end sub

//
// play a freq with optional duration
//  freq in hz, duration in msecs
// if duration is not specified then the tone plays until stop() is called
//
public sub play(freq as word, duration as longint = 0)
    dim prescalarbits as byte
    dim ocr as longword = 0

    // compute compare value for the 16-bit timer assuming prescaler = 1
    ocr = FCYC / 2 / freq

    prescalarbits = %00             // prescaler = 1
    if (ocr > $ffff) then           // if we exceed range with prescaler == 1 then
        prescalarbits = %11 << 4    // set prescaler = 8
        ocr = ocr >> 3              // divide by 8
    endif
    // compare regs are 16-bit (minus one for decr to 0 wrap)
    ocr.words(0) = ocr.words(0) - 1
   
    // set TMR prescaler
    T1CON.bits(0) = 0           // stop TMR1
    TMR1H = 0
    TMR1L = 0
    T1CON = (T1CON and %11001111) or prescalarbits

    // calculate how long to play the note in terms of the toggle count
    if (duration > 0) then
        tmr_toggle_count = word(2 * freq) * duration / 1000
    else
        tmr_toggle_count = -1
    endif

    // set the output compare regs for the given timer and turn on the interrupts
    load_compare(ocr)
    T1CON.bits(0) = 1           // turn on TMR1
end sub

// stop playing
public sub stop()
    T1CON.bits(0) = 0           // stop TMR1
    CCP1IE = 0                  // disable intr
    OUTPUT_PIN = 0
  #if (_TONE_TRAP)
    _trap()     // halt debugger
  #endif
end sub

// check to see if a note is currently playing
//  returns true = playing, false = not playing/done
public function isPlaying() as boolean
    result = boolean(CCP1IE)
end function

end module

Here's an example of using it:
Code:
// tone generator using CCP compare
device = 18F26K22
clock = 64

include "intosc.bas"
#option DIGITALIO_INIT = true
include "setdigitalio.bas"

// specify tone library output pin
#option _TONE_OUTPUT_PIN = PORTC.2
include "tone.bas"

dim ix as byte
dim note as word

main:
    // init tone library module
    tone.init()

    // play A (440) until stop()
    tone.play(NOTE_A4)
    delayms(1000)
    tone.stop()

    // play all 88 notes for 100msecs each
    for ix = 0 to bound(tone.notes)
        note = tone.notes(ix)       // current note
        tone.play(note, 100)
        while(tone.isPlaying())
        end while
        delayms(10)                 // short delay between notes
    next

    while (true)
    end while
 
Last edited:
Comment from the peanut gallery, from one who has learned his lesson:

Post #24 states " made suggested changes."

Changes made:

> variables changed to WORD

Changes NOT MADE:

> Still setting WORD values to decimal values, all less than 2.

> Still using DelayMS with those values.

Therefore:

The defined "notes" of

C=1.91
D = 1.70
E=1.50
F=1.43

all result in:

DelayMS(1)

which all result in a square wave with a period of 2mS, a note of 500Hz.


1. Change the DelayMS( ) statements to DelayUS( )

2. Multiply the "note" values by 1000.


Gentlemen, recognize the Sisyphean nature of this task.

tumbleweed, thanks for porting the tone module. Nice work!

Couldn't help but comment. My last on this topic.
 
Last edited:
  • Like
Reactions: Buk
I downloaded Tumbleweeds code and module but the module won't compile?
Made suggested changes as per Visitor and will give it a try.
 
didn't seem to make any difference. Attempting to cycle through all 7 notes but it just all gets mashed together.
Code:
Device = 18F43k22
Clock = 8
Config FOSC = INTIO67   'internal oscillator 
//Config MCLRE = off
// some LCD options...


 
#option LCD_DATA = PORTD.4
#option LCD_RS = PORTD.2
#option LCD_EN = PORTD.3
#option DIGITALIO_INIT = true
Include "setdigitalio.bas"
Include "utils.bas"
Include "LCD.bas"
Include "convert.bas"
Include "intosc.bas"
Include "utils.bas"

Const Notes(7) As Word = (262,294,330,349,392,440,494) //notes
Dim Index As Byte                                      //use to count to end of medeloy
Dim Buzzer As PORTB.2                                  //defing buzzer output pin
Dim C As Word
Dim D As Word
Dim E As Word
Dim F As Word
Dim G As Word
Dim a As Word
Dim b As Word
Dim Duration As Integer // length of time note is played  333ms 1/3 of a second
Dim x As Byte


C =1910
D =1700
E =1500
F =1430
output(buzzer)
SetAllDigital
While true

Duration = d
Buzzer = 1
DelayuS(Duration)
Toggle(Buzzer)
DelayuS(Duration)
 {
'delayms(2000)
 
     Duration = c
        Buzzer = 1
        DelayuS(Duration)
        Toggle(Buzzer)
        DelayuS(Duration)

' delayms(2000)
     Duration = e
        Buzzer = 1
        DelayuS(Duration)
        Toggle(Buzzer)
        DelayuS(Duration)
  
  }



Wend
 
Gentlemen, recognize the Sisyphean nature of this task.
Thank you for that lesson in Greek mythology, I have learned something today.

JimB
 
I downloaded Tumbleweeds code and module but the module won't compile?
What version of swordfish are you using (open IDE Help | About...)?
If you're up to date it should say "Version 2.2.3.6 - ICC 1.2.0.7"

What error message(s) do you get?

I'm going to go out on a limb and assume you have an older version that doesn't support
declarations with initializers.

Try using the attached version instead. It compiles fine for me using the 18F43K22

Code:
// port of arduino Tone library for swordfish
// (device = 18FxxK22)
module tone

// **WARNING**
// Do NOT connect the pin directly to some sort of audio input... the voltage is considerably
// higher (5V) than standard line level voltages, and can damage sound card inputs, etc. 
// If required, use a voltage divider to bring the voltage down
// Also, the output pin cannot directly drive a low-impedance 8/16 ohm speaker.
//

// specify default output pin
#option _TONE_OUTPUT_PIN = PORTC.2

// 88-key piano note frequencies, in Hz
public const NOTE_B0  as word = 31
public const NOTE_C1  as word = 33
public const NOTE_CS1 as word = 35
public const NOTE_D1  as word = 37
public const NOTE_DS1 as word = 39
public const NOTE_E1  as word = 41
public const NOTE_F1  as word = 44
public const NOTE_FS1 as word = 46
public const NOTE_G1  as word = 49
public const NOTE_GS1 as word = 52
public const NOTE_A1  as word = 55
public const NOTE_AS1 as word = 58
public const NOTE_B1  as word = 62
public const NOTE_C2  as word = 65
public const NOTE_CS2 as word = 69
public const NOTE_D2  as word = 73
public const NOTE_DS2 as word = 78
public const NOTE_E2  as word = 82
public const NOTE_F2  as word = 87
public const NOTE_FS2 as word = 93
public const NOTE_G2  as word = 98
public const NOTE_GS2 as word = 104
public const NOTE_A2  as word = 110
public const NOTE_AS2 as word = 117
public const NOTE_B2  as word = 123
public const NOTE_C3  as word = 131
public const NOTE_CS3 as word = 139
public const NOTE_D3  as word = 147
public const NOTE_DS3 as word = 156
public const NOTE_E3  as word = 165
public const NOTE_F3  as word = 175
public const NOTE_FS3 as word = 185
public const NOTE_G3  as word = 196
public const NOTE_GS3 as word = 208
public const NOTE_A3  as word = 220
public const NOTE_AS3 as word = 233
public const NOTE_B3  as word = 247
public const NOTE_C4  as word = 262
public const NOTE_CS4 as word = 277
public const NOTE_D4  as word = 294
public const NOTE_DS4 as word = 311
public const NOTE_E4  as word = 330
public const NOTE_F4  as word = 349
public const NOTE_FS4 as word = 370
public const NOTE_G4  as word = 392
public const NOTE_GS4 as word = 415
public const NOTE_A4  as word = 440
public const NOTE_AS4 as word = 466
public const NOTE_B4  as word = 494
public const NOTE_C5  as word = 523
public const NOTE_CS5 as word = 554
public const NOTE_D5  as word = 587
public const NOTE_DS5 as word = 622
public const NOTE_E5  as word = 659
public const NOTE_F5  as word = 698
public const NOTE_FS5 as word = 740
public const NOTE_G5  as word = 784
public const NOTE_GS5 as word = 831
public const NOTE_A5  as word = 880
public const NOTE_AS5 as word = 932
public const NOTE_B5  as word = 988
public const NOTE_C6  as word = 1047
public const NOTE_CS6 as word = 1109
public const NOTE_D6  as word = 1175
public const NOTE_DS6 as word = 1245
public const NOTE_E6  as word = 1319
public const NOTE_F6  as word = 1397
public const NOTE_FS6 as word = 1480
public const NOTE_G6  as word = 1568
public const NOTE_GS6 as word = 1661
public const NOTE_A6  as word = 1760
public const NOTE_AS6 as word = 1865
public const NOTE_B6  as word = 1976
public const NOTE_C7  as word = 2093
public const NOTE_CS7 as word = 2217
public const NOTE_D7  as word = 2349
public const NOTE_DS7 as word = 2489
public const NOTE_E7  as word = 2637
public const NOTE_F7  as word = 2794
public const NOTE_FS7 as word = 2960
public const NOTE_G7  as word = 3136
public const NOTE_GS7 as word = 3322
public const NOTE_A7  as word = 3520
public const NOTE_AS7 as word = 3729
public const NOTE_B7  as word = 3951
public const NOTE_C8  as word = 4186
public const NOTE_CS8 as word = 4435
public const NOTE_D8  as word = 4699
public const NOTE_DS8 as word = 4978

public const notes() as word = 
(
    NOTE_B0,
    NOTE_C1,
    NOTE_CS1,
    NOTE_D1,
    NOTE_DS1,
    NOTE_E1,
    NOTE_F1,
    NOTE_FS1,
    NOTE_G1,
    NOTE_GS1,
    NOTE_A1,
    NOTE_AS1,
    NOTE_B1,
    NOTE_C2,
    NOTE_CS2,
    NOTE_D2,
    NOTE_DS2,
    NOTE_E2,
    NOTE_F2,
    NOTE_FS2,
    NOTE_G2,
    NOTE_GS2,
    NOTE_A2,
    NOTE_AS2,
    NOTE_B2,
    NOTE_C3,
    NOTE_CS3,
    NOTE_D3,
    NOTE_DS3,
    NOTE_E3,
    NOTE_F3,
    NOTE_FS3,
    NOTE_G3,
    NOTE_GS3,
    NOTE_A3,
    NOTE_AS3,
    NOTE_B3,
    NOTE_C4,
    NOTE_CS4,
    NOTE_D4,
    NOTE_DS4,
    NOTE_E4,
    NOTE_F4,
    NOTE_FS4,
    NOTE_G4,
    NOTE_GS4,
    NOTE_A4,
    NOTE_AS4,
    NOTE_B4,
    NOTE_C5,
    NOTE_CS5,
    NOTE_D5,
    NOTE_DS5,
    NOTE_E5,
    NOTE_F5,
    NOTE_FS5,
    NOTE_G5,
    NOTE_GS5,
    NOTE_A5,
    NOTE_AS5,
    NOTE_B5,
    NOTE_C6,
    NOTE_CS6,
    NOTE_D6,
    NOTE_DS6,
    NOTE_E6,
    NOTE_F6,
    NOTE_FS6,
    NOTE_G6,
    NOTE_GS6,
    NOTE_A6,
    NOTE_AS6,
    NOTE_B6,
    NOTE_C7,
    NOTE_CS7,
    NOTE_D7,
    NOTE_DS7,
    NOTE_E7,
    NOTE_F7,
    NOTE_FS7,
    NOTE_G7,
    NOTE_GS7,
    NOTE_A7,
    NOTE_AS7,
    NOTE_B7,
    NOTE_C8,
    NOTE_CS8,
    NOTE_D8,
    NOTE_DS8
)

// for optional icd debugger _trap() support
#if isoption(MPLAB_ICD) and (MPLAB_ICD)
  include "mplabicd.bas"
  #option _TONE_TRAP = true
#endif
#option _TONE_TRAP = false

// CCP requires using instruction cycle (FOSC/4)
const FCYC as longword = (_clock * 1000000) / 4

// sound output pin
dim OUTPUT_PIN as _TONE_OUTPUT_PIN._TONE_OUTPUT_PIN@

// ccp1 interrupt bits (18FxxK22)
dim CCP1IF as PIR1.bits(2),
    CCP1IE as PIE1.bits(2)

// duration 'timer'
// setting duration = -1 --> play until stop() is called
dim tmr_toggle_count as longint

interrupt ccp1_interrupt()
    if (tmr_toggle_count <> 0) then
        toggle(OUTPUT_PIN)      // toggle pin
        if (tmr_toggle_count > 0) then
            tmr_toggle_count = tmr_toggle_count - 1
        endif
    else
        CCP1IE = 0               // disable the interrupt
        OUTPUT_PIN = 0          // keep pin low after stop
    endif
    CCP1IF = 0
end interrupt

// load CCP1 compare value
inline sub load_compare(w as word)
    CCP1IF = 0
    CCPR1H = w.bytes(1)
    CCPR1L = w.bytes(0)
    CCP1IE = 1
end sub

// initialize TMR1 and CCP1 (18FxxK22)
public sub init(enable_intr as boolean = true)
    low(OUTPUT_PIN)

    // TMR1 setup
    T1CON = (%00 << 6) +        // TMR1 clock source is instruction clock (FOSC/4)
            (%00 << 4) +        // prescaler value 1:1
            (%0 << 3) +         // sec osc disabled
            (%0 << 2) +         // ignored
            (%0 << 1) +         // 8-bit rd/wr
            (%0 << 0)           // TMR1 OFF
    TMR1H = 0
    TMR1L = 0

    // CCP1 setup
    CCP1IF = 0
    CCP1IE = 0
    // CCP1 (output on pin RC2)
    CCP1CON = (%0000 << 4) +            // unused
              (%1011 << 0)              // Compare mode: Special Event Trigger (CCPxIF is set, TMRX is reset)
    // assign TMR1 to CCP1 (K22 specific)
    CCPTMRS0.bits(1) = 0                // CCP1 timer select bits: 00 = CCP1 – Capture/Compare modes use Timer1
    CCPTMRS0.bits(0) = 0
    
    if (enable_intr) then
        enable(ccp1_interrupt)
    endif
end sub

// stop playing
public sub stop()
    T1CON.bits(0) = 0           // stop TMR1
    CCP1IE = 0                  // disable intr
    OUTPUT_PIN = 0
  #if (_TONE_TRAP)
    _trap()     // halt debugger
  #endif
end sub

//
// play a freq with optional duration
//  freq in hz, duration in msecs
// if duration is not specified then the tone plays until stop() is called
// exec(approx): 2800 cycles (175us @ 64MHz)
//
public sub play(freq as word, duration as longint = 0)
    dim prescalarbits as byte
    dim ocr as longword

    // disable ccp intr
    CCP1IE = 0

    // compute compare value for the 16-bit timer assuming prescaler = 1
    ocr = FCYC / 2 / freq

    prescalarbits = %00             // prescaler = 1
    if (ocr > $ffff) then           // if we exceed range with prescaler == 1 then
        prescalarbits = %11 << 4    // set prescaler = 8
        ocr = ocr >> 3              // divide by 8
    endif
    // compare regs are 16-bit (minus one for decr to 0 wrap)
    ocr.words(0) = ocr.words(0) - 1
    
    // set TMR prescaler
    T1CON.bits(0) = 0           // stop TMR1
    TMR1H = 0
    TMR1L = 0
    T1CON = (T1CON and %11001111) or prescalarbits

    // calculate how long to play the note in terms of the toggle count
    if (duration > 0) then
        tmr_toggle_count = word(2 * freq) * duration / 1000
    else
        tmr_toggle_count = -1
    endif

    // set the output compare regs for the given timer and turn on the interrupts
    load_compare(ocr)
    T1CON.bits(0) = 1           // turn on TMR1
end sub

// check to see if a note is currently playing
//  returns true = playing, false = not playing/done
public function isPlaying() as boolean
    result = boolean(CCP1IE)
end function

// module init
tmr_toggle_count = 0

end module
 

Attachments

  • tone.bas
    8.9 KB · Views: 205
Last edited:
Also, when you're using the intosc.bas module you should remove the line
Code:
Config FOSC = INTIO67   'internal oscillator
from your main program since intosc.bas will automatically take care of that for you, and it will only confuse things.
 
I have version 2.2.30 icc 1200
tried updating and error occurred. I have the paid version but won't update?
will try your attached file
thanks
 
I am installing Swordfish on my wife's computer since I can't access the Swordfish website on my computer (Nortons won't allow me and settings ?? are confusing at best.)
I see the SE version is 2.2.3.6 icc 1207
Am attempting to copy onto thumb drive then put on my computer.
Hopefully it will work.
 
There's no good reason for the website to be blocked... I'd dump Norton if it won't let you 'whitelist' the site.
It's probably what's keeping you from being able to update.

The code I posted in #30 should work ok with your older 2.2.3.0 version.
For this, the SE version should work ok too. It's only limitation is the amount of ram (256 bytes).
 
IT won't compile
anything with CCPTMR
 

Attachments

  • Screenshot (54).png
    Screenshot (54).png
    206.9 KB · Views: 231
Lord help me. Against my better judgment....

1. Put the tone.bas module file and the example program file in the same directory. Do not change the name of tone.bas for any reason.

2. Compile only the example program in the same directory as tone.bas. Tone.bas will take care of itself without your help or interference.

As any explanations will not be read, none will be given.
 
As vistor said, Tone.bas is a module, not the main program. You can't compile a module by itself.

Compile the example code in post #25
 
I still get the same errors.
Going to try and get the updated SF compiler 2.2.3.6 icp 1207
 
It works in Version 2.2.3.4 ICC 1.2.0.4.

If you are getting the same error, you didn't follow exactly the steps in post #36. Follow those steps exactly as written.
 
Going to try and get the updated SF compiler 2.2.3.6 icp 1207
You don't have to. The main example program compiles with V2.2.3.0 .

Have you copied the example code shown in the post, save it to a file, and compile it?
What device do you have it set for? The CCPTMRS0 register is in the 18F43K22 (all of the K22 devices, actually)

If you downloaded the SE version you got SE 2.2.3.6, and it compiles ok there too.
Post another screen shot
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top