Greetings!
I recently tried to rework uSupply rev.c with my own code and i took the schematics and created new code for my Atmega16A so that it operates my power supply. But I dunno why my while(1) loop doesn't start. please check my code and help me please because something wrong with my code.
Notes:
1- Micro-controller: ATMEGA16A.
2- Clock speed: 16MHz.
3- LFuse: 0xFF
4- HFuse: 0xD9
5- EEVBLOG uSupply Rev.c (for people who doesn't know and will start saying things i don't like).
6- Rework done: (for people who like to talk much).
A- Changed how the unit main voltage power rail to an offline transformer and a dc plug-in.
B- Changed the LCD to 16x2.
C- Eliminated the Ethernet, The Rotary and the DAC.
7- Inspection done to Hardware and the result is WORKING!.
8- I don't have a debugging tool.
9- Please be subjective and don't just insult or attack with words.
Thanks!!!
PSU.c:
#include <\Power Supply\Program\PSU\PSU\MrLCD.h> #include <\Power Supply\Program\PSU\PSU\PSU.h> volatile int global = 0; //Variable for buttons selection 0=idle, 1=set button active, 2=start button active and 3=stop button active volatile int setstatus = 0; //Variable for "Set" button selection (Multi-function Button) volatile int devicestatus = 0; //Variable for working condition of the device 0=idle, 1=on and 2=off volatile double vsetp = 0.00; //Variable for Voltage Pot volatile double isetp = 0.00; //Variable for Current Pot volatile double vref = 5.81; //AVCC of Atmega16 volatile double vsetgain = 4; //Voltage gain of voltage selection Op-Amp volatile double maxcurrent = 3.50; //Max current allowed volatile double regref = 1.25; //Voltage ref of voltage regulator volatile double mainvolt = 00.0; //Main voltage volatile double voltout = 00.00; //Voltage output volatile double Currentout = 00.00; //Current Output volatile double mainvoltdividerratio = 5.125; //Resistor voltage divider ratio for main voltage volatile double voltoutdividerratio = 4.375; //Resistor Voltage divider ratio for output voltage volatile uint16_t adc_result; //Variable for ADC read int main(void) { sei(); // Enable Interrupt InitializeMrLCD(); //initialization LCD InitADC(); //initialization of ADC Enable_Interface(); // Setting bits for buttons and leds while(1) { if(BON_PORT & (1<<BON)) //Check if On/Off button is activated { if(devicestatus == 0) //check if device condition is idle { devicestatus = 1; //set device condition to ON } else if(devicestatus == 1) //check if device condition is already ON { devicestatus = 2; //set device condition to OFF } else { devicestatus = 0; //set device condition to idle } } switch(devicestatus) //switch statements for device condition { case 0: //Idle clearBit(RELAY_PORT, RELAY); //Close Output relay break; case 2: //OFF Enable_OffLED(); Disable_Interrupts(); Disable_PWM(); clearBit(RELAY_PORT, RELAY); clearBit(OVERLED_PORT, OVERLED); Send_A_StringToMrLCDWithLocation(5, 1, "Tronix"); Send_A_StringToMrLCDWithLocation(2, 2, "Power Supply"); Send_A_Command(0x18); Send_A_Command(0x01); Send_A_Command(0x08); break; case 1: //ON Enable_OnLED(); Enable_Interrupts(); Send_A_Command(0x0C); Send_A_StringToMrLCDWithLocation(5, 1, "Tronix"); Send_A_StringToMrLCDWithLocation(2, 2, "Power Supply"); Send_A_Command(0x1C); adc_result = ReadADC(0xC0); mainvolt = ((adc_result * vref)/1024)*mainvoltdividerratio; Send_A_StringToMrLCDWithLocation(2, 1, "Main Voltage"); Send_An_DoubleToMrLCD(6, 2, mainvolt, 4); Send_A_Command(0x01); Send_A_StringToMrLCDWithLocation(1 ,1, "VSet:00.00 00.00"); Send_A_StringToMrLCDWithLocation(1 ,2, "ISet:00.00 00.00"); break; switch(global) { case 1: //Set button is active clearBit(RELAY_PORT, RELAY); clearBit(OVERLED_PORT, OVERLED); Disable_PWM(); switch(setstatus) { case 1: //Voltage Set while(setstatus == 1) { adc_result = ReadADC(0xC3); vsetp = ((adc_result * vref)/1024)*vsetgain; GotoMrLCDsLocation(6, 1); Send_A_Command(0x0E); Send_An_DoubleToMrLCD(6, 1, vsetp, 5); } break; case 2: //Current Set while(setstatus == 2) { adc_result = ReadADC(0xC4); isetp = ((adc_result * vref)/1024); if(isetp > maxcurrent) { isetp = maxcurrent; } GotoMrLCDsLocation(6, 2); Send_A_Command(0x0E); Send_An_DoubleToMrLCD(6, 2, isetp, 5); } break; case 0: //Idle condition Send_A_Command(0x08); Send_A_Command(0x0C); } break; case 2: // Start button is active OCR1A = ICR1 - (((vsetp - regref)/vsetgain)/5)*ICR1; OCR1B = ICR1 - (isetp/5)*ICR1; Enable_PWM(); Send_A_Command(0x0C); setBit(RELAY_PORT, RELAY); while (setstatus == 2) { if(!(CLIM_PORT & (1<<CLIM))) //Check over current pin { setBit(OVERLED_PORT, OVERLED); //Light over current led adc_result = ReadADC(0xC1); voltout = ((adc_result * vref)/1024)*voltoutdividerratio; Send_An_DoubleToMrLCD(12, 1, voltout, 5); adc_result = ReadADC(0xC2); Currentout = ((adc_result * vref)/1024); Send_An_DoubleToMrLCD(12, 2, Currentout, 5); } else { clearBit(OVERLED_PORT, OVERLED); adc_result = ReadADC(0xC1); voltout = ((adc_result * vref)/1024)*voltoutdividerratio; Send_An_DoubleToMrLCD(12, 1, voltout, 5); adc_result = ReadADC(0xC2); Currentout = ((adc_result * vref)/1024); Send_An_DoubleToMrLCD(12, 2, Currentout, 5); } } break; case 0: //Stop button is active clearBit(RELAY_PORT, RELAY); Disable_PWM(); clearBit(OVERLED_PORT, OVERLED); break; } } } } ISR(INT0_vect) // INT for Set button { global = 1; if(setstatus == 0) { setstatus = 1; } else if(setstatus == 1) { setstatus = 2; } else { setstatus = 0; } } ISR(INT1_vect) //INT for start button { global = 2; } ISR(INT2_vect) //INT for stop button { global = 0; }
PSU.h:
#include <avr/interrupt.h> #define BSTOP PB2 //Stop button #define BSTOP_DDR DDRB #define BSTOP_PORT PORTB #define BON PB4 //On/Off Button #define BON_DDR DDRB #define BON_PORT PORTB #define OVERLED PD7 //Over Current Led #define OVERLED_DDR DDRD #define OVERLED_PORT PORTD #define CLIM PD6 //Over Current Op-Amp Output #define CLIM_DDR DDRD #define CLIM_PORT PORTD #define BSTART PD3 //Start Button #define BSTART_DDR DDRD #define BSTART_PORT PORTD #define BSET PD2 /Set Button #define BSET_DDR DDRD #define BSET_PORT PORTD #define RELAY PD1 //Relay Transistor #define RELAY_DDR DDRD #define RELAY_PORT PORTD #define ONOFFLED PD0 //On Led #define ONOFFLED_DDR DDRD #define ONOFFLED_PORT PORTD #define VSET PD5 //PWM Pin for Voltage Op-Amp #define VSET_DDR DDRD #define VSET_PORT PORTD #define ISET PD4 //PWM pin for Current Op-Amp #define ISET_DDR DDRD #define ISET_PORT PORTD #define setBit(sfr, bit) (_SFR_BYTE(sfr) |= (1 << bit)) #define clearBit(sfr, bit) (_SFR_BYTE(sfr) &= ~(1 << bit)) #define toggleBit(sfr, bit) (_SFR_BYTE(sfr) ^= (1 << bit)) #define PWMSpeed 8000 //PWM Speed void Enable_Interface(void); //Set Button directions High or Low void Enable_Interrupts(void); // Set INT void Enable_OffLED(void); //Enable On LED void Enable_OnLED(void); void Disable_Interrupts(void); void InitADC(void); uint16_t ReadADC(uint8_t ch); void Enable_PWM(void); void Disable_PWM(void); void Enable_Interface() { clearBit(BON_DDR, BON); setBit(ONOFFLED_DDR, ONOFFLED); clearBit(BSTOP_DDR, BSTOP); //Enable Stop Button clearBit(BSTOP_PORT, BSTOP); setBit(OVERLED_DDR, OVERLED); //Enable Over-Current Led clearBit(OVERLED_PORT, OVERLED); clearBit(CLIM_DDR, CLIM); //Enable Over--Current Sense setBit(CLIM_PORT, CLIM); clearBit(BSTART_DDR, BSTART); //Enable Start Button clearBit(BSTART_PORT, BSTART); clearBit(BSET_DDR, BSET); //Enable Set Button clearBit(BSET_PORT, BSET); setBit(RELAY_DDR, RELAY); //Enable Relay Control setBit(VSET_DDR, VSET); //Enable VSET PWM setBit(ISET_DDR, ISET); //Enable ISET PWM } void Enable_Interrupts() { MCUCR = (1 << ISC11) | (1 << ISC10) | (1 << ISC01) | (1 << ISC00); //Set Interrupts to work on Raising Edge for INT0 and INT1 MCUCSR = (1 << ISC2); //Set Interrupts to work on Raising Edge for INT2 GICR = (1 << INT1) | (1 <<INT0) | (1 << INT2); //Enable Interrupts } void Enable_OffLED() { clearBit(ONOFFLED_PORT, ONOFFLED); } void Enable_OnLED() { setBit(ONOFFLED_PORT, ONOFFLED); } void Disable_Interrupts() { GICR &= ~(1 << INT1) | ~(1 <<INT0) | ~(1 << INT2); //Disable Interrupts } void InitADC() { ADMUX |= (1<<REFS0); ADCSRA |= (1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); } uint16_t ReadADC(uint8_t ch) { ch = ch & 0b01011111; ADMUX = ch; ADCSRA |= (1<<ADSC); while(!(ADCSRA & (1<<ADIF))); ADCSRA |= (1<<ADIF); return(ADC); } void Enable_PWM() { TCCR1A |= (1<<WGM11) | (1<<COM1A1) | (1<<COM1A0) | (1<<COM1B1) | (1<<COM1B0); TCCR1B |= (1<<WGM13) | (1<<WGM12) | (1<<CS10); ICR1 = (F_CPU / PWMSpeed); } void Disable_PWM() { TCCR1B &= ~(1<<CS10); }
MrLCD.h:
#define F_CPU 16000000L #include <avr/io.h> #include <util/delay.h> #include <stdlib.h> #define MrLCDsCrib PORTC #define DataDir_MrLCDsCrib DDRC #define MrLCDsControl PORTB #define DataDir_MrLCDsControl DDRB #define LightSwitch PB0 #define ReadWrite PB1 #define BiPolarMood PB3 char firstColumnPositionsForMrLCD[4] = {0, 64, 20, 84}; void Check_IF_MrLCD_isBusy(void); void Peek_A_Boo(void); void Send_A_Command(unsigned char command); void Send_A_Character(unsigned char character); void Send_A_String(char *StringOfCharacters); void GotoMrLCDsLocation(uint8_t x, uint8_t y); void Send_A_StringToMrLCDWithLocation(uint8_t x, uint8_t y, char *StringOfCharacters); void Send_An_DoubleToMrLCD(uint8_t x, uint8_t y, double DoubleToDisplay, char NumberOfDigits); void InitializeMrLCD(void); void Check_IF_MrLCD_isBusy() { DataDir_MrLCDsCrib = 0; MrLCDsControl |= 1<<ReadWrite; MrLCDsControl &= ~1<<BiPolarMood; while (MrLCDsCrib >= 0x80) { Peek_A_Boo(); } DataDir_MrLCDsCrib = 0xFF; //0xFF means 0b11111111 } void Peek_A_Boo() { MrLCDsControl |= 1<<LightSwitch; asm volatile ("nop"); asm volatile ("nop"); MrLCDsControl &= ~1<<LightSwitch; } void Send_A_Command(unsigned char command) { Check_IF_MrLCD_isBusy(); MrLCDsCrib = command; MrLCDsControl &= ~ ((1<<ReadWrite)|(1<<BiPolarMood)); Peek_A_Boo(); MrLCDsCrib = 0; } void Send_A_Character(unsigned char character) { Check_IF_MrLCD_isBusy(); MrLCDsCrib = character; MrLCDsControl &= ~ (1<<ReadWrite); MrLCDsControl |= 1<<BiPolarMood; Peek_A_Boo(); MrLCDsCrib = 0; } void Send_A_String(char *StringOfCharacters) { while(*StringOfCharacters > 0) { Send_A_Character(*StringOfCharacters++); } } void GotoMrLCDsLocation(uint8_t x, uint8_t y) { Send_A_Command(0x80 + firstColumnPositionsForMrLCD[y-1] + (x-1)); } void Send_A_StringToMrLCDWithLocation(uint8_t x, uint8_t y, char *StringOfCharacters) { GotoMrLCDsLocation(x, y); Send_A_String(StringOfCharacters); } void Send_An_DoubleToMrLCD(uint8_t x, uint8_t y, double DoubleToDisplay, char NumberOfDigits) { char StringToDisplay[NumberOfDigits]; dtostrf(DoubleToDisplay, NumberOfDigits, 2, StringToDisplay); Send_A_StringToMrLCDWithLocation(x, y, StringToDisplay); Send_A_String(" "); } void InitializeMrLCD() { DataDir_MrLCDsControl |= 1<<LightSwitch | 1<<ReadWrite | 1<<BiPolarMood; _delay_ms(15); Send_A_Command(0x01); //Clear Screen 0x01 = 00000001 _delay_ms(2); Send_A_Command(0x38); _delay_us(50); Send_A_Command(0b00001110); _delay_us(50); }
Best Regards
Ahmed Hamdy