AR1010 Pic Basic Program for FM Radio

AR1010 Pic Basic Program for FM Radio

By: Don McClatchie

This is for those who have been trying to make an AR1010 sub-board work using PIC BASIC Pro and a Pic Microcontroller. I was not able to find any examples of BASIC programming for this neat little radio sub-board using the AR1010 from AIROHA Technology Corp. This system uses two 8 position switches to select the 9 bit FM channel, 1 bit De-Emphasis, 1 bit Mono/Stereo, 2 bit Band, and 3 bit Audio Level output. This is just a working example of Pic BASIC programming to help anyone trying to make their project work. The switch selections are multiplexed into the Pic Microcontroller using two M74HC166B1 Parallel to Serial converter chips. There is an LCD to read internal registers for testing and development. Here is the schematic. This may not be the best way to program this, but it will get the AR1010 hart started and play the music.

‘*****************************************************************************

‘*  Name    : FMR412C2.BAS                                                                                         *

‘*  Author  : Don McClatchie                                                                                         *

‘*  Notice  : Copyright (c) 2022 FM SYSTEMS, INC                                                        *

‘*          : All Rights Reserved                                                                                         *

‘*  Date    : 5/16/2022                                                                                                    *

‘*  Version : 2.0 Two Wire Communications AR1010 Sub-Board A15-45-B-04              *

‘*  Notes   : FM Stereo Receiver using AR1010 Module 76 to 108 Mhz FM Band          *

‘*          : Selectable De-Emphasis,Band,Stereo/Mono,Squelch,& Audiolevel                 *

‘*****************************************************************************

                           ; PBP -p16f685

;@_CONFIG_HS_OSC           ; OSC External 20MHz

;@_CONFIG_WDT_ON           ; WatchDog Timer ON

;@_CONFIG_PWRT_ON          ; Power Up Timer ON

;@_CONFIG_MCLR_OFF         ; MCLR as I/O

;@_CONFIG_BOD_ON           ; Brown Out Detector ON

;@_CONFIG_PROTECT_ON       ; Code Protect ON

;@_CONFIG_CPD_ON           ; Memory Protect ON                                         

include “modedefs.bas”

                           ; Set-Up I/O Pins

    trisA  = %000000           ; Set all pins to output

    trisB  = %00100000       ; Set All Outputs Except Pin 12

    trisC  = %00000000        ; Set Pins All Output Except Pin 7

    ANSEL  = %00000000       ; AN0-AN7 Analog Off 

    ANSELH = %00000100     ; AN11 Pin 12 Analog Other Pins Digital                                

    ADCON0 = %00101101     ; Left Justified Vref Pin 12

    ADCON1 = %00100000     ; A/D Conversion Clock Focs/32   

                           ; Defines

DEFINE OSC 20              ; Set oscillator for 20MHz

define ser2_bits 8         ; Set Serial Data Bits to 8

define ADC_bits 10         ; ADC to 10 Bits

define ADC_CLOCK 3         ; Clock Source RC

define ADC_SAMPLEUS 50     ; ADC Sample Time in uS

                           ; Variables                                   

W0          var word       ; Saved Switch Data

W1          var word       ; S1/S2 Saved Switch Data Variable  

TUNE        var word       ; 9 Bit Tuning Select Variable S1-1-8 S2-1

Alev        var Byte       ; Audio Level Selector Variable S2-6-8

DATA1       var byte       ; Read Data Variable

DATA2       var byte       ; Read Data Variable

DATA3       var word       ; Read Data Variable

DATA4       var byte       ; Read Data Variable

CNT         var word       ; Squelch Pot Variable Temp used for loop

TT          var word       ; Used for display temp

AR1         var word       ; AR1 Register

AR2         var word       ; AR2 Register

AR3         var word       ; AR3 Register

RSSIL       var word       ; AR11 Low Side Injection Word

RSSIH       var word       ; AR11 High side Injection Word

AR14        var word       ; AR14 Register

VOL2VOL     var byte       ; Audio Level Variable

AR2CLR      var byte       ; AR2 Clear Register (tune bit)

AR2SET      var byte       ; AR2 Set Register (tune bit)

AR11SET     var word       ; AR11 Hilow Injection Variable

AR11L       var word

AR11H       var word

                           ; Constants

AR11L  =  %0100111101010000

AR11H  =  %1100111111010101

                           ; Presets

Clear                      ; Clear All Variables

