PIC Code Snippet – ProtonBasic Compiler

Pic-Snippet

Setting-up-breadboard-and-programmer

Crystal-Configuration
ADC Read and Using-Analog-Pin-As-Digital-ADCON1

Digital-pin-Output-blink-led

Digital-pin-Input-push-switch

Read-ADC

Hardware-serial

Software-serial

Use-of-timer-in-different-mode

Use-of-interrupts-(covers-all-in-sub-categories)

External Interrupt on RB0

Port Change Interrupt

Sleep/idle

SPI

CAN

Watchdog

I2C

LCD Character 16×2

Thermistor for temperature monitoring

LM35 for temperature monitoring

DS1307 for date and time

Usb

Memory

Macro

GPSim
Find right speed for software serial of 12F675


Setting-up-breadboard-and-programmer

 

PicKit2 Connection:

pickit2-icsp-connection

 

 

 

 

 

 

* Connect MCLR pin to breadboard’s VDD/VCC with a 1k resistor

* VDD pin to breadboard’s VDD

* VSS pin to breadboard’s GND

* OSC1 and OSC2 conneted to Crystal, 22pF capacitor to GND for each

 

* Programmer VPP/MCLR pin to MCU MCLR pin

* Programmer VDD to breadboard’s VDD

* Programmer VSS to breadboard’s GND

* Programmer ICSPDAT/PGD to MCU ICSPDAT

* Programmer ICSPCLK/PGC to MCU ICSPCLK

* Programmer AUX not connected and remains floating.

 

Top


 


Crystal-Configuration

 

Use JGB Tools to configure crystal and other settings. On Proton IDE,
click View > Plugin > JGB Tools > Fuse Configurator. After
setting, go to ‘Config Code’ tab. Copy the line and paste it on top of
the source file, bellow device declaration. Example, here external
crystal 8 MHz is used and declared as HS_OSC:

 

Device = 16F73

Config BODEN_OFF, CP_OFF, PWRTE_ON, WDT_OFF, HS_OSC

Declare Xtal = 8

 

 

Top


 


Using-Analog-Pin-As-Digital-ADCON1

 

Any PICmicro with analogue inputs, such as the PIC16C7xx,
PIC16F87x,  PIC12C67x and all the 18Fxxxx series devices, will
power up in analogue mode. If you intend to use them as digital types
you must set the pins to digital by using the following line of code:

 

Declare All_Digital = True

 

This will set analogue pins to digital on any compatible device.
Alternatively, you can manipulate the hardware registers directly: –

 

ADCON1 = 7
If you want to use some pins as digital and some pins as analogue,
of
an analogue port, see the datasheet for ADCON1. There is a list of
settings which says which pins can be used as analogue and digital. You
can not go outside of this settings. Bellow is the chart for ADCON1 of
PIC16F73:

 

ADCON1

 

 

 

 

 

 

Example Code:

Read analog input from analog channel 0 and 1 (RA0 and RA1). RA2 and
RA5 set as output and 2 leds are attached to it. If reading of channel
0 is greater than 100, turn led of RA2 on/high. If reading of channel 1
is greater than 100, turn led of RA5 on/high.

 

###################

Device = 16F73

Config BODEN_OFF, CP_OFF, PWRTE_ON, WDT_OFF, HS_OSC

 

Declare Xtal = 8

 

TRISA = %00001011       ‘
Configure AN0 (PortA.0) +  AN1 (PORTA.1) +  AN3 (PORTA.3)as
input. All other output

ADCON1 = %00000100      ‘ Set analogue input on PORTA.0 PORTA.1 PORTA.3

Low PORTA.2 ‘Make digital pin 2 low

Low PORTA.5 ‘Make digital pin 5 low

 

‘  When ADCON1 is set as above %00000100, this makes the pins (6 pin port. 0 to 5) of PORTA as bellow,

‘  PORTA.0 = ANALOGUE

‘  PORTA.1 = ANALOGUE

‘  PORTA.2 = DIGITAL

‘  PORTA.3 = ANALOGUE

‘  PORTA.4 =

‘  PORTA.5 = DIGITAL

 

‘Configure Analogue

Declare Adin_Res = 8   ‘ 8-bit result. PIC 16F73 has only 8 bit analogue

Declare Adin_Tad = FRC ‘ RC OSC chosen

Declare Adin_Stime = 100

 

Dim AnZero As Word  ‘Reading from Analog channel 0

Dim AnOne As Word   ‘Reading from Analog channel 1

 

Output PORTC.6 ‘TX

Input PORTC.7  ‘RX

 

While 1 = 1

AnZero = ADIn 0

DelayMS 100 ‘Make small delay between multiple analog readings

 

If AnZero > 100 Then

High PORTA.2

EndIf

 

”””””””””””””

 

AnOne = ADIn 1

DelayMS 100

 

If AnOne > 100 Then

High PORTA.5

EndIf

 

HRSOut “AnOne : “,Dec AnOne, 13, 10

DelayMS 1000

Wend

###################

Top


 


