Microcontroladores PIC en Linux.
¿Quieres reaccionar a este mensaje? Regístrate en el foro con unos pocos clics o inicia sesión para continuar.

PIC12F675 música bit con buzzer

Ir abajo

PIC12F675 música bit con buzzer Empty PIC12F675 música bit con buzzer

Mensaje por aztk Vie 17 Feb 2012 - 5:22

Saludos bros/sis!!!!

Acá les publico un código en asm para el PIC12F675. Un pic pequeñito, de apenas 8 pines, pero de las cuales sólo necesitamos 3, dos para alimentarlo y una salida.

Dicho programita nos permite generar las notas LA, LA#, SI, DO, DO#, RE, RE#, MI, FA, FA#, SOL, SOL# en cuarta octava; y en tiempos de SEMICORCHEA, CORCHEA, NEGRA.

Para generar las frecuencias, uso el timer0.

Como ejemplo del uso de las notas musicales, programé un fragmento de la canción "It's hard to say goodbye" (https://www.youtube.com/watch?v=a_Am4cHMBKM)

Anexo también diagrama, pero es demasiado fácil la conexión, jajaja.

Código:

; -----------------------------------------------------------------------
; Title:  buzzer_tone
; Author:  aztk
; Licence: CopyLeft
; Date:    Febrero 2012
;
; Este programa se vale del uso del TMR0 para generar tonos a emitir en un
;  buzzer, los tonos programados han sido LA, LA#, SI, DO, DO#, RE, RE#,
;  MI, FA, FA#, SOL, SOL# en la cuarta octava. También se ha programado
;  SILENCIO - ENDSILENCIO el cual no emite sonido alguno.
; Los tonos pueden ser emitidos en una duración de SEMICORCHEA (1/4),
;  CORCHEA (1/2), NEGRA (1). La duración de SEMICORCHEA es de aprox 0.1923s.
;
; Se programó un fragmento de la canción "It's hard to say goodbye" de
;  Michael Ortega (http://www.youtube.com/watch?v=a_Am4cHMBKM)
;

    processor 12F675
    #include

; -----------------------------------------------------------------------
; Configuration bits: adapt to your setup and needs
    __CONFIG _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT
; Usar oscilador interno a 4MHZ

#define  BUZZER  GPIO,02        ; Pin de BUZZER
#define  BUZZER_W BUZZER_W_R,00  ; Bandera de estado de BUZZER (0 - OFF; 1 - ON)
#define  SILENTF  BUZZER_W_R,01  ; Bandera si BUZZER no debe emitir un tono o si
                                ;  (1 - SILENCIO; 0 - EMITIR SONIDO)

; -----------------------------------------------------------------------
; Variables declaration
CBLOCK 0x20
    CounterA        ; Contador para rutina de tiempo (SUB_semi)
    CounterB        ; Contador para rutina de tiempo (SUB_semi)
    TONE_VAL        ; Valor a cargar a TMR0 para generar una frecuencia dada
    BUZZER_W_R      ; Registro para bandera de estado de buzzer y silenciar buzzer
    w_saved          ; Temporal para W, en interrupción
    status_saved    ; Temporal para STATUS, en interrupción
ENDC

; -----------------------------------------------------------------------
; MACROS

NEGRA MACRO
    call    SUB_negra
 ENDM

CORCHEA MACRO
    call    SUB_corchea
 ENDM

SEMICORCHEA MACRO
    call    SUB_semi
 ENDM

LA MACRO
    call    SUB_LA
 ENDM

LA_S MACRO
    call    SUB_LA_S
 ENDM

SI MACRO
    call    SUB_SI
 ENDM

DO MACRO
    call    SUB_DO
 ENDM

DO_S MACRO
    call    SUB_DO_S
 ENDM

RE MACRO
    call    SUB_RE
 ENDM

RE_S MACRO
    call    SUB_RE_S
 ENDM

MI MACRO
    call    SUB_MI
 ENDM

FA MACRO
    call    SUB_FA
 ENDM

FA_S MACRO
    call    SUB_FA_S
 ENDM

SOL MACRO
    call    SUB_SOL
 ENDM

SOL_S MACRO
    call    SUB_SOL_S
 ENDM

SILENCIO MACRO
    bsf    SILENTF
 ENDM

ENDSILENCIO MACRO
    bcf    SILENTF
 ENDM

; -----------------------------------------------------------------------
; reset vector
    org 0x000
    nop                    ; needed for ICD2 debugging
    goto    INIT

    org 0x04
; interrupt vector
    goto    interrupt      ; go to start of interrupt code

INIT
    BANKSEL 0x80          ; Bank01
    call    0x3FF          ; INT OSC
    movwf  OSCCAL

    movlw  B'11010010'    ;set internal clock(bit5=0)
                          ;prescaler 1:8
    movwf  OPTION_REG
    bsf    INTCON,T0IE    ;Timer0 interruption enabled

    clrf    VRCON          ;Vref Off (power off the comparator voltage, saves power)
    clrf    ANSEL

    bcf    BUZZER
    BANKSEL 0x00          ;BANK 0
    bcf    BUZZER_W

    movlw  0x07
    movwf  CMCON          ;Comparator Off

    bcf    INTCON,T0IF    ;Timer0
    clrf    TMR0
    bsf    INTCON,GIE

    movlw  high main      ; load upper byte of 'main' label
    movwf  PCLATH        ; initialize PCLATH
    goto    main          ; go to start of main code

; ISR
interrupt
    movwf  w_saved        ; save context
    swapf  STATUS,w
    movwf  status_saved

    ; TMR0 disparará una interrupción en base al valor que se le haya
    ;  cargado a TONE_VAL, y cambiará el estado del pin BUZZER

    bcf    INTCON,T0IF    ; Limpiamos flag de interrupción
    movf    TONE_VAL,W    ; Refrescamos el valor de TMR0 para la frecuencia
    movwf  TMR0          ;  configurada en TONE_VAL

    btfsc  SILENTF        ; Si SILENTF está levantada entonces apagar BUZZER
    goto    OFFb

    ; Cambiar estado de BUZZER
    btfsc  BUZZER_W
    goto    OFFb
    btfss  BUZZER_W
    goto    ONb
ONb                        ; Encender BUZZER y levantar flag de su estado
    bsf    BUZZER
    bsf    BUZZER_W
    ;retfie
    goto    return_int
OFFb
    bcf    BUZZER        ; Apagar BUZZER y bajar flag de su estado
    bcf    BUZZER_W
    ;retfie
    ;;;

return_int
    swapf  status_saved,w ; restore context
    movwf  STATUS
    swapf  w_saved,f
    swapf  w_saved,w
    retfie

; -----------------------------------------------------------------------
; PROGRAMA PRINCIPAL
;
;  Emite un fragmento de la melodía "It's hard to say goodbye",
;  canción de Michael Ortega (http://www.youtube.com/watch?v=a_Am4cHMBKM)

main
    FA_S
    CORCHEA

    DO_S
    CORCHEA

    FA_S
    CORCHEA

    DO_S
    NEGRA
    NEGRA

    DO_S
    SEMICORCHEA

    ;;;

    RE_S
    CORCHEA

    MI
    CORCHEA

    SOL_S
    CORCHEA

    DO_S
    CORCHEA

    MI
    NEGRA

    DO
    CORCHEA

    DO_S
    CORCHEA

    DO_S
    SEMICORCHEA

    ;;;

    MI
    CORCHEA

    RE
    CORCHEA

    LA
    CORCHEA

    RE
    CORCHEA

    FA_S
    NEGRA

    RE
    CORCHEA

    DO_S
    CORCHEA

    ;;;

    RE
    CORCHEA

    LA
    CORCHEA

    MI
    CORCHEA

    LA
    CORCHEA

    DO_S
    CORCHEA

    DO_S
    CORCHEA

    SOL
    CORCHEA

    DO_S
    CORCHEA

    ;;;

    MI
    CORCHEA

    FA_S
    CORCHEA

    DO_S
    CORCHEA

    FA_S
    CORCHEA

    DO_S
    NEGRA
    NEGRA

    DO_S
    SEMICORCHEA

    ;;;

    RE_S
    CORCHEA

    MI
    CORCHEA

    SOL_S
    CORCHEA

    DO_S
    CORCHEA

    MI
    NEGRA

    DO_S
    CORCHEA

    DO_S
    SEMICORCHEA

    ;;;

    MI
    CORCHEA

    RE
    CORCHEA

    LA
    CORCHEA

    RE
    CORCHEA

    FA_S
    NEGRA

    RE
    CORCHEA

    DO_S
    CORCHEA

    ;;;

    RE
    CORCHEA

    LA
    CORCHEA

    MI
    CORCHEA

    LA
    CORCHEA

    DO_S
    NEGRA

    DO_S
    CORCHEA

    SOL_S
    SEMICORCHEA

    DO_S
    SEMICORCHEA

    ;;;

    MI
    CORCHEA

    SOL_S
    NEGRA
    NEGRA

    FA_S
    SEMICORCHEA

    ;;;

;    FA_S
;    CORCHEA

;    DO_S
;    CORCHEA

;    FA_S
;    CORCHEA

;    LA
;    CORCHEA

;    FA_S
;    CORCHEA

;    DO_S
;    CORCHEA

;    DO_S
;    SEMICORCHEA

    ;;;

;    RE_S
;    CORCHEA

;    DO_S
;    CORCHEA

;    SOL_S
;    CORCHEA

;    DO_S
;    CORCHEA

;    MI
;    CORCHEA

;    DO_S
;    CORCHEA

;    SOL_S
;    CORCHEA

;    DO_S
;    SEMICORCHEA

    ;;;

;    MI
;    CORCHEA

;    RE
;    CORCHEA

;    LA
;    CORCHEA

;    RE
;    CORCHEA

;    FA_S
;    CORCHEA

;    RE
;    CORCHEA

;    LA
;    CORCHEA

;    DO_S
;    SEMICORCHEA


    SILENCIO
    NEGRA
    NEGRA
    NEGRA
    ENDSILENCIO

    goto    main        ; loop forever
;END main

;---------------------------------------------------------------
; SUBROUTINES

; Delay code generated by PikLoops (Tue 2012-Feb-14 21:58:25)
; Time Delay = 0.19229800s  with  Osc = 4.00000000MHz
SUB_semi ; semicorchea 1/4
    movlw  D'250'
    movwf  CounterB
    movlw  D'187'
    movwf  CounterA
semi_loop
    decfsz  CounterA,1
    goto    semi_loop
    decfsz  CounterB,1
    goto    semi_loop
    return

SUB_corchea ; corchea 1/2
    call    SUB_semi
    call    SUB_semi
    return

SUB_negra ; negra 1
    call    SUB_semi
    call    SUB_semi
    call    SUB_semi
    call    SUB_semi
    return

; Valores para notas, TMR0 con prescaler 1:8
; 4*Tosc = 1us
;
; TONE_VAL = 0x100 - (((1/f)/2)/8)/(4 Tosc)
;          = 0x100 - (10^6)/(16 f)

SUB_LA ; f = 440 Hz
    movlw  0x71
    movwf  TONE_VAL
    return

SUB_LA_S ; f = 466.16 Hz
    movlw  0x79
    movwf  TONE_VAL
    return

SUB_SI ; f = 493.88 Hz
    movlw  0x81
    movwf  TONE_VAL
    return

SUB_DO ; f = 261.63 Hz
    movlw  0x11
    movwf  TONE_VAL
    return

SUB_DO_S ; f = 277.18 Hz
    movlw  0x1E
    movwf  TONE_VAL
    return

SUB_RE ; f = 293.67 Hz
    movlw  0x2B
    movwf  TONE_VAL
    return

SUB_RE_S ; f = 311.13 Hz
    movlw  0x37
    movwf  TONE_VAL
    return

SUB_MI ; f = 329.63 Hz
    movlw  0x42
    movwf  TONE_VAL
    return

SUB_FA ; f = 349.23 Hz
    movlw  0x4D
    movwf  TONE_VAL
    return

SUB_FA_S ; f = 369.99 Hz
    movlw  0x57
    movwf  TONE_VAL
    return

SUB_SOL ; f = 392 Hz
    movlw  0x60
    movwf  TONE_VAL
    return

SUB_SOL_S ; f = 415.31 Hz
    movlw  0x69
    movwf  TONE_VAL
    return

; pk2cmd no modifica el valor de la posición 0x3FF
; -----------------------------------------------------------------------
; Valor de fábrica para oscilador interno a 4MHz
; ***IMPORTANTE***
; Ajustar a valor propio del chip usado
;    org 0x3FF
;    retlw  0x44 ;0x4C

END


Cualquier duda, sugerencia, loquesea, aquí andamos. Smile

PIC12F675 música bit con buzzer Schemep

aztk
Participante Activo
Participante Activo

Mensajes : 52
Fecha de inscripción : 08/06/2009
Edad : 35
Localización : Tenochtitlan

Volver arriba Ir abajo

Volver arriba

- Temas similares

 
Permisos de este foro:
No puedes responder a temas en este foro.