[an error occurred while processing this directive]
Может поможет
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено En_Serg 17 августа 2005 г. 03:42
В ответ на: Измеритель числа оборотов (000-999) на PIC16 с кодом на Си. отправлено <font color=gray>Умник</font> 16 августа 2005 г. 15:25

Делали коробочку на PIC16 для измерения числа оборотов
вала. На валу был закреплен магнит, бесконтакный датчик
- неподвижный. На индикатор выводилась скорость.

Удачи.

//*************************************************************
// Программа определения числа оборотов вала экструдера
// Считывает состояние датчика и вычисляет частоту вращения
// PIC16F84, 4Mhz
//************************************************************/
#define PIC_CLK 4000000

#include

#define SENSOR RB0
#define DOT_LIGHT RA3

#define MAX_TICS 65500
#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

const unsigned char segment[12]= {
ZERO, ONE, TWO, THREE,
FOUR, FIVE, SIX, SEVEN,
EIGTH, NINE, BLANK, FUL
}; // знакогенератор

const unsigned char place[3]= { 0b00001110,
0b00001101,
0b00001011}; //адрес столбца

unsigned char digit[3]; //буфер для отдельных цифр числа оборотов

void Display(void);
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;

unsigned char new_data;

float sum; // накопленная сумма
float sum_loc; // накопленная сумма для внутр. расчетов
int middle_rot;
int num_rot; // число накоплений суммы
int num_rot_loc; // число накоплений локальной суммы
float fl_n; // обороты вала - float

unsigned char stop;
unsigned char i;

/////// BIN TO BCD CONVERSION ///////////////////////////////////////
void Int_Bin_BCD(unsigned int );
void B2_BCD(void);

unsigned char L_byte, // буфер преобразования, мл.б.
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;

float middle;


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;

DOT_LIGHT=1;


for(;;)
{

time_dot++;

for(disp_pos=0; disp_pos<3; disp_pos++)
{

if(time_limit >= MAX_TIME_LIMIT && disp_pos==0 && num_rot!=0)
{

sum_loc=sum;
num_rot_loc=num_rot;

sum=num_rot=time_limit=0;
}
else
if(disp_pos == 0)
time_limit++;

Calc_Speed();

//Рассчитаем среднее по буферным данным
if(num_rot_loc !=0)
middle=sum_loc/num_rot_loc;
else
middle=0;

disp_rot=(int)middle;
//округление
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;
}

Display();
}
} //конец бесконечного цикла
} //конец main()

//////////////////////////////////////////////////
// Функция выводит одну цифру на индикатор
// в соответствии с disp_pos
/////////////////////////////////////////////////
void Display(void)
{
OPTION=0b11001000;
INTCON=0b10110000;
CLRWDT();

TRISA=0;
PORTA=0x07; //выключаем все
TRISB=0b0000001; // RB0-на ввод, ост- на вывод
PORTB=segment[digit[disp_pos]];

if(time_dot>MAX_DOT )
PORTA= place[disp_pos];
else
PORTA= (place[disp_pos] & 0b11110111);
}

void interrupt Int_Service(void)
{
if(T0IF==1) //таймер
{
if(temp_t < MAX_TICS) // нормально
temp_t++;
else // или мало оборотов
stop=1; // нет импульсов с датчика

T0IF=0;
}
if(INTF==1)
{
for(i=0;i ;

if(SENSOR == 1)
{ if(temp_t < MIN_TICS) // много оборотов
{ stop=2;
big_time=MIN_TICS;
}
else
{
time_dot=0;

if(stop==1)
{ 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; //сбросим счетчики
}

INTF=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

decfsz _count, F
goto adjDEC
RETLW 0

adjDEC movlw _R2
movwf _FSR
call adjBCD

movlw _R1
movwf _FSR
call adjBCD

goto loop16

adjBCD movlw 3
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); //скопируем данное в буфер

B2_BCD(); // Преобразуем BIN в BCD

// Выделим в R0,R1,R2 3 цифры результата
// 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=((float)small_time_loc)/256;
val += big_time_loc;
fl_n=REDUCTION_FACTOR/val;


if(new_data==1 && disp_pos==0)
{ new_data=0;

sum += fl_n;
num_rot++;
}
}


Составить ответ  |||  Конференция  |||  Архив

Ответы


Отправка ответа

Имя (обязательно): 
Пароль: 
E-mail: 
NoIX ключ Запомнить

Тема (обязательно):
Сообщение:

Ссылка на URL: 
Название ссылки: 

URL изображения: 


Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание  |||  Без кадра

E-mail: info@telesys.ru