Convert code PIC16F88 to PIC16F887

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Kocmuk
Родился
Сообщения: 1
Зарегистрирован: Пн ноя 21, 2011 15:32:44

Convert code PIC16F88 to PIC16F887

Сообщение Kocmuk »

Есть код на PIC16F88. Сам проект находится отсюда http://www.best-microcontroller-project ... sonar.html

Код: Выделить всё

//////////////////////////////////////////////////////////////////////
// File: bit.h
//
// Description: Bit manipulation macros
//
//    These macros preserve the current value of the 'PORT' or register.
//
//    WRITEPORT is the same as writing to a port
//    but preserves the keepmask bits.
//
//////////////////////////////////////////////////////////////////////
// See below for detailed description of WRITEPORT(port,newval,keepMask)
#define WRITEPORT(port,newval,keepMask) \
    (port) =  ((newval) & (~keepMask)) | ((port) & (keepMask));
#define setBit(var, bitnum)   (var)|=(1<<(bitnum))
#define resBit(var, bitnum)   (var)&=~(1<<(bitnum))
#define clearBit(var, bitnum) (var)&=~(1<<(bitnum))
#define testBit(var, bitnum)  (var)&(1<<(bitnum))
///////////////////////////////////////////////////////////////////////
//
// Macro: WRITEPORT(port,newval,keepMask)
//
// Description: A macro to write only to specific bits of a port.
//
// Author: John Main.
//
//  The PORT is read, keepMask bits are preserved when the
//  data value is output to the port.
//
// Note this macro reads the specified port
//
// Beware of port loading (too much current) e.g. if drive an LED with
//   larger current then the input high voltage will not be met
//   (see data sheet graphs of Voh vs Io) so reading back a zero.
// If this is a problem the use a variable to hold the port state
//    and only read/update this, the putput to port.
//
// Breakdown of action of macro WRITEPORT.
//
//  1. Read the port and only keep the desired 'keepMask' bits.
//
//      e.g. if the current value of the port is 0x6b
//      and the mask is 0x0c (keep bits b3..2) from the port read.
//
//       ((port) & (keepMask)) results in 0x6b & 0x0c
//            0110-1011 port
//            0000-1100 keepMask
//            000001000 Result 1
//
//  2. Create the output value and send only to the used bits
//     i.e. to the non 'keepMask' bits of the port.
//     e.g. if newval is 0xa7 (1010-0111)
//
//       ((newval) & (~keepMask))
//            1010-0111 newval
//            1111-0011 ~keepMask
//            1010-0011 Result 2
//
//  3. 'OR' these together to get the final result.
//            0000-1000 Result 1
//            1010-0011 Result 2
//            1010-1011 Ored Result 3
//
//////////////////////////////////////////////////////////////////////

Код: Выделить всё

//////////////////////////////////////////////////////////////////////
//
// File: 16F88_Ultrasonic_ranger.c
//
// Author: J F Main.
//
// Description:
//
//   Range finding by generation and reception of
//   ultrasonic audio at 40kHz.
//
// Compiler : mikroC, mikroElektronika C compiler
//            for Microchip PIC microcontrollers
//            Version: 5.0.0.3
//
// Note Testing:
//
//   Tested on 16F88
//
// Requirements:
//
//   40kHz Ultrasonic amplifier (transistor amp).
//
//   40kHz ultrasonic transducer - for different transducers
//   e.g. for a 32kHz transducer change the software appropriately.
//
//   Target : 16F88
//
// Notes :
//
//  For the CCP module (16F88):
//  Which pin is used is controlled by bit 12 of the configuration
//  word (either RB0 or RB3).  Use the compiler settings to set the
//  configuration word i.e. you can not set this from within the
//  source code
//
//  This software uses RB0 as input to the CCP module.
//
// RB0 : ultrasonic in  (via amplifier, peak hold, level detect).
// RB3 : ultrasonic out (40kHz pulses)
//
// Version:
// 1.02 22/Feb/06 - moved segment drives to free TX pin for debug
//   SEG1 was on RB2 now on RB5
//   SEG2 was on RB5 now on RB2
// 1.01 15/Feb/06 - Changed to compiler 5.0.0.3
//   More efficient so had to re-code gen_ultra for correct frequency.
// 1.00 14/Feb/06 - Initial release.
//
// Copyright : Copyright © John Main 2006
//   http://www.best-microcontroller-projects.com
//   Free for non commercial use as long as this entire copyright notice
//   is included in source code and any other documentation.
//
//////////////////////////////////////////////////////////////////////
#include "bit.h"

//////////////////////////////////////////////////////////////////////
// macros

//////////////////////////////////////////////////////////////////////
// globals for interrupt.
//
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.
}

//////////////////////////////////////////////////////////////////////
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
}

//////////////////////////////////////////////////////////////////////
// RA% can only be input on 16F88
// ret table is for straight through
// PORT 0 1 2 3 4 5 6 7 to a b c d e f g dp
// So map to new outputs:
// 0 a, 1 b, 2 c, 3 d, 4 e, 6 f, 7 g - loosing dp
// i.e. keep 1st 5 and move bits 5,6 to 6,7

int2seg(unsigned short digit) {
unsigned short r;
unsigned short ret[10] = { 0x3F, 0x06, 0x5B, 0x4F, 0x66,
                           0x6D, 0x7D, 0x07, 0x7F, 0x6F };

   if (digit<0 || digit>9) {
      r = 0x7f;
   } else {
      r =(  ret[digit] & 0x1f ) | \
         ( (ret[digit] & 0x60)<< 1);
   }

   return r;
}
//////////////////////////////////////////////////////////////////////
void seg_display_int(unsigned 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.
    PORTA=int2seg(op[2]-'0');
    setBit(PORTB,5);
    delay_ms(4);
    resBit(PORTB,5);

    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) {

   setBit(PORTB,3);
   delay_us(12);
   resBit(PORTB,3);
   delay_us(11);

   setBit(PORTB,3);
   delay_us(12);
   resBit(PORTB,3);
   delay_us(11);

   setBit(PORTB,3);
   delay_us(12);
   resBit(PORTB,3);
   delay_us(11);

   setBit(PORTB,3);
   delay_us(12);
   resBit(PORTB,3);
   delay_us(11);
}

//////////////////////////////////////////////////////////////////////
void main() {
unsigned int i,val,s1,s2,tH,tL,tO;
char op[12];
unsigned long calc=0;

   init_ports();
   init();

   gCapInt=0; // Reset capture indicator.
   gen_ultra();

   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

         // 4MHz clock so timer 1 returns us
         // gCapVal * 1,000,000 = seconds.
         // speed of sound in air at 20degC = 340m/s
         // (gCapVal*1000000*340)/(2*100) = distance in cm

         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
}
Надо код переделывать под PIC16f887? Полностью или частично?
Реклама
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»