Hello I am new to this world of microcontrollers and programming. I am not a programmer at all. I just want it to write code for my fun and needs, but
I have the issues to get this code running and I do not know how to properly debug. I am using PICKIT3,5 with MPLAB X IDE 6.15 and XC8 compiler.
For simulation I am using SimuliDE and I can use real components on breadbord.
Just the brief description, what this code should do. Turn the LED on/off, by the long press as it´s written in the code. With the short press to cycle thrue POWER levels. It´s also checking the temperature of the LED from the analog sensor LM35, and when the temperature reach set limits it will deploy temperature derating. Checking battery supply voltage for battery protection. LED is controlled by the PWM. PWM output pin is connected to the mosfet, which will control the LED by the switching current. And that´s it.
Thank you for any help
I have the issues to get this code running and I do not know how to properly debug. I am using PICKIT3,5 with MPLAB X IDE 6.15 and XC8 compiler.
For simulation I am using SimuliDE and I can use real components on breadbord.
Just the brief description, what this code should do. Turn the LED on/off, by the long press as it´s written in the code. With the short press to cycle thrue POWER levels. It´s also checking the temperature of the LED from the analog sensor LM35, and when the temperature reach set limits it will deploy temperature derating. Checking battery supply voltage for battery protection. LED is controlled by the PWM. PWM output pin is connected to the mosfet, which will control the LED by the switching current. And that´s it.
C:
#include <xc.h>
#include <stdint.h>
// Function prototypes
void initialize();
void setPWM(uint8_t dutyCycle);
uint16_t readADC(uint8_t channel);
uint16_t readTemperature();
uint16_t readBatteryVoltage();
void handleTemperature();
void handleLowBattery();
// Configuration settings for the PIC12F683
#pragma config FOSC = INTOSCIO, WDTE = OFF, PWRTE = ON, MCLRE = OFF, CP = OFF, BOREN = OFF
#define _XTAL_FREQ 2000000 // Oscillator frequency for delay calculations
// Pin definitions
#define LED_PIN 0x04 // LED connected to GP2
#define BUTTON_PIN 0x08 // Button connected to GP5
#define TEMP_CHANNEL GP0 // ADC channel for temperature sensor, connected to GP0
// State definitions
#define STATE_OFF 0
#define STATE_ON 1
#define STATE_LOW_VOLTAGE 2
// Timing definitions
#define LONG_PRESS_TIME 1500 // ms, for turning LED on/off
#define SHORT_PRESS_TIME 1000 // ms, for changing LED power level
#define DEBOUNCE_TIME 100 // ms, debounce time for button press
#define BLINK_INTERVAL 500 // ms, not used in this version
// Button states
#define BUTTON_RELEASED 1
#define BUTTON_PRESSED 0
// LED power levels (PWM duty cycle as a percentage of 255)
#define POWER_OFF 0
#define POWER_10 26
#define POWER_20 51
#define POWER_25 64
#define POWER_50 128
#define POWER_75 192
#define POWER_90 230
#define POWER_100 255
// Adjusted temperature limits (ADC values)
#define TEMP_50 122
#define TEMP_60 146
#define TEMP_70 171
#define TEMP_80 195
// Global variables
volatile uint16_t timer = 0; // Incremented by ISR, used for timing
uint8_t state = STATE_OFF; // Current state of the system
uint8_t powerLevel = POWER_25; // Current power level of LED
uint8_t lowVoltageMode = 0; // Flag for low voltage mode
uint16_t lowVoltageTimer = 0; // Timer for low voltage mode, incremented by ISR
// Interrupt Service Routine for Timer0
void __interrupt() ISR() {
if (T0IF) { // Check Timer0 overflow flag
T0IF = 0; // Clear Timer0 interrupt flag
TMR0 = 6; // Reset Timer0 for next interrupt
timer++; // Increment global timer
if (lowVoltageMode && state == STATE_LOW_VOLTAGE) {
lowVoltageTimer++; // Increment low voltage timer if in low voltage mode
}
}
}
// Set PWM duty cycle for LED brightness
void setPWM(uint8_t dutyCycle) {
CCPR1L = dutyCycle; // Set upper 8 bits of duty cycle
}
// Initialize system configuration
void initialize() {
// Initialize I/O
TRISIO = 0b00100001; // Set GP2 as output, GP5 and GP0 as input
GPIO = 0; // Turn off all pins initially
// Initialize ADC
ANSEL = 0b00000001; // Set GP0 as analog input
ADCON0 = 0b00000001; // Enable ADC, select channel AN0, use Fosc/8
// Initialize Timer0 for timing
OPTION_REG = 0b00000111; // Prescaler 1:256 for Timer0
TMR0 = 6; // Set Timer0 for 1ms interrupts
T0IE = 1; // Enable Timer0 interrupts
// Initialize PWM for LED control
CCP1CON = 0b00001100; // PWM mode
PR2 = 255; // PWM period
T2CON = 0b00000101; // Enable Timer2, prescaler 1:4
// Set initial PWM duty cycle to 0 (LED off)
CCPR1L = 0;
setPWM(POWER_OFF); // Set PWM duty cycle to 0%
// Enable global interrupts
GIE = 1;
PEIE = 1;
}
// Read ADC value from specified channel
uint16_t readADC(uint8_t channel) {
ADCON0 = ((uint8_t)(channel << 3) | 1); // Select ADC channel
__delay_us(10); // Delay for ADC settling
GO_DONE = 1; // Start conversion
while (GO_DONE); // Wait for conversion to complete
return (uint16_t)((ADRESH << 8) + ADRESL); // Return ADC result
}
// Read temperature from sensor
uint16_t readTemperature() {
return readADC(TEMP_CHANNEL); // Read ADC value from temperature channel
}
// Read battery voltage
uint16_t readBatteryVoltage() {
uint16_t adcValue = readADC(1); // Assume channel AN1 for battery voltage
return (uint16_t)(((uint32_t)adcValue * 4200) / 1023); // Convert ADC value to voltage
}
// Handle button presses to change LED power level or toggle state
void checkButton() {
static uint16_t lastButtonPress = 0;
static uint8_t buttonState = BUTTON_RELEASED;
uint8_t currentButtonState = BUTTON_PIN;
if (currentButtonState == BUTTON_PRESSED && buttonState == BUTTON_RELEASED) {
lastButtonPress = timer;
buttonState = BUTTON_PRESSED;
} else if (currentButtonState == BUTTON_RELEASED && buttonState == BUTTON_PRESSED) {
uint16_t buttonPressDuration = timer - lastButtonPress;
if (buttonPressDuration >= LONG_PRESS_TIME) {
// Toggle system state on long press
state = (state == STATE_OFF) ? STATE_ON : STATE_OFF;
powerLevel = (state == STATE_ON) ? POWER_25 : POWER_OFF;
} else if (buttonPressDuration >= SHORT_PRESS_TIME && state == STATE_ON) {
// Cycle power levels on short press, only if system is on
switch (powerLevel) {
case POWER_25: powerLevel = POWER_50; break;
case POWER_50: powerLevel = POWER_75; break;
case POWER_75: powerLevel = POWER_90; break;
case POWER_90: powerLevel = POWER_100; break;
case POWER_100: powerLevel = POWER_25; break;
default: powerLevel = POWER_25; break;
}
}
buttonState = BUTTON_RELEASED;
}
}
// Adjust LED power level based on temperature to prevent overheating
void applyTemperatureDerating(uint16_t temperature) {
if (temperature > TEMP_80) powerLevel = POWER_50;
else if (temperature > TEMP_70) powerLevel = POWER_75;
else if (temperature > TEMP_60) powerLevel = POWER_90;
}
// Handle low voltage condition by reducing LED power level
void handleLowVoltage(uint16_t voltage) {
if (voltage < 3300) {
state = STATE_LOW_VOLTAGE;
lowVoltageMode = 1;
lowVoltageTimer = 0;
} else if (voltage < 3400) powerLevel = POWER_10;
else if (voltage < 3500) powerLevel = POWER_20;
}
// Main loop
void main() {
initialize();
while(1) {
checkButton(); // Independently check button state
if (state == STATE_ON) {
uint16_t temperature = readTemperature();
uint16_t batteryVoltage = readBatteryVoltage();
applyTemperatureDerating(temperature);
handleLowVoltage(batteryVoltage);
setPWM(powerLevel); // Set LED power level
} else {
setPWM(POWER_OFF); // Turn off LED if not in STATE_ON
}
}
}
Thank you for any help