[an error occurred while processing this directive]
|
Делали коробочку на PIC16 для измерения числа оборотов
вала. На валу был закреплен магнит, бесконтакный датчик
- неподвижный. На индикатор выводилась скорость.
Удачи.
//*************************************************************
// Программа определения числа оборотов вала экструдера
// Считывает состояние датчика и вычисляет частоту вращения
// PIC16F84, 4Mhz
//************************************************************/
#define PIC_CLK 4000000
#include #define SENSOR RB0 #define MAX_TICS 65500 const unsigned char segment[12]= { const unsigned char place[3]= { 0b00001110, unsigned char digit[3]; //буфер для отдельных цифр числа оборотов void Display(void); unsigned char new_data; float sum; // накопленная сумма unsigned char stop; /////// BIN TO BCD CONVERSION /////////////////////////////////////// unsigned char L_byte, // буфер преобразования, мл.б. float middle; DOT_LIGHT=1; time_dot++; for(disp_pos=0; disp_pos<3; disp_pos++) if(time_limit >= MAX_TIME_LIMIT && disp_pos==0 && num_rot!=0) sum=num_rot=time_limit=0; Calc_Speed(); //Рассчитаем среднее по буферным данным disp_rot=(int)middle; //Подавим выдачу лидирующих нулей Display(); ////////////////////////////////////////////////// TRISA=0; if(time_dot>MAX_DOT ) void interrupt Int_Service(void) T0IF=0; if(SENSOR == 1) if(stop==1) INTF=0; decfsz _count, F adjDEC movlw _R2 movlw _R1 goto loop16 adjBCD movlw 3 B2_BCD(); // Преобразуем BIN в BCD // Выделим в R0,R1,R2 3 цифры результата /////////////////////////////////////////////////////////////// val=((float)small_time_loc)/256;
E-mail:
info@telesys.ru
#define DOT_LIGHT RA3
#define MIN_TICS 117
#define MAX_IMP 10
#define MAX_MIDDLE 125
//#define REDUCTION_FACTOR 117187.5 //предделитель 1:2
#define REDUCTION_FACTOR 234375 // нет предделителя
#define MAX_DOT 10
#define MAX_TIME_LIMIT 150
#define ZERO 0b10000000
#define ONE 0b11110010
#define TWO 0b01001000
#define THREE 0b01100000
#define FOUR 0b00110010
#define FIVE 0b00100100
#define SIX 0b00000100
#define SEVEN 0b10110000
#define EIGTH 0b00000000
#define NINE 0b00100000
#define BLANK 0b11111110
#define FUL 0b00011100
ZERO, ONE, TWO, THREE,
FOUR, FIVE, SIX, SEVEN,
EIGTH, NINE, BLANK, FUL
}; // знакогенератор
0b00001101,
0b00001011}; //адрес столбца
void interrupt Int_Service(void);
void Calc_Speed(void);
void Calc_Middle_All(void);
unsigned char disp_pos;
unsigned int temp_t;
unsigned int small_time;
unsigned int big_time;
unsigned int small_time_loc;
unsigned int big_time_loc;
float sum_loc; // накопленная сумма для внутр. расчетов
int middle_rot;
int num_rot; // число накоплений суммы
int num_rot_loc; // число накоплений локальной суммы
float fl_n; // обороты вала - float
unsigned char i;
void Int_Bin_BCD(unsigned int );
void B2_BCD(void);
H_byte; // старший байт
unsigned char R0, // байт результата 1
R1, // байт результата 2
R2; // байт результата 3
unsigned char count; // временный счетчик для BCD
unsigned char adj_bcd; // промеж. регистр для BCD
////////////////////////////////////////////////////////////////////
unsigned int time_dot;
int disp_rot;
unsigned char time_limit;
void main(void)
{
// Начальная инициализация
OPTION=0b11001000; //7- pull up -dis; 6- edge int - 0/1; 5- timer - int
//4 - front TMR0; 3=1 - no prescaler to TMR0; 2,1,0 - 1:2 prescaler
INTCON=0b10110000;
CLRWDT();
stop=1;
big_time_loc=MAX_TICS;
for(;;)
{
{
{
sum_loc=sum;
num_rot_loc=num_rot;
}
else
if(disp_pos == 0)
time_limit++;
if(num_rot_loc !=0)
middle=sum_loc/num_rot_loc;
else
middle=0;
//округление
if((middle-disp_rot)>=0.5)
disp_rot++;
Int_Bin_BCD(disp_rot);
digit[0]= (R0 == 0) ? 10 : R0;
digit[1]= (R0==0 && R1==0) ? 10 : R1;
digit[2]=R2;
if(stop==2) //для режима больших оборотов
digit[0]=digit[1]=digit[2]=11;
if(stop==1) //для режима стоп
{ digit[0]=digit[1]=10; digit[2]=0;
}
}
} //конец бесконечного цикла
} //конец main()
// Функция выводит одну цифру на индикатор
// в соответствии с disp_pos
/////////////////////////////////////////////////
void Display(void)
{
OPTION=0b11001000;
INTCON=0b10110000;
CLRWDT();
PORTA=0x07; //выключаем все
TRISB=0b0000001; // RB0-на ввод, ост- на вывод
PORTB=segment[digit[disp_pos]];
PORTA= place[disp_pos];
else
PORTA= (place[disp_pos] & 0b11110111);
}
{
if(T0IF==1) //таймер
{
if(temp_t < MAX_TICS) // нормально
temp_t++;
else // или мало оборотов
stop=1; // нет импульсов с датчика
}
if(INTF==1)
{
for(i=0;i
{ if(temp_t < MIN_TICS) // много оборотов
{ stop=2;
big_time=MIN_TICS;
}
else
{
time_dot=0;
{ stop=0;
big_time=temp_t=0;
small_time=TMR0=0;
new_data=1;
}
else //stop уже =0(работа)
{ stop=0;
big_time=temp_t;
small_time=TMR0;
new_data=1;
}
}
temp_t=TMR0=0; //сбросим счетчики
}
}
}
//******* BIN TO BCD CONVERSION ***********************************
void B2_BCD(void)
{
#asm
bcf _STATUS,0 ; clear the carry bit
movlw 16
movwf _count
clrf _R0
clrf _R1
clrf _R2
loop16 rlf _L_byte, F
rlf _H_byte, F
rlf _R2, F
rlf _R1, F
goto adjDEC
RETLW 0
movwf _FSR
call adjBCD
movwf _FSR
call adjBCD
addwf 0,W
movwf _adj_bcd
btfsc _adj_bcd,3 ; test if result > 7
movwf 0
movlw 30h
addwf 0,W
movwf _adj_bcd
btfsc _adj_bcd,7 ; test if result > 7
movwf 0 ; save as MSD
#endasm
}
////////////////////////////////////////////////////////////////
// Функция показывает число до 0-999 в регистрах R0,R1,R2
////////////////////////////////////////////////////////////////
void Int_Bin_BCD(unsigned int i_int)
{
L_byte=(char)i_int;
H_byte=(char)(i_int>>8); //скопируем данное в буфер
// R0=R1 & 0x0F;
R0=R1;
R0 &= 0x0F;
#asm
SWAPF _R2,W; R1=(R2 & 0xF0)>>4
ANDLW 0Fh; R2&F0 -> W
MOVWF _R1
#endasm
R2 &= 0x0F;
// теперь в R0,R1,R2 - цифры результата
}
// Функция рассчитывает число оборотов/мин по
// значениям счетчиков времени
//
///////////////////////////////////////////////////////////////
void Calc_Speed(void)
{
float val;
unsigned int small_time_loc;
unsigned int big_time_loc;
if(new_data==1 && disp_pos==0)
{ //new_data=0;
GIE=0;
small_time_loc=small_time;
big_time_loc=big_time;
GIE=1;
}
val += big_time_loc;
fl_n=REDUCTION_FACTOR/val;
if(new_data==1 && disp_pos==0)
{ new_data=0;
sum += fl_n;
num_rot++;
}
}
Ответы