PIC10F320 ADC + PWM

PIC10F320 ADC + PWM

Postby Angle » Sun Dec 15, 2019 11:17 pm

Code: Select all
// PIC10F320 Configuration Bit Settings
// 'C' source line config statements
// CONFIG
#pragma config FOSC = INTOSC // Oscillator Selection bits (INTOSC oscillator: CLKIN function disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable (Brown-out Reset disabled)
#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
#pragma config LVP = ON // Low-Voltage Programming Enable (Low-voltage programming enabled)
#pragma config LPBOR = OFF // Brown-out Reset Selection bits (BOR disabled)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
 

#include <xc.h>
#include <htc.h>
#define _XTAL_FREQ 8000000
#define MINLEVEL 73 //1.42V=>73
#define MAXLEVEL 130 //2.54V=>130
void InitPWM();
void ADCInit();
unsigned char ADCRead();
void Interrupt();
unsigned char advalue;
unsigned char PWM;
void __interrupt() interrup_handler(void)
{
       if(ADIF){
       ADCInit();
       ADCRead();
       if ((MINLEVEL>ADRES)||(ADRES>MAXLEVEL))
        {
           RA0=0;
        }
       
       }
         PIR1bits.ADIF = 0;
   
}

void main()
{

PORTA = 0b00000000;
TRISA = 0b00000100;
ANSELA = 0b00000100;
CLC1CON = 0b00000000;
CWG1CON0 = 0b00000000;

INTCONbits.GIE = 1;
INTCONbits.PEIE = 1;
PIE1bits.ADIE = 1;

ADCON=0b00101001; //Fosc/8, AN2 setted as analog input,enable ADC

ADCInit();
ADCRead();
InitPWM();
while(1)
{
   
       
   
}
}
void InitPWM()
{
PWM1CON = 0b00000000; // Clear PWM1CON
PR2 = 77; //400Hz=77
PWM1CON = 0b11000000; //Enable PWM Module, Module Output

TMR2IF = 0; //Clear the timer 2 interrupt flag
T2CON = 0b00000011; //Set prescaler to 1

TMR2ON = 1; //Enable timer 2
TRISA=0b00000100; //Enable the pwm pin output

//Set duty cycle to %70
PWM1DCH = 0b00110110 ;
PWM1DCL = 0b10000000;

return;
}

//Function to Initialise the ADC Module
void ADCInit()
{
//Port Configuration
ADCON=0b00101010;
PIE1bits.ADIE = 1;

}
//Function to Read ADC channel
unsigned char ADCRead()
{
GO_nDONE = 1;
while (GO_nDONE); // wait until conversion complete
return ADRES; //return 8 bit value*/
}


It's a simple thing I want to do, but I just couldn't do it. I'm new to MCU.
I want to do
1-)As long as the voltage I read from the RA2 pin is between 1.42V and 2.54V, the output of the RA0 pin is 400Hz with 70% Duty Cyle.
2-)If the voltage at the RA2 pin goes below 1.42V or above 2.54V while PWM is running, it will not output PWM from the RA0 pin.
3-)If the voltage on the RA2 pin is between 1.42V and 2.54V, it will continue to give PWM again.
4-)This will last forever as long as the MCU is running.

I can not. There's a mistake somewhere. It doesn't work the way I want.
1-)I get the PWM output correctly. No problem creating PWM.
2-)I can read at ADC value.
3-)But when I read the voltage from the ADC I want it to come out of PWM, but PWM continues to work.So I can't control the ADC change.
Angle
 
Posts: 1
Joined: Sun Dec 15, 2019 11:11 pm

Re: PIC10F320 ADC + PWM

Postby GettinBetter » Sun Jan 19, 2020 11:30 am

Angle wrote:.... but PWM continues to work.So I can't control the ADC change.


Well I reckon (and more learned people may disagree) the 'ADCRead' may or may set RA to 0, but if it did, then in your main loop 'InitPWM' just starts it again.
History teaches us that history doesn't teach us.
User avatar
GettinBetter
 
Posts: 43
Joined: Wed Jun 06, 2018 8:48 pm

Re: PIC10F320 ADC + PWM

Postby ric » Sun Feb 02, 2020 8:45 pm

I would disagree.
The main loop only calls InitPWM() once, before it enters the main loop.
The big problem here is assuming that setting RA0 to 0 will stop PWM.
Once you enable the PWM, it has control of the RA0 pin, and manual writes to the pin have no effect.
Then the test logic is faulty. If where you wrote to RA0 did manage to stop PWM, then it would ever restart again.
Plus the code in the interrupt service is all wrong. You should not be calling ADCInit() or ADCRead() in there. If you got an interrupt, it means the ADC is already initialised, and the read has just completed.
You should just read the result, and start another conversion.
This seems like code originally written for polling, trying to jam it into an interrupt without understanding how the peripheral works at all.
Latest test project, an LED matrix display made from one reel of addressable LEDs. here
User avatar
ric
Verified identity
 
Posts: 659
Joined: Sat May 24, 2014 2:35 pm
Location: Melbourne, Australia
PIC experience: Professional 5+ years with MCHP products


Return to ADC & Comparators

Who is online

Users browsing this forum: No registered users and 6 guests

cron