0% found this document useful (0 votes)
17 views3 pages

PIC12F508 Configuration and Code

This document contains C code for a PIC12F508 microcontroller, configuring its settings and defining pin assignments for controlling a relay and an LED. The main function implements a loop that monitors phase states, detects faults, and manages timing for toggling outputs based on the health of the system. It includes logic for blinking an LED and activating a relay based on the system's operational status.

Uploaded by

akshaybpatil575
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views3 pages

PIC12F508 Configuration and Code

This document contains C code for a PIC12F508 microcontroller, configuring its settings and defining pin assignments for controlling a relay and an LED. The main function implements a loop that monitors phase states, detects faults, and manages timing for toggling outputs based on the health of the system. It includes logic for blinking an LED and activating a relay based on the system's operational status.

Uploaded by

akshaybpatil575
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Python Code

1 #include <xc.h>
2
3 // Configuration bits for PIC12F508 (XC8 compiler)
4 #pragma config WDTE = ON // Watchdog Timer enabled
5 #pragma config FOSC = INTRC // Internal RC oscillator (~4 MHz)
6 #pragma config MCLRE = OFF // MCLR disabled (GP3 as input)
7
8 // Pin definitions
9 #define PIN_R (1 << 1) // GP1 - Phase R
10 #define PIN_Y (1 << 4) // GP4 - Phase Y
11 #define PIN_B (1 << 5) // GP5 - Phase B
12 #define PIN_RELAY (1 << 0) // GP0 - Relay control (high = active)
13 #define PIN_LED (1 << 2) // GP2 - Status LED (high = on)
14
15 #define CLRWDT() asm("clrwdt")
16
17 // Global variables (PIC12F508 has very limited RAM - these fit comfortably)
18 unsigned char time_no_toggle[3]; // 0=R, 1=Y, 2=B (ms since last toggle)
19 unsigned char same_time_ry = 0;
20 unsigned char same_time_rb = 0;
21 unsigned char same_time_yb = 0;
22 unsigned int healthy_time = 0; // ms of continuous healthy state
23 unsigned char blink_state = 0;
24 unsigned int blink_timer = 0;
25 unsigned char last_phases = 0;
26 unsigned char current_phases = 0;
27 unsigned char last_tmr0 = 0;
28 unsigned int us_accumulator = 0; // Accumulates microseconds for 1 ms
ticks
29
30 void main(void)
31 {
32 // Calibrate internal oscillator using factory value
33 OSCCAL = __osccal_val();
34
35 // Configure TMR0: no prescaler on TMR0 (increments every instruction cy
cle ~1 µs),
36 // prescaler assigned to WDT with 1:128 ratio for longer WDT timeout
37 OPTION = 0b00001111; // PSA=1 (prescaler to WDT), PS2:0=111 (1:128), TO
CS=0 (internal clock)
38
39 // Configure GPIO directions (1 = input, 0 = output)
40 // GP5(in), GP4(in), GP3(in/don't care), GP2(out), GP1(in), GP0(out)
41 TRISGPIO = 0b00111010;
42
43 // Initialise outputs off
44 GPIO &= ~(PIN_RELAY | PIN_LED);
45
46 // Initialise TMR0 reading
47 last_tmr0 = TMR0;
48
49 // Read initial phase states to avoid spurious "toggles" on startup
50 current_phases = ((GPIO & PIN_R) ? 1 : 0) |
51 ((GPIO & PIN_Y) ? 2 : 0) |
52 ((GPIO & PIN_B) ? 4 : 0);
53 last_phases = current_phases;
54
55 // Main infinite loop
56 while (1)
57 {
58 CLRWDT();
59
60 // ----- Accurate microsecond timing using TMR0 -----
61 unsigned char curr_tmr = TMR0;
62 char delta = (char)(curr_tmr - last_tmr0);
63 if (delta < 0) delta += 256;
64 us_accumulator += (unsigned char)delta;
65 last_tmr0 = curr_tmr;
66
67 // ----- Update current phase logic levels -----
68 current_phases = ((GPIO & PIN_R) ? 1 : 0) |
69 ((GPIO & PIN_Y) ? 2 : 0) |
70 ((GPIO & PIN_B) ? 4 : 0);
71
72 // ----- Detect toggles and reset no-toggle timers -----
73 unsigned char changed = current_phases ^ last_phases;
74 if (changed & 1) time_no_toggle[0] = 0; // R toggled
75 if (changed & 2) time_no_toggle[1] = 0; // Y toggled
76 if (changed & 4) time_no_toggle[2] = 0; // B toggled
77 last_phases = current_phases;
78
79 // ----- Process 1 ms ticks -----
80 while (us_accumulator >= 1000)
81 {
82 us_accumulator -= 1000;
83
84 // Increment no-toggle timers (cap at 255)
85 if (time_no_toggle[0] < 255) time_no_toggle[0]++;
86 if (time_no_toggle[1] < 255) time_no_toggle[1]++;
87 if (time_no_toggle[2] < 255) time_no_toggle[2]++;
88
89 // Extract current logic levels
90 unsigned char r = current_phases & 1;
91 unsigned char y = (current_phases >> 1) & 1;
92 unsigned char b = (current_phases >> 2) & 1;
93
94 // Update same-phase timers
95 if (r == y) {
96 if (same_time_ry < 255) same_time_ry++;
97 } else {
98 same_time_ry = 0;
99 }
100 if (r == b) {
101 if (same_time_rb < 255) same_time_rb++;
102 } else {
103 same_time_rb = 0;
104 }
105 if (y == b) {
106 if (same_time_yb < 255) same_time_yb++;
107 } else {
108 same_time_yb = 0;
109 }
110
111 // Detect faults
112 bit missing_phase = (time_no_toggle[0] > 25) ||
113 (time_no_toggle[1] > 25) ||
114 (time_no_toggle[2] > 25);
115 bit same_phase_fault = (same_time_ry > 15) ||
116 (same_time_rb > 15) ||
117 (same_time_yb > 15);
118 bit fault = missing_phase | same_phase_fault;
119
120 // Healthy duration counter (reset on any fault)
121 if (fault) {
122 healthy_time = 0;
123 } else {
124 if (healthy_time < 2000) healthy_time++; // Cap to prevent
overflow
125 }
126
127 // 2 Hz blink timer (~250 ms period, 50% duty)
128 blink_timer++;
129 if (blink_timer >= 250) {
130 blink_timer = 0;
131 blink_state ^= 1;
132 }
133 }
134
135 // ----- Set outputs -----
136 bit relay_on = (!fault && healthy_time >= 1000);
137
138 if (relay_on) {
139 GPIO |= PIN_RELAY; // Relay active
140 } else {
141 GPIO &= ~PIN_RELAY; // Relay off
142 }
143
144 bit led_on = relay_on ? 1 : blink_state; // Solid when healthy, bli
nk when fault
145
146 if (led_on) {
147 GPIO |= PIN_LED;
148 } else {
149 GPIO &= ~PIN_LED;
150 }
151 }
152 }

You might also like