Digital-pin-Output-blink-led

 

Example:

 

Device = 16F73

Config BODEN_OFF, CP_OFF, PWRTE_ON, WDT_OFF, HS_OSC

Declare Xtal = 8

 

PORTB = %11000111 ‘ RB.3, RB.4, RB.5 as output

‘ Above can also be declared as Output PORTB.3 , but has
to be declared for each pin separaely like Output PORTB.4, Output
PORTB.5

High PORTB.3 ‘Turn Led On

DelayMS 1000 ‘Delay for 1000ms

Low PORTB.3 ‘Turn Led Off

 

Top


 



Digital-pin-Input-push-switch

 

Work this out by 2 methods. One is to look continuously for the input inside loop and another using interrupt.

 

Example for continuous look:

 

Device = 16F73

Config BODEN_OFF, CP_OFF, PWRTE_ON, WDT_OFF, HS_OSC

 

Declare Xtal = 8

All_Digital = true

‘Push button connected to RB1. Led connected to RB2

 

TRISB = %00000010 ‘RB1 input and all other output

 

High PORTB.2 ‘Turn on Led for test

DelayMS 1000

Low PORTB.2 ‘Turn off Led

 

While 1 = 1

If PORTB.1 = 1 Then ‘Look

DelayMS 100 ‘debounce
time. Test it with various delay time as needed, for example 25ms

If PORTB.1 = 1 Then ‘really pressed?

Toggle PORTB.2
DelayMS 5000 ‘Lock here, else it goes to ‘Look, above. Also here test
with different delay time

EndIf

EndIf ‘If PORTB.1 = 1 Then ‘Look

Wend

 

 

 

 

For interrupt see bellow ‘External Interrupt on RB0’.

 

Top



Hardware-serial

Example:

======

###############################################################################

Device 16F73

Config BODEN_OFF, CP_ALL, PWRTE_ON, WDT_OFF, HS_OSC ‘WDT OFF. Protect Code

Xtal 8

 

‘ Hardware serial

TRISC = %10000000 ‘RX Input, TX and all other PORTC are output

Hserial_Baud = 9600

Hserial_RCSTA = %10010000 ‘ Enable continuous receive

Hserial_TXSTA = %00100000  ‘ Enable transmit and asynchronous mode

Hserial_Clear = On     ‘ Clear the buffer before receiving

HRSOut “BISMILLAH”, 13, 10

‘ Hardware serial setup ends

 

Dim Var1 As Byte

 

Loop:

Var1 = HRSIn ‘ Receive a byte serially into Var1

HRSOut Var1        ‘ Display the byte received

GoTo Loop           ‘ Loop forever

Stop

###############################################################################

Top


 


 

External Interrupt on RB0

From Pic 16F73’s datasheet (page 100)  :

External interrupt on the RB0/INT pin is edge triggered,

either rising, if bit INTEDG (OPTION_REG<6>) is set,

or falling, if the INTEDG bit is clear. When a valid edge

appears on the RB0/INT pin, flag bit INTF

(INTCON<1>) is set. This interrupt can be disabled by

clearing enable bit INTE (INTCON<4>). Flag bit INTF

must be cleared in software in the Interrupt Service

Routine before re-enabling this interrupt. The INT inter-

rupt can wake-up the processor from SLEEP, if bit INTE

was set prior to going into SLEEP. The status of global

interrupt enable bit GIE decides whether or not the pro-

cessor branches to the interrupt vector following wake-

up. See Section 12.14 for details on SLEEP mode.

 

Example:

Device 16F73

Config BODEN_OFF, CP_OFF, PWRTE_ON, WDT_OFF, HS_OSC

Xtal = 8

 

All_Digital = true

 

Output PORTC.1 ‘Led

Low PORTC.1 ‘turn off led

 

’16F73 Datasheet page 20, 21 for OPTION_REG and INTCON description

On_Hardware_Interrupt GoTo IntRoutine

Input PORTB.0 ‘RB0 INT

INTCON.4 = 1 ‘Enables the RB0/INT external interrupt

INTCON.1 = 0 ‘Clear Interrupt Flag bit

OPTION_REG.6 = 1 ‘INTEDG: Interrupt Edge Select. Interrupt on rising edge of RB0/INT pin. Use pull down resistor.

OPTION_REG.7 = 1 ‘1 = PORTB pull-ups are disabled. 0 = PORTB pull-ups are enabled by individual port latch values

 

INTCON.7 = 1 ‘Global Interrupt Enable

 

While 1 = 1

‘Mainloop

Wend

 

IntRoutine:

If INTCON.1 = 1 Then ‘RB0 External Interrupt

INTCON.1 = 0 ‘Clear Interrupt Flag bit

Toggle PORTC.1

DelayMS 100 ‘debounce

EndIf ‘If INTCON.1 = 1 Then

 

INTCON.7 = 1 ‘Enable global interrupt Again

Return

 

Top


Port Change Interrupt

 

 

Top


 


 


 


 


 



Use-of-timer-in-different-mode

