Simple FSK modulator enables data transmission over low-speed link
Israel Schleicher, Prescott Valley, Arizona -- EDN Europe, 01 Jul 2009
FSK (frequency-shift keying) is a type of signal modulation for transmitting digital data over an analog communication link. An FSK modulator comprises a digitally controlled sine-wave generator whose frequency shifts between two predetermined frequencies in response to the two logic levels of the digital data. The circuit in Figure 1 generates a sine wave by continuously sampling a single sine cycle. The output of IC2A is proportional to the currents through R1, R2, and R3. These resistors connect together at one end to the inverting input of IC2A, which is biased at VCC/2. The outputs GP0, GP1, and GP2 of microcontroller IC1 produce nonoverlapping pulse trains. When you set either output high or low, the others are off—that is, at high impedance. When you set an output high, the voltage across the resistor that connects to it is VCC/2. When you set the output low, the voltage across the resistor is -VCC/2.
Select the values of R1, R2, and R3 so that the current pulses have magnitudes proportional to samples of sin 30, 60, and 90°, respectively. Setting all the outputs of IC1 to off produces the sample of sin(0°), and no current flows through the resistors. Thus, starting with all outputs of IC1 at off and consecutively and periodically setting GP0, GP1, and GP2 to high and then, in reverse order, setting GP1 and GP0 high again generates the positive half of a sine wave. Repeating the process but setting the outputs to low generates the negative half of the waveform.
This scheme produces a sampled sine waveform with 12 samples per cycle. In addition to the desired frequency component, f0, this waveform contains higher-frequency components at (12k+1)f0 and (12k-1)f0, k=1,2,3, and so forth. The lowpass filter comprising IC2B, R7, R8, C3, and C4 easily filters out these undesired components of smaller amplitude. Listing 1, which is available with the Web version of this Design Idea at www.edn-europe.com/ article.asp?articleid=3144, is the assembly- program code that implements the Bell 202 FSK standard. When the control input Data In is high, the output frequency is 1200 Hz; when the control is low, the output frequency is 2200 Hz. The transition from one frequency to the other occurs in a manner that retains phase continuity. Figure 2 shows the FSK-modulator output (CH1) in response to a modulating signal (CH2).
| Listing 1: |
************************************************************* * A SIMPLE FSK MODULATOR * ************************************************************* ; THIS CODE IMPLEMENTS A BELL 202 FSK MODULATOR list p=10F200 include ; This fi le is part of Microchip MPLAB IDE ;-------------- PIC10F2xx CONFIGURATION ------------- __CONFIG _MCLRE_OFF & _WDT_OFF & _CP_OFF ; External Reset off ; Watch Dog timer off ; Code Protection off ;-------------- VARIABLE DEFINITIONS ---------------- UDATA PERIOD RES 1 ; Delay counter (Presets to time between sine samples) #defi ne DATA_IN GPIO,3 ; GP3 is DATA_IN input pin OUT_0 EQU b’00001111’ ; GP0-GP3 confi gured as High Impedance OUT_1 EQU b’00001110’ ; Only GP0 confi gured as output OUT_2 EQU b’00001101’ ; Only GP1 confi gured as output OUT_3 EQU b’00001011’ ; Only GP2 confi gured as output P1 EQU d’19’ ; Delay constant for 1200 Hz P2 EQU d’9’ ; Delay constant for 2200 Hz ; Start of program RESET CODE 0x000 GOTO init SUBS CODE 0X10 CHK_DATA: ; Checks Data input pin MOVLW P1 ; Load W with 1200 Hz Delay constant BTFSS DATA_IN ; If DATA_IN == High skip next instruction MOVLW P2 ; Load W with 2200 Hz Delay constant MOVWF PERIOD ; Load Delay counter; NOP ; NOP’S added here to fi ne tune FSK frequencies NOP RETLW 0 init: MOVWF OSCCAL ; Load the factory Internal oscillator calibration ; value MOVLW OUT_0 ; GP0 - GP3 are OFF (High impedance) TRIS GPIO CLRF GPIO ; initialize outputs to Low Level ; initialize OPTION register MOVLW b’11000111’ ; Weak Pull-ups disabled ,Wake-up on pin change OPTION ; disabled LOOP: ; This loop produces the twelve sine samples CALL CHK_DATA ; Check Data DECF PERIOD,F ; decrement delay counter twice to compensate for DECF PERIOD,F ; the 6 added instruction cycles: ; GOTO LOOP(2 cycles) DECF PERIOD,F DECF PERIOD,F ; MOVLW 0xFF and MOVWF GPIO MOVLW OUT_0 TRIS GPIO ; GP0-GP2 are OFF (High impedance) MOVLW 0xFF MOVWF GPIO L1: DECFSZ PERIOD,F GOTO L1 CALL CHK_DATA MOVLW OUT_1 TRIS GPIO ; GP0 is High L2: DECFSZ PERIOD,F GOTO L2 CALL CHK_DATA MOVLW OUT_2 TRIS GPIO ; GP1 is High L3: DECFSZ PERIOD,F GOTO L3 CALL CHK_DATA MOVLW OUT_3 TRIS GPIO ; GP2 is High L4: DECFSZ PERIOD,F GOTO L4 CALL CHK_DATA MOVLW OUT_2 TRIS GPIO ; GP1 is High L5: DECFSZ PERIOD,F GOTO L5 CALL CHK_DATA MOVLW OUT_1 TRIS GPIO ; GP0 is High L6: DECFSZ PERIOD,F GOTO L6 CALL CHK_DATA DECF PERIOD,F ; decrement delay counter to compensate for the ; following 3 added instruction cycles ; (DECF PERIOD,F MOVLW 0x00 and MOVWF GPIO ) MOVLW OUT_0 TRIS GPIO ; GP0-GP2 are OFF (High impedance) MOVLW 0x00 MOVWF GPIO L7: DECFSZ PERIOD,F GOTO L7 CALL CHK_DATA MOVLW OUT_1 TRIS GPIO ; GP0 is Low L8: DECFSZ PERIOD,F GOTO L8 CALL CHK_DATA MOVLW OUT_2 TRIS GPIO ; GP1 is Low L9: DECFSZ PERIOD,F GOTO L9 CALL CHK_DATA MOVLW OUT_3 TRIS GPIO ; GP2 is Low L10: DECFSZ PERIOD,F GOTO L10 CALL CHK_DATA MOVLW OUT_2 TRIS GPIO ; GP1 is Low L11: DECFSZ PERIOD,F GOTO L11 CALL CHK_DATA MOVLW OUT_1 TRIS GPIO ; GP0 is Low L12: DECFSZ PERIOD,F GOTO L12 GOTO LOOP END |