Новичок
Профиль
Группа: Участник
Сообщений: 1
Регистрация: 21.11.2011
Репутация: нет Всего: нет
|
Есть код на PIC16F88. Сам проект находится отсюда http://www.best-microcontroller-projects.com/pic-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?
|