* Use Mr. E Pic multi-calc

Timer0 Overflow Interrupt

 

1,000 millisecond/mSec = 1 second

10,00,000 microsecond/uSec = 1 second

100,00,00,000 nanosecond = 1 second

 

The hertz is equivalent to cycles per second.

1 KHz = 1000 Hertz

1 MHz = 1000000 Hertz

 

Basic understanding:

Timer0 of PIC-16F73 is a 8 bit timer. This counts 0 to 255 and then
overflow interrupt occurs. It is necessary to understand the duration
or time needed to count from 0 to 255, or duration of each interrupt.
This depends on the clock source – internal or external. Now the
internal clock source will be discussed which would depend on the
external crystal.

 

In simple the counter of the Timer will increase by 1, on every
instruction cycle of the microcontroller. This happens when the
prescaler is set to 1:1. When the prescaler is set to 1:2, the Timer
counter would increase by 1, on every 2 instruction cycles. When
prescaler is 1:4, counter increases at each 4th instruction cycle. So,
the duration of a single instruction cycle is the main factor to
calculate the duration for the interrupt.

 

For example, say the crystal to be used is 1MHz, that means it has
10,00,000 cycles per second. For PIC microcontroller, 4 clock cycles are
needed to complete one intruction.So, what is the duration of a
single instruction cycle? And how many instruction cycles in 1 second?

 

    Instruction Cycles = 10,00,000 ÷ 4 = 2,50,000
 2,50,000 instruction cycles in 1 second. And the duration for each cycle,

 

    2,50,000 instruction completes in 100,00,00,000 nanosecond


1

”         ”  100,00,00,000
÷ 2,50,000 = 4,000 nanosecond

So, duration for 1 instruction cycle is 4,000 nanosecond, or 4000 ÷ 1000 = 4 microsecond

 

Now, if the prescaler is set to 1:1, Timer counter would increase by 1,
on each instruction cycle. It would count from 0 to 255, then the
overflow interrupt occurs. Total 256 instruction cycles are needed for
this interrupt. Duration for the interrupt is,

 

     256 X 4 microsecond = 1,024 microsecond

 

So 1,024 microsecond or 1,024 ÷ 1,000 = 1.024 millisecond is needed for one interrupt.

 

That’s it. If you need a 1 second delay, increase counting of a
variable inside the interrupt routine. Count up to 1000 and you would
get approximately 1 second delay.

 

    1,000 X 1.024 millisecond = 1,024 millisecond

 

  1,024 millisecond needed to count up to 1,000. (1,000 millisecond = 1 second. It counts 24 milliseconds more. This is why it was said earlier approx 1 second delay)

 

Practical Crystal:

Say the crystal is 8 MHz. What would be the duration for each interrupt with prescaler 1:1?

 

1st of all, get how many instruction cycles per second and duration of each cycle:

 

8 MHz = 10,00,000 X 8 = 80,00,000 clock cycles per second

Instruction cycles = 80,00,000 ÷ 4 = 20,00,000

Total instruction cycles = 20,00,000

 

20,00,000 instruction cycles in 1 second or 100,00,00,000 nanosecond

1

”       100,00,00,000 ÷ 20,00,000 =
500 nanosecond

Duration for 1 instruction cycle = 500 nanosecond

 

As prescaler is 1:1, it would increase the counter on each instruction
cycle. Which needs 256 instruction cycles and the duration for
interrupt is,

256 X 500 nanosecond = 1,28,000 nanosecond

 

1,28,000 nanosecond = 1,28,000 ÷ 1,000 = 128 microsecond

 

So, interrupt occurs at each 128 microseconds.

 

What happens if the prescaler is 1:4?

Now it would take 4 instruction cycles, to increase timer counter by one. Duration for 4 instruction cycle is,

 

500 nanosecond X 4 = 2,000 nanosecond, or

2,000 nanosecond ÷ 1,000 = 2 microsecond

 

2 microsecond is needed to increase the timer counter by one. So interrupt occurs on each,

     256 X 2 microsecond = 512 microsecond

 

So, interrupt occurs at each 512 microsecond.

 

Additionally it is also worth mentioning:

  • When the prescaler is assigned to the timer/counter, any write to the TMR0 register will clear the prescaler;
  • When the prescaler is assigned to watch-dog timer, a CLRWDT instruction will clear both the prescaler and WDT;
  • Writing to the TMR0 register used as a timer, will not cause the
    pulse counting to start immediately, but with two instruction cycles
    delay. Accordingly, it is necessary to adjust the value written to the
    TMR0 register;
  • When the microcontroller is setup in sleep mode, the
    oscillator is turned off. Overflow cannot occur since there are no
    pulses to count. This is why the TMR0 overflow interrupt cannot wake up
    the processor from Sleep mode;
  • When used as an external clock counter without prescaler, a minimal
    pulse length or a pause between two pulses must be 2 Tosc + 20 nS. Tosc
    is the oscillator signal period;
  • When used as an external clock counter with prescaler, a minimal pulse length or a pause between two pulses is 10nS;
  • The 8-bit prescaler register is not available to the user, which means that it cannot be directly read or written to;

 

 

