Claro, me imaginaba que pensabas eso, pero no... Lamentablemente para generar con una buena resolución la señal senoidal y lograr así mismo una frecuencia de 10kHz (consigna de uno de los profesores) el PIC no tiene "tiempo extra" para variar, es decir no se usaron delay's (como delay_ms(), por ejemplo) en ningún momento, el código que muestra la señal (ni siquiera se calcula la señal sino que se muestra una tabla fija pre-calculada) es siempre el mismo, construido de manera modular y lo que cambia la frecuencia de la señal (que de hecho no es variable de a 1 o 10 Hz sino valores fijos de 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000 y 10000 Hz) es la cantidad de valores seguidos de la tabla que se muestran y entre estos una cantidad variable de NOP's (que son los que tuve que ir toqueteando de a poco). Te muestro un trozo para que entiendas mejor porque no soy muy bueno con las ideas y peor con algo tan rebuscado jaja
Para generar 100 Hz obviamente sobra muchisimo tiempo:
case 100: //100 Hz
#ASM ASIS
MOVLW 2
MOVWF FSR0H
MOVLW 0
MOVWF FSR0L
RETORNO_100:
MOVF INDF0, W
MOVWF PORTD
INCFSZ FSR0L, 1
GOTO SALTO_1_100
INCF FSR0H, 1
MOVLW 6
SUBWF FSR0H, 0
BTFSS STATUS, 2
GOTO SALTO_1_100
MOVLW 2
MOVWF FSR0H
MOVLW 0
MOVWF FSR0L
SALTO_1_100:
MOVF INDF0, W
MOVWF PORTD
INCFSZ FSR0L, 1
GOTO SALTO_2_100
INCF FSR0H, 1
MOVLW 6
SUBWF FSR0H, 0
BTFSS STATUS, 2
GOTO SALTO_2_100
MOVLW 2
MOVWF FSR0H
MOVLW 0
MOVWF FSR0L
SALTO_2_100:
MOVF INDF0, W
MOVWF PORTD
INCFSZ FSR0L, 1
GOTO SALTO_3_100
INCF FSR0H, 1
MOVLW 6
SUBWF FSR0H, 0
BTFSS STATUS, 2
GOTO SALTO_3_100
MOVLW 2
MOVWF FSR0H
MOVLW 0
MOVWF FSR0L
SALTO_3_100:
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
NOP NOP NOP
GOTO RETORNO_100
#ENDASM
break;
No así para la generación de 10000 Hz:
case 10000: //10000 Hz
#ASM ASIS
MOVLW 1
MOVWF FSR0H
MOVLW 0
MOVWF FSR0L
RETORNO_10000:
MOVF INDF0, W
MOVWF PORTD
INCF FSR0L
MOVF INDF0, W
MOVWF PORTD
INCF FSR0L
MOVF INDF0, W
MOVWF PORTD
INCF FSR0L
NOP NOP NOP
GOTO RETORNO_10000
#ENDASM
break;
Lo que hace el código es simple, en vez de mostrar un valor de la tabla y luego un NOP (o más) para ajustar la frecuencia (cosa que no funciona bajo ningún punto de vista, incluso con el PIC a 48 MHz) lo que se hace es mostrar un número variable de valores de la tabla (puestos por prueba y error) y luego un número también variable de NOP's (también puestos a prueba y error), de esta forma la distorsión de la señal es mínima (de cualquier manera luego pasa por un muy buen filtro) y pueden así alcanzarse los valores pedidos con un mínimo error en frecuencia.