Skip to main content

#@$%

  1.  
  2. #include  "msp430x21x2.h"
  3.  
  4.  
  5. #define PWM_OUTPUT              0x03
  6. #define DUTY_CYCLE              TA0CCR2
  7. #define MAX_LIMIT               300
  8.  
  9. /*
  10. #define no_of_samples           1
  11. #define duty_cycle_limit        1000
  12. #define temp_sensor             0xA000
  13.  
  14. #define panel_selection_cutoff  250
  15. */
  16. #define PV_VOLTAGE              INCH_0
  17. #define PV_CURRENT              INCH_1
  18. #define BATT_VOLTAGE            INCH_2
  19. #define BATT_CURRENT            INCH_3
  20.  
  21. #define UPPER_CRG_LVL           0x0105 // 0x00FF // 0x00F5 //0x023A
  22. #define LOWER_CRG_LVL           0x00FA // 0x00F5// 0x00EA// 0x00DA
  23. #define UPPER_DIFF              2//0x10
  24. #define LOWER_DIFF              0//0x05
  25.  
  26. #define UPPER_CUTOFF            0x00C8 // 0x00BF // 0x00B0
  27. #define LOWER_CUTOFF            0x00B8 // 0x00AE // 0x00A2
  28. #define SHORT_CKT_CURRENT       0x01C0 //for 750 mA //0x0085  for 550 mA
  29.  
  30. #define MAX_CURRENT_LIMIT       0x0310
  31.  
  32. #define POOR_BATTERY_VOLTAGE    0x00C5 // 0x00B8 // 0x00A8    //0x00AA for 6.75V
  33.  
  34. #define RED_INDICATOR           0x04
  35. #define YELLOW_INDICATOR        0x02
  36. #define GREEN_INDICATOR         0x01
  37. #define LOAD_RELAY              0x08
  38.  
  39. #define TRICLE_CKT              0//0x01
  40. #define TURN_OFF_CKT            4//0x10
  41. #define SHORT_CKT               5//0x20
  42. #define POOR_INDICATION         7//0x80
  43.  
  44. unsigned int  tricle_level =    LOWER_CRG_LVL;
  45. unsigned int  tricle_indicator_counter;
  46. unsigned char tricle_circuit = 0;
  47. unsigned char pannel_cutoff_voltage = 40;
  48. unsigned int load_switching_voltage  = LOWER_CUTOFF;
  49.  
  50.  
  51. unsigned int previous_panel_voltage;
  52. unsigned int previous_panel_current;
  53. unsigned int recent_panel_voltage;
  54. unsigned int recent_panel_current;
  55.  
  56. unsigned long recent_panel_power;
  57. unsigned long previous_panel_power;
  58.  
  59. int panel_voltage_difference;
  60. int panel_current_difference;
  61. long panel_power_difference;
  62. double incremental_conductance;
  63. double instantanious_conductance;
  64.  
  65. unsigned int battery_voltage;
  66. unsigned int battery_current;
  67.  
  68. unsigned int temperature;                                 //20 degC - 0x02E1, 32deg - 0x02EB, 50 deg - 0x02FA
  69. unsigned int adc_result;
  70. unsigned int sensor_voltage;
  71.  
  72.  
  73. unsigned char transmit_buffer[16] = {0xAA,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  74. unsigned char transmision_index = 0;
  75.  
  76. unsigned char boolean_bits = 0x00;
  77.  
  78. unsigned char discharge_ckt_off = 0;
  79. unsigned char short_ckt_active = 0;
  80. unsigned char discharge_ckt_on_counter = 0;
  81. unsigned char discharge_ckt_off_counter = 0;
  82. unsigned char short_ckt_on_counter = 0;
  83. unsigned char short_ckt_off_counter = 0;
  84.  
  85. unsigned char tricle_ckt_on_counter = 0;
  86. unsigned char tricle_ckt_off_counter = 0;
  87.  
  88. unsigned int poor_indication_counter = 0;
  89. unsigned char poor_indication_decision_counter = 0;
  90.  
  91. unsigned int i;
  92. unsigned int j;
  93.  
  94.  
  95. #pragma vector = TIMER1_A0_VECTOR
  96. __interrupt void ISR_TIMER1_A0()
  97. {
  98.         if(boolean_bits&(1<<TRICLE_CKT))
  99.         {
  100.                 tricle_indicator_counter ++;           
  101.         }
  102.        
  103.         if(boolean_bits&(1<<POOR_INDICATION))
  104.         {
  105.                 poor_indication_counter ++;          
  106.         }      
  107.        
  108. }
  109.  
  110.  
  111. #pragma vector=USCIAB0TX_VECTOR
  112. __interrupt void USCI0TX_ISR(void)
  113. {  
  114.   UCA0TXBUF = transmit_buffer[transmision_index];
  115.  
  116.   if(transmision_index >= 15)
  117.   {
  118.     transmision_index = 0;
  119. //    UCSRB &= ~(1<<TXEN);
  120.   }
  121.   else transmision_index ++;
  122. }
  123.  
  124.  
  125. void initialize_TimerA0()
  126. {
  127.   TA0CCR0  = MAX_LIMIT;                         // PWM Period
  128.  
  129.   TA0CCTL2 = OUTMOD_7;                          // CCR1 Reset/Set
  130.   TA0CCR2  = 180;                               // CCR1 PWM duty cycle  
  131.   TA0CTL   = TASSEL_2 + MC_1;                   // SMCLK, up mode
  132. }
  133.  
  134. void initialize_TimerA1()                       // Timer setup
  135. {
  136.   TA1CCR0  = 40000;//55556;                            
  137.   TA1CCTL0 = 0x0010;                            
  138.   TA1CTL   = TASSEL_2 + MC_3;                   // SMCLK, up/down mode
  139. }
  140.  
  141. void initialize_UART()
  142. {
  143.   P3SEL |= 0x10;                                // P3.4,5 = USCI_A0 TXD/RXD
  144.   P3DIR |= 0x10;                                // All P3.x outputs
  145.   P3OUT = 0;                                    // All P3.x reset
  146.  
  147.   UCA0CTL1 |= UCSSEL_2;                     // SMCLK
  148.   UCA0BR0 = 0x83; //226;                            // 12MHz 9600
  149.   UCA0BR1 = 0x06; //4;                              // 12MHz 9600
  150. //  UCA0MCTL = UCBRS0;                        // Modulation UCBRSx = 1
  151.   UCA0CTL1 &= ~UCSWRST;                     // **Initialize USCI state machine**
  152.   IE2 |= UCA0TXIE;                          // Enable USCI_A0 TX interrupt
  153.  
  154. }
  155.  
  156. void initialize_ADC10()
  157. {
  158.   ADC10CTL0 =  SREF_1 + ADC10SHT_2 + REFON;// + ADC10IE;                     // + ADC10SR + REF2_5V + REFOUT     1.5V Reference
  159. //  ADC10CTL1 = (ADC10DIV_0 | ADC10SSEL_1);
  160. }
  161.  
  162. unsigned int get_ADC_Data(unsigned int channel_no)
  163. {
  164.  unsigned char a;
  165.  adc_result = 0;
  166.  
  167. // ADC10CTL1 |= channel_no;
  168.  ADC10CTL0 |= ADC10ON;
  169.  
  170.  for(a=0;a<8;a++)
  171.  {
  172.     while(ADC10CTL1 & ADC10BUSY);
  173.     ADC10CTL0 &= ~ENC;
  174. //    ADC10CTL1 = channel_no + ADC10SSEL_1;                                   //  + ADC10DIV_4    
  175.     ADC10CTL1 = channel_no + ADC10DIV_7 + ADC10SSEL_3;                                  
  176.        
  177.     switch(channel_no)
  178.     {
  179.         case INCH_0:    ADC10AE0 = 0x01;                               
  180.                         break;
  181.         case INCH_1:    ADC10AE0 = 0x02;                               
  182.                         break; 
  183.         case INCH_2:    ADC10AE0 = 0x04;                               
  184.                         break;
  185.         case INCH_3:    ADC10AE0 = 0x08;                               
  186.                         break; 
  187.         case INCH_4:    ADC10AE0 = 0x10;                               
  188.                         break;
  189.         case INCH_5:    ADC10AE0 = 0x20;                               
  190.                         break; 
  191.         case INCH_6:    ADC10AE0 = 0x40;                               
  192.                         break;
  193.         case INCH_7:    ADC10AE0 = 0x80;                               
  194.                         break; 
  195.         default    :    ADC10AE0 = 0x00;
  196.                         break;
  197.     }
  198.    
  199.     ADC10CTL0 |= ENC + ADC10SC;
  200.  
  201.     while((ADC10CTL0 & ADC10IFG)==0);
  202.     ADC10CTL0 &= ~ADC10IFG;
  203.    
  204.     adc_result += ADC10MEM;
  205.  }
  206.  
  207.   ADC10CTL0 &= ~ADC10ON;
  208.   adc_result = (adc_result >> 3);
  209.  
  210.   ADC10CTL1 &= ~channel_no;
  211.  
  212.   return adc_result;    
  213. }
  214.  
  215. void main (void)
  216. {
  217. //  unsigned char observation_counter = 0;
  218.  
  219.    
  220.   WDTCTL = WDTPW + WDTHOLD;                     // Stop WDT
  221.  
  222.   DCOCTL  = 0x93; //CALDCO_16MHZ;
  223.   BCSCTL1 = 0x8F; //CALBC1_16MHZ;               // Set range for max frequency  
  224.  
  225. //  DCOCTL  = 0x81; //CALDCO_12MHZ;
  226. //  BCSCTL1 = 0x8E; //CALBC1_12MHZ;             // Set range for max frequency  
  227.  
  228.   P1DIR = 0x80;                                 // P1.7 PWM output
  229.   P1SEL = 0x80;
  230.  
  231.   P2DIR = 0x00;
  232.  
  233.   P3DIR = (RED_INDICATOR | GREEN_INDICATOR | YELLOW_INDICATOR | LOAD_RELAY);
  234.   P3OUT &= ~(RED_INDICATOR | GREEN_INDICATOR | YELLOW_INDICATOR | LOAD_RELAY);
  235.    
  236.   initialize_TimerA0();
  237.   initialize_TimerA1();
  238.  
  239.   initialize_UART();
  240.   initialize_ADC10();
  241.  
  242.   __bis_SR_register(GIE);
  243.  
  244.  
  245.   P3OUT |= GREEN_INDICATOR;
  246.  
  247.   for(i=0;i<4000;i++)
  248.     for(j=0;j<1000;j++);
  249.  
  250. //  P3OUT &= ~GREEN_INDICATOR;
  251.  
  252.   while(1)                                
  253.   {
  254.        for(i=0;i<800;i++)
  255.         for(j=0;j<1000;j++);
  256.                      
  257. //      sensor_voltage  = get_ADC_Data(BATT_VOLTAGE);        
  258.  
  259.        
  260.         recent_panel_voltage = get_ADC_Data(PV_VOLTAGE);
  261.         recent_panel_current = get_ADC_Data(PV_CURRENT);        
  262.  
  263.         battery_voltage = get_ADC_Data(BATT_VOLTAGE);
  264.         battery_current = get_ADC_Data(BATT_CURRENT);
  265.                
  266.        
  267.         if(recent_panel_voltage > (battery_voltage + 5))
  268.         {
  269.               if(P3IN & (RED_INDICATOR|YELLOW_INDICATOR|LOAD_RELAY))
  270.               {
  271.                 P3OUT &= ~(RED_INDICATOR | YELLOW_INDICATOR | LOAD_RELAY);
  272.               }
  273.              
  274.               if(battery_voltage < LOWER_CRG_LVL)                                          // 700 -- 18.5v  , 600 -- 18v
  275.               {
  276.      
  277.                     if(recent_panel_voltage > 0x0130)
  278.                     {
  279.                         if((DUTY_CYCLE < (MAX_LIMIT-50)) && (recent_panel_current < MAX_CURRENT_LIMIT))
  280.                         {
  281.                              DUTY_CYCLE += 1;
  282.                         }
  283.                         else
  284.                         {
  285.                               if((DUTY_CYCLE > 0) && (recent_panel_current > MAX_CURRENT_LIMIT))
  286.                               {
  287.                                     DUTY_CYCLE -= 1;
  288.                               }        
  289.                         }  
  290.                      }
  291.                      else
  292.                      {
  293.                         DUTY_CYCLE -= 1;
  294.                      }      
  295.               }
  296.               else
  297.               {
  298.                       if((battery_voltage > UPPER_CRG_LVL)&&(boolean_bits&(1<<TRICLE_CKT)))
  299.                       {
  300.                               DUTY_CYCLE -= 1;
  301.                       }
  302.               }
  303.              
  304. //...................................Temperature Compensation.......................................................
  305. /*
  306.                 temperature = get_ADC_Data(temp_sensor);
  307.                
  308.                 if(temperature > 758)                           // If temp is greater than 45 degC
  309.                 {
  310.                         tricle_level = 276; //253;
  311.                 }
  312.                 else if(temperature > 750)                      // If temp is greater than 35 degC
  313.                 {
  314.                         tricle_level = 278; //255;
  315.                 }
  316.                 else if(temperature > 742)                      // If temp is greater than 25 degC
  317.                 {
  318.                         tricle_level = 280; //256;
  319.                 }
  320.                 else if(temperature > 735)                      // If temp is greater than 18 degC
  321.                 {
  322.                         tricle_level = 282; //258;
  323.                 }
  324. */
  325.  
  326. //......................................... Tricle Charging ...........................................................
  327.  
  328.                                
  329.                 if((battery_voltage >= (tricle_level + 0))&&(!(boolean_bits&(1<<TRICLE_CKT))))
  330.                 {
  331.                     tricle_ckt_off_counter = 0;
  332.                     tricle_ckt_on_counter++;          
  333.                    
  334.                     if(tricle_ckt_on_counter>5)
  335.                     {
  336.                         boolean_bits |= (1<<TRICLE_CKT);
  337.                         tricle_ckt_on_counter = 0;
  338.                     }
  339.                 }
  340.                 else if((battery_voltage < (tricle_level - 5))&&(boolean_bits&(1<<TRICLE_CKT)))
  341.                 {
  342.                     tricle_ckt_on_counter = 0;
  343.                     tricle_ckt_off_counter++;
  344.                    
  345.                     if(tricle_ckt_off_counter>10)
  346.                     {                
  347.                         boolean_bits &= ~(1<<TRICLE_CKT);
  348.                         tricle_ckt_off_counter = 0;
  349.                     }
  350.                 }
  351.                 else
  352.                 {
  353.                     tricle_ckt_on_counter = 0;
  354.                     tricle_ckt_off_counter = 0;
  355.                 }
  356.                        
  357.                 if(boolean_bits&(1<<TRICLE_CKT))
  358.                 {              
  359.                         if(tricle_indicator_counter > 150)
  360.                         {                                              
  361.                                 P3OUT ^= GREEN_INDICATOR;
  362.                                 tricle_indicator_counter = 0;  
  363.                         }
  364.                 }
  365.                 else
  366.                 {
  367.                         if(!(P3IN&GREEN_INDICATOR))
  368.                         {
  369.                                 P3OUT |= GREEN_INDICATOR;
  370.                                 tricle_indicator_counter = 0;
  371.                         }
  372.                 }
  373.                                                
  374.                
  375. ///////////////////////////////////////////////// End of Charging Gircuit //////////////////////////////////////////////////////////////////////////////              
  376.              
  377.         }
  378.         else
  379.         {
  380.                  
  381.                 if(P3IN&GREEN_INDICATOR)
  382.                 {
  383.                         P3OUT &= ~GREEN_INDICATOR;                     
  384.                 }
  385.                
  386.                 if(DUTY_CYCLE > 180)
  387.                 {
  388.                         DUTY_CYCLE -= 1;
  389.                 }
  390.  // .......................................... Discharge Circuit ................................................      
  391.                                
  392.                                                        
  393.                 if(battery_voltage <= load_switching_voltage)
  394.                 {
  395.                         discharge_ckt_on_counter = 0;
  396.                         discharge_ckt_off_counter ++;
  397.                         if((discharge_ckt_off_counter > 15)&&(!(boolean_bits&(1<<TURN_OFF_CKT))))
  398.                         {
  399.                                 boolean_bits |= (1<<TURN_OFF_CKT);     
  400.                                 discharge_ckt_off_counter = 0;                 
  401.                                 load_switching_voltage = UPPER_CUTOFF;                         
  402.                         }
  403.                        
  404.                 }
  405.                 else
  406.                 {
  407.                         discharge_ckt_off_counter = 0;
  408.                         discharge_ckt_on_counter ++;
  409.                         if((discharge_ckt_on_counter > 10)&&(boolean_bits&(1<<TURN_OFF_CKT)))
  410.                         {
  411.                                 boolean_bits &= ~(1<<TURN_OFF_CKT);    
  412.                                 discharge_ckt_on_counter = 0;
  413.                                 load_switching_voltage = LOWER_CUTOFF;
  414.                         }
  415.                        
  416.                 }
  417.                
  418.                 if(battery_current > SHORT_CKT_CURRENT)
  419.                 {
  420.                         short_ckt_off_counter = 0;
  421.                         short_ckt_on_counter ++;
  422.                        
  423.                         if(short_ckt_on_counter > 0)
  424.                         {
  425.                                 boolean_bits |= (1<<SHORT_CKT);
  426.                                 short_ckt_on_counter = 0;
  427.                         }
  428.                 }
  429.                 else
  430.                 {
  431.                     if((boolean_bits&(1<<SHORT_CKT)))
  432.                     {
  433.                         short_ckt_on_counter = 0;
  434.                         short_ckt_off_counter ++;
  435.                        
  436.                         if(short_ckt_off_counter > 60)
  437.                         {
  438.                                 boolean_bits &= ~(1<<SHORT_CKT);
  439.                                 short_ckt_off_counter = 0;
  440.                         }
  441.                     }
  442.                 }
  443.  
  444.                
  445.                 if((!(boolean_bits&(1<<TURN_OFF_CKT))) && (!(boolean_bits&(1<<SHORT_CKT))) && (!(P3IN&LOAD_RELAY)))
  446.                 {
  447.                         P3OUT |= LOAD_RELAY;   
  448.                         P3OUT &= ~RED_INDICATOR;                                       
  449.                 }
  450.                 if(((boolean_bits&(1<<TURN_OFF_CKT)) || (boolean_bits&(1<<SHORT_CKT))) && (P3IN&LOAD_RELAY))
  451.                 {
  452.                         P3OUT &= ~LOAD_RELAY;
  453.                         P3OUT |= RED_INDICATOR;                
  454.                 }              
  455.  
  456. //............................................ Poor Indication ....................................................
  457.  
  458.                 if((battery_voltage <= POOR_BATTERY_VOLTAGE) && (!(boolean_bits&(1<<TURN_OFF_CKT))))
  459.                 {
  460.                         poor_indication_decision_counter ++;
  461.                        
  462.                         if((poor_indication_decision_counter > 15) && (!(boolean_bits&(1<<POOR_INDICATION))))
  463.                         {
  464.                                 boolean_bits |= (1<<POOR_INDICATION);
  465.                                 poor_indication_decision_counter = 0;
  466.                                
  467.                         }
  468.                 }
  469.                 else
  470.                 {
  471.                         poor_indication_decision_counter = 0;
  472.                        
  473.                         if(((battery_voltage > (POOR_BATTERY_VOLTAGE + 10)) || (boolean_bits&(1<<TURN_OFF_CKT))) && (boolean_bits&(1<<POOR_INDICATION)))
  474.                         {
  475.                                 boolean_bits &= ~(1<<POOR_INDICATION);
  476.                         }
  477.                 }
  478.                
  479.                
  480.                
  481.                 if(boolean_bits&(1<<POOR_INDICATION))
  482.                 {
  483.                         if((poor_indication_counter > 400) && (!(P3IN & YELLOW_INDICATOR)))
  484.                         {
  485.                                 P3OUT |= YELLOW_INDICATOR;
  486.                                 poor_indication_counter = 0;
  487.                         }
  488.                         if((poor_indication_counter > 100) && (P3IN & YELLOW_INDICATOR))
  489.                         {
  490.                                 P3OUT &= ~YELLOW_INDICATOR;
  491.                                 poor_indication_counter = 0;
  492.                         }
  493.                 }
  494.                 else
  495.                 {
  496.                         P3OUT &= ~YELLOW_INDICATOR;
  497.                 }
  498.                
  499.         }
  500. //.....................................................................................................................        
  501.         previous_panel_voltage = recent_panel_voltage;
  502.         previous_panel_current = recent_panel_current;
  503.         previous_panel_power   = recent_panel_power;
  504.  
  505.         transmit_buffer[2] = recent_panel_voltage;
  506.         transmit_buffer[1] = (recent_panel_voltage >> 8);
  507.  
  508.  
  509.         transmit_buffer[4] = recent_panel_current;
  510.         transmit_buffer[3] = (recent_panel_current >> 8);
  511.  
  512.  
  513.         transmit_buffer[6] = battery_voltage;
  514.         transmit_buffer[5] = (battery_voltage >> 8);
  515.  
  516.  
  517.         transmit_buffer[8] = battery_current;
  518.         transmit_buffer[7] = (battery_current >> 8);
  519.  
  520.         transmit_buffer[12] = DUTY_CYCLE;
  521.         transmit_buffer[11] = (DUTY_CYCLE >> 8);
  522.        
  523.         transmit_buffer[14] = short_ckt_off_counter;
  524.         transmit_buffer[15] = boolean_bits;
  525.   }
  526. }

Comments

Popular posts from this blog

Questions

1. What is a Stub function? Ans : A function without any definition which presents no error when called. 2. Why there are two ld scripts generated by STM32Cube IDE? Ans: The CubeIDE always presents two different LDscripts on for generating the executable for Debugging which goes to RAM another for normal code upload that goes to flash memory. 3. What is Supervisory Mode/ privileged mode ? Ans : When you are using a Kernel then there are two modes user mode and privileged mode. In User mode the applications cant have system calls. 4. What is "make -j6" ? Ans : Make has an argument for number of jobs, so when you add -j6 it will create 6 different compiler instances, so that the systems could use multicore to the fullest.  Linux people generally do add "-j $(nproc)" where nproc is a command line which returns number of processors attached. 5. What is weak attribute ? Ans : Weak attribute used to denote weak symbols which helps linkers to choose one function out of mul...

Preparing for embedded systems interview

  Preparing for a technical interview in embedded systems involves a wide range of topics, as the field encompasses both hardware and software components. Here are some key areas and example questions that you might encounter in such an interview: Basic Concepts and Theory: What is an embedded system? Can you explain the difference between a microprocessor and a microcontroller? Describe the various types of memory in an embedded system. Programming and Software Design: 4. How do you write an interrupt service routine in C? 5. Explain the concept of a real-time operating system (RTOS). How does it differ from a general-purpose operating system? 6. What are the different states of a thread in an RTOS? Hardware and Interfacing : 7. How does SPI communication work? What about I2C communication? 8. Explain the concept of GPIO (General-Purpose Input/Output). How would you use it in an embedded application? 9. What are interrupts, and how are they handled in embedded systems? Low-Level P...