//****************************************************************************************** // PIC12F1822 Sample Program // Project : // Program Name : // Programer : // Create date : Version 1.0 H25.09.22 // History : // Laungage : HI_TECH PICC C Laungage Version 9.83 //****************************************************************************************** // Description // Oscillator : Internal Oscillator 16MHz // Output : P1A(RA2), P1B(RA0) // Voltage Senser C1IN0-(RA1) // RA4 Check current // RA5 Monitor LED //****************************************************************************************** #include __CONFIG( FOSC_INTOSC & WDTE_OFF & PWRTE_OFF & MCLRE_OFF & CP_OFF & CPD_OFF & BOREN_OFF & CLKOUTEN_OFF & IESO_OFF & FCMEN_OFF ); __CONFIG( WRT_OFF & PLLEN_OFF & STVREN_OFF & BORV_HI & LVP_OFF ) ; // #define CCP1SEL 0 #define P1BSEL 1 // void Init_PWM(void); void Init_COMP(void); void Error_OverCurt(void); void Wait_01S(unsigned int); void Wait_100mS(void); // void main() { unsigned char incre_val; unsigned char lower_val; // ***************************** // 1.Initialized // ***************************** // (1)Define OSC (16MHz, IntOSC) OSCCON = 0b01111010; // 16MHz, IntOSC // (2)Define ANSELA (ALL Digital Port) ANSELA = 0x00; // (3)Define I/O port PORTA = 0b00000000; TRISA = 0b00011010; // (4)Initialized PWM module Init_PWM(); // (5)Initialized Compare module Init_COMP(); // ***************************** // 2.Program main // ***************************** // (1)Start incre_val = PR2 / 4 ; lower_val = PR2 ; while(1){ if((CMOUT & 0b00000001) != 0){ //Compare C1OUT PWM1CON = incre_val; //This command to increase the output voltage PORTA &= 0b11011111; //Monitor LED OFF if((PORTA & 0b00010000) == 0) Error_OverCurt(); }else{ PWM1CON = lower_val ; //This command lowers the output voltage (PWM STOP) PORTA |= 0b00100000; //Monitor LED ON if((PORTA & 0b00010000) == 0) Error_OverCurt(); } } } //****************************************************************************************** // Function Name : Init_PWM // Title : // Input : // Output : //****************************************************************************************** void Init_PWM(void) { // ******************************************************* // 1.ALTERNATE PIN FUNCTION CONTROL REGISTER // CCP1SEL // 0 = CCP1/P1A function is on RA2 // 1 = CCP1/P1A function is on RA5 // P1BSEL // 0 = P1B function is on RA0 // 1 = P1B function is on RA4 // ******************************************************* APFCON &= ~(1 << CCP1SEL) & ~(1 << P1BSEL) ; // CCP1SEL:0, P1BSEL:0 // ******************************************************* // 2.Define CCP1CON: CCP1 CONTROL REGISTER // CCP1CON[7-6] P1M<1:0>: Enhanced PWM Output Configuration bits(1) // Capture mode: Unused // Compare mode: Unused // PWM mode: // If CCP1M<3:2> = 00, 01, 10: // xx = P1A assigned as Capture/Compare input; P1B, P1C, P1D assigned as port pins PIC16F/LF1823 only // If CCP1M<3:2> = 11: // 00 = Single output; P1A modulated; P1B, P1C, P1D assigned as port pins // 01 = Full-Bridge output forward; P1D modulated; P1A active; P1B, P1C inactive PIC16F/LF1823 only // 10 = Half-Bridge output; P1A, P1B modulated with dead-band control; P1C, P1D assigned as port pins // 11 = Full-Bridge output reverse; P1B modulated; P1C active; P1A, P1D inactive PIC16F/LF1823 only // CCP1CON[5-4] DC1B<1:0>: PWM Duty Cycle Least Significant bits // Capture mode: Unused // Compare mode: Unused // PWM mode: // These bits are the two LSbs of the PWM duty cycle. The eight MSbs are found in CCPR1L. // CCP1CON[3-0] CCP1M<3:0>: ECCP1 Mode Select bits // 0000 = Capture/Compare/PWM off (resets ECCP1 module) // 0001 = Reserved // 0010 = Compare mode: toggle output on match // 0011 = Reserved // 0100 = Capture mode: every falling edge // 0101 = Capture mode: every rising edge // 0110 = Capture mode: every 4th rising edge // 0111 = Capture mode: every 16th rising edge // 1000 = Compare mode: initialize ECCP1 pin low; set output on compare match (set CCP1IF) // 1001 = Compare mode: initialize ECCP1 pin high; clear output on compare match (set CCP1IF) // 1010 = Compare mode: generate software interrupt only; ECCP1 pin reverts to I/O state // 1011 = Compare mode: Special Event Trigger (CCP1 resets TMR1, sets CCP1IF bit, and starts A/D conversion if A/D module is enabled) // PWM mode: // 1100 = PWM mode: P1A, P1C active-high; P1B, P1D active-high // 1101 = PWM mode: P1A, P1C active-high; P1B, P1D active-low // 1110 = PWM mode: P1A, P1C active-low; P1B, P1D active-high // 1111 = PWM mode: P1A, P1C active-low; P1B, P1D active-low // ******************************************************* CCP1CON = 0b10001100; // ******************************************************* // 3.T2CON: TIMER2 CONTROL REGISTER // T2CON[7] Unimplemented: Read as e0f // T2CON[6-3] TOUTPS<3:0>: Timer Output Postscaler Select bits // 0000 = 1:1 Postscaler // 0001 = 1:2 Postscaler // 0010 = 1:3 Postscaler // 0011 = 1:4 Postscaler // 0100 = 1:5 Postscaler // 0101 = 1:6 Postscaler // 0110 = 1:7 Postscaler // 0111 = 1:8 Postscaler // 1000 = 1:9 Postscaler // 1001 = 1:10 Postscaler // 1010 = 1:11 Postscaler // 1011 = 1:12 Postscaler // 1100 = 1:13 Postscaler // 1101 = 1:14 Postscaler // 1110 = 1:15 Postscaler // 1111 = 1:16 Postscaler // T2CON[2] TMR2ON: Timer2 On bit // 1 = Timer2 is on // 0 = Timer2 is off // T2CON[1-0] T2CKPS<1:0>: Timer2 Clock Prescale Select bits // 00 = Prescaler is 1 // 01 = Prescaler is 4 // 10 = Prescaler is 16 // 11 = Prescaler is 64 // ******************************************************* // T2CON = 0b00000100; T2CON = 0b00000000; // ******************************************************* // 4.PSTR1CON: PWM STEERING CONTROL REGISTER // PSTR1CON[7-5] Unimplemented: Read as e0f // PSTR1CON[4] STR1SYNC: Steering Sync bit // 1 = Output steering update occurs on next PWM period // 0 = Output steering update occurs at the beginning of the instruction cycle boundary // PSTR1CON[3] STR1D: Steering Enable bit D(2) // 1 = P1D pin has the PWM waveform with polarity control from CCP1M<1:0> // 0 = P1D pin is assigned to port pin // PSTR1CON[2] STR1C: Steering Enable bit C(2) // 1 = P1C pin has the PWM waveform with polarity control from CCP1M<1:0> // 0 = P1C pin is assigned to port pin // PSTR1CON[1] STR1B: Steering Enable bit B // 1 = P1B pin has the PWM waveform with polarity control from CCP1M<1:0> // 0 = P1B pin is assigned to port pin // PSTR1CON[0] STR1A: Steering Enable bit A // 1 = P1A pin has the PWM waveform with polarity control from CCP1M<1:0> // 0 = P1A pin is assigned to port pin // ******************************************************* PSTR1CON = 0b00010011; // ******************************************************* // 5.Set the frequency (PR2 Register) // ******************************************************* // PR2 = 200; // 20KHz // PR2 = 80; // 50KHz // PR2 = 40; //100KHz PR2 = 20; //200KHz // PR2 = 4; //800KHz // ******************************************************* // 6.Set the delay (PWM1CON : ENHANCED PWM CONTROL Register) // PWM1CON[7] P1RSEN: PWM Restart Enable bit // 1 = Upon auto-shutdown, the CCP1ASE bit clears automatically once the shutdown event goes away; the PWM restarts automatically // 0 = Upon auto-shutdown, CCP1ASE must be cleared in software to restart the PWM // PWM1CON[6-0] P1DC<6:0>: PWM Delay Count bits // P1DC1 = Number of FOSC/4 (4 * TOSC) cycles between the scheduled time when a PWM signal // should transition active and the actual time it transitions active // ******************************************************* PWM1CON = PR2 / 4 ; // ******************************************************* // 7.Set the duty cycle (CCPR1L Register) // This makes 50 percent duty cycle // ******************************************************* CCPR1L = PR2 / 2; // ******************************************************* // 8.Start // ******************************************************* T2CON |= 0b00000100; } //****************************************************************************************** // Function Name : Init_COMP // Title : initialized compare module // Input : // Output : // Description : C1VP:FVR / C1VN:C1IN0- //****************************************************************************************** void Init_COMP(void) { // ******************************************************* // 1.FVRCON: FIXED VOLTAGE REFERENCE CONTROL REGISTER // FVRCON(7) FVREN: Fixed Voltage Reference Enable bit // 0 = Fixed Voltage Reference is disabled // 1 = Fixed Voltage Reference is enabled // FVRCON(6) FVRRDY: Fixed Voltage Reference Ready Flag bit (1) // 0 = Fixed Voltage Reference output is not ready or not enabled // 1 = Fixed Voltage Reference output is ready for use // FVRCON(5-4) Reserved: Read as e0f. Maintain these bits clear. // FVRCON(3-2) CDAFVR<1:0>: Comparator and DAC Fixed Voltage Reference Selection bits // 00 = Comparator and DAC Fixed Voltage Reference Peripheral output is off // 01 = Comparator and DAC Fixed Voltage Reference Peripheral output is 1x (1.024V) // 10 = Comparator and DAC Fixed Voltage Reference Peripheral output is 2x (2.048V) (2) // 11 = Comparator and DAC Fixed Voltage Reference Peripheral output is 4x (4.096V) (2) // FVRCON(1-0) ADFVR<1:0>: ADC Fixed Voltage Reference Selection bits // 00 = ADC Fixed Voltage Reference Peripheral output is off // 01 = ADC Fixed Voltage Reference Peripheral output is 1x (1.024V) // 10 = ADC Fixed Voltage Reference Peripheral output is 2x (2.048V) (2) // 11 = ADC Fixed Voltage Reference Peripheral output is 4x (4.096V) (2) // // Note 1: FVRRDY is always e1f on devices with the LDO (PIC12F1822/16F1823). // 2: Fixed Voltage Reference output cannot exceed VDD. // ******************************************************* FVRCON = 0b11000100; // Comparator and DAC Fixed Voltage // ******************************************************* // 2.CM1CON0: COMPARATOR 1 CONTROL REGISTER 0 // CM1CON0[7] CxON: Comparator Enable bit // 1 = Comparator is enabled and consumes no active power // 0 = Comparator is disabled // CM1CON0[6] CxOUT: Comparator Output bit // If CxPOL = 1 (inverted polarity): // 1 = CxVP < CxVN // 0 = CxVP > CxVN // If CxPOL = 0 (non-inverted polarity): // 1 = CxVP > CxVN // 0 = CxVP < CxVN // CM1CON0[5] CxOE: Comparator Output Enable bit // 1 = CxOUT is present on the CxOUT pin. Requires that the associated TRIS bit be cleared to actually // drive the pin. Not affected by CxON. // 0 = CxOUT is internal only // CM1CON0[4] CxPOL: Comparator Output Polarity Select bit // 1 = Comparator output is inverted // 0 = Comparator output is not inverted // CM1CON0[3] Unimplemented: Read as e0f // CM1CON0[2] CxSP: Comparator Speed/Power Select bit // 1 = Comparator operates in normal power, higher speed mode // 0 = Comparator operates in low-power, low-speed mode // CM1CON0[1] CxHYS: Comparator Hysteresis Enable bit // 1 = Comparator hysteresis enabled // 0 = Comparator hysteresis disabled // CM1CON0[0] CxSYNC: Comparator Output Synchronous Mode bit // 1 = Comparator output to Timer1 and I/O pin is synchronous to changes on Timer1 clock source. // Output updated on the falling edge of Timer1 clock source. // 0 = Comparator output to Timer1 and I/O pin is asynchronous. // ******************************************************* CM1CON0 = 0b10000100; // ******************************************************* // 3.CM1CON1: COMPARATOR CX CONTROL REGISTER 1 // CM1CON1[7] CxINTP: Comparator Interrupt on Positive Going Edge Enable bits // 1 = The CxIF interrupt flag will be set upon a positive going edge of the CxOUT bit // 0 = No interrupt flag will be set on a positive going edge of the CxOUT bit // CM1CON1[6] CxINTN: Comparator Interrupt on Negative Going Edge Enable bits // 1 = The CxIF interrupt flag will be set upon a negative going edge of the CxOUT bit // 0 = No interrupt flag will be set on a negative going edge of the CxOUT bit // CM1CON1[5-4] CxPCH<1:0>: Comparator Positive Input Channel Select bits // 00 = CxVP connects to CxIN+ pin // 01 = CxVP connects to DAC Voltage Reference // 10 = CxVP connects to FVR Voltage Reference // CM1CON1[3-2] Unimplemented: Read as e0f // CM1CON1[1-0] CxNCH<1:0>: Comparator Negative Input Channel Select bits // PIC12F/LF1822: // 0 = C1VN connects to C1IN0- pin // 1 = C1VN connects to C1IN1- pin // PIC16F/LF1823: // 00 = CxVN connects to C12IN0- pin // 01 = CxVN connects to C12IN1- pin // 10 = CxVN connects to C12IN2- pin // 11 = CxVN connects to C12IN3- pin // ******************************************************* CM1CON1 = 0b00100000; // FVR / C1IN0- // ******************************************************* // 4.CMOUT: COMPARATOR OUTPUT REGISTER // CMOUT[7-2] Unimplemented: Read as e0f // CMOUT[1] MC2OUT: Mirror Copy of C2OUT bit (PIC16F/LF1823 only) // CMOUT[0] MC1OUT: Mirror Copy of C1OUT bit // ******************************************************* CMOUT = 0b00000000; } //****************************************************************************************** // Function Name : Error_OverCurt // Title : // Input : // Output : // Description : //****************************************************************************************** void Error_OverCurt(void) { // ********************** // 1.Stop PWM // ********************** PWM1CON = PR2 ; // ********************** // 2.LED on // ********************** while(1){ PORTA |= 0b00100000; //Monitor LED ON Wait_01S((unsigned int)2); PORTA &= 0b11011111; //Monitor LED OFF Wait_01S((unsigned int)2); } } //****************************************************************************************** // Function Name : Wait_01S // Title : This function will wait n times of 0.1 seconds // Input : // Output : //****************************************************************************************** void Wait_01S(unsigned int n) { unsigned int lp; for(lp=0;lp = 1X. // T1CON(1) Unimplemented: Read as e0f // T1CON(0) TMR1ON: Timer1 On bit // 1 = Enables Timer1 // 0 = Stops Timer1 // Clears Timer1 Gate flip-flop // ******************************************************* T1CON = 0b00110001; // ******************************************************* // 2.Define T1GCON (TIMER1 GATE CONTROL REGISTER) Register // T1GCON(7) TMR1GE: Timer1 Gate Enable bit // If TMR1ON = 0: // This bit is ignored // If TMR1ON = 1: // 1 = Timer1 counting is controlled by the Timer1 gate function // 0 = Timer1 counts regardless of Timer1 gate function // T1GCON(6) T1GPOL: Timer1 Gate Polarity bit // 1 = Timer1 gate is active-high (Timer1 counts when gate is high) // 0 = Timer1 gate is active-low (Timer1 counts when gate is low) // T1GCON(5) T1GTM: Timer1 Gate Toggle Mode bit // 1 = Timer1 Gate Toggle mode is enabled // 0 = Timer1 Gate Toggle mode is disabled and toggle flip-flop is cleared // Timer1 gate flip-flop toggles on every rising edge. // T1GCON(4) T1GSPM: Timer1 Gate Single-Pulse Mode bit // 1 = Timer1 gate Single-Pulse mode is enabled and is controlling Timer1 gate // 0 = Timer1 gate Single-Pulse mode is disabled // T1GCON(3) T1GGO/DONE: Timer1 Gate Single-Pulse Acquisition Status bit // 1 = Timer1 gate single-pulse acquisition is ready, waiting for an edge // 0 = Timer1 gate single-pulse acquisition has completed or has not been started // This bit is automatically cleared when T1GSPM is cleared. // T1GCON(2) T1GVAL: Timer1 Gate Current State bit // Indicates the current state of the Timer1 gate that could be provided to TMR1H:TMR1L. // Unaffected by Timer1 Gate Enable (TMR1GE). // T1GCON(1-0) T1GSS1,T1GSS0: Timer1 Gate Source Select bits // 00 = Timer1 Gate pin // 01 = Timer0 overflow output // 10 = Comparator 1 optionally synchronized output (SYNCC1OUT) // 11 = Comparator 2 optionally synchronized output (SYNCC2OUT) // ******************************************************* T1GCON = 0b00000000; // ******************************************************* // 3.Define TMR1 Register // ******************************************************* // TMR1 data ( OSC:16MHz, FOSC/4, 1:8 Prescale value, 0.01[S];100Hz ) // 10mS(100Hz): 16MHz / 4(FOSC/4) / 8(Prescale) / 100(100Hz)==> 0d5,000(Count) ==> 0x1388(Count) // TMR1 = 0xFFFF - 0x1388 ==> 0xEC77 // TMR1 data ( OSC:16MHz, FOSC/4, 1:8 Prescale value, 0.1[S];10Hz ) // 100mS(10Hz): 16MHz / 4(FOSC/4) / 8(Prescale) / 10(10Hz) ==> 0d50,000(Count) ==> 0xC350(Count) // TMR1 = 0xFFFF - 0xC350 ==> 0x3CAF TMR1H = 0x3C; TMR1L = 0xAF; // ******************************************************* // 4.Check Timer1 // PIR1: PERIPHERAL INTERRUPT REQUEST REGISTER 1 // PIR1[7] TMR1GIF: Timer1 Gate Interrupt Flag bit // 1 = Interrupt is pending / 0 = Interrupt is not pending // PIR1[6] ADIF: A/D Converter Interrupt Flag bit // 1 = Interrupt is pending / 0 = Interrupt is not pending // PIR1[5] RCIF: USART Receive Interrupt Flag bit // 1 = Interrupt is pending / 0 = Interrupt is not pending // PIR1[4] TXIF: USART Transmit Interrupt Flag bit // 1 = Interrupt is pending / 0 = Interrupt is not pending // PIR1[3] SSP1IF: Synchronous Serial Port (MSSP) Interrupt Flag bit // 1 = Interrupt is pending / 0 = Interrupt is not pending // PIR1[2] CCP1IF: CCP1 Interrupt Flag bit // 1 = Interrupt is pending / 0 = Interrupt is not pending // PIR1[1] TMR2IF: Timer2 to PR2 Interrupt Flag bit // 1 = Interrupt is pending / 0 = Interrupt is not pending // PIR1[0] TMR1IF: Timer1 Overflow Interrupt Flag bit // 1 = Interrupt is pending / 0 = Interrupt is not pending // ******************************************************* // (1)Clear the TMR1IF Flag bit PIR1 &= 0b11111110; // (2)Check the TMR1IF Flag bit while((PIR1 &= 0b00000001) == 0 ); }