pause 1000                 ; Pause for Start Up and LCD

Start1:                    ; Main Program Initial Data Read

PortA.0 = 0                ; LCD Data Line to 0

PortC.7 = 1                ; AR1010 SDA Data Line to 1

PortB.7 = 0                ; AR1010 SCL Clock Line to 1

PortC.5 = 1                ; M74HC166B1 Shift/Load to Shift

PortC.4 = 0                ; M74HC166B1 Clock Low

gosub SCANLOAD             ; Scan and Load Switch Data

ASSIGN:                    ; Assign Tune Switchs

Tune.0  = W0.bit0          ; Get  0 bit from SW Data for Tune

Tune.1  = W0.bit1          ; Get  1 bit from SW Data for Tune

Tune.2  = W0.bit2          ; Get  2 bit from SW Data for Tune

Tune.3  = W0.bit3          ; Get  3 bit from SW Data for Tune

Tune.4  = W0.bit4          ; Get  4 bit from SW Data for Tune

Tune.5  = W0.bit5          ; Get  5 bit from SW Data for Tune

Tune.6  = W0.bit6          ; Get  6 bit from SW Data for Tune

Tune.7  = W0.bit7          ; Get  7 bit from SW Data for Tune

Tune.8  = W0.bit8          ; Get  8 Bit from SW Data for Tune

AR1 = %0101101100000101    ; Preset AR1.byte1 0101101100000101

AR1.bit4 = W0.bit9         ; De-Emphasis S2 bit4 75uS = 1 50uS = 0

AR1.bit3 = W0.bit10        ; Stereo/Mono S2 bit3 Mono = 1 Stereo = 0

AR2 = %1101000010111001        ; Preset AR2 1101000010111001

AR2.byte0 = Tune                ; Add Low byte of tune

AR2CLR = 208                    ; Byte1 bit1 = 0 TUNE off

AR2SET = 210                    ; Byte1 bit1 = 1 TUNE on

AR2CLR.bit0 = W0.bit8           ; Add 9th bit to tune off

AR2SET.bit0 = W0.bit8           ; Add 9th bit to tune on

AR3 = %1010000000010000         ; Default seekup,seek,space,band,vol,seekth

AR3.bit12 = W0.bit11            ; Band bit1

AR3.bit11 = W0.bit12            ; Band bit0

ALEV.bit0 = W0.bit13            ; SW2-6 Audio Level Bit0

ALEV.bit1 = W0.bit14            ; SW2-7 Audio Level Bit1

Alev.bit2 = W0.bit15            ; SW2-8 Audio Level Bit2

                                ;     VOL2  VOL

if Alev = 0 then VOL2VOL = 15   ; +0  0000;1111 Turns 3bits into 4bits 7 Select

if Alev = 1 then VOL2VOL = 75   ; +4  0100;1011

if Alev = 2 then VOL2VOL = 251  ; +6  1111,1011

if Alev = 3 then VOL2VOL = 249  ; +8  1111,1001

if Alev = 4 then VOL2VOL = 247  ; +10 1111,0111

If Alev = 5 then VOL2VOL = 230  ; +12 1110,0110

if Alev = 6 then VOL2VOL = 113  ; +14 1110,0011

if Alev = 7 then VOL2VOL = 240  ; +18 1111,0000

AR3.bit10 = VOL2VOL.bit3        ; Volume Bit3 SW2-8

AR3.bit9  = VOL2VOL.bit2        ; Volume Bit2 SW2-7

AR3.bit8  = VOL2VOL.bit1        ; Volume Bit1 SW2-6

AR3.bit7  = VOL2VOL.bit0        ; Volume Bit0

AR14 = %1111110000101101        ; AR14 Default Register

AR14.bit15 = VOL2VOL.bit7       ; Volume2 Bit3

AR14.bit14 = VOL2VOL.bit6       ; Volume2 Bit2

AR14.bit13 = VOL2VOL.bit5       ; Volume2 Bit1

AR14.bit12 = VOL2VOL.bit4       ; Volume2 Bit0

W1 = W0                                  ; Load Switch Data to store for change

REGISTERLOAD:                            ; Registerload Routine 1=READ 0=WRITE       

gosub STARTCLK                           ; Start Clock Sequence

gosub ARADD                              ; Go to Chip Address Send Routine

shiftout PortC.7,PortB.7,1,[1]           ; Write Address R1 De-E