PIC 16F73 Example:

Timer0 (8 bit timer) Overflow

Operation is controlled through two registers:

OPTION_REG register (Bit 0 to 5). Set prescaler, clock source here.

INTCON register. Enable Timer0 and get/set Overflow flag here (Bit 2 and Bit 5).

 

OPTION_REG

 

 

 

 

 

 

 

 

 

###############################################################################

INTCON

 

 

 

 

 

 

 

 

 

###############################################################################

Example: 8 MHz crystal. Toggle Led on RC2 on every 5 second.

 

###############################################################################

Device = 16F73

Config BODEN_OFF, CP_OFF, PWRTE_ON, WDT_OFF, HS_OSC

Declare Xtal = 8

 

Declare Reminders = Off

Declare Warnings = Off

 

All_Digital = true

 

‘Set PORTC.2 for Led

Output PORTC.2

 

‘Set prescaler and clock source

OPTION_REG.3 = 0 ‘Prescaler Assignment bit. 0 for Timer0 and 1 for Watchdog. Who would get the prescaler?

OPTION_REG.5 = 0 ‘T0CS: TMR0 Clock Source Select Bit [ 0 For internal ]

 

‘Set the prescaler to 1:256 to increase TMR0 counter by one on every 256th instruction cycle

   ‘ Optional
note:  To achieve a 1:1 prescaler assignment for the TMR0
register, assign the prescaler to the Watchdog Timer.

   ‘ For Timer0’s prescaler 1:1, it doesn’t matter whether watchdog is enabled or not.

 

OPTION_REG.0 = 1

OPTION_REG.1 = 1

OPTION_REG.2 = 1

 

‘Set INTCON register, which enables Timer0 overflow interrupt

INTCON = 0 ‘Clear the initial interrpt control register

INTCON.5 = 1 ‘TMR0IE TMR0 Overflow Interrupt Enable bit

TMR0 = 0 ‘Intcon.2 – TMR0IF – Clear Initial TMR0 register

INTCON.7 = 1 ‘Enable Global Interrupt

 

On_Hardware_Interrupt GoTo IntRoutine

 

‘Main Loop

While 1 = 1

 

Wend

 

Dim cntr As Byte

‘cntr is variable to count. Counting will be bellow than
255. So using BYTE variable. WORD variable counts up to 65535

‘Led on PORTC.2 should toggle on every 5 second

‘Crystal is 8 MHz

‘Instructions in 1 second = 8000000 / 4 = 2000000

‘Time for 1 instruction = 1000000000 / 2000000 = 500 nano second

‘Prescaler is Set To 1:256. Time for 256 instruction = 500 X 256 = 128000 nano second.

‘TMR0 counter increases by 1 in 128000 nano second. As set in Prescaler 1:256

‘Timer0 counter counts up to 255 and then interrupt occurs.

‘Interrupt time = 255 X 128000 = 32640000 nanosecond

‘Or 32640000 / 1000 = 32640 micro second

‘Or 32640 / 1000 = 32.64 millisecod

‘Interrupt time = 32.64 millisecod

‘======X======’

‘1000 millisecond = 1 second. One interrupt time is 32.64 millisecond.

‘For a 1 second delay approximately 31 interrupts are needed (1000 / 32.64)

‘For a 5 second delay 155 interrupts are needed (31 X 5)

‘The variable – “cntr” would count up to 155

 

 

IntRoutine:

Context Save

 

If INTCON.2 = 1 And INTCON.5 = 1 Then  ‘If TMR0 is enabled (INTCON.5) and an overflow has occured (INTCON.2)

INTCON.2 = 0 ‘TMR0 must be cleared. “Context Restore” bellow is needed, as

‘when the prescaler is assigned to the
timer/counter, any write to the TMR0 register will clear the prescaler

 

cntr = cntr + 1

 

If cntr >= 155 Then

Toggle PORTC.2

cntr = 0

EndIf

 

EndIf

 

Context Restore

Return

 

###############################################################################

 

 

Timer2 Example:

——————————-

Blink/Toggle a LED on every minute,

Example:

 

###############################################################################

Device = 16F73

‘   Config BODEN_OFF, CP_OFF, PWRTE_ON, WDT_ON, HS_OSC ‘WDT ON. No Protect Code

‘   Config BODEN_OFF, CP_OFF, PWRTE_ON, WDT_OFF, HS_OSC ‘WDT OFF. No Protect Code

‘   Config BODEN_OFF, CP_ALL, PWRTE_ON, WDT_ON, HS_OSC ‘WDT ON. Protect Code

Config BODEN_OFF, CP_ALL, PWRTE_ON, WDT_OFF, HS_OSC ‘WDT OFF. Protect Code

‘#define NO_CLRWDT 1 ‘ Don’t automatically insert CLRWDT’s

Xtal 8

Declare Flash_Capable = FALSE ‘Needed for LCD. Specially for 16F72

 

