Andre Abelian [aabelian@mason-electric.com]
I needed software PWM and I used Scott Dattalo's software PWM idea and I can tell he is a genus. The test I did on my demo board I only had 2 leds and 1 pot. The pot is dimming one of the led and the other PWM is fixed number entered manually before compiling. The resolution is 10 bit and the result is excellent. see attachment file. It is written in CCS C. Note that there are some extra unused stuff. I am using timer 0 interrupt. Also thanks to CCS for making nice compiler.
Andre
// // Scott Dattalo's Software PWM idea // Thanks to him // #include <18F4550.h> #rom int 0xf00000={0x19,0x11,0x09,0x00} // write to eeprom project number #device ADC=10 #define DEBUG // comment this line (to program): Remove comment (to debug) #ifdef DEBUG #fuses HS,NOWDT,NOPROTECT,NOLVP,MCLR // use this line to debug #else #fuses NOMCLR,STVREN,BORV20,WDT2048,HS,PROTECT,NOLVP // use this line to programmer #endif #use delay(clock=20000000) #use rs232(DEBUGGER) #use rs232(baud=57600,xmit=PIN_B5,bits=8,invert) #ZERO_RAM // clear all variables #define pwm_output1_on output_high(PIN_B5); #define pwm_output1_off output_low(PIN_B5); #define pwm_output2_on output_high(PIN_B4); #define pwm_output2_off output_low(PIN_B4); #define pwm1 1023 #define pwm2 1023 #define cycle_t0 0xFF5a long int duty_cycle1,rising_edge1,falling_edge1; long int duty_cycle2,rising_edge2,falling_edge2; ///////////////////////////////////////////////////// // Main Program ///////////////////////////////////////////////////// void main (void) { set_tris_a (0xFF); // make all output no use for now set_tris_b (0b11111111); // make all input set_tris_c (0xff); // all output set_tris_d (0b00010000); // set_tris_e (0xff); // make all output OUTPUT_D (0xff); // OUTPUT_C (0xff); // turn off all setup_adc( ADC_CLOCK_INTERNAL); // setup_counters (RTCC_INTERNAL, RTCC_DIV_1); enable_interrupts (int_RTCC); enable_interrupts (GLOBAL); set_timer0(cycle_t0); // adjust timer0 pwm_output1_on; rising_edge1= 0; // falling_edge1 = pwm1 - duty_cycle1; pwm_output2_on; rising_edge2= 0; // falling_edge2 = pwm2 - duty_cycle2; while (TRUE) { set_adc_channel(0); delay_ms(1); duty_cycle1 = read_ADC(); // set_adc_channel(1); // delay_ms(1); // duty_cycle2 = read_ADC(); } } #int_rtcc void pwm_isr() { set_timer0(cycle_t0); // adjust timer0 if (rising_edge1 ++ > pwm1) { rising_edge1= 0; pwm_output1_on; falling_edge1 = pwm1 - duty_cycle1; } if (falling_edge1 ++ > pwm1) { falling_edge1 = 0; pwm_output1_off; } if (rising_edge2 ++ > pwm2) { rising_edge2 = 0; pwm_output2_on; falling_edge2 = pwm2 - 900; } if (falling_edge2 ++ > pwm2) { falling_edge2 = 0; pwm_output2_off; } }
Comments:
set_tris_a (0xFF); // make all output no use for nowJames Newton of MassMind replies: Yeah, that's certainly a typo. A 1 in any tris register makes the pin an input. So A is being set to all input, not all output. This is a common problem with commenting programs where the programmer sets something up, and comments it, then changes the settings and forgets to change the comment. A better comment would be // set TRIS, 0 = output, 1 = input because it's always true.+
set_tris_b (0b11111111); // make all input
what is the difference in both commands how one is input and one is output
Questions:
file: /Techref/microchip/language/c/leddimmer-aa.htm, 5KB, , updated: 2019/1/23 11:11, local time: 2024/11/5 00:37,
3.133.115.47:LOG IN ©2024 PLEASE DON'T RIP! THIS SITE CLOSES OCT 28, 2024 SO LONG AND THANKS FOR ALL THE FISH!
|
©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://linistepper.com/Techref/microchip/language/c/leddimmer-aa.htm"> LED dimmer. Software PWM, A2D, Potentiometer, CCS C</A> |
Did you find what you needed? |