How to sense feedback voltage using C8051F120 Development Kit

Discussion in 'Embedded Systems and Microcontrollers' started by gdylp2004, Feb 4, 2012.

  1. gdylp2004

    Thread Starter Member

    Dec 2, 2011
    101
    0
    Hi,

    I am currently using the C8051F120 development kit (see attached) in attempt to sense the o/p voltage from my Buck convertor and adjust the PWM signal, which is also generated from the 8051 chip.

    However my question is how should I connect point A (see another attachment) and interface it with the development kit?

    I've read somewhere from the datasheet that there is an internal reference voltage of 1.2V and therefore I've stepped down the 28V output with a set of appropriate resistors (R1 & R2).

    Assuming I would like to make about 30 samples before I made one adjustment to the PWM duty cycle, would what I've drawn in the attached been feasible?

    Also, I got a hunch that I might as well omit the comparator and DAC, that is, connecting the register output directly to the processor.

    Any comments would be appreciated.

    Thanks in advance.

    - Michael
     
  2. gdylp2004

    Thread Starter Member

    Dec 2, 2011
    101
    0
    Ok, my objective is to get an as accurate 28V output voltage as possible. Right now, my open-loop Buck converter output is only at about 26.67V DC while "pumping" 28% duty cycle, 100kHz 3.3V PWM into my Buck.

    As seen in my attached with a red circle, the input coming into the ADC0 seems like in pairs. So my question is would a single-ended input be better or a differential input to this ADC0 be more appropriate for me to obtain an as accurate 28V output as possible?

    Let's say if I do not want the output voltage to exceed +/- 0.1% away from my ideal 28V, that is, assuming after stepping down to 1.2V at point A, the voltage sensed by the ADC0 must be able to detect a tiny difference of about 1.2mV (0.1% of 1.2V), would the single-ended input or the differential input configuration allow me to achieve this?

    Next, I understand be it which configuration I used in the end, there would be a 8-bit register storing the ADC0 digital output after converting the analog signal. I would like to know (assuming I am using the single-ended sensing configuration, which is sensing the 1.2V directly from point A) what would the 8 bits data looks like? And also, what type of variable should I declare to capture this 8-bit data that actually represents my 1.2V for example?

    Attached is my Buck converter schematic and the real photo, just in case you're interested to know what do I mean of the 28V output voltage.
     
  3. gdylp2004

    Thread Starter Member

    Dec 2, 2011
    101
    0
    Recently, I've been trying to use the sample codes: ADC and PCA (for PWM) in attempt to 1) produce a 100kHz, 28% duty cycle 3.3V PWM & 2) read an analog voltage signal in the range of 0-2.43V and display it on Hyperterminal via UART1.

    Had realised that in order to create a 100kHz PWM, the CLK divider should be 0x20 and CLK multiplier should be about 0x21 to get that 100kHz, but if I change PLL0DIV = 0x20 and PLL0MUL = 0x21 accordingly, the display at the hyperterminal could not display the sensed mV properly. And if I used the default settings for PLL0DIV & PLL0MUL, the PWM will be 194kHz instead of 100kHz. So, it is really a chicken or egg problem.

    Could anyone know how to do it in order for me to achieve both 1) 100kHz PWM and 2) displaying the sensed voltage correctly?

    My codes are as below.

    Code ( (Unknown Language)):
    1.  
    Code ( (Unknown Language)):
    1.  
    2. [I][I][COLOR=black]//-----------------------------------------------------------------------------[/COLOR][/I][/I]
    3. [I][I][COLOR=black]// Includes[/COLOR][/I][/I]
    4. [I][I][COLOR=black]//-----------------------------------------------------------------------------[/COLOR][/I][/I]
    5. [COLOR=black] [/COLOR]
    6. [I][COLOR=black]#include <c8051f120.h> // SFR declarations[/COLOR][/I]
    7. [I][COLOR=black]#include <stdio.h> [/COLOR][/I]
    8. [COLOR=black] [/COLOR]
    9. [I][I][COLOR=black]//-----------------------------------------------------------------------------[/COLOR][/I][/I]
    10. [I][I][COLOR=black]// Global Constants[/COLOR][/I][/I]
    11. [I][I][COLOR=black]//-----------------------------------------------------------------------------[/COLOR][/I][/I]
    12. [COLOR=black] [/COLOR]
    13. [I][COLOR=black]#define INTCLK 24500000 // Internal oscillator frequency in Hz[/COLOR][/I]
    14. [I][COLOR=black]#define SYSCLK 49000000 // Output of PLL derived from (INTCLK*2)[/COLOR][/I]
    15. [I][COLOR=black]#define BAUDRATE 115200 // Baud [/COLOR][URL="http://forum.allaboutcircuits.com/newreply.php?do=postreply&t=65640#"][FONT=monospace][COLOR=black]rate[/COLOR][/FONT][/URL][COLOR=black] of UART in bps[/COLOR][/I]
    16. [I][COLOR=black]#define SYSCLK 49000000 // Output of PLL derived from (INTCLK*2)[/COLOR][/I]
    17. [I][COLOR=black]#define SAMPLE_RATE 50000 // Sample frequency in Hz[/COLOR][/I]
    18. [I][COLOR=black]#define INT_DEC 256 // Integrate and decimate ratio[/COLOR][/I]
    19. [I][COLOR=black]#define SAR_CLK 2500000 // Desired SAR [/COLOR][URL="http://forum.allaboutcircuits.com/newreply.php?do=postreply&t=65640#"][FONT=monospace][COLOR=black]clock [/COLOR][/FONT][/URL][URL="http://forum.allaboutcircuits.com/newreply.php?do=postreply&t=65640#"][FONT=monospace][COLOR=black]speed[/COLOR][/FONT][/URL][/I]
    20. [COLOR=black] [/COLOR]
    21. [I][COLOR=black]#define SAMPLE_DELAY 50 // Delay in ms before taking sample[/COLOR][/I]
    22. [COLOR=black] [/COLOR]
    23. [I][COLOR=black]sbit LED = P1^6; [I]// LED='1' means ON[/I][/COLOR][/I]
    24. [I][COLOR=black]sbit SW1 = P3^7; [I]// SW1='0' means switch pressed[/I][/COLOR][/I]
    25. [COLOR=black] [/COLOR]
    26. [I][I][COLOR=black]//-----------------------------------------------------------------------------[/COLOR][/I][/I]
    27. [I][I][COLOR=black]// 16-bit SFR Definitions for 'F12x[/COLOR][/I][/I]
    28. [I][I][COLOR=black]//-----------------------------------------------------------------------------[/COLOR][/I][/I]
    29. [COLOR=black] [/COLOR]
    30. [I][COLOR=black]sfr16 ADC0 = 0xbe; [I]// ADC0 data[/I][/COLOR][/I]
    31. [I][COLOR=black]sfr16 RCAP2 = 0xca; [I]// Timer2 capture/reload[/I][/COLOR][/I]
    32. [I][COLOR=black]sfr16 RCAP3 = 0xca; [I]// Timer3 capture/reload[/I][/COLOR][/I]
    33. [I][COLOR=black]sfr16 TMR2 = 0xcc; [I]// Timer2[/I][/COLOR][/I]
    34. [I][COLOR=black]sfr16 TMR3 = 0xcc; [I]// Timer3[/I][/COLOR][/I]
    35. [COLOR=black] [/COLOR]
    36. [I][I][COLOR=black]//-----------------------------------------------------------------------------[/COLOR][/I][/I]
    37. [I][I][COLOR=black]// Function Prototypes[/COLOR][/I][/I]
    38. [I][I][COLOR=black]//-----------------------------------------------------------------------------[/COLOR][/I][/I]
    39. [COLOR=black] [/COLOR]
    40. [I][COLOR=black]void OSCILLATOR_Init (void);[/COLOR][/I]
    41. [I][COLOR=black]void PORT_Init (void);[/COLOR][/I]
    42. [I][COLOR=black]void PCA0_Init (void);[/COLOR][/I]
    43. [I][COLOR=black]void Set_PCA0_Duty_Cycle(unsigned short l_us_duty_cycle);[/COLOR][/I]
    44. [I][COLOR=black]void UART1_Init (void);[/COLOR][/I]
    45. [I][COLOR=black]void ADC0_Init (void);[/COLOR][/I]
    46. [I][COLOR=black]void TIMER3_Init (int counts);[/COLOR][/I]
    47. [I][COLOR=black]void ADC0_ISR (void);[/COLOR][/I]
    48. [I][COLOR=black]void Wait_MS (unsigned int ms);[/COLOR][/I]
    49. [COLOR=black] [/COLOR]
    50. [I][I][COLOR=black]//-----------------------------------------------------------------------------[/COLOR][/I][/I]
    51. [I][I][COLOR=black]// Global Variables[/COLOR][/I][/I]
    52. [I][I][COLOR=black]//-----------------------------------------------------------------------------[/COLOR][/I][/I]
    53. [COLOR=black] [/COLOR]
    54. [I][COLOR=black]long Result; [I]// ADC0 decimated value[/I][/COLOR][/I]
    55.  
    56.  
     
  4. gdylp2004

    Thread Starter Member

    Dec 2, 2011
    101
    0
    Code ( (Unknown Language)):
    1.  
    2. //-----------------------------------------------------------------------------
    3. // main() Routine
    4. //-----------------------------------------------------------------------------
    5.  
    6. void main (void)
    7. {
    8. long measurement; // Measured voltage in mV
    9. unsigned int delay_count; // Used to implement a delay
    10. bit duty_direction = 0; // 0 = Decrease; 1 = Increase
    11.  
    12. // Disable watchdog timer
    13. WDTCN = 0xde;
    14. WDTCN = 0xad;
    15.  
    16. PORT_Init (); // Initialize crossbar and GPIO
    17. OSCILLATOR_Init (); // Initialize oscillator
    18. PCA0_Init (); // Initialize PCA0
    19. UART1_Init (); // Initialize UART1
    20. TIMER3_Init (SYSCLK/SAMPLE_RATE); // Initialize Timer3 to overflow at sample rate
    21.  
    22. ADC0_Init (); // Init ADC
    23.  
    24. SFRPAGE = ADC0_PAGE;
    25. AD0EN = 1; // Enable ADC
    26.  
    27. EA = 1; // Enable global interrupts
    28.  
    29. while (1)
    30. {
    31. EA = 0; // Disable interrupts
    32.  
    33. // The 12-bit ADC value is averaged across INT_DEC measurements. The result is
    34. // then stored in Result, and is right-justified
    35. // The measured voltage applied to AIN 0.1 is then:
    36. //
    37. // Vref (mV)
    38. // measurement (mV) = --------------- * Result (bits)
    39. // (2^12)-1 (bits)
    40.  
    41. measurement = Result * 2430 / 4095;
    42.  
    43. EA = 1; // Re-enable interrupts
    44.  
    45. SFRPAGE = UART1_PAGE;
    46.  
    47. [URL="http://www.opengroup.org/onlinepubs/009695399/functions/printf.html"]printf[/URL]("AIN0.1 voltage: %ld mV\n",measurement);
    48.  
    49. SFRPAGE = CONFIG_PAGE;
    50. LED = ~SW1; // LED reflects state of switch
    51.  
    52. Wait_MS(SAMPLE_DELAY); // Wait 50 milliseconds before taking another sample
    53. Set_PCA0_Duty_Cycle(74);
    54. }
    55.  
    56. // SFRPAGE = PCA0_PAGE; // Change to PCA0 page
    57. //
    58. // while (1)
    59. // {
    60. // Set_PCA0_Duty_Cycle(74);
    61. // // Wait a little while
    62. // for (delay_count = 30000; delay_count > 0; delay_count--);
    63. //
    64. // if (duty_direction == 1) // Direction = Increase
    65. // {
    66. // // First, check the ECOM0 bit
    67. // if ((PCA0CPM0 & 0x40) == 0x00)
    68. // {
    69. // PCA0CPM0 |= 0x40; // Set ECOM0 if it is '0'
    70. // }
    71. // else // Increase duty cycle otherwise
    72. // {
    73. // PCA0CPH0--; // Increase duty cycle
    74. //
    75. // if (PCA0CPH0 == 0x00)
    76. // {
    77. // duty_direction = 0; // Change direction for next time
    78. // }
    79. // }
    80. // }
    81. // else // Direction = Decrease
    82. // {
    83. // if (PCA0CPH0 == 0xFF)
    84. // {
    85. // PCA0CPM0 &= ~0x40; // Clear ECOM0
    86. // duty_direction = 1; // Change direction for next time
    87. // }
    88. // else
    89. // {
    90. // PCA0CPH0++; // Decrease duty cycle
    91. // }
    92. // }
    93. //
    94. // };
    95. }
    96.  
    97.  
    98.  
    99.  
    100.  
    101. //-----------------------------------------------------------------------------
    102. // OSCILLATOR_Init
    103. //-----------------------------------------------------------------------------
    104. //
    105. // Return Value : None
    106. // Parameters : None
    107. //
    108. // This function initializes the system clock to use the internal oscillator
    109. // at 24.5 MHz multiplied by two using the PLL.
    110. //
    111. //-----------------------------------------------------------------------------
    112.  
     
  5. gdylp2004

    Thread Starter Member

    Dec 2, 2011
    101
    0
    Code ( (Unknown Language)):
    1.  
    2. void OSCILLATOR_Init (void)
    3. {
    4. int loop; // Software timer
    5.  
    6. char SFRPAGE_save = SFRPAGE; // Save Current SFR page
    7.  
    8. SFRPAGE = CONFIG_PAGE; // Set SFR page
    9.  
    10. OSCICN = 0x83; // Set internal oscillator to run
    11. // at its maximum frequency
    12.  
    13. CLKSEL = 0x00; // Select the internal osc. as
    14. // the SYSCLK source
    15.  
    16. //Turn on the PLL and increase the [URL="http://forum.allaboutcircuits.com/newreply.php?do=postreply&t=65640#"][COLOR=#397a44 !important]system[/URL] clock by a factor of M/N = 2[/COLOR]
    17. SFRPAGE = CONFIG_PAGE;
    18.  
    19. PLL0CN = 0x00; // Set internal osc. as PLL source
    20. SFRPAGE = LEGACY_PAGE;
    21. FLSCL = 0x10; // Set FLASH read time for 50MHz clk
    22. // or less
    23. SFRPAGE = CONFIG_PAGE;
    24. PLL0CN |= 0x01; // Enable Power to PLL
    25. PLL0DIV = 0x01; // Set Pre-divide value to N (N = 1)
    26. PLL0FLT = 0x01; // Set the PLL filter register for
    27. // a reference clock from 19 - 30 MHz
    28. // and an output clock from 45 - 80 MHz
    29. PLL0MUL = 0x02; // Multiply SYSCLK by M (M = 2)
    30.  
    31. for (loop=0; loop < 256; loop++); // Wait at least 5us
    32. PLL0CN |= 0x02; // Enable the PLL
    33. while(!(PLL0CN & 0x10)); // Wait until PLL frequency is locked
    34. CLKSEL = 0x02; // Select PLL as SYSCLK source
    35.  
    36. SFRPAGE = SFRPAGE_save; // Restore SFR page
    37. }
    38.  
    39. //-----------------------------------------------------------------------------
    40. // PORT_Init
    41. //-----------------------------------------------------------------------------
    42. //
    43. // Return Value : None
    44. // Parameters : None
    45. //
    46. // This function configures the crossbar and GPIO ports.
    47. //
    48. // P0.0 digital push-pull PCA0 CEX0
    49. //
    50. //-----------------------------------------------------------------------------
    51. void PORT_Init (void)
    52. {
    53. char SFRPAGE_save = SFRPAGE; // Save Current SFR page
    54.  
    55. SFRPAGE = CONFIG_PAGE; // set SFR page
    56.  
    57. P0MDOUT = 0x07;
    58. XBR0 = 0x08;
    59. XBR2 = 0xC4;
    60.  
    61. // Enable UART1
    62. P0MDOUT |= 0x01; // Set TX1 pin to push-pull
    63. P1MDOUT |= 0x40; // Set P1.6(LED) to push-pull
    64.  
    65. SFRPAGE = SFRPAGE_save; // Restore SFR page
    66. }
    67.  
    68. //-----------------------------------------------------------------------------
    69. // PCA0_Init
    70. //-----------------------------------------------------------------------------
    71. //
    72. // Return Value : None
    73. // Parameters : None
    74. //
    75. // This function configures the PCA time base, and sets up 8-bit PWM output
    76. // mode for Module 0 (CEX0 pin).
    77. //
    78. // The frequency of the PWM signal generated at the CEX0 pin is equal to the
    79. // PCA main timebase frequency divided by 256.
    80. //
    81. // The PCA time base in this example is configured to use SYSCLK, and SYSCLK
    82. // is set up to use the internal PLL running at 49 MHz. Therefore,
    83. // the frequency of the PWM signal will be 49 MHz / 256 = 191.4 kHz.
    84. // Using different PCA clock sources or a different processor clock will
    85. // result in a different frequency for the PWM signal.
    86. //
    87. // -------------------------------------------------------------------------
    88. //
    89. //-----------------------------------------------------------------------------
    90. void PCA0_Init (void)
    91. {
    92. char SFRPAGE_save = SFRPAGE; // Save current SFR Page
    93.  
    94. SFRPAGE = PCA0_PAGE;
    95. // configure PCA time base; overflow interrupt disabled
    96. PCA0CN = 0x00; // Stop counter; clear all flags
    97. PCA0MD = 0x08; // Use SYSCLK as time base
    98.  
    99. PCA0CPM0 = 0x42; // Module 0 = 8-bit PWM mode
    100.  
    101. // Configure initial PWM duty cycle = 50%
    102. PCA0CPH0 = 256 - (256 * 0.5);
    103.  
    104. // Start PCA counter
    105. CR = 1;
    106. SFRPAGE = SFRPAGE_save;
    107. }
    108.  
    109. void Set_PCA0_Duty_Cycle(unsigned short l_us_duty_cycle)
    110. {
    111. //Save current SFR Page
    112. char SFRPAGE_SAVE = SFRPAGE;
    113.  
    114. SFRPAGE = PCA0_PAGE;
    115.  
    116. if (l_us_duty_cycle == 0)
    117. {
    118. //For 0% duty cycle, clear ECOM0
    119. //PCA0CPM0 &= 0xBF;
    120.  
    121. //lsl : 02 Jun 2011 : 1744hrs
    122. //For 0% duty cycle, clear ECOM0 (bit 6) & PWM0 (bit 1)
    123. PCA0CPM0 &= 0xBD;
    124. }
    125. else if (l_us_duty_cycle > 255)
    126. {
    127. //For 100% duty cycle
    128. //a. Set ECOM0 (bit 6) & PWM0 (bit 1)
    129. //b. Load 0x00 into PCA0CPH0
    130.  
    131. PCA0CPM0 |= 0x42; //0x40;
    132.  
    133. PCA0CPH0 = 0;
    134. }
    135. else
    136. {
    137. PCA0CPM0 |= 0x42; //0x40;
    138.  
    139. PCA0CPH0 = 256 - (unsigned char)(l_us_duty_cycle & 0xFF);
    140. }
    141.  
    142. //Restore the SFRPAGE
    143. SFRPAGE = SFRPAGE_SAVE;
    144. }
    145.  
    146. void UART1_Init (void)
    147. {
    148. char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
    149.  
    150. SFRPAGE = UART1_PAGE;
    151. SCON1 = 0x10; // SCON1: mode 0, 8-bit UART, enable RX
    152.  
    153. SFRPAGE = TIMER01_PAGE;
    154. TMOD &= ~0xF0;
    155. TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit reload
    156.  
    157.  
    158. if (SYSCLK/BAUDRATE/2/256 < 1) {
    159. TH1 = -(SYSCLK/BAUDRATE/2);
    160. CKCON |= 0x10; // T1M = 1; SCA1:0 = xx
    161. } else if (SYSCLK/BAUDRATE/2/256 < 4) {
    162. TH1 = -(SYSCLK/BAUDRATE/2/4);
    163. CKCON &= ~0x13; // Clear all T1 related bits
    164. CKCON |= 0x01; // T1M = 0; SCA1:0 = 01
    165. } else if (SYSCLK/BAUDRATE/2/256 < 12) {
    166. TH1 = -(SYSCLK/BAUDRATE/2/12);
    167. CKCON &= ~0x13; // T1M = 0; SCA1:0 = 00
    168. } else {
    169. TH1 = -(SYSCLK/BAUDRATE/2/48);
    170. CKCON &= ~0x13; // Clear all T1 related bits
    171. CKCON |= 0x02; // T1M = 0; SCA1:0 = 10
    172. }
    173.  
    174. TL1 = TH1; // Initialize Timer1
    175. TR1 = 1; // Start Timer1
    176.  
    177. SFRPAGE = UART1_PAGE;
    178. TI1 = 1; // Indicate TX1 ready
    179.  
    180. SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
    181.  
    182. }
    183.  
    184. //-----------------------------------------------------------------------------
    185. // ADC0_Init
    186. //-----------------------------------------------------------------------------
    187. //
    188. // Return Value : None
    189. // Parameters : None
    190. //
    191. // Configure ADC0 to use Timer3 overflows as conversion source, to
    192. // generate an interrupt on conversion complete, and to use right-justified
    193. // output mode. Enables ADC end of conversion interrupt. Leaves ADC disabled.
    194. //
    195. //-----------------------------------------------------------------------------
    196. void ADC0_Init (void)
    197. {
    198. char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
    199.  
    200. SFRPAGE = ADC0_PAGE;
    201.  
    202. ADC0CN = 0x04; // ADC0 disabled; normal tracking
    203. // mode; ADC0 conversions are initiated
    204. // on overflow of Timer3; ADC0 data is
    205. // right-justified
    206.  
    207. REF0CN = 0x07; // Enable temp sensor, on-chip VREF,
    208. // and VREF output buffer
    209.  
    210. AMX0CF = 0x00; // AIN inputs are single-ended (default)
    211.  
    212. AMX0SL = 0x01; // Select AIN0.1 pin as ADC mux input
    213.  
    214. ADC0CF = (SYSCLK/SAR_CLK) << 3; // ADC conversion clock = 2.5MHz
    215. ADC0CF |= 0x00; // PGA gain = 1 (default)
    216.  
    217. EIE2 |= 0x02; // enable ADC interrupts
    218.  
    219. SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
    220. }
    221.  
    222. //-----------------------------------------------------------------------------
    223. // TIMER3_Init
    224. //-----------------------------------------------------------------------------
    225. //
    226. // Return Value : None
    227. // Parameters :
    228. // 1) int counts - calculated Timer overflow rate
    229. // range is postive range of integer: 0 to 32767
    230. //
    231. // Configure Timer3 to auto-reload at interval specified by <counts> (no
    232. // interrupt generated) using SYSCLK as its time base.
    233. //
    234. //-----------------------------------------------------------------------------
    235. void TIMER3_Init (int counts)
    236. {
    237. char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
    238.  
    239. SFRPAGE = TMR3_PAGE;
    240.  
    241. TMR3CN = 0x00; // Stop Timer3; Clear TF3;
    242. TMR3CF = 0x08; // use SYSCLK as timebase
    243.  
    244. RCAP3 = -counts; // Init reload values
    245. TMR3 = RCAP3; // Set to reload immediately
    246. EIE2 &= ~0x01; // Disable Timer3 interrupts
    247. TR3 = 1; // start Timer3
    248.  
    249. SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
    250. }
    251.  
    252. //-----------------------------------------------------------------------------
    253. // Interrupt Service Routines
    254. //-----------------------------------------------------------------------------
    255.  
    256. //-----------------------------------------------------------------------------
    257. // ADC0_ISR
    258. //-----------------------------------------------------------------------------
    259. //
    260. // Here we take the ADC0 sample, add it to a running total <accumulator>, and
    261. // decrement our local decimation counter <int_dec>. When <int_dec> reaches
    262. // zero, we post the decimated result in the global variable <Result>.
    263. //
    264. //-----------------------------------------------------------------------------
    265. void ADC0_ISR (void) interrupt 15
    266. {
    267. static unsigned int_dec=INT_DEC; // Integrate/decimate counter
    268. // we post a new result when
    269. // int_dec = 0
    270. static long accumulator=0L; // Here's where we integrate the
    271. // ADC samples
    272.  
    273. AD0INT = 0; // Clear ADC conversion complete
    274. // indicator
    275.  
    276. accumulator += ADC0; // Read ADC value and add to running
    277. // total
    278. int_dec--; // Update decimation counter
    279.  
    280. if (int_dec == 0) // If zero, then post result
    281. {
    282. int_dec = INT_DEC; // Reset counter
    283. Result = accumulator >> 8;
    284. accumulator = 0L; // Reset accumulator
    285. }
    286. }
    287.  
    288. //-----------------------------------------------------------------------------
    289. // Support Subroutines
    290. //-----------------------------------------------------------------------------
    291.  
    292. //-----------------------------------------------------------------------------
    293. // Wait_MS
    294. //-----------------------------------------------------------------------------
    295. //
    296. // Return Value : None
    297. // Parameters:
    298. // 1) unsigned int ms - number of milliseconds of delay
    299. // range is full range of integer: 0 to 65335
    300. //
    301. // This routine inserts a delay of <ms> milliseconds.
    302. //
    303. //-----------------------------------------------------------------------------
    304. void Wait_MS(unsigned int ms)
    305. {
    306. char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
    307.  
    308. SFRPAGE = TMR2_PAGE;
    309.  
    310. TMR2CN = 0x00; // Stop Timer3; Clear TF3;
    311. TMR2CF = 0x00; // use SYSCLK/12 as timebase
    312.  
    313. RCAP2 = -(SYSCLK/1000/12); // Timer 2 overflows at 1 kHz
    314. TMR2 = RCAP2;
    315.  
    316. ET2 = 0; // Disable Timer 2 interrupts
    317.  
    318. TR2 = 1; // Start Timer 2
    319.  
    320. while(ms)
    321. {
    322. TF2 = 0; // Clear flag to initialize
    323. while(!TF2); // Wait until timer overflows
    324. ms--; // Decrement ms
    325. }
    326.  
    327. TR2 = 0; // Stop Timer 2
    328.  
    329. SFRPAGE = SFRPAGE_SAVE; // Restore SFRPAGE
    330. }
    331.  
    332. //-----------------------------------------------------------------------------
    333. // End Of File
    334. //-----------------------------------------------------------------------------
    335.  
     
Loading...