All_Digital True

 

Output PORTA.2 ‘Green Led Attached

Output PORTC.3 ‘Red Led Attached

 

”==========================================================”

” TIMER2 SETUP

” This occurs every 30.6372 times a second. Setting: Crystal 8MHz, Prescaler 1:16, Postscaler 1:16

” Used pic timer tool PicTimerCalcV4.exe

T2CON.0 =  0 ‘Timer2 Prescaler is 1:16

T2CON.1 =  1 ‘Timer2 Prescaler is 1:16

 

T2CON.3 =  1 ‘Timer2 1:16 Postscale

T2CON.4 =  1 ‘Timer2 1:16 Postscale

T2CON.5 =  1 ‘Timer2 1:16 Postscale

T2CON.6 =  1 ‘Timer2 1:16 Postscale

 

T2CON.2 = 1 ‘Timer2 On bit

 

TMR2 =  0 ‘Start counting from 0

PR2 =  255 ‘Count up to 255

 

PIR1.1 = 0  ‘TMR2 to PR2 Match Interrupt Flag bit. 1
= TMR2 to PR2 match occurred (must be cleared in software). 0 = No TMR2
to PR2 match occurred

PIE1.1 = 1 ‘TMR2 to PR2 Match Interrupt Enable bit

INTCON.6 = 1 ‘PEIE: Peripheral Interrupt Enable bit

”Timer2 Setup Ends

 

On_Hardware_Interrupt GoTo INTROUTINE

INTCON.7 = 1 ‘ENABLE GLOBAL INTERRUPT

 

Dim CNTR As Byte

Dim SECONDS As Byte

Dim MINUTES As Byte

Dim BlinkDelay As Byte

 

CNTR = 0

SECONDS = 0

MINUTES = 0

BlinkDelay = 5

 

While 1 = 1

 

Wend

 

INTROUTINE:

 

Context Save

If PIR1.1 = 1 And PIE1.1 = 1 Then   ‘IF TMR2
Match Int is enabled (PIE1.1) AND A Match HAS OCCURED (PIR.1)

PIR1.1 = 0 ‘Software Clear

 

CNTR = CNTR + 1

 

If CNTR >= 31 Then

SECONDS = SECONDS + 1

CNTR = 0

‘clrwdt

EndIf ‘IF CNTR >= 31 THEN

 

If SECONDS >= 60 Then

SECONDS = 0

MINUTES = MINUTES + 1

Toggle PORTA.2

‘clrwdt

EndIf

 

If MINUTES >= 60 Then

MINUTES = 0

 

EndIf

EndIf

 

 

 

 

clrwdt

Context Restore

Return ‘INTROUTINE:

””””””””””””””””””””””””””””

###############################################################################

 

 

Top



LCD Character 16×2

The LCD now I am using is character LCD, 16 characters, 2 lines. I am
using it in 4 bit mode. It has 16 pins. Solder 6 pins from the left,
and 6 pins from the right. 4 pins in the middle would be unconnected.
Connection and example code for PIC-16F73 is as bellow:

 

LCD-16x2-Character-Pin-Description

 

 

 

 

 

 

 

 

 

 

LCD-16x2-Character-MCU-Interface

 

 

 

 

 

 

 

 

Example Code:

===========

 

Device 16F73

Config BODEN_OFF, CP_ALL, PWRTE_ON, WDT_OFF, HS_OSC ‘Protect Code

‘   Config BODEN_OFF, CP_OFF, PWRTE_ON, WDT_ON, HS_OSC ‘WDT ON

‘   #define NO_CLRWDT 1 ‘ Don’t automatically insert CLRWDT’s

‘   clrwdt ‘Reset watchdog

 

Declare Xtal = 8

All_Digital = true

 

Declare Flash_Capable = FALSE ‘Needed for PIC-16F72, also works with PIC-16F73

 

‘Read Description on Proton Compiler Manual Page 172

LCD_DTPin = PORTC.0 ‘ LCD’s DT lines

LCD_RSPin = PORTC.4 ‘LCD RS line. Register Select signal.

LCD_ENPin = PORTC.5 ‘LCD EN line. Enable signal.

LCD_Interface = 4 ‘4 BIT or 8 BIT. Inform the compiler as
to whether a 4-line or 8-line interface is required by the LCD.

LCD_Lines = 2 ‘2 line by 16 character type

LCD_Type = 0 ‘0 or 1 or 2, Alpha or Graphic or Samsung or Toshiba

LCD_CommandUs = 2000 ‘Time to wait (in microseconds)
between commands sent to the LCD. If the Declare is not used, default
2000us (2ms).

LCD_DataUs = 50 ‘Time to wait (in microseconds) between
data sent to the LCD. If the Declare is Not used, default 50us.

 

DelayMS 100 ‘ Wait for the LCD to stabilise

Print Cls ‘Clear LCD

Print $FE, 2 ‘Return Home

Print Cls, “Bismillah”

Print $FE, $C0 ‘Move cursor to beginning of second line. Compiler manual page 320