gosub WRITEACK                           ; Send Ack Clock Pulse + Receive ACK

shiftout PortC.7,PortB.7,1,[AR1.byte1]   ; Write Data D15-D8  01011011

gosub WRITEACK                           ; Send Ack Clock Pulse + Receive ACK

shiftout PortC.7,PortB.7,1,[AR1.byte0]   ; Write Data D7-D0 00010101 = no mute

gosub WRITEACK                           ; Send Ack Clock Pulse + Receive ACK

gosub STOPCLK                            ; Send Stop Comm to AR1010

gosub STARTCLK                           ; Start Clock Sequence

gosub ARADD                              ; Go to Chip Address Send Routine

shiftout PortC.7,PortB.7,1,[2]           ; Write Address R2 Tune

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[AR2SET]      ; Write Data D15-D8 Tune HBits 11000110

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[tune.byte0]  ; Write Data D7-D0 Tune Lbyte  11000110

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

gosub STOPCLK                            ; Send Stop Comm to AR1010

gosub STARTCLK                           ; Start Clock Sequence

gosub ARADD                              ; Go to Chip Address Send Routine

shiftout PortC.7,PortB.7,1,[3]           ; Write Address R2 Tune

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[AR3.byte1]   ; Write Data D15-D8 Tune HBits 10100111

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[AR3.byte0]   ; Write Data D7-D0 Tune LowBits00010000

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

gosub STOPCLK                            ; Send Stop Comm to AR1010

gosub STARTCLK                           ; Start Clock Sequence

gosub ARADD                              ; Go to Chip Address Send Routine

shiftout PortC.7,PortB.7,1,[10]          ; Write Address R10 Seek_wrap

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[%10000010]   ; Write Data D15-D8 10000010  

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[%11001110]   ; Write Data D7-D0 seek_wrap 11001010

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

gosub STOPCLK                            ; Send Stop Comm to AR1010

gosub STARTCLK                           ; Start Clock Sequence

gosub ARADD                              ; Go to Chip Address Send Routine

shiftout PortC.7,PortB.7,1,[11]          ; Write Address R11 hilo_side

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[%01001111]   ; Write Data D15-D8  11001111

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[%01010101]   ; Write Data D7-D0   01010101

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

gosub STOPCLK                            ; Send Stop Comm to AR1010

gosub STARTCLK                           ; Start Clock Sequence

gosub ARADD                              ; Go to Chip Address Send Routine

shiftout PortC.7,PortB.7,1,[14]          ; Write Address R14 Volume

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[AR14.byte1]  ; Write Data D15-D8 Volume 11111111

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[AR14.byte0]  ; Write Data D7-D0 00000000

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

gosub STOPCLK                            ; Send Stop Comm to AR1010

gosub STARTCLK                           ; Start Clock Sequence

gosub ARADD                              ; Go to Chip Address Send Routine

shiftout PortC.7,PortB.7,1,[0]           ; Write Address R1 xo_en/Enable

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[%11111111]   ; Write Data D15-D8 11111111

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[%11111011]   ; Write Data D7-D0 Set Enable 11111011

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

gosub STOPCLK                            ; Send Stop Comm to AR1010

pause 1000                               ; Pause 1 S

for CNT = 0 to 1                         ; Clear Squelch Variable

TUNE2:                                   ; Tuning Routine

gosub STARTCLK                           ; Start Clock Sequence

gosub ARADD                              ; Go to Chip Address Send Routine

shiftout PortC.7,PortB.7,1,[1]           ; Write Address R1

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[AR1.byte1]   ; Write Data D15-D8   01011011

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[AR1.byte0]   ; Write Data D7-D0 Set Hmute 00010111

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

gosub STOPCLK                            ; Send Stop Comm to AR1010

gosub STARTCLK                           ; Start Clock Sequence

gosub ARADD                              ; Go to Chip Address Send Routine

shiftout PortC.7,PortB.7,1,[2]           ; Write Address R1 Tune

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[AR2CLR]      ; Write Data D15-D8 Clear Tune bit

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[TUNE.byte0]  ; Write Data D7-D0 Load Tune bits

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

gosub STOPCLK                            ; Send Stop Comm to AR1010

gosub STARTCLK                           ; Start Clock Sequence

gosub ARADD                              ; Go to Chip Address Send Routine

