My current project involves using 3 PICs; PIC18F14K50, PIC18F26K42, and PIC16F18426...all on the same board. Can I install jumpers between the PIC's Vpp and the IDC 4 / PICkit3 (etc) ICSP header? The idea is to jump Vpp on the PIC I want to program next. This would leave DAT & CLK lines permanently connected. I left these pins dedicated for ICSP (no secondary use in circuit).
↧
Programming several PICs on same PCB board
↧
HTML and PIC communication
I am trying to understand how can a PIC communicate to an HTML page for displaying and receive data.
Say that on the HTML page there is a text box to enter a value and a button to send this value to PIC.
Also a value from the PIC is to be send and displayed on the HTML page.
Anyone done this?
I attach the test HTML code I have done so far that displays buttons and input text boxes but have no clue how to use that.
Ioannis
Attachment 8878
Say that on the HTML page there is a text box to enter a value and a button to send this value to PIC.
Also a value from the PIC is to be send and displayed on the HTML page.
Anyone done this?
I attach the test HTML code I have done so far that displays buttons and input text boxes but have no clue how to use that.
Ioannis
Attachment 8878
↧
↧
Pickit 2 and 3 Standalone IDE
Long time ago I used the standalone IDE for the Pickit2 and Pickit3 but the program was a bit buggy.
Now, Evan at http://pickitplus.co.uk/ has developed his own IDE that is identical to the old one. As he stated, development continuous and will include other chips too. I asked for a specific PIC24 that I hope to use soon.
Ioannis
Now, Evan at http://pickitplus.co.uk/ has developed his own IDE that is identical to the old one. As he stated, development continuous and will include other chips too. I asked for a specific PIC24 that I hope to use soon.
Ioannis
↧
Si4702 FM Radio chip
Hi Guys :)
Has anyone done anything with one of these, and/or shared code? I can’t find anything in a search.
It looks to support i2c and SPI despite not using either of those terms in the data sheet.
I’ve breadboarded one up, but if anyone can save me time to get it going I’m up for it.
Otherwise I’ll be back later with code example I suppose. It feels like an Arduino project minus the Arduino :D
Si470x , Si4703
Attachment 8892
Has anyone done anything with one of these, and/or shared code? I can’t find anything in a search.
It looks to support i2c and SPI despite not using either of those terms in the data sheet.
I’ve breadboarded one up, but if anyone can save me time to get it going I’m up for it.
Otherwise I’ll be back later with code example I suppose. It feels like an Arduino project minus the Arduino :D
Si470x , Si4703
Attachment 8892
↧
Flyback/forward power supply using comparator and hpwm/timer, possible?
Hello.
I have a following idea. Say we have hpwm configured to deliver 30khz. It drives external mosfet which operates flyback transformer to deliver 170V 10mA at output. Rectified output is fed to comparator, which, according to output voltage, enables-disables hpwm. All this done via config, no CPU cycles stolen from main code. Will it work? I don't need spot-on voltage stability, +-5% variation is absolutely ok.
I have a following idea. Say we have hpwm configured to deliver 30khz. It drives external mosfet which operates flyback transformer to deliver 170V 10mA at output. Rectified output is fed to comparator, which, according to output voltage, enables-disables hpwm. All this done via config, no CPU cycles stolen from main code. Will it work? I don't need spot-on voltage stability, +-5% variation is absolutely ok.
↧
↧
pic16f876a-i/sp replacement
I'm looking for a pin compatible processor with lots more memory to be used in an existing project
↧
error collection with try or catch
Within PBP3.0 is there any type of error collection like with a try or catch type statement?
Thanks
George
Thanks
George
↧
7-Seg display not counting
Hi All,
I have a 3 digit 7-seg LED display and this works fine, but it's only display the ones...
I'm missing the tens and hundreds.
If I make W1 = 123, then it's show 123 on the display!
Thanks,
W1 = 0
Loop_1:
W1 = W1 + 1
for I = 1 to 50
gosub Display
pause 1
Next I
I = 0
goto Loop_1
' Sub to send the binary number (0-999) in W1 to 7-seg
display:
B0 = W1 / 100 ' Find number of hundreds
W1 = W1 // 100 ' Remove hundreds from W1
Gosub bin2seg ' Convert number to segments
poke PortC, B0 ' Send segments to LED
high PortA.2
Pause 5 ' Leave it on 5 ms
low PortA.2 ' Turn off to prevent ghosting
B0 = W1 / 10 ' Find number of tens
W1 = W1 // 10 ' Remove tens from W1
Gosub bin2seg ' Convert number to segments
Poke PortC, B0 ' Send segments to LED
high PortA.1
Pause 5 ' Leave it on 5 ms
low PortA.1 ' Turn off to prevent ghosting
B0 = W1 ' Get number of ones
Gosub bin2seg ' Convert number to segments
Poke PortC, B0 ' Send segments to LED
High PortA.0
Pause 5 ' Leave it on 5 ms
Low PortA.0 ' Turn off to prevent ghosting
Return ' Go back to caller
bin2seg:
' Convert binary number in B0 (0 t/m 9) to segments for LED
Lookup B0,[$3F,$6,$5B,$4F,$66,$6D,$7D,$7,$7F,$6F],B0
Return
END
I have a 3 digit 7-seg LED display and this works fine, but it's only display the ones...
I'm missing the tens and hundreds.
If I make W1 = 123, then it's show 123 on the display!
Thanks,
W1 = 0
Loop_1:
W1 = W1 + 1
for I = 1 to 50
gosub Display
pause 1
Next I
I = 0
goto Loop_1
' Sub to send the binary number (0-999) in W1 to 7-seg
display:
B0 = W1 / 100 ' Find number of hundreds
W1 = W1 // 100 ' Remove hundreds from W1
Gosub bin2seg ' Convert number to segments
poke PortC, B0 ' Send segments to LED
high PortA.2
Pause 5 ' Leave it on 5 ms
low PortA.2 ' Turn off to prevent ghosting
B0 = W1 / 10 ' Find number of tens
W1 = W1 // 10 ' Remove tens from W1
Gosub bin2seg ' Convert number to segments
Poke PortC, B0 ' Send segments to LED
high PortA.1
Pause 5 ' Leave it on 5 ms
low PortA.1 ' Turn off to prevent ghosting
B0 = W1 ' Get number of ones
Gosub bin2seg ' Convert number to segments
Poke PortC, B0 ' Send segments to LED
High PortA.0
Pause 5 ' Leave it on 5 ms
Low PortA.0 ' Turn off to prevent ghosting
Return ' Go back to caller
bin2seg:
' Convert binary number in B0 (0 t/m 9) to segments for LED
Lookup B0,[$3F,$6,$5B,$4F,$66,$6D,$7D,$7,$7F,$6F],B0
Return
END
↧
PIC 18F2431 PORTB.6 and 7 - strange behavior on restart after a few hours "rest"
Hello everyone,
I have made a little circuit based on a 18F2431; it's un circling dot on a 8x8 LED matrix.
My code below works well BUT when I restart my circuit after a few hours "rest" (= no power on the circuit), both PORTB.6 and PORTB.7 seem not to work as outputs anymore. I can see it because the dot doesn't light up when those two PORTs are used.
If I reprogram the chip, it will work fine again. Even after two hours with no power on the circuit, it will still work. But after maybe 5 or 6 hours, the problems occurs.
I'm not sure what is wrong but I might have to set something in the CONFIG fuses I couldn't find up to now. I'm beginning with 18F PIcs....
Anyone an idea what I'm missing?
I have made a little circuit based on a 18F2431; it's un circling dot on a 8x8 LED matrix.
My code below works well BUT when I restart my circuit after a few hours "rest" (= no power on the circuit), both PORTB.6 and PORTB.7 seem not to work as outputs anymore. I can see it because the dot doesn't light up when those two PORTs are used.
If I reprogram the chip, it will work fine again. Even after two hours with no power on the circuit, it will still work. But after maybe 5 or 6 hours, the problems occurs.
I'm not sure what is wrong but I might have to set something in the CONFIG fuses I couldn't find up to now. I'm beginning with 18F PIcs....
Anyone an idea what I'm missing?
Code:
' ====== FUSES =====================================================================================
' PIC 18F2431
' INTernal oscillator
@ __CONFIG _CONFIG1H, _OSC_HS_1H '& _FCMEN_ON_1H & _IESO_OFF_1H
@ __CONFIG _CONFIG2L, _PWRTEN_OFF_2L & _BOREN_OFF_2L & _BORV_45_2L
@ __CONFIG _CONFIG2H, _WDTEN_OFF_2H & _WINEN_OFF_2H & _WDPS_1_2H
@ __CONFIG _CONFIG3L, _T1OSCMX_OFF_3L & _HPOL_LOW_3L & _LPOL_LOW_3L & _PWMPIN_OFF_3L
@ __CONFIG _CONFIG3H, _MCLRE_OFF_3H
@ __CONFIG _CONFIG4L, _STVREN_OFF_4L & _LVP_OFF_4L & _DEBUG_OFF_4L
@ __CONFIG _CONFIG5L, _CP0_OFF_5L & _CP1_OFF_5L
@ __CONFIG _CONFIG5H, _CPB_OFF_5H & _CPD_OFF_5H
@ __CONFIG _CONFIG6L, _WRT0_OFF_6L & _WRT1_OFF_6L
@ __CONFIG _CONFIG6H, _WRTB_OFF_6H & _WRTC_OFF_6H & _WRTD_OFF_6H
@ __CONFIG _CONFIG7L, _EBTR0_OFF_7L & _EBTR1_OFF_7L
@ __CONFIG _CONFIG7H, _EBTRB_OFF_7H
' ====== REGISTERS =================================================================================
' 76543210
OSCCON = %01110000 'set INTRC to 8 MHZ
OSCTUNE = %00000000 'OSCILLATOR TUNING REGISTER
ADCON0 = %00000000 'A/D CONTROL REGISTER 0
ADCON1 = %00000000 'A/D CONTROL REGISTER 1
ADCON2 = %00000000 'A/D CONTROL REGISTER 2
ANSEL0 = %00000000 'Analog Select Register 0
INTCON = %00000000 'INTERRUPT CONTROL REGISTER, Enable global interrupts, enable overflow flag
INTCON2 = %00000000 'INTERRUPT CONTROL REGISTER 2
INTCON3 = %00000000 'INTERRUPT CONTROL REGISTER 3
'PORTA = %00000000 'State High (1) or Low (0)
LATA = %00000000 'State High (1) or Low (0)
TRISA = %00001111 'Data Direction Control Register (Input/Output)
'PORTB = %00000000 'State High (1) or Low (0)
LATB = %00000000 'State High (1) or Low (0)
TRISB = %00000000 'Data Direction Control Register (Input/Output)
'PORTC = %00000000 'State High (1) or Low (0)
LATC = %00000000 'State High (1) or Low (0)
TRISC = %00000000 'Data Direction Control Register (Input/Output)
' ====== DEFINES ===================================================================================
DEFINE OSC 8
' ====== VARIABLES =================================================================================
Counter_A VAR BYTE
Cycles VAR BYTE
Row_Port VAR LATC ' this is ROW
Col_Port VAR LATB ' this is COLUMN
Row_State VAR BYTE(30)
Col_State VAR BYTE(30)
Cycle_Speed VAR BYTE
' ====== ALIASES =================================================================================
' ====== INITIALIZE ================================================================================
Counter_A = 0
Cycles = 3
Row_Port = %11111111
Col_Port = %00000000
Cycle_Speed = 50
' For ROW, 0 is ACTIVE
Row_State(1) = %11111110
Row_State(2) = %11111110
Row_State(3) = %11111110
Row_State(4) = %11111110
Row_State(5) = %11111110
Row_State(6) = %11111110
Row_State(7) = %11111110
Row_State(8) = %11111110
Row_State(9) = %11111101
Row_State(10) = %11111011
Row_State(11) = %11110111
Row_State(12) = %11101111
Row_State(13) = %11011111
Row_State(14) = %10111111
Row_State(15) = %01111111
Row_State(16) = %01111111
Row_State(17) = %01111111
Row_State(18) = %01111111
Row_State(19) = %01111111
Row_State(20) = %01111111
Row_State(21) = %01111111
Row_State(22) = %01111111
Row_State(23) = %10111111
Row_State(24) = %11011111
Row_State(25) = %11101111
Row_State(26) = %11110111
Row_State(27) = %11111011
Row_State(28) = %11111101
Row_State(29) = %00000000 ' all ON
Row_State(30) = %11111111 ' all OFF
' For COL, 1 is ACTIVE
Col_State(1) = %00000001
Col_State(2) = %00000010
Col_State(3) = %00000100
Col_State(4) = %00001000
Col_State(5) = %00010000
Col_State(6) = %00100000
Col_State(7) = %01000000
Col_State(8) = %10000000
Col_State(9) = %10000000
Col_State(10) = %10000000
Col_State(11) = %10000000
Col_State(12) = %10000000
Col_State(13) = %10000000
Col_State(14) = %10000000
Col_State(15) = %10000000
Col_State(16) = %01000000
Col_State(17) = %00100000
Col_State(18) = %00010000
Col_State(19) = %00001000
Col_State(20) = %00000100
Col_State(21) = %00000010
Col_State(22) = %00000001
Col_State(23) = %00000001
Col_State(24) = %00000001
Col_State(25) = %00000001
Col_State(26) = %00000001
Col_State(27) = %00000001
Col_State(28) = %00000001
Col_State(29) = %00000000 ' all OFF
Col_State(30) = %11111111 ' all ON
' ====== PROGRAM TOP ===============================================================================
MAIN:
FOR Counter_A = 1 TO 28
Col_Port = Col_State(Counter_A)
Row_Port = Row_State(Counter_A)
PAUSE Cycle_Speed
NEXT Counter_A
GOTO MAIN
END
↧
↧
18F66K80 adc
OK i'm confused by the 12 bit adc register settings.. I've got the pic adc working but is it optimal?
I'm trying to avoid using defines but am using adcin...
Processor is running at 64mhz
My current ADC config..
ADCON0 = %00000001 'SETUP ADC & ENABLE ADC MODULE on AN0
ADCON1 = %00010000 'SETUP ADC SET REFV to the 2.5V VREF+ & VSS
ADCON2 = %10011110 'SETUP ADC FOSC/64 RIGHT JUSTIFY TAD 6 (12 Bit)
My input has a 4.7k series resistor and 0.1uf cap (Higher impedance than spec but should work with a suitable TAD)
So with fosc 64 have I got TAD correct? What do you make it?
Maths isn't my strong point so the example calculations in the datasheet are :confused:
18F66K80 Datasheet link for info..
http://ww1.microchip.com/downloads/e...doc/39977c.pdf
There is also some info in the Errata datasheet for the part concerning the 12bit adc.
How will that effect me? Comments welcome?
http://ww1.microchip.com/downloads/e...-80000519P.pdf
I'm trying to avoid using defines but am using adcin...
Processor is running at 64mhz
My current ADC config..
ADCON0 = %00000001 'SETUP ADC & ENABLE ADC MODULE on AN0
ADCON1 = %00010000 'SETUP ADC SET REFV to the 2.5V VREF+ & VSS
ADCON2 = %10011110 'SETUP ADC FOSC/64 RIGHT JUSTIFY TAD 6 (12 Bit)
My input has a 4.7k series resistor and 0.1uf cap (Higher impedance than spec but should work with a suitable TAD)
So with fosc 64 have I got TAD correct? What do you make it?
Maths isn't my strong point so the example calculations in the datasheet are :confused:
18F66K80 Datasheet link for info..
http://ww1.microchip.com/downloads/e...doc/39977c.pdf
There is also some info in the Errata datasheet for the part concerning the 12bit adc.
How will that effect me? Comments welcome?
http://ww1.microchip.com/downloads/e...-80000519P.pdf
↧
ANNEX ESP8266 basic announcement and invitation
Hi group,
Its been a while since I made a post here as I have been busy as an informal beta tester on a new OS for the esp8266 (and future esp32) modules.
I'd like to invite you all to check out ANNEX RDS Home
This is an incredibly capable BASIC operating system for the ESP8266 modules (most any/all of them)
The amazing thing is that once Annex is flashed to the module via a usb connection then all your code development takes place from an IDE webpage that is hosted right on the module itself!
There is no need to compile or upload new code to the module. It all takes place from a wifi connection directly with the module and from a web browser.
There is a vast amount of example code and very well documented language reference.
With just a few lines of code you can send an email/text message based on an input. Create a webpage with buttons, sliders, meters, temperature values, ect. ect.
I can't say enough good about Annex RDS (Rapid Development System)
It is also very easy to integrate it to a PIC microcontroller for the web interface or wifi capability via serial or what ever you choose.
NTP time is super simple.
LCD's, I2C, mems gyros, PWM, OLED, IR remotes.
If you have been around here for a while you may recall a similar post about espBASIC but this is different and MUCH more stable and capable.
really you will be amazed and delighted at its capability and simplicity of use.
Come on over and check it out!!
Not a replacement for this very powerful PICBASIC but an amazing tool to add wifi in just a few lines of code.
regards
dwight
Its been a while since I made a post here as I have been busy as an informal beta tester on a new OS for the esp8266 (and future esp32) modules.
I'd like to invite you all to check out ANNEX RDS Home
This is an incredibly capable BASIC operating system for the ESP8266 modules (most any/all of them)
The amazing thing is that once Annex is flashed to the module via a usb connection then all your code development takes place from an IDE webpage that is hosted right on the module itself!
There is no need to compile or upload new code to the module. It all takes place from a wifi connection directly with the module and from a web browser.
There is a vast amount of example code and very well documented language reference.
With just a few lines of code you can send an email/text message based on an input. Create a webpage with buttons, sliders, meters, temperature values, ect. ect.
I can't say enough good about Annex RDS (Rapid Development System)
It is also very easy to integrate it to a PIC microcontroller for the web interface or wifi capability via serial or what ever you choose.
NTP time is super simple.
LCD's, I2C, mems gyros, PWM, OLED, IR remotes.
If you have been around here for a while you may recall a similar post about espBASIC but this is different and MUCH more stable and capable.
really you will be amazed and delighted at its capability and simplicity of use.
Come on over and check it out!!
Not a replacement for this very powerful PICBASIC but an amazing tool to add wifi in just a few lines of code.
regards
dwight
↧
Can I change LCD enable bit to port A instead of Port B ?
Hello. Standard DEFINEs indicate that LCD enable port is Port.B and uses PortB.3
As I understand, it is set by these two lines:
So the question is, can I change it to PortA (where other lcd pins are connected) and use say, PortA.7 for that? it would be easy to trace PCB in that way.
Correct? I have no hardware on hands right now, so can't check, this is why I'm asking....
Code:
' Set LCD Data port
DEFINE LCD_DREG PORTA
' Set starting Data bit (0 or 4) if 4-bit bus
DEFINE LCD_DBIT 0
' Set LCD Register Select port
DEFINE LCD_RSREG PORTA
' Set LCD Register Select bit
DEFINE LCD_RSBIT 4
' Set LCD Enable port
DEFINE LCD_EREG PORTB
' Set LCD Enable bit
DEFINE LCD_EBIT 3
' Set LCD bus size (4 or 8 bits)
DEFINE LCD_BITS 4
' Set number of lines on LCD
DEFINE LCD_LINES 2
' Set command delay time in us
DEFINE LCD_COMMANDUS 1500
' Set data delay time in us
DEFINE LCD_DATAUS 44
As I understand, it is set by these two lines:
Code:
DEFINE LCD_EREG PORTB
' Set LCD Enable bit
DEFINE LCD_EBIT 3
' Set LCD bus size (4 or 8 bits)
So the question is, can I change it to PortA (where other lcd pins are connected) and use say, PortA.7 for that? it would be easy to trace PCB in that way.
Code:
DEFINE LCD_EREG PORTA
' Set LCD Enable bit
DEFINE LCD_EBIT 7
' Set LCD bus size (4 or 8 bits)
Correct? I have no hardware on hands right now, so can't check, this is why I'm asking....
↧
PIC to PIC (3 digit LED display)
Hello,
I'm sending a Word VAR (0-999) from PIC to PIC with 1200baud.
But, the communications is not stable all the time. Like start_Up problems. The multiplexing of 3 digit LEDs works very well.
Maybe I need some tricks in the communication ?!?
This (PIC '883) is the sender:
W2 VAR WORD
Loop:
W2 = W2 + 1
Serout PortA.7,T1200,[W2.highbYTE,W2.lowBYTE] ' Send two byte
Pause 1000
Goto Loop
And this is the 3 digit LED Display (PIC '687) receiver:
DEFINE OSC 4 ' Set Speed (INT OSC)
DEFINE HSER_RCSTA 90h ' Enable USART receive
DEFINE HSER_TXSTA 24h ' TXSTA=%00100100 TX enable, BRGH=1 for high-speed
'DEFINE HSER_TXSTA 20h ' TXSTA=%00100000 TX enable, BRGH=0 for low-speed
DEFINE HSER_BAUD 1200 ' Set Baudrate to 1200
DEFINE HSER_CLROERR 1 ' Auto clear over-run errors
Main:
' ******************** Main Program ********************
IF RCIF = 1 THEN ' If RCIF = 1 there's new char in RCREG
hserin [W1.HIGHBYTE,W1.LOWBYTE] ' Get char from serial port (UART)
gosub Display
Else
gosub Display
endif
goto Main
' Sub to send the number (0-999) in W1 to 7-seg
display:
D1 = W1 ' Put W1 entry value in D1
B0 = D1 / 100 ' Find number of hundreds
D1 = D1 // 100 ' Remove hundreds from W1
Gosub bin2seg ' Convert number to segments
poke PortC,B0 ' Send segments to LED
high PortA.2
Pause 3 ' Leave it on 3 ms
low PortA.2 ' Turn off to prevent ghosting
B0 = D1 / 10 ' Find number of tens
D1 = D1 // 10 ' Remove tens from W1
Gosub bin2seg ' Convert number to segments
Poke PortC,B0 ' Send segments to LED
high PortA.1
Pause 3 ' Leave it on 3 ms
low PortA.1 ' Turn off to prevent ghosting
B0 = D1 ' Get number of ones
Gosub bin2seg ' Convert number to segments
Poke PortC,B0 ' Send segments to LED
High PortA.0
Pause 3 ' Leave it on 3 ms
Low PortA.0 ' Turn off to prevent ghosting
Return ' Go back to caller
I'm sending a Word VAR (0-999) from PIC to PIC with 1200baud.
But, the communications is not stable all the time. Like start_Up problems. The multiplexing of 3 digit LEDs works very well.
Maybe I need some tricks in the communication ?!?
This (PIC '883) is the sender:
W2 VAR WORD
Loop:
W2 = W2 + 1
Serout PortA.7,T1200,[W2.highbYTE,W2.lowBYTE] ' Send two byte
Pause 1000
Goto Loop
And this is the 3 digit LED Display (PIC '687) receiver:
DEFINE OSC 4 ' Set Speed (INT OSC)
DEFINE HSER_RCSTA 90h ' Enable USART receive
DEFINE HSER_TXSTA 24h ' TXSTA=%00100100 TX enable, BRGH=1 for high-speed
'DEFINE HSER_TXSTA 20h ' TXSTA=%00100000 TX enable, BRGH=0 for low-speed
DEFINE HSER_BAUD 1200 ' Set Baudrate to 1200
DEFINE HSER_CLROERR 1 ' Auto clear over-run errors
Main:
' ******************** Main Program ********************
IF RCIF = 1 THEN ' If RCIF = 1 there's new char in RCREG
hserin [W1.HIGHBYTE,W1.LOWBYTE] ' Get char from serial port (UART)
gosub Display
Else
gosub Display
endif
goto Main
' Sub to send the number (0-999) in W1 to 7-seg
display:
D1 = W1 ' Put W1 entry value in D1
B0 = D1 / 100 ' Find number of hundreds
D1 = D1 // 100 ' Remove hundreds from W1
Gosub bin2seg ' Convert number to segments
poke PortC,B0 ' Send segments to LED
high PortA.2
Pause 3 ' Leave it on 3 ms
low PortA.2 ' Turn off to prevent ghosting
B0 = D1 / 10 ' Find number of tens
D1 = D1 // 10 ' Remove tens from W1
Gosub bin2seg ' Convert number to segments
Poke PortC,B0 ' Send segments to LED
high PortA.1
Pause 3 ' Leave it on 3 ms
low PortA.1 ' Turn off to prevent ghosting
B0 = D1 ' Get number of ones
Gosub bin2seg ' Convert number to segments
Poke PortC,B0 ' Send segments to LED
High PortA.0
Pause 3 ' Leave it on 3 ms
Low PortA.0 ' Turn off to prevent ghosting
Return ' Go back to caller
↧
↧
Lcdout
Hi :)
According to my calculations, this code works first go in PBP without even testing it :D
If that’s found not to be the case, please let me know, and I’ll fix it.
This was written in C, and ported from there. It is NOT disassembled PBP code.
According to my calculations, this code works first go in PBP without even testing it :D
If that’s found not to be the case, please let me know, and I’ll fix it.
This was written in C, and ported from there. It is NOT disassembled PBP code.
Code:
'
'****************************************************************
'* *
'* PBP LCDOUT Replacement Functions *
'* Brek Martin (Art) 2019 *
'* *
'****************************************************************
'
'define your own LCD pin aliases here
'and set tris registers for output ports
'
arg var byte 'function arguments
nib var byte '
cnt var byte 'counter
worka var word 'work variables
workb var byte '
line var byte[16] 'string array
RS_PIN = 1 '
E_PIN = 1 '
pause 1000 'full second delay before talking to the LCD at all
'
'******************************************************************************
‘
gosub lcdinit
'
line[0] = 'H' 'set data
line[1] = 'e'
line[2] = 'l'
line[3] = 'l'
line[4] = 'o'
'
arg = $02 : gosub fsend_command_byte 'go to start of line 1 - Hex $80 is first line $02 home
for cnt = 0 to 4 'print line 1
arg = line[cnt] : gosub send_data_byte
next cnt
'
worka = 12345 'set data (this data is destroyed)
workb = 10000 '
'
arg = $C0 : gosub fsend_command_byte 'go to start of line 2
'
for cnt = 0 to 5
arg = worka / workb : gosub send_data_byte
worka = worka - workb
workb = workb / 10
next cnt
'
'******************************************************************************
'
' HD44780 lcd functions
'
lcdinit: 'module initialisation sequence for 4 bit interface
pause 16 ' must be more than 15ms
nib = %0011 : gosub send_nibble
pause 6 ' must be more than 4.1ms
nib = %0011 : gosub send_nibble
pause 3 ' must be more than 100us
nib = %0011 : gosub send_nibble
pause 6 ' must be more than 4.1ms
nib = %0010 : gosub send_nibble 'set 4 bit mode
'2x16 character LCD display settings
arg = %00101000 : gosub send_command_byte 'N=0 : 2 lines F=0 : 5x7 font
arg = %00001000 : gosub send_command_byte 'display: display off, cursor off, blink off
arg = %00000001 : gosub send_command_byte 'clear display
arg = %00000110 : gosub send_command_byte 'set entry mode
arg = %00001100 : gosub send_command_byte 'display: display on
return
'
'
send_nibble:
E_PIN = 0
portb = (portb & $FFF0) | (nib ^ $F)
pause 2
E_PIN = 1
pause 2 'enough time for slowest command
return
'
'
send_command_byte:
RS_PIN = 1
nib = arg >> 4 : gosub send_nibble
nib = arg & $F : gosub send_nibble
return
'
'
send_data_byte:
RS_PIN = 0
nib = arg >> 4 : gosub send_nibble
nib = arg & $F : gosub send_nibble
return
'
'
'******************************************************************************
'
'
↧
LCDOUT Replacement
Hi :)
This code can replace the code inserted by PBP whenever you use the LCDOUT command.
The reasons to do so are for probably speed and memory savings.
Also, since LCDOUT is meaningless in any other language, it will be needed unless you never use anything else.
Attachment 8905
This is tested as is with 16F628A at 10 MHz, and the output in the image is the small demo routine.
Use it as you will (or not).
Cheers, Brek.
This code can replace the code inserted by PBP whenever you use the LCDOUT command.
The reasons to do so are for probably speed and memory savings.
Also, since LCDOUT is meaningless in any other language, it will be needed unless you never use anything else.
Attachment 8905
This is tested as is with 16F628A at 10 MHz, and the output in the image is the small demo routine.
Use it as you will (or not).
Cheers, Brek.
Code:
'
'****************************************************************
'* *
'* PBP LCDOUT Replacement Functions *
'* Brek Martin (Art) 2019 *
'* *
'****************************************************************
'
' RA0 = lcd d0
' RA1 = lcd d1
' RA2 = lcd d2
' RA3 = lcd d3
' RA4 = lcd rs
' RB2 = lcd en
'
DEFINE OSC 10
'
E_PIN var portb.2
'
CMCON = 7 'set ports to digital
trisb = %01000000 '
trisa = %00000000 '
'
rsflag var bit
lata var byte 'port a latch
arg var byte 'function arguments
nib var byte '
cnt var byte 'counter
worka var word 'work variables
workb var word '
line var byte[16] 'string array
'
'******************************************************************************
'
pause 1000 'one second delay before talking to the LCD
gosub lcdinit 'initialise lcd
'
line[0] = "H" 'set data
line[1] = "e" '
line[2] = "l" '
line[3] = "l" '
line[4] = "o" '
'
arg = $02 : gosub send_command_byte 'go to start of line 1
for cnt = 0 to 4 'print line 1
arg = line[cnt] : gosub send_data_byte
next cnt
'
worka = 12345 'set data (this data is destroyed)
workb = 10000 '
'
arg = $C0 : gosub send_command_byte 'go to start of line 2
for cnt = 0 to 4
arg = worka / workb
worka = worka - (arg*workb)
arg = arg + $30 : gosub send_data_byte
workb = workb / 10
next cnt
'
infinite: 'do forever
pause 10
goto infinite
'
'******************************************************************************
'
' HD44780 lcd functions
'
lcdinit: 'module initialisation sequence for 4 bit interface
nib = $03 : gosub send_nibble
pause 6 ' must be more than 4.1ms
nib = $03 : gosub send_nibble
pause 6 ' must be more than 100us
nib = $03 : gosub send_nibble
pause 6 ' must be more than 4.1ms
nib = $02 : gosub send_nibble 'set 4 bit mode
pause 6 '2x16 character LCD display settings
arg = %00101000 : gosub send_command_byte 'N=0 : 2 lines F=0 : 5x7 font
pause 10
arg = %00001000 : gosub send_command_byte 'display: display off, cursor off, blink off
pause 10
arg = %00000001 : gosub send_command_byte 'clear display
pause 10
arg = %00000110 : gosub send_command_byte 'set entry mode
pause 10
arg = %00001100 : gosub send_command_byte 'display: display on
pause 10
return
'
'
send_nibble:
E_PIN = 1
lata = nib & $0F
lata.4 = rsflag
porta = lata
pause 1 'both of these pauses should be
@ nop 'replaed with a bunch of nops
@ nop 'after testing like this, or it
@ nop 'will be much slower than lcdout
@ nop 'start with ten or so either side
E_PIN = 0
pause 1 'enough time for slowest command
@ nop 'replace this pause with nops too
return
'
'
send_command_byte:
rsflag = 0
goto send_byte
send_data_byte:
rsflag = 1
send_byte:
nib = arg >> 4 : gosub send_nibble
nib = arg & $F : gosub send_nibble
return
'
'
'******************************************************************************
↧
HPWM outputs only on two channels on PIC16F886, when it should do more.
Hello.
PIC16F886 has 4 PWM channels. However, HPWM statement works only for first 2 - Ones at PortC. HPWM 0 outputs at PortC.2 and HPWM 1 outputs at PortC.1. However, HPWM 2 or HPWM 3 which are expected to output on the corresponding pins of PortB, do nothing. As I read from datasheet, CCP1CON register controls configuration of PortB PWM registers, but it gives no clue how it should be configured, so HPWM statement will work with these ports?
PIC16F886 has 4 PWM channels. However, HPWM statement works only for first 2 - Ones at PortC. HPWM 0 outputs at PortC.2 and HPWM 1 outputs at PortC.1. However, HPWM 2 or HPWM 3 which are expected to output on the corresponding pins of PortB, do nothing. As I read from datasheet, CCP1CON register controls configuration of PortB PWM registers, but it gives no clue how it should be configured, so HPWM statement will work with these ports?
↧
need a low frequency pulse out while still performing serial comms
I have an application which will need to product a low frequency pulse ranging from 1hz to 6 hz. I need this output to be operating in the background because the PIC18F4680 will also be handling communications to the PC and if the PC doesn't have response back in time, it will force a reset of the PIC.
In the past I simply used the Pause to create the timing frequency when I needed it, but I think I need a more complete solution this time.
Is it possible to use a timer?
What happens if the timer kicks while the serial port is being read?
Is this something which should go to a separate PIC which receives the frequency from the main uController and then runs independently when enabled?
The other options is to figure out how long the communications transfer last between the two and use the pause time to service the communications.
Thanks
George
In the past I simply used the Pause to create the timing frequency when I needed it, but I think I need a more complete solution this time.
Is it possible to use a timer?
What happens if the timer kicks while the serial port is being read?
Is this something which should go to a separate PIC which receives the frequency from the main uController and then runs independently when enabled?
The other options is to figure out how long the communications transfer last between the two and use the pause time to service the communications.
Thanks
George
↧
↧
Generate a non-blocking pulse with an Interrupt Service Routine
Saw a similar thread (http://www.picbasic.co.uk/forum/showthread.php?t=24119) and it was a very timely question. A project I'm working on has a somewhat similar pulse requirement and I have been asking myself how to accomplish it with out tying myself up with PAUSE commands in the ISR.
In my case, I need to trigger a couple of 500uS pulses on different pins at different intervals.
I'm using DT INTs and have two 8 bit timers free (TMR0 and TMR2 on a 12F683).
Currently have a line in the ISR: "pulsout Drive, 50" for a 500uS pulse, but I'm concerned that it's an unnecessary delay.
Daryl's Blinky example (http://dt.picbasic.co.uk/INT16/BlinkyLED) is close, but with the TOGGLE scheme, when I entered the ISR, it would toggle the pin on and load the ON time, then I would have to toggle it back off somehow. I'm trying to understand how you would do that. The only ways I can think of require that you stay in the ISR ( with the attendant delay) or maybe enter the ISR twice and change the timer preload for ON and OFF times.
The pulse times are constant, it's just how often I fire them that changes.
Any suggestions?
thanks
bo
In my case, I need to trigger a couple of 500uS pulses on different pins at different intervals.
I'm using DT INTs and have two 8 bit timers free (TMR0 and TMR2 on a 12F683).
Currently have a line in the ISR: "pulsout Drive, 50" for a 500uS pulse, but I'm concerned that it's an unnecessary delay.
Daryl's Blinky example (http://dt.picbasic.co.uk/INT16/BlinkyLED) is close, but with the TOGGLE scheme, when I entered the ISR, it would toggle the pin on and load the ON time, then I would have to toggle it back off somehow. I'm trying to understand how you would do that. The only ways I can think of require that you stay in the ISR ( with the attendant delay) or maybe enter the ISR twice and change the timer preload for ON and OFF times.
The pulse times are constant, it's just how often I fire them that changes.
Any suggestions?
thanks
bo
↧
I2CREAD/WRITE Clarification
Hi :)
Im having some trouble interpreting the manual for these two commands.
Ive always fully populated the command arguments when using it, and incremented the address until maximum.
For reading registers from the FM radio chip Im playing with, Darrel did this:
Now I do understand why the incoming bytes are ordered the way they are.
The chip sends them in this order, ie. 0x0A-0x0F, 0x00-0x09, so hes receiving them into their correct RAM locations.
What I dont understand is what PBP does when you omit an address argument.
It could send no address at all, or it could begin at zero, and if so, the zero could be either a byte or a word.
I suspect it sends no address, and the chip begins reading register 0x0A this way.
Ive tried every which way to roll this into a loop though, and the code is smaller every time, but fails every time.
I suspect preceding commands would send no address either, so one example is:
No such luck!
Im having some trouble interpreting the manual for these two commands.
Ive always fully populated the command arguments when using it, and incremented the address until maximum.
For reading registers from the FM radio chip Im playing with, Darrel did this:
Code:
i2cread portb.1,portb.7,$20,[Si_REGS(10),Si_REGS(11),Si_REGS(12),Si_REGS(13),Si_REGS(14),Si_REGS(15),_
Si_REGS(0),Si_REGS(1),Si_REGS(2),Si_REGS(3),Si_REGS(4),Si_REGS(5),Si_REGS(6),Si_REGS(7),Si_REGS(8),Si_REGS(9)],SiError
The chip sends them in this order, ie. 0x0A-0x0F, 0x00-0x09, so hes receiving them into their correct RAM locations.
What I dont understand is what PBP does when you omit an address argument.
It could send no address at all, or it could begin at zero, and if so, the zero could be either a byte or a word.
I suspect it sends no address, and the chip begins reading register 0x0A this way.
Ive tried every which way to roll this into a loop though, and the code is smaller every time, but fails every time.
I suspect preceding commands would send no address either, so one example is:
Code:
for cnt = 10 to 15
i2cread portb.1,portb.7,$20,[Si_REGS(cnt)],SiError
next cnt
for cnt = 0 to 9
i2cread portb.1,portb.7,$20,[Si_REGS(cnt)],SiError
next cnt
↧
Si4703 FM Radio DDS Hack
Hi :)
This is my most recent 16F628A controller code for Silicon Labs Si4703 FM radio chip.
This chip gets its watch crystal disconnected, and its clock input (RCLK) taken from the 16F628A via a resistor divider.
I suppose Ill have to do a schematic after all of this :D Ill also post a simpler code, all in PBP from another thread which is easy to understand and modify.
This version is as much as I could cram into the pic in some weeks, is much better to use, and has more functionality, but will be more difficult to follow.
Major features:
Turns the Si4703 FM radio IC into a dual band radio (FM Broadcast band, and VHF amateur band).
Displays accurate frequencies up to two decimal places ie. 146.30 MHz.
Displays signal strength and volume with a pixel width resolution graphic bar graph and numbers.
Squelch feature for muting radio silence, particularly good for VHF amateur band.
Printed debug error codes to warn of some hardware errors during project construction.
Six buttons supported with 74HC165 parallel shift register, as well as a jumper to set hardware configuration.
A jumper configures hardware for serial output or for a character LCD display, to aid testing during construction.
This is my most recent 16F628A controller code for Silicon Labs Si4703 FM radio chip.
This chip gets its watch crystal disconnected, and its clock input (RCLK) taken from the 16F628A via a resistor divider.
I suppose Ill have to do a schematic after all of this :D Ill also post a simpler code, all in PBP from another thread which is easy to understand and modify.
This version is as much as I could cram into the pic in some weeks, is much better to use, and has more functionality, but will be more difficult to follow.
Major features:
Turns the Si4703 FM radio IC into a dual band radio (FM Broadcast band, and VHF amateur band).
Displays accurate frequencies up to two decimal places ie. 146.30 MHz.
Displays signal strength and volume with a pixel width resolution graphic bar graph and numbers.
Squelch feature for muting radio silence, particularly good for VHF amateur band.
Printed debug error codes to warn of some hardware errors during project construction.
Six buttons supported with 74HC165 parallel shift register, as well as a jumper to set hardware configuration.
A jumper configures hardware for serial output or for a character LCD display, to aid testing during construction.
Code:
'
'****************************************************************
'* *
'* FM Radio DDS controller V2 (c) Art 2019 *
'* Some base code by Darrel Taylor (RIP) *
'* For Microchip Pic 16F628A @ 10MHz *
'* Tested with Si4703 & version 19 firmware *
'* *
'****************************************************************
'
' RB4 = sr load
' RB5 = sr clock
' RB6 = sr data
' RB0 = si reset
' RB1 = si sdio
' RB7 = si clock
' RB3 = freq out
' RB2 = lcd en
' RA0 = lcd d0
' RA1 = lcd d1 or default serial out
' RA2 = lcd d2
' RA3 = lcd d3
' RA4 = lcd rs
' RA5 = reset or spare input
' Shift register input pins are buttons and a jumper
' Shift register jumper sets lcd or serial output
' One spare input on 74HC165 shift register
' Shift register pins should be tied normally high
' Two unused outputs on Si4703 gpio pins
'
' printed lcd debug error code messages:
' ERROR: 1 - i2c communication failure
' ERROR: 2 - Si470x device id incorrect
' ERROR: 3 - 74HC165 shift register error
'
DEFINE OSC 10 '10 MHz oscillator
DEFINE NO_CLRWDT 1 'tell compiler not to insert clrwdt instructions
'
DATA " DDS HACK RADIOBREK MARTIN 2019 BROADCAST AMATEUR"
DATA " VHF FMVOLUME: MHz FREQ: SIGNAL: ERROR: Si470"
DATA " DDS Radio V2 -" ' load credit string to eeprom
DATA " Brek Martin 2019" ' DDS Radio V2 - Brek Martin 2019
'
E_PIN var portb.2 'lcd enable pin alternative name
'
'Darrel Taylor's register variables with extras and omissions
Si_REGS VAR WORD[16]
deviceid VAR Si_REGS[0] ' Read Only
chipid VAR Si_REGS[1] ' Read Only
powercfg VAR Si_REGS[2] ' R/W
DSMUTE VAR powercfg.15
DMUTE VAR powercfg.14
MONO VAR powercfg.13
RDSM VAR powercfg.11
SEEK VAR powercfg.8
SiDISABLE VAR powercfg.6
SiENABLE VAR powercfg.0
channel VAR Si_REGS[3] ' R/W
TUNE VAR channel.15
sysconfig1 VAR Si_REGS[4] ' R/W
RDSIEN VAR sysconfig1.15
STCIEN VAR sysconfig1.14
RDS VAR sysconfig1.12
DE VAR sysconfig1.11
AGCD VAR sysconfig1.10
sysconfig2 VAR Si_REGS[5] ' R/W
SPACEH VAR sysconfig2.5 ' channel spacing
SPACEL VAR sysconfig2.4 '
sysconfig3 VAR Si_REGS[6] ' R/W
VOLEXT VAR sysconfig3.8
test1 VAR Si_REGS[7] ' R/W
XOSCEN VAR test1.15
AHIZEN VAR test1.14
test2 VAR Si_REGS[8] ' R/W, Reserved
bootconfig VAR Si_REGS[9] ' R/W, Reserved
statusrssi VAR Si_REGS[10] ' Read Only
RDSR VAR statusrssi.15
STC VAR statusrssi.14
SF_BL VAR statusrssi.13
AFCRL VAR statusrssi.12
RDSS VAR statusrssi.11
ST VAR statusrssi.8
readchan VAR Si_REGS[11] ' Read Only
SI470X_CURRENTVOLUME VAR BYTE
SI470X_CURRENTBAND VAR BYTE
SI470X_CURRENTSPACE VAR BYTE
SI470X_CURRENTFREQUENCY VAR WORD
SI470X_CURRENTRSSI VAR BYTE
SI470X_MINFREQUENCY VAR WORD
SI470X_MAXFREQUENCY VAR WORD
SI470X_TempB VAR BYTE
SI470X_TempW VAR WORD
' application variables
bflags var word 'bit flags
userfreq var word 'user frequency
displayfreq var word'frequency for display
vwork var word 'work variable
sigst var word 'signal strength
sigstb var word '
psthr var byte 'delay counters and
psfor var byte 'i2c comms buffers
psnin var byte '
psone var byte '
pstwo var byte '
psfiv var byte '
psate var byte '
pssix var byte 'tuning down delay timer
pssev var byte 'tuning up delay timer
'alternative names for serial port
delay var psfiv 'set baud rate delay
txbyte var psate 'byte to send
bcount var psnin 'serial counter
'character lcd control
lata var byte 'port latch
arg var byte 'lcd function arguments
nib var byte 'lcd nibble buffer
'shift register control
srbuff var byte '
srcnt var byte '
srbyte var byte '
cnt var byte 'text counter
uservol var byte 'user volume
volchanged var byte 'volume changed
freqchanged var byte'frequency changed
vchan var byte 'vhf channel value
lll var byte 'counter
squelch var byte 'squelch enabled flag
srbit var bit 'shift register control
userband var bit 'current selected band
itwosee var bit 'i2c control
startup var bit 'first cycle flag
rssitype var bit 'signal display type
demobar var bit 'animated bar control
mutebuf var bit 'mute value for squelch
rsflag var bit 'lcd rs flag
buttona var bflags.0'shift register button flags
buttonb var bflags.1'
buttonc var bflags.2'
buttond var bflags.3'
buttone var bflags.4'
buttonf var bflags.5'
hwconfg var bflags.6'hardware configuration flag
srstats var bflags.7'shift register status flag
silinfo var bflags.8'print chip info flag
itceror var bit 'i2c error flag
'serial output pin if enabled by shift register jumper
serpin var porta.1 'set port pin for serial out
'
'execution begins
'@ call order_66 ;destroy all jedi
'
userband = 1 'toggled to zero at startup
volchanged = 0 '
freqchanged = 0 '
rssitype = 0 '
demobar = 0 '
squelch = 0 '
mutebuf = 1 '
startup = 1 'set first cycle flag
pssix = 0 'reset tuning delay timers
pssev = 0
'
CMCON = 7 'set ports to digital
trisb = %01000000 '
trisa = %00100000 '
'
gosub pauseten '10ms
gosub shiftbytein 'read hardware configuration jumper
if hwconfg = 0 then 'for serial enabled jumper configuration
serpin = 1 'set serial pin idle normally high
endif ' hwconfg
'
gosub onesec 'delay
gosub lcdinit 'initialise lcd
gosub pauseten '10ms
gosub setchars 'set bargraph graphics
gosub pauseten '10ms
gosub lcdcls 'clear lcd display
arg = $07 : gosub send_data_byte 'custom antenna symbol
for cnt = 0 to 14
gosub getdata
next cnt
arg = $C0 : gosub send_command_byte 'start of second line
for cnt = 15 to 30
gosub getdata
next cnt
gosub onesec : gosub onesec 'pause for title display
'
silinfo = 0 'set flag to display chip info
gosub initradio 'initialise to display chip info
silinfo = 1 'disable chip info
arg = $C0 : gosub send_command_byte ' set second lcd line
gosub sixspaces 'print ok message since we got here
pssix = 1 'enable a single serial test message
arg = "O" : gosub send_data_byte : gosub serialarg
arg = "K" : gosub send_data_byte : gosub serialarg
txbyte = $0D : gosub serialout
txbyte = $0A : gosub serialout
pssix = 0 'disable serial until frequency change
gosub sevenspaces 'fill lcd line with spaces
gosub onesec 'delay for info display
'
'
start:
gosub shiftbytein 'read shift register inputs
'
if startup = 1 then 'only executes once at startup
buttone = 1 'change band to fm broadcast
endif 'for first program cycle
'
if buttona = 1 then 'audio volume down
if uservol > 0 then
uservol = uservol - 1
endif
gosub radiosetvol
endif
'
if buttonb = 1 then 'audio volume up
if uservol < 15 then
uservol = uservol + 1
endif
gosub radiosetvol
endif
'
if buttonc = 1 then 'tuned frequency down
if pssix < $1A then
pssix = pssix + 1
endif
if (pssix = $1A) || (pssix = 1) then
volchanged = 0 'kill volume display
if userband = 1 then
if vchan > 0 then 'channel steps for vhf amateur
vchan = vchan - 1
userfreq = userfreq - 1
endif
else
if userfreq > 871 then
userfreq = userfreq - 1
if userband = 0 then '200 kHz steps for fm broadcast
userfreq = userfreq - 1
endif
endif
endif
gosub radiotune
endif 'pssix
else
pssix = 0 'reset tuning delay timer
endif
'
if buttond = 1 then 'tuned frequency up
if pssev < $1A then
pssev = pssev + 1
endif
if (pssev = $1A) || (pssev = 1) then
volchanged = 0 'kill volume display
if userband = 1 then
if vchan < 28 then 'channel steps for vhf amateur
vchan = vchan + 1
userfreq = userfreq + 1
endif
else
if userfreq < 1076 then
userfreq = userfreq + 1
if userband = 0 then '200 kHz steps for fm broadcast
userfreq = userfreq + 1
endif
endif
endif
gosub radiotune
endif 'pssev
else
pssev = 0 'reset tuning delay timer
endif
'
if buttone = 1 then 'change reciever band
volchanged = 0 'kill volume display
userband = userband + 1 'increment band
if userband > 1 then
userband = 0
endif
'
arg = $C0 : gosub send_command_byte 'start of second line
if userband = 0 then 'fm broadcast
gosub printvhf
else 'vhf amateur
arg = $20 : gosub send_data_byte
gosub printvhffm
for cnt = 41 to 49
gosub getdata
next cnt
endif
demobar = 1 'progress bar effect
for sigstb = 0 to 95
psone = 10 : gosub pausems 'progress bar speed
gosub drawsig
next sigstb
psone = 254 : gosub pausems '100ms
psone = 254 : gosub pausems '100ms
sigstb = 0
gosub drawsig
demobar = 0
squelch = 0 'disable squelch
gosub initradio 'initialise the radio ic
psone = 10 : gosub pausems '4ms
if userband = 0 then
userfreq = 945 'default broadcast frequency 94.9 MHz
else
userfreq = 1039 'default vhf amateur band frequency 146.9 MHz
endif
gosub radiotune
'
if startup = 1 then 'only executes once at startup
uservol = 0 'reset volume byte
while uservol < 4 'ramp volume up to 4
buttone = 1
gosub radiosetvol
buttone = 0
uservol = uservol + 1
psone = 254 : gosub pausems '100ms
wend
startup = 0
endif
'
gosub radiosetvol
psone = 6 : gosub pausems '2ms
endif
'
if buttonf = 1 then 'signal display type button
volchanged = 0 'kill volume display
squelch = 1 'enable squelch
psone = 254 : gosub pausems '100ms
if rssitype = 0 then 'alternate signal display
rssitype = 1
else
rssitype = 0
endif
psone = 254 : gosub pausems '100ms
psone = 254 : gosub pausems '100ms
endif
'
if srstats = 0 then 'print shift register error
goto printerror '
endif 'srstats
'
gosub radioread
if volchanged = 0 then 'display bargraph for volume
gosub printinfo
else
volchanged = volchanged - 1
endif
'
if squelch = 1 then 'handle squelch if enabled
if sigstb < 13 then 'hard coded squelch level
mutebuf = 0 'mute
else
mutebuf = 1 'unmute
endif
if DMUTE != mutebuf then
DMUTE = mutebuf
gosub radiowrite
endif
endif
'
goto start
'
'
'
'
shiftbit: 'private shift register routine
psone = 2 : gosub pausems '1ms
if srbit = 0 then
portb.6 = 0
else
portb.6 = 1
endif
psone = 2 : gosub pausems '1ms
portb.5 = 1
return
'
'
sbprivate: 'private shift register routine
gosub pausethree
portb.5 = 0
gosub pausethree
portb.5 = 1
return
'
'
'this is the function called by the user to read 74hc165
shiftbytein: 'read byte from the shift register
portb.5 = 0
gosub pausethree
portb.4 = 1
gosub pausethree
portb.4 = 0
gosub pausethree
portb.4 = 1
gosub pausethree
buttona = portb.6 : gosub sbprivate
buttonb = portb.6 : gosub sbprivate
buttonc = portb.6 : gosub sbprivate
buttond = portb.6 : gosub sbprivate
buttone = portb.6 : gosub sbprivate
buttonf = portb.6 : gosub sbprivate
hwconfg = portb.6 : gosub sbprivate
srstats = portb.6 : gosub sbprivate
psone = 2 : gosub pausems '1ms
portb.5 = 0
psone = 2 : gosub pausems '1ms
@ comf _bflags ,f ;invert for normally high buttons
portb.4 = 1
return
'
'
initradio: 'initialise function
if userband = 0 then 'fm broadcast
PR2 = %00010010
T2CON = %00000101
CCPR1L = %00001001
CCP1CON = %00011100
else 'vhf amateur
vchan = 20 'set default channel
PR2 = %00110101
T2CON = %00000100
CCPR1L = %00011010
CCP1CON = %00111100
endif
gosub pauseten
portb.1 = 0 'start with SDA LOW
gosub pausethree
portb.0 = 0 'reset the device
gosub pausethree
portb.0 = 1 'release reset
gosub pausethree
trisb.1 = 1 'release SDA
gosub radioread 'read all registers
XOSCEN = 1 'turn on oscillator
gosub radiowrite
gosub onesec 'wait for startup
gosub radioread 'read all registers
'
if userband = 0 then
SPACEH = 0 'set 100 kHz spacing for this version for vhf amateur
SPACEL = 1 '200kHz steps for broadcast implemented in application
else
SPACEH = 0 'reserved this program memory for future 50 kHz spacing
SPACEL = 1 'set vhf to 100 kHz steps also for this program version
endif
DMUTE = silinfo 'mute disable
MONO = 1 'force mono for communications reciever
SiEnable = 1 'powerup enable
gosub radiowrite
psone = 254 : gosub pausems '100ms
psone = 180 : gosub pausems '60ms
gosub radioread 'read all registers
'print information about the radio chip to the lcd
if silinfo = 0 then 'executes for first pass only
if Si_REGS(0) != $1242 then 'check device id register
gosub printerror
else
lll = Si_REGS(1) 'save firmware version area
lll.bit7 = 0 '
lll.bit6 = 0 '
Si_REGS(1) = Si_REGS(1) << 6
arg = $80 : gosub send_command_byte
gosub pauseten '10ms
for cnt = 90 to 95 'print Si470
gosub getdata
next cnt
Si_REGS(1) = Si_REGS(1) >> 12
arg = "?"
if Si_REGS(1) = %0001 then 'complete for Si4702
arg = $32
endif
if Si_REGS(1) = %1001 then 'complete for Si4703
arg = $33
endif
gosub send_data_byte
arg = $20 : gosub send_data_byte 'space
gosub send_data_byte 'space
arg = "F" : gosub send_data_byte 'FW:
arg = "W" : gosub send_data_byte '
arg = ":" : gosub send_data_byte '
arg = $20 : gosub send_data_byte 'space
arg = lll / 10
gosub sendnumeral
arg = arg - $30
lll = lll - (arg * 10)
arg = lll
gosub sendnumeral
arg = $20 : gosub send_data_byte
gosub onesec 'delay
endif 'device
endif 'silinfo
return
'
'
radioread: 'read all registers
gosub itcreadctrl
for cnt = 10 to 15
itwosee = 0
gosub icread
itwosee = 1
gosub icread
next cnt
for cnt = 0 to 8
itwosee = 0
gosub icread
itwosee = 1
gosub icread
next cnt
itwosee = 0
cnt = 9
gosub icread
'
asm
CALL itcend
BTFSC STATUS, 0
GOTO _SiError
MOVWF _arg
endasm
Si_REGS(9) = Si_REGS(9) + arg
SI470X_CURRENTVOLUME = sysconfig2 & $0F
SI470X_CURRENTRSSI = statusrssi & $FF
SI470X_CURRENTSPACE = (sysconfig2 >> 4) & %11
SI470X_CURRENTBAND = (sysconfig2 >> 6) & %11
SI470X_CURRENTFREQUENCY = (readchan & $1FF)
SI470X_CURRENTFREQUENCY = SI470X_CURRENTFREQUENCY + 875 ; 87.5ñ108 MHz (USA, Europe)
SI470X_MINFREQUENCY = 875
SI470X_MAXFREQUENCY = 1081
return
'
icread:
@ CALL itcbyte
@ BTFSC STATUS, 0
@ GOTO _SiError
@ MOVWF _arg
if itwosee = 0 then
Si_REGS(cnt) = arg
Si_REGS(cnt) = Si_REGS(cnt) << 8
else
Si_REGS(cnt) = Si_REGS(cnt) + arg
endif
return
'
radiowrite: 'write all writeable registers
itceror = 0 'reset comms error flag
asm
MOVLW 0x2
MOVWF _psfiv
MOVLW 0x80
MOVWF _psate
MOVLW 0x20
CALL itcrd
BTFSC STATUS, 0
GOTO _SiError
endasm
'
for cnt = 2 to 6
itwosee = 0
gosub icwrite
itwosee = 1
gosub icwrite
next cnt
itwosee = 0
cnt = 7
gosub icwrite
arg = Si_REGS(7)
@ MOVF _arg, W
@ CALL itcre
@ BTFSC STATUS, 0
@ GOTO _SiError
return
'
'
icwrite:
if itwosee = 0 then
arg = Si_REGS(cnt) >> 8
else
arg = Si_REGS(cnt)
endif
@ MOVF _arg, W
@ CALL itcrd
@ BTFSC STATUS, 0
@ GOTO _SiError
return
'
'
SiError: 'i2c comms error
itceror = 1 'set comms error flag
goto printerror 'will return from here
'
'
'i2c read and write chunk of code that gets inserted by PBP
'little if any optimisation here, but it's disassembled in
'order to optimise the calls that PBP normally makes to it.
asm
itcend:
BSF _psone, 0x5
BTFSS _psone, 0x5
itcbyte:
BCF _psone, 0x5
BTFSC _psone, 0x3
GOTO oxb
BSF _psone, 0x3
CALL fortyfour
BTFSC STATUS, 0
GOTO thirtytwo
oxb:
MOVLW 0x8
MOVWF _psfor
oxd:
CALL fiftynine
RLF _psthr, F
DECFSZ _psfor, F
GOTO oxd
BTFSS _psone, 0x5
CALL threedee
CALL sixtythree
CALL fivef
BTFSC _psone, 0x5
CALL thirtytwo
CALL thirtyseven
MOVF _psthr, W
BCF STATUS, 0
GOTO _beforeprogstart
itcre:
BSF _psone, 0x5
BTFSS _psone, 0x5
itcrd:
BCF _psone, 0x5
BTFSC _psone, 0x2
GOTO twentyfive
ANDLW 0xfe
MOVWF _pstwo
BSF _psone, 0x2
BCF STATUS, 0
GOTO _beforeprogstart
twentyfive:
BTFSC _psone, 0x4
GOTO twodee
MOVWF _psnin
BSF _psone, 0x4
CALL fortyfour
BTFSC STATUS, 0
GOTO thirtytwo
MOVF _psnin, W
twodee:
CALL fourcee
BTFSC STATUS, 0
GOTO thirtytwo
BTFSS _psone, 0x5
GOTO _beforeprogstart
thirtytwo:
CALL threedee
CALL sixtythree
BCF _psone, 0x2
BCF _psone, 0x4
BCF _psone, 0x3
thirtyseven:
MOVLW 0x6
MOVWF 0x4
MOVF _psfiv, W
BSF 0x4, 0x7
IORWF 0, F
GOTO fortythree
threedee:
MOVLW 0x6
MOVWF FSR
COMF _psfiv, W
forty:
ANDWF 0, F
BSF FSR, 0x7
ANDWF 0, F
fortythree:
GOTO _beforeprogstart
fortyfour:
CALL thirtyseven
CALL sixtythree
CALL _progstartfeight
CALL threedee
CALL fivef
MOVF _pstwo, W
BTFSC _psone, 0x3
IORLW 0x1
fourcee:
MOVWF _psthr
MOVLW 0x8
MOVWF _psfor
fourf:
RLF _psthr, F
BTFSC STATUS, 0
CALL thirtyseven
BTFSS STATUS, 0
CALL threedee
CALL sixtythree
CALL fivef
DECFSZ _psfor, F
GOTO fourf
CALL thirtyseven
fiftynine:
CALL sixtythree
MOVLW 0x6
MOVWF FSR
MOVF _psfiv, W
ANDWF 0, W
ADDLW 0xff
fivef:
MOVLW 0x6
MOVWF FSR
COMF _psate, W
GOTO forty
sixtythree:
MOVLW 0x6
MOVWF FSR
sixtyfive:
MOVF _psate, W
BSF FSR, 0x7
IORWF 0, F
BCF FSR, 0x7
ANDWF 0, W
BTFSC STATUS, 0x2
GOTO sixtyfive
GOTO fortythree
endasm
beforeprogstart:
@ BCF STATUS, 0x7
@ BCF STATUS, 0x6
@ BCF STATUS, 0x5
@ clrwdt
progstartfeight:
return
'
'
radiotune: 'tune radio to selected frequency
freqchanged = 15 'start band changed timer
SI470X_TempW = userfreq
SI470X_FREQ VAR SI470X_TempW
Khz VAR SI470X_TempB
FREQ2CHANNEL:
gosub radioread 'read all registers
Khz = 10
Channel = (Channel & $FE00) | (((SI470X_FREQ * 10) - (SI470X_MINFREQUENCY * 10)) / Khz)
TUNE = 1
gosub radiowrite
WAIT4STC:
while !STC
gosub radiostat
wend
TUNE = 0
SEEK = 0
goto radiowrite
'
'
radiostat:
gosub itcreadctrl
cnt = 10
itwosee = 0
gosub icread
itwosee = 1
gosub icread
cnt = 11
itwosee = 0
gosub icread
@ CALL itcend
@ BTFSC STATUS, 0
@ GOTO _SiError
@ MOVWF _arg
Si_REGS(11) = Si_REGS(11) + arg
return
'
'
radiosetvol:
if buttone = 0 then
gosub drawvol
endif
SI470X_CURRENTVOLUME = uservol 'intermediate var could be optimised out
VOLEXT = 0
sysconfig2 = (sysconfig2 & $fff0) | (SI470X_CURRENTVOLUME & $0F)
if SI470X_CURRENTVOLUME = 0 then
VOLEXT = 1
sysconfig2 = (sysconfig2 & $fff0) | (8 & $0F)
endif
goto radiowrite
'
'
printinfo:
if userband = 0 then 'fm broadcast
displayfreq = userfreq + 4 'apply offset for broadcast band
else 'vhf amateur
'do sexy maths for accurate centre frequency display
vwork = vchan
vwork = vwork * 1429
displayfreq = 1440
displayfreq = displayfreq + (vwork DIG 4 * 10)
displayfreq = displayfreq + vwork DIG 3
'
if freqchanged = 0 then
if vwork dig 2 > 4 then 'round up first decimal place
displayfreq = displayfreq + 1
endif
endif
'
endif
'
if rssitype = 0 then 'signal strength display type
sigstb = SI470X_CURRENTRSSI 'copy to word buffer
gosub drawsig 'graphic bar graph
else 'or numeric
arg = $80 : gosub send_command_byte
for cnt = 76 to 83
gosub getdata
next cnt
arg = SI470X_CURRENTRSSI dig 1 : gosub sendnumeral
arg = SI470X_CURRENTRSSI dig 0 : gosub sendnumeral
gosub sixspaces
endif
arg = $C0 : gosub send_command_byte
for cnt = 70 to 75
gosub getdata
next cnt
'
if displayfreq > 999 then
arg = displayfreq dig 3 : gosub sendnumeral : gosub serialarg '
else
txbyte = $20 : gosub serialout 'transmit leading space
endif
arg = displayfreq dig 2 : gosub sendnumeral : gosub serialarg '
arg = displayfreq dig 1 : gosub sendnumeral : gosub serialarg '
arg = "." : gosub send_data_byte : gosub serialarg '
arg = displayfreq dig 0 : gosub sendnumeral : gosub serialarg '
'
if freqchanged > 0 then 'temporarily display true centre frequency
if userband = 1 then 'extra decimal place for vhf amateur band
arg = vwork dig 2 : gosub sendnumeral : gosub serialarg '
endif
freqchanged = freqchanged - 1
endif
'
for cnt = 64 to 69
gosub getdata : gosub serialarg
next cnt
txbyte = $0D : gosub serialout 'send new line and return characters
txbyte = $0A
goto serialout 'will return from here
'
'
'sets up character lcd custom character buffers
'could be stored at the end of on chip eeprom
setchars: 'custom characters for graphic bargraphs
for lll = $40 to $47
arg = lll+$00 : gosub send_command_byte
arg = %000000 : gosub send_data_byte
arg = lll+$08 : gosub send_command_byte
arg = %010000 : gosub send_data_byte
arg = lll+$10 : gosub send_command_byte
arg = %011000 : gosub send_data_byte
arg = lll+$18 : gosub send_command_byte
arg = %011100 : gosub send_data_byte
arg = lll+$20 : gosub send_command_byte
arg = %011110 : gosub send_data_byte
arg = lll+$28 : gosub send_command_byte
arg = %011111 : gosub send_data_byte
arg = lll+$30 : gosub send_command_byte
arg = %011111 : gosub send_data_byte
next lll
lll = $38 + $40 'and custom intro screen antenna symbol
arg = lll+$00 : gosub send_command_byte
arg = %000000 : gosub send_data_byte
arg = lll+$01 : gosub send_command_byte
arg = %011111 : gosub send_data_byte
arg = lll+$02 : gosub send_command_byte
arg = %010001 : gosub send_data_byte
arg = lll+$03 : gosub send_command_byte
arg = %001010 : gosub send_data_byte
arg = lll+$04 : gosub send_command_byte
arg = %000100 : gosub send_data_byte
arg = lll+$05 : gosub send_command_byte
arg = %000100 : gosub send_data_byte
arg = lll+$06 : gosub send_command_byte
arg = %000100 : gosub send_data_byte
arg = lll+$07 : gosub send_command_byte
arg = %000000
goto send_data_byte
'
'
'draw graphic signal strength
drawsig:
sigst = sigstb
if demobar = 0 then
sigst = sigst + sigst + sigst 'scale for display
endif
if sigst > 95 then 'apply display limit
sigst = 95
endif
lll = 16
arg = $80 : gosub send_command_byte 'go to first lcd line
while sigst > 5
arg = $06 : gosub send_data_byte 'print solid bar
lll = lll - 1
sigst = sigst - 6
wend
arg = sigst : gosub send_data_byte 'print the last partial bar
lll = lll - 1
while lll > 0
arg = $00 : gosub send_data_byte '
lll = lll - 1
wend
return
'
'
'draw graphic and printed volume level
drawvol:
arg = $C0 : gosub send_command_byte
for cnt = 56 to 63
gosub getdata
next cnt
arg = uservol DIG 1 : gosub sendnumeral
arg = uservol DIG 0 : gosub sendnumeral
gosub sevenspaces
demobar = 1
sigstb = uservol + 1
sigstb = sigstb * 6
gosub drawsig
demobar = 0
volchanged = 20
psone = 254 : gosub pausems '100ms
psone = 254
goto pausems '100ms
'
'
'print hard coded string to lcd
printvhf:
gosub printvhffm
for cnt = 31 to 40
gosub getdata
next cnt
return
'
'
'print hard coded string to lcd
printvhffm:
for cnt = 50 to 55
gosub getdata
next cnt
return
'
'
'print a number of spaces to lcd
sevenspaces:
arg = $20 : gosub send_data_byte
sixspaces:
for cnt = 0 to 6 'six spaces
arg = $20 : gosub send_data_byte
next cnt
return
'
'
'HD44780 character lcd functions for PBP - Brek Martin 2019
lcdinit: 'module initialisation sequence for 4 bit interface
if hwconfg = 0 then ' disable lcd for serial configuration
return
endif ' hwconfg
gosub lcdinthand
gosub pauseten '10ms
gosub lcdinthand
gosub pauseten '10ms
gosub lcdinthand
gosub pauseten '10ms
nib = $02 : gosub send_nibble 'set 4 bit mode
gosub pauseten '10ms
arg = %00101000 : gosub send_command_byte 'N=0 : 2 lines F=0 : 5x7 font
gosub pauseten '10ms
arg = %00001000 : gosub send_command_byte 'display: display off, cursor off, blink off
gosub pauseten '10ms
arg = %00000001 : gosub send_command_byte 'clear display
gosub pauseten '10ms
arg = %00000110 : gosub send_command_byte 'set entry mode
gosub pauseten '10ms
arg = %00001100 : gosub send_command_byte 'display: display on
goto pauseten '10ms
'
'
lcdinthand:
nib = $03
send_nibble:
if hwconfg = 0 then ' disable lcd for serial configuration
return
endif ' hwconfg
E_PIN = 1
lata = nib & $0F
lata.4 = rsflag
porta = lata
gosub tennops
E_PIN = 0
tennops:
@ nop
@ nop
@ nop
@ nop
@ nop
@ clrwdt
@ nop
@ nop
@ nop
@ nop
return
'
'
sendnumeral:
arg = arg + $30 'convert numeral to ascii
goto send_data_byte
getdata:
read cnt,arg 'read data from on chip eeprom
goto send_data_byte
send_command_byte:
rsflag = 0
goto send_byte
send_data_byte:
rsflag = 1
send_byte:
nib = arg >> 4 : gosub send_nibble
nib = arg & $F
goto send_nibble
'
'
'delay routine based on those by Mark Crosbie
'all delays have been tweaked for application
'and are not accurate for real time keeping
'psone wass ms delay time approx for 4 MHz
pausethree:
psone = 8 : goto pausems
pauseten:
psone = 25
pausems:
@ movlw 50
@ movwf _pstwo
delaytwo:
@ nop
@ nop
@ clrwdt
@ nop
@ nop
@ nop
@ decfsz _pstwo, f
@ goto _delaytwo
@ decfsz _psone, f
@ goto _pausems
return
'
'
'delay routine based on those by Mark Crosbie
'all delays have been tweaked for application
'and are not accurate for real time keeping
'psfor was sec delay time approx for 10 MHz
onesec: 'approx one second delay
psfor = 1
pauses: 'or an arbitrary number of seconds
for lata = 0 to psfor
for psthr = 0 to 9
psone = 249 : gosub pausems '100ms
next psthr
next lata
return
'
'
itcreadctrl: 'optimised i2c calls
itceror = 0 'reset comms error flag
asm
MOVLW 0x2 ;i2c read
MOVWF _psfiv
MOVLW 0x80
MOVWF _psate
MOVLW 0x20 ;send control byte
CALL itcrd
BTFSC STATUS, 0
GOTO _SiError
endasm
return
'
'
'print an error code to character lcd
printerror:
gosub lcdcls 'clear lcd display
for cnt = 83 to 90 'print error
gosub getdata
next cnt
arg = $32
if itceror = 1 then
arg = $31
endif
if srstats = 0 then
arg = $33
endif
gosub send_data_byte
psfor = 9
goto pauses '9s
'
'
'clear the lcd display
lcdcls:
arg = $01 : gosub send_command_byte
goto pauseten '10ms
'
'
'PBP software serial out 8N1 - Brek Martin 2016.
'this is smaller than the PBP debugout command
serialarg:
txbyte = arg
serialout:
if hwconfg = 1 then ' disable serial for lcd configuration
return
endif ' hwconfg
if pssix != 1 then 'allow changed data only
if pssev != 1 then
if (pssev != $1A) && (pssix != $1A) then
return
endif
endif
endif
asm
movlw 8
movwf _bcount
bcf _serpin
call pausedelay
sendbyte:
btfss _txbyte ,0
goto snd0
bsf _serpin
goto sndd
snd0:
bcf _serpin
sndd:
rrf _txbyte ,F
call pausedelay
decfsz _bcount ,F
goto sendbyte
bsf _serpin
pausedelay:
movlw 84 ;constant for 9600 baud @ 10 MHz
movwf _delay
zpausedelay:
decfsz _delay ,F
goto zpausedelay
return
endasm
'
'
↧