sbit LCD_RS at LATE5_bit;
sbit LCD_EN at LATD0_bit;
sbit LCD_D4 at LATE1_bit;
sbit LCD_D5 at LATE2_bit;
sbit LCD_D6 at LATE3_bit;
sbit LCD_D7 at LATE4_bit;
sbit LCD_RS_Direction at TRISE5_bit;
sbit LCD_EN_Direction at TRISD0_bit;
sbit LCD_D4_Direction at TRISE1_bit;
sbit LCD_D5_Direction at TRISE2_bit;
sbit LCD_D6_Direction at TRISE3_bit;
sbit LCD_D7_Direction at TRISE4_bit;
void ADC_init(void);
void pwm_init(void);
void timer1_init(void);
void InitTimer1();
volatile unsigned adc_value = 0;
char adc_txt[6];
char txt1[11];
volatile unsigned ticks_lcd;
void main() {
unsigned val = 0;
unsigned long clk=0;
trisd1_bit = 0;
latd1_bit = 0;
InitTimer1();
pwm_init();
ADC_init();
LCD_init();
lcd_cmd(_lcd_cursor_off);
lcd_cmd(_lcd_clear);
ADIF_bit = 0;
INTCON1bits.NSTDIS = 1; // interrupt nesting disabled
PTCONbits.PTEN = 1; // pwm enabled
ADON_bit = 1; // adc enabled
ADCON1bits.ASAM = 1; // auto sampling enabled
ADIE_bit = 1; // adc interrupt enabled
clk = clock_MHz();
longwordtostr(clk, txt1);
lcd_out(2, 1, txt1);
delay_ms(1000);
lcd_cmd(_lcd_clear);
while(1)
{
if(ticks_lcd == 1000)
{
val = adc_value;
wordtostr(val, adc_txt);
lcd_out(2, 4, adc_txt);
ticks_lcd = 0;
}
}
}
void ADC_init(void)
{
ADCON1 = 0x0060; // continue idle mode, integer format, motor control trigger, sequential sampling, SAMP auto = 0
ADCHS = 0x0000; // ch0 positve input AN0, ch0 negative -VREF, CH1 positive AN0, CH1 negative -VREF
ADCSSL = 0; // no scan
ADCON3 = 0x0009; // auto sample time = 0Tad, system clock, ADCS<5:0> = 9
ADCON2 = 0x0104; // converts CH0 and CH1, 2 conversions per interrupt
IPC0 = IPC0 | 0x7000; // priority 7
ADPCFG = 0xFFFE; // AN0 is analog
}
void pwm_init(void)
{
PTCON.PTEN = 0; // pwm timebase off
PWMCON1.PEN1L = 1; // PWM1L pin is configured for pwm operation
PWMCON1bits.PMOD1 = 1; // PWM1L and PWM1H pair is independent
PTCONbits.PTMOD = 2; // free running mode
PTCONbits.PTOPS = 0; // 1:1
PTCONbits.PTCKPS = 0; // 1:1 pwm timebase input clock is Tcy
PTCONbits.PTSIDL = 0; // pwm runs in idle mode
SEVTCMP = 159; // Triggers the ADC in the middle of PWM off time
PTPER = 159; // period register value. 100kHz for up-down mode
PDC1 = 160; // duty cycle 0.5
}
//Timer1
//Prescaler 1:1; PR1 Preload = 32000; Actual Interrupt Time = 1 ms
void InitTimer1(){
T1CON = 0x8000;
TMR1 = 0;
T1IE_bit = 1;
T1IF_bit = 0;
IPC0 = IPC0 | 0x6000; // priority 6
PR1 = 32000; // 1ms
}
void ADCInt() iv IVT_ADDR_ADCINTERRUPT ics ICS_AUTO
{
adc_value = ADCBUF0;
latd1_bit = !latd1_bit;
ADIF_bit = 0;
}
void T1Int() iv IVT_ADDR_T1INTERRUPT ics ICS_AUTO
{
ticks_lcd++;
T1IF_bit = 0;
}