shiftout PortC.7,PortB.7,1,[3]           ; Write Address R3 Seekup

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[AR3.byte1]   ; Write Data D15-D8 Clr seek bit

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[AR3.byte0]   ; Write Data D7-D0         00000000

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

gosub STOPCLK                            ; Send Stop Comm to AR1010

gosub STARTCLK                           ; Start Clock Sequence

gosub ARADD                              ; Go to Chip Address Send Routine

shiftout PortC.7,PortB.7,1,[2]           ; Write Address R3 Seekup

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[AR2CLR]      ; Write Data D15-D8    11010010

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[TUNE.byte0]  ; Write Data D7-D0 Volume     11001011

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

gosub STOPCLK                            ; Send Stop Comm to AR1010

gosub STARTCLK                           ; Start Clock Sequence

gosub ARADD                              ; Go to Chip Address Send Routine

shiftout PortC.7,PortB.7,1,[2]           ; Write Address R0 xo_en/Enable

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[AR2SET]      ; Write Data D15-D8      11111111

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[TUNE.byte0]  ; Write Data D7-D0

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

gosub STOPCLK                            ; Send Stop Comm to AR1010

gosub STARTCLK                           ; Start Clock Sequence

gosub ARADD                              ; Go to Chip Address Send Routine

shiftout PortC.7,PortB.7,1,[1]           ; Write Address R3 Seekup

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[%01011011]   ; Write Data D15-D8

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

shiftout PortC.7,PortB.7,1,[%00010101]   ; Write Data D7-D0 Clr Hmutebit00010101

gosub WRITEACK                           ; Send Acknowledge Clock Pulse

gosub STOPCLK                            ; Send Stop Comm to AR1010

pause 100                               ; Pause 1S

DATA1 = 0                                ; Clear Data1 Variable

DATA2 = 0                                ; Clear Data2 Variable

DATA3 = 0                                ; Clear Data3 Variable

DATA4 = 0                                ; Clear DATA 4 Variable

READ1:                                   ; Read Register Data

gosub STARTCLK                           ; Start Clock Sequence

gosub ARADD                              ; Send 7bit Slave Address + 0 Write(32)

shiftout PortC.7,PortB.7,1,[18]          ; Write Address from switches (READ)   

gosub WRITEACK                           ; Send Acknowledge Clock Pulse REC

gosub STARTCLK                           ; Start Clock Sequence Again

shiftout PortC.7,PortB.7,1,[33]          ; Send 7bit Slave Address + 1 READ(33)

gosub WRITEACK                           ; Send Acknowledge Clock Pulse REC

shiftin PortC.7,PortB.7,0,[DATA1]        ; Clock in High Byte Data from AR1010

trisC.bit7 = 0                           ; Make PortC.7 an Output

gosub READACK                            ; Send READ Acknowledge to AR1010

shiftin PortC.7,PortB.7,0,[DATA2]        ; Clock in Low Byte Data from AR1010

trisC.bit7 = 0                           ; Make PortC.7 an Output

gosub READACK                            ; Send READ Acknowledge to AR101

gosub STOPCLK                            ; Send Stop Com to AR1010

READ2:                                   ; Read Register Data

gosub STARTCLK                           ; Start Clock Sequence

gosub ARADD                              ; Send 7bit Slave Address + 0 Write(32)

shiftout PortC.7,PortB.7,1,[19]          ; Write Address from switches (READ)   

gosub WRITEACK                           ; Send Acknowledge Clock Pulse REC

gosub STARTCLK                           ; Start Clock Sequence Again

shiftout PortC.7,PortB.7,1,[33]          ; Send 7bit Slave Address + 1 READ(33)

gosub WRITEACK                           ; Send Acknowledge Clock Pulse REC

shiftin PortC.7,PortB.7,0,[DATA3.byte0]  ; Clock in High Byte Data from AR1010

trisC.bit7 = 0                           ; Make PortC.7 an Output

gosub READACK                            ; Send READ Acknowledge to AR1010

shiftin PortC.7,PortB.7,0,[DATA4]        ; Clock in Low Byte Data4 from AR1010

trisC.bit7 = 0                           ; Make PortC.7 an Output

gosub READACK                            ; Send READ Acknowledge to AR101

gosub STOPCLK                            ; Send Stop Com to AR1010

pause 100                                ; Pause for STC

next                                     ; Do it again

if DATA4.bit5 <> 1 then goto TUNE2       ; Go back if STC Flag not set

If DATA2 < 150 then goto TUNE2           ; Read Data2 for IF-CNT re-tune if low

                                         ; Compute Channel Frequency Routine

DATA3 = DATA3 *2                         ; Test for display Channel

If DATA4 > 128 then DATA3 = DATA3 + 1    ; test for display Channel

if DATA4 > 128 then DATA4 = DATA4 – 128  ; test for display Channel

DATA3 = DATA3 + 690                      ; test for display Channel

Main:                                    ; Main Loop

gosub SCANLOAD                           ; Get Switch Settings

if W0 = W1 then PortB.6 = 0              ; test if Sw is changed

if W0 <> W1 then PortB.6 = 1             ; LED off if switch changed until lock

If W0 <> W1 then goto START1             ; Go back if Switch has changed

if DATA4.bit3 = 1 then PortB.4 = 1       ; Stereo Led ON

if data4.bit3 = 0 then PortB.4 = 0       ; Stereo Led Off

If DATA4.bit4 = 1 then goto START1       ; Check STC flag = 1 Seektune Complete

                                         ; LCD READOUT Routine for Testing                                         

ADCIN 11, SQL                            ; Get Squelch knob Analog level

serout2 PortA.0, 16416, [254,88]         ; Send LCD Clear

serout2 PortA.0, 16416, [254,71,1,1]     ; Select 1rst Row of LCD

serout2 PortA.0, 16416, [“18D1 “,#DATA1,” D2 “,#DATA2] ;Send 1rst Row to LCD

serout2 PortA.0, 16416, [254,71,1,2]     ; Select 2nd Row of LCD  

serout2 PortA.0, 16416, [“19D3 “,#DATA3,” D4 “,#DATA4] ;Send 2nd row DATA to LCD

Pause 100                                ; pause (display flash) to see in loop

goto Main                                ; Loop main program

ARADD:                                   ; Subroutine to send chip address

shiftout PortC.7,PortB.7,1,[32]          ; Write AR1010 Address + Write   32

trisC.bit7 = 1                           ; Make PortC.7 an Input

PortB.7 = 0

PortB.7 = 1                              ; Clock Line High

pauseus 2                                ; Wait 1 uS

PortB.7 = 0                              ; Clock Line Low

trisC.bit7 = 0                           ; Make PortC.7 an Output            

return                                   ; go back

STARTCLK:                                ; AR1010 Start Clock Routine

PortB.7 = 1                              ; Clock Line High

PortC.7 = 1                              ; Data Line High

pauseus 2                                ; Wait 2 uS

PortC.7 = 0                              ; Data Line Low

pauseus 2                                ; Wait 2 uS

PortB.7 = 0                              ; Clock line Low

return                                   ; Go back

STOPCLK:                                 ; AR1010 Stop Clock Routine

PortC.7 = 0                              ; Data Line Low

pauseus 2                                ; Wait 2 uS

PortB.7 = 1                              ; Clock line High

pauseus 2                                ; Wait 2 uS

PortC.7 = 1                              ; Data Line High

return                                   ; Go back

READACK:                                 ; READ Acknowledge Routine

PortC.7 = 0                              ; Data Line Low

PortB.7 = 1                              ; Clock Line High

pauseus 1                                ; Wait 1 uS

PortB.7 = 0                              ; Clock Line Low

PortC.7 = 1                              ; Data Line High

return                                   ; Go Back

WRITEACK:                                ; Write Acknowledge Routine

trisC.bit7 = 1                           ; Make PortC.7 an Input

PortB.7 = 0                              ; Clock Line Low

PortB.7 = 1                              ; Clock Line High

pauseus 2                                ; Wait 1 uS

PortB.7 = 0                              ; Clock Line Low

trisC.bit7 = 0                           ; Make PortC.7 an Output

Return                                   ; Go Back

SCANLOAD:                                ; SCANLOAD Read Switch Routine

PORTC.5 = 0                              ; Shift/Load to Load

PORTC.4 = 0                              ; Clock Low

PORTC.4 = 1                              ; Clock High

PORTC.4 = 0                              ; Clock Low

PORTC.5 = 1                              ; Shift/Load to Shift

PORTC.5 = 1                              ; Shift/Load to Shift

shiftin PORTC.3, PORTC.4, 0, [W0\16]     ; Receive Data from Switchs 16 bit

trisC.bit7 = 0                           ; Make Data Line PortC.7 an output

Return                                   ; go back

end                                      ; end

Post Tags: