moindsp
Newbie level 6

- Joined
- Sep 16, 2009
- Messages
- 14
- Helped
- 0
- Reputation
- 0
- Reaction score
- 0
- Trophy points
- 1,281
- Location
- Karlskrona
- Activity points
- 1,412
Hello
I am using PIC16F887A with 8Mhz Crystal to do range measurement the transducers are standard 40Khz Tx and RX module , The problem is 37 always appear on the LCD screen , The code goes here , Its compiled with
mikroc_pro_pic_2011_v460
Downloaded from
https://www.mikroe.com/eng/downloads/get/29/mikroc_pro_pic_2011_v460_setup.zip
The output is from Pin B3 and input on B0
//////////////////////////////////////////////////////////////////////////////////////////////
sbit LCD_RS at RE2_bit;
sbit LCD_EN at RC2_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;
sbit LCD_RS_Direction at TRISE2_bit;
sbit LCD_EN_Direction at TRISC2_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
extern sfr sbit Abit;
sbit Abit at PORTB.B3;
unsigned int T1_O = 0; // timer1 overflow updated in interrupt routine.
unsigned short gCapInt = 0; // captured something in interrupt routine.
unsigned short gfCapOn = 1; // control capture only capture 1st value.
unsigned int t_capL = 0; // timer 1 low.
unsigned int t_capH = 0; // timer 1 high.
unsigned int t_capO = 0; // timer 1 overflow.
unsigned int gCapVal = 0; // captured this.
//////////////////////////////////////////////////////////////////////
void init(void) {
// OSCCON = 0x60; // b6..4 = 110 = 4MHz
// set CCP to capture mode every rising edge.
CCP1CON = 0x05;
// ANSEL = 0; // all ADC pins to digital I/O
// Timer 1 on
T1CON = (1<<TMR1ON);
}
//////////////////////////////////////////////////////////////////////
void init_ports(void) {
PORTA = 0;
TRISA = 0; // 0=o/p - sets analogue pins to digital output.
PORTB = 0;
TRISB = 0x01; // 0=o/p Receive on RB0.
// PORTD = 0;
// TRISD = 0;
}
//////////////////////////////////////////////////////////////////////
void enable_interrupts(void) {
// Timer 1
PIR1 &= ~(1<<TMR1IF); // Zero T1 overflow register value.
// Capture
PIR1 &= ~(1<<CCP1IF); // Zero Capture flag
// Interrupt enable.
PIE1 = (1<<CCP1IE);
// Global interrupt enable.
INTCON = (1<<GIE) | (1<<PEIE); // enable global & peripheral
}
//////////////////////////////////////////////////////////////////////
void disable_interrupts(void) {
INTCON &= ~(1<<GIE); // disable global & peripheral
}
void seg_display_int(int val) {
char op[7];
IntToStr(val,op);
// 6 digits op by above.
// e.g. for num 1234
// pos 5 4 3 2 1 0
// num x x 1 2 3 4 \0
// index from left ! 0 1 2 3 4 5
// Display the lower 4 digits.
Lcd_Out(2, 1, op) ;
Lcd_Out(2, 1, op) ;
/* PORTA=int2seg(op[2]-'0');
setBit(PORTB,5);
delay_ms(4);
resBit(PORTB,5);
Lcd_Config(&PORTA,1,2,0,3,5,4,6);
PORTA=int2seg(op[3]-'0');
setBit(PORTB,2);
delay_ms(4);
resBit(PORTB,2);
PORTA=int2seg(op[4]-'0');
setBit(PORTB,6);
delay_ms(4);
resBit(PORTB,6);
PORTA=int2seg(op[5]-'0');
setBit(PORTB,7);
delay_ms(4);
resBit(PORTB,7);
PORTB &= ~0xe4; // turn off all resBit should do this
PORTB=0; */
// PORTA=0x00;
}
//////////////////////////////////////////////////////////////////////
// generate 4 pulses of ultrasonic @ 32kHz (8 periods of 32kHz).
// Use the simulator to set correct period.
// single ended drive
void gen_ultra(void) {
Abit = 1; // setBit(PORTB,3);
// original 12 usc and 11 usec
delay_us(12);
Abit = 0; // resBit(PORTB,3);
delay_us(11);
Abit =1; // setBit(PORTB,3);
delay_us(12);
Abit = 0; //resBit(PORTB,3);
delay_us(11);
Abit = 1;// setBit(PORTB,3);
delay_us(12);
Abit = 0; //resBit(PORTB,3);
delay_us(11);
Abit= 1;//setBit(PORTB,3);
delay_us(12);
Abit = 0;//resBit(PORTB,3);
delay_us(11);
}
void main() {
int j = -4220,val;
char txt[7];
unsigned int i,s1,s2,tH,tL,tO;
char op[12];
unsigned long calc=0;
// IntToStr(j,txt);
// Lcd_Init();
init_ports();
init();
Lcd_Init();
//Lcd_Config(&PORTD,1,2,0,3,5,4,6);
Lcd_Cmd(_LCD_CLEAR); // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off
//Lcd_Out(1,1,"Initializing");
//Delay_ms(2000);
Lcd_Out(1, 1, "UltraSonicRanger") ;
Lcd_Out(2, 5, "cm") ;
gCapInt=0; // Reset capture indicator.
while(1) {
gfCapOn = 1; // allow one capture value
tO = T1_O; // Get the current timer value.
tH = TMR1H;
tL = TMR1L;
t_capL = 0; t_capH = 0; t_capO = 0; // initialise capture
gen_ultra();
enable_interrupts();
seg_display_int(val);
disable_interrupts(); // had 20 ish ms of time so stop
if (! gCapInt) { // no echo from soft output ? try loud
enable_interrupts();
seg_display_int(val);
seg_display_int(val);
disable_interrupts(); // had 20 ish ms of time so stop
}
// Did we get any echo from soft or loud ?
if (gCapInt) { // captured anything ?
gCapInt=0; // reset for next time
s1=(t_capH-tH);
s2=(t_capL-tL);
calc = ((s1)<<8)+s2;
calc *= 34;
calc /= 2000; // output in cm
val = (int)calc;
}
} // while(1)
}
////////////////////////////////////////////////////////////////////////
void interrupt(void) {
// Free run Timer 1 get the overflow to extend counter here.
if (PIR1 & (1<<TMR1IF) ) { // T1 overflowed ?
PIR1 &= ~(1<<TMR1IF); // clear timer1 overflow bit.
T1_O++;
}
// Capture
if (PIR1 & (1<<CCP1IF)) {
PIR1 &= ~(1<<CCP1IF); // Zero Capture flag.
if (gfCapOn) { // allow only 1 capture
gfCapOn = 0;
t_capL = CCPR1L;
t_capH = CCPR1H;
t_capO = T1_O;
gCapInt = 1; // signal that a capture occured.
}
}
// Interrupts are only enabled at a specific point from program.
// They are not re-enabled here
// Note GIE set by RETFIE instruction
}
///////////////////////////////////////////////////////////////////////////////////////////////////
regards
Moin Karlskrona SE
I am using PIC16F887A with 8Mhz Crystal to do range measurement the transducers are standard 40Khz Tx and RX module , The problem is 37 always appear on the LCD screen , The code goes here , Its compiled with
mikroc_pro_pic_2011_v460
Downloaded from
https://www.mikroe.com/eng/downloads/get/29/mikroc_pro_pic_2011_v460_setup.zip
The output is from Pin B3 and input on B0
//////////////////////////////////////////////////////////////////////////////////////////////
sbit LCD_RS at RE2_bit;
sbit LCD_EN at RC2_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;
sbit LCD_RS_Direction at TRISE2_bit;
sbit LCD_EN_Direction at TRISC2_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
extern sfr sbit Abit;
sbit Abit at PORTB.B3;
unsigned int T1_O = 0; // timer1 overflow updated in interrupt routine.
unsigned short gCapInt = 0; // captured something in interrupt routine.
unsigned short gfCapOn = 1; // control capture only capture 1st value.
unsigned int t_capL = 0; // timer 1 low.
unsigned int t_capH = 0; // timer 1 high.
unsigned int t_capO = 0; // timer 1 overflow.
unsigned int gCapVal = 0; // captured this.
//////////////////////////////////////////////////////////////////////
void init(void) {
// OSCCON = 0x60; // b6..4 = 110 = 4MHz
// set CCP to capture mode every rising edge.
CCP1CON = 0x05;
// ANSEL = 0; // all ADC pins to digital I/O
// Timer 1 on
T1CON = (1<<TMR1ON);
}
//////////////////////////////////////////////////////////////////////
void init_ports(void) {
PORTA = 0;
TRISA = 0; // 0=o/p - sets analogue pins to digital output.
PORTB = 0;
TRISB = 0x01; // 0=o/p Receive on RB0.
// PORTD = 0;
// TRISD = 0;
}
//////////////////////////////////////////////////////////////////////
void enable_interrupts(void) {
// Timer 1
PIR1 &= ~(1<<TMR1IF); // Zero T1 overflow register value.
// Capture
PIR1 &= ~(1<<CCP1IF); // Zero Capture flag
// Interrupt enable.
PIE1 = (1<<CCP1IE);
// Global interrupt enable.
INTCON = (1<<GIE) | (1<<PEIE); // enable global & peripheral
}
//////////////////////////////////////////////////////////////////////
void disable_interrupts(void) {
INTCON &= ~(1<<GIE); // disable global & peripheral
}
void seg_display_int(int val) {
char op[7];
IntToStr(val,op);
// 6 digits op by above.
// e.g. for num 1234
// pos 5 4 3 2 1 0
// num x x 1 2 3 4 \0
// index from left ! 0 1 2 3 4 5
// Display the lower 4 digits.
Lcd_Out(2, 1, op) ;
Lcd_Out(2, 1, op) ;
/* PORTA=int2seg(op[2]-'0');
setBit(PORTB,5);
delay_ms(4);
resBit(PORTB,5);
Lcd_Config(&PORTA,1,2,0,3,5,4,6);
PORTA=int2seg(op[3]-'0');
setBit(PORTB,2);
delay_ms(4);
resBit(PORTB,2);
PORTA=int2seg(op[4]-'0');
setBit(PORTB,6);
delay_ms(4);
resBit(PORTB,6);
PORTA=int2seg(op[5]-'0');
setBit(PORTB,7);
delay_ms(4);
resBit(PORTB,7);
PORTB &= ~0xe4; // turn off all resBit should do this
PORTB=0; */
// PORTA=0x00;
}
//////////////////////////////////////////////////////////////////////
// generate 4 pulses of ultrasonic @ 32kHz (8 periods of 32kHz).
// Use the simulator to set correct period.
// single ended drive
void gen_ultra(void) {
Abit = 1; // setBit(PORTB,3);
// original 12 usc and 11 usec
delay_us(12);
Abit = 0; // resBit(PORTB,3);
delay_us(11);
Abit =1; // setBit(PORTB,3);
delay_us(12);
Abit = 0; //resBit(PORTB,3);
delay_us(11);
Abit = 1;// setBit(PORTB,3);
delay_us(12);
Abit = 0; //resBit(PORTB,3);
delay_us(11);
Abit= 1;//setBit(PORTB,3);
delay_us(12);
Abit = 0;//resBit(PORTB,3);
delay_us(11);
}
void main() {
int j = -4220,val;
char txt[7];
unsigned int i,s1,s2,tH,tL,tO;
char op[12];
unsigned long calc=0;
// IntToStr(j,txt);
// Lcd_Init();
init_ports();
init();
Lcd_Init();
//Lcd_Config(&PORTD,1,2,0,3,5,4,6);
Lcd_Cmd(_LCD_CLEAR); // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF); // Turn cursor off
//Lcd_Out(1,1,"Initializing");
//Delay_ms(2000);
Lcd_Out(1, 1, "UltraSonicRanger") ;
Lcd_Out(2, 5, "cm") ;
gCapInt=0; // Reset capture indicator.
while(1) {
gfCapOn = 1; // allow one capture value
tO = T1_O; // Get the current timer value.
tH = TMR1H;
tL = TMR1L;
t_capL = 0; t_capH = 0; t_capO = 0; // initialise capture
gen_ultra();
enable_interrupts();
seg_display_int(val);
disable_interrupts(); // had 20 ish ms of time so stop
if (! gCapInt) { // no echo from soft output ? try loud
enable_interrupts();
seg_display_int(val);
seg_display_int(val);
disable_interrupts(); // had 20 ish ms of time so stop
}
// Did we get any echo from soft or loud ?
if (gCapInt) { // captured anything ?
gCapInt=0; // reset for next time
s1=(t_capH-tH);
s2=(t_capL-tL);
calc = ((s1)<<8)+s2;
calc *= 34;
calc /= 2000; // output in cm
val = (int)calc;
}
} // while(1)
}
////////////////////////////////////////////////////////////////////////
void interrupt(void) {
// Free run Timer 1 get the overflow to extend counter here.
if (PIR1 & (1<<TMR1IF) ) { // T1 overflowed ?
PIR1 &= ~(1<<TMR1IF); // clear timer1 overflow bit.
T1_O++;
}
// Capture
if (PIR1 & (1<<CCP1IF)) {
PIR1 &= ~(1<<CCP1IF); // Zero Capture flag.
if (gfCapOn) { // allow only 1 capture
gfCapOn = 0;
t_capL = CCPR1L;
t_capH = CCPR1H;
t_capO = T1_O;
gCapInt = 1; // signal that a capture occured.
}
}
// Interrupts are only enabled at a specific point from program.
// They are not re-enabled here
// Note GIE set by RETFIE instruction
}
///////////////////////////////////////////////////////////////////////////////////////////////////
regards
Moin Karlskrona SE