Print “Solar Charger.”

 

‘ LCD

‘ Control Command   Operation

‘ $FE, 1         Clear display

‘ $FE, 2         Return home (beginning of first Line)

‘ $FE, $0C        Cursor off

‘ $FE, $0E        Underline Cursor On

‘ $FE, $0F        Blinking Cursor On

‘ $FE, $10        Move Cursor left one position

‘ $FE, $14        Move Cursor right one position

‘ $FE, $C0        Move Cursor To beginning of second Line

‘ $FE, $94        Move Cursor To beginning of third Line (If applicable)

‘ $FE, $D4        Move Cursor To beginning of fourth Line (If applicable)

 

 

lock:

‘Mainloop

GoTo lock

 

 

Top


 


Thermistor for temperature monitoring

 

Using thermistor to monitor temperature is not much accurate and it is
not linear. But not bad though, it is cheap and usable. Temperature
measuring range is probably -55c to 150c. I shall use to measure
0-125c. To calibrate either tune the R1 (10k resistor – using POT) or
change code. These are called NTC thermistor. Use a 10k thermistor and
10k resistor.

 

thermistor

 

 

 

 

 

 

 

 

Example code:

==========

Device 16F73

‘Config BODEN_OFF, CP_OFF, PWRTE_ON, WDT_ON, HS_OSC ‘WDT ON. No Protect Code

Config BODEN_OFF, CP_OFF, PWRTE_ON, WDT_OFF, HS_OSC ‘WDT OFF. No Protect Code

‘Config BODEN_OFF, CP_ALL, PWRTE_ON, WDT_ON, HS_OSC ‘WDT ON. Protect Code

‘#define NO_CLRWDT 1 ‘ Don’t automatically insert CLRWDT’s

 

Declare Xtal = 8

 

”==========================================================”

”Serial Setup

TRISC = %10110111

Hserial_Baud = 9600

Hserial_TXSTA = %00100100 ‘ NOT SYNCHRONOUS

HRSOut “BISMILLAH”, 13, 10

”Serial Setup Ends

”==========================================================”

 

 

”==========================================================”

‘ADC SETUP

Declare Adin_Res = 8     ‘ 8-BIT RESULT REQUIRED

Declare Adin_Tad = FRC     ‘ RC OSC CHOSEN

Declare ADIN_DELAY = 100    ‘ ALLOW 50US SAMPLE TIME

TRISA = %00001011       ‘
CONFIGURE AN0 (PORTA.0) +  AN1 (PORTA.1) +  AN3 (PORTA.3)AS
INPUT. ALL OTHER OUTPUT

ADCON1 = %00000100      ‘ SET ANALOGUE INPUT ON PORTA.0 PORTA.1 PORTA.3

”==========================================================”

 

Dim Temperature As Byte

Temperature = 0

 

 

While 1 = 1

DelayMS 1000

GoSub ReadTemp

Wend

 

ReadTemp:

Temperature = ADIn 0

Temperature =  Temperature – 6 ‘ I am deducting 6 to
calibrate/match with the reading of a LM35 temperature sensor

 

If Temperature <= 199 Then

Temperature = LRead8 TEMPERATURETABLE[Temperature]

Else

Temperature = 00

EndIf

 

 

HRSOut “NTC: “, Dec Temperature, 13

Return ‘ ReadTemp

‘Place this table at the end of the program

TEMPERATURETABLE: LData 250, 214, 178, 159, 147, 137, 130, 124, 119, 115, 111, 107,_

104, 101, 99, 97, 94, 92, 90, 89, 87,85, 84, 82, 81, 80, 78, 77, 76, 75, 74, 73,_

72, 71, 70, 69, 68, 67, 66, 65, 64, 64, 63, 62,61, 61, 60, 59, 59, 58, 57, 57, 56,_

55, 55, 54, 54, 53, 53, 52, 51, 51, 50, 50, 49, 49, 48, 48, 47, 47, 46, 46, 45,_

45, 45, 44, 44, 43, 43, 42, 42, 42, 41, 41, 40, 40, 39, 39, 39, 38, 38, 37, 37, 37,_

36, 36, 36, 35, 35, 34, 34, 34, 33, 33, 33, 32, 32, 32, 31, 31, 31, 30, 30, 30, 29,_

29, 28, 28, 28, 27, 27, 27, 26, 26, 26, 25, 25, 25, 25, 24, 24, 24, 23, 23, 23, 22,_

22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 17, 17, 17, 16, 16, 16, 15,_

15, 15, 15, 14, 14, 14, 13, 13, 13, 12, 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 8,_

8, 8, 7, 7, 6, 6, 6, 5, 5, 5, 4, 4, 4, 3, 3, 2, 2, 2, 1, 1, 0

 

Top


 


LM35 for temperature monitoring.

Good for measuring temperature easily & accurately. Range is −55˚
to +150˚C. The LM35 does not require any external calibration or
trimming. Linear + 10.0 mV/˚C scale factor. Calibrated directly in ˚
Celsius (Centigrade).

 

LM35-Pinout

 

 

 

 

 

 

 

 

 

LM35

 

 

 

 

 

 

 

 

 

Example Code:

==========

Device 16F73

‘Config BODEN_OFF, CP_OFF, PWRTE_ON, WDT_ON, HS_OSC ‘WDT ON. No Protect Code

Config BODEN_OFF, CP_OFF, PWRTE_ON, WDT_OFF, HS_OSC ‘WDT OFF. No Protect Code

‘Config BODEN_OFF, CP_ALL, PWRTE_ON, WDT_ON, HS_OSC ‘WDT ON. Protect Code

‘#define NO_CLRWDT 1 ‘ Don’t automatically insert CLRWDT’s

 

Declare Xtal = 8

 

 

”==========================================================”

”Serial Setup

TRISC = %10110111

Hserial_Baud = 9600

Hserial_TXSTA = %00100100 ‘ NOT SYNCHRONOUS

HRSOut “BISMILLAH”, 13, 10

”Serial Setup Ends

”==========================================================”

 

 

”==========================================================”

‘ADC SETUP

Declare Adin_Res = 8     ‘ 8-BIT RESULT REQUIRED

Declare Adin_Tad = FRC     ‘ RC OSC CHOSEN

Declare ADIN_DELAY = 100    ‘ ALLOW 50US SAMPLE TIME

TRISA = %00001011       ‘
CONFIGURE AN0 (PORTA.0) +  AN1 (PORTA.1) +  AN3 (PORTA.3)AS
INPUT. ALL OTHER OUTPUT

ADCON1 = %00000100      ‘ SET ANALOGUE INPUT ON PORTA.0 PORTA.1 PORTA.3

”==========================================================”

 

 

”===========================================================”

 

‘Dim LM35 as byte

Dim LM35 As Float ‘Using as float as I am going to
multiply ADC result with 2.2 instead of 2. Read bellow. If using
default 2
‘to multiply ADC
result, use byte variable. Anyway using the default 2 is recommended.

 

 

While 1 = 1

DelayMS 1000

GoSub ReadTemp

Wend

 

”’ LM35 has a 10mV change per celsius. 16F73 has 8 bit adc which would
read upto 255… (5V / 255) or (5000mV / 255) =  approx 20mV

”’ Each change of ADC is change of 20mV or 2 celcius. Multiply ADC
result with 2 to get temperature. Example when ADC reading is 14

”’ temperature is 14 * 2 = 28 celsius.

ReadTemp:

LM35 = ADIn 0

LM35 = LM35 * 2.2 ‘Temperature = Temperature * 2.2 ‘ Using
2.2 instead of 2. I am increasing slightly to be on safe side.

 

HRSOut ” LM35: “, Dec LM35, 13

Return ‘ ReadTemp

 

 

Top


 


DS1307 for date and time

DS1307 is used as RTC. Shows time and date (upto year 2100). Connect it
with MCU as the image bellow. Use 4k7 pullup resistor for SDA and SCL
pin (pin 5 and 6). If using a battery for backup, use a lithium coin
cell battery. Battery voltage must be held between 2.0V and 3.5V for
proper operation. A lithium battery with 48mAhr or greater will back up
the DS1307 for more than 10 years in the absence of power at 25ºC.
Connect battery positive terminal to pin 3 (VBAT) and battery negative
terminal to pin 4 (GND).

 

DS1307

 

 

 

 

 

 

 

 

Example Code:

==========

Device 16F73

‘Config BODEN_OFF, CP_OFF, PWRTE_ON, WDT_ON, HS_OSC ‘WDT ON. No Protect Code

Config BODEN_OFF, CP_OFF, PWRTE_ON, WDT_OFF, HS_OSC ‘WDT OFF. No Protect Code

‘   Config BODEN_OFF, CP_ALL, PWRTE_ON, WDT_ON, HS_OSC ‘WDT ON. Protect Code

‘   #define NO_CLRWDT 1 ‘ Don’t automatically insert CLRWDT’s

 

Declare Xtal = 8

 

 

”==========================================================”

”Serial Setup

TRISC = %10110111

Hserial_Baud = 9600

Hserial_TXSTA = %00100100 ‘ NOT SYNCHRONOUS

HRSOut “BISMILLAH”, 13, 10

”Serial Setup Ends

”==========================================================”

 

 

”==========================================================”

‘ADC SETUP

Declare Adin_Res = 8     ‘ 8-BIT RESULT REQUIRED

Declare Adin_Tad = FRC     ‘ RC OSC CHOSEN

Declare ADIN_DELAY = 100    ‘ ALLOW 50US SAMPLE TIME

TRISA = %00001011       ‘
CONFIGURE AN0 (PORTA.0) +  AN1 (PORTA.1) +  AN3 (PORTA.3)AS
INPUT. ALL OTHER OUTPUT

ADCON1 = %00000100      ‘ SET ANALOGUE INPUT ON PORTA.0 PORTA.1 PORTA.3

”==========================================================”

 

‘ ”===========================================================”

”DS1307

SDA_Pin = PORTC.2 ‘DS1307 SDA pin

SCL_Pin =PORTC.3 ‘DS1307 SCL pin

Declare Slow_Bus On

 

 

Dim Secs As Byte

Dim Mins As Byte

Dim Hrs As Byte

Dim DayOfWeek As Byte

Dim date As Byte

Dim Month As Byte

Dim Year As Byte

Dim Ctrl As Byte

 

Dim Secs_last As Byte

 

‘ Set initial DS1307 time / Date

 

Secs = 0 ‘ Set seconds

Mins = 25 ‘ Set minutes

Hrs = 6 ‘ Set hours

 

DayOfWeek = 6 ‘ Set day of week value. 1=SUN 2=MON 3=TUE 4=WED 5=THU 6=FRI 7=SAT

 

date = 30 ‘ Day of month value

Month = 09 ‘ Month value

Year = 11 ‘ Year value. Last 2 digits. For 2011 enter 11

 

Ctrl = 0 ‘ Set the control byte (leave as 0 in this example)

 

Dim Num As Byte

Num = 0

 

Num = Hrs

GoSub DecToBcd

Hrs = Num

 

Dim AMPM As Bit

AMPM = 0

Hrs.6 = 1 ’12 hour mode

Hrs.5 = 1 ‘Set AM PM. 0=AM, 1=PM. Default is set to 0 AM

 

Num = Mins

GoSub DecToBcd

Mins = Num

 

Num = Secs

GoSub DecToBcd

Secs = Num

 

Num = DayOfWeek

GoSub DecToBcd

DayOfWeek = Num

 

Num = date

GoSub DecToBcd

date = Num

 

Num = Month

GoSub DecToBcd

Month = Num

 

Num = Year

GoSub DecToBcd

Year = Num

 

BStart

 

‘ The datasheet specifies the first byte is 1101000x where x is read(1) or write(0).

‘ The second byte tells the DS 1307 where to start reading, 0 is at the start.

‘ The Ctrl byte contains advanced features, read the datasheet for more info

BusOut 11010000, 0, [Secs, Mins, Hrs, DayOfWeek, date, Month, Year, Ctrl]

‘Write initial values for time / Date

 

BStop

 

DelayMS 20

 

Main:

 

BStart

‘ The datasheet specifies the first byte is 1101000x where x is read(1) or write(0).

‘ The second byte tells the DS 1307 where to start reading, 0 is at the start.

BusIn 11010001, 0, [Secs, Mins, Hrs, DayOfWeek, date, Month, Year, Ctrl]

 

BStop

 

‘ The DS1307 sends it data in BCD, therefore it must be changed to

‘ DEC so that it can be easily used (eg, print onto an LCD)

 

 

 

Num = Secs & $7F

GoSub BcdToDec

Secs = Num

 

Num = Mins

GoSub BcdToDec

Mins = Num

 

If Hrs.5 = 1 Then

AMPM = 1

Else

AMPM = 0

EndIf

 

Num = Hrs & $1F

GoSub BcdToDec

Hrs = Num

 

Num = DayOfWeek

GoSub BcdToDec

DayOfWeek = Num

 

Num = date

GoSub BcdToDec

date = Num

 

Num = Month

GoSub BcdToDec

Month = Num

 

Num = Year

GoSub BcdToDec

Year = Num

 

‘If there is update in Secs, display time and Date

If Secs – Secs_last = 0 Then GoTo Main

 

‘ The Dec2 modifier makes sure that each value will have 2 characters, eg 1 becomes 01

”’Print At 1,1,”Time: “,Dec2 Hrs, “:”, Dec2 Mins,”:”, Dec2 Secs

”’Print At 2,1,”Date: “, Dec2 Date, “-“, Dec2 Month, “-“, Dec2 Year

 

If AMPM = 1 Then

HRSOut “Time: “,Dec2 Hrs, “:”, Dec2 Mins,”:”, Dec2 Secs, ” PM”, 13,10

Else

HRSOut “Time: “,Dec2 Hrs, “:”, Dec2 Mins,”:”, Dec2 Secs, ” AM”, 13,10

EndIf

 

HRSOut “Date: “, Dec2 date, “/”, Dec2 Month, “/20″, Dec2 Year, ” :Day of week: “, Dec1 DayOfWeek, 13, 10

 

 

Secs_last = Secs

 

GoTo Main

 

 

DecToBcd:

Num = (Num / 10 * 16) + (Num // 10)

Return

 

BcdToDec:

Num = (Num / 16 * 10) + (Num // 16)

Return

 

 

 

”===========================================================”

 

Top


Find right speed for software serial of 12F675

Dim ax As Word
For ax = 10 To 150
SerOut GPIO.4, ax, [“Speed: “, Dec ax, 13,10]
DelayMS 10
Next ax


 

 

 

Top


 


 

 

Top


 


 

 

 

Top


 


 

 

Top


 


 

 

 

Top


 


 

 

Top


 


 

 

 

Top


 


 

 

 

 

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s