MasterCat писал(а):
с примерчиком. шоб понятно было.
Чтоб было понятно. Только в майне будет пустой цикл, а все задачи рассредоточены по кейсам...
Код:
#include <pic.h>
#include "delay.h"
#include "main.h"
#define r1 un.bt.d1
#define r2 un.bt.d2
#define r3 un.bt.d3
#define r4 un.bt.d4
#define HOT un.bt.e1
#define ARK un.bt.e2
#define RELE un.bt.e3
#define FAN un.bt.e4
#define DIG un.led_port
#define PWM_ARC CCPR1L // Регистр длит. импульса ШИМа преобразователя.
#define PWM_REF CCPR2L // Регистр длит. имп. ШИМа опорного напряжения (задания)
#define I_U RC0 // тумблер индикации "Напряжение/Ток"
#define Lat_LED RC4 // защелка регистров 74HC595
//----------------------------
#define vref_p 4860 // в миливольтах
#define vref_m 0
#define lsb (vref_p - vref_m)/1024.0
#define k 10
//----------------------------
#define Zmin 10 // Мин.скважность шим ЦАП опоры (0,1).
#define Zmax 85 // Макс.скважность шим ЦАП опоры (0,85).
#define Zfors 100 // Макс. скважность шим ЦАП опоры (1 для форсажа дуги).
#define k_ref (Zmax-Zmin)/254 // Коэфф. для масштабирования результата АЦП задания тока (для опоры).
//----------------------------
#define ind_Imin 50 // Мин. сварочный ток, А.
#define ind_Imax 155 // Макс. сварочный ток, А.
#define k_ind (ind_Imax-ind_Imin)/254 // Коэфф. для масштабирования результата АЦП задания тока (для индикации).
//-----------------------------------------------------------
__CONFIG(HS & WDTDIS & PWRTDIS & MCLRDIS & BOREN & LVPDIS & UNPROTECT & DUNPROTECT & IESODIS & FCMDIS & BORV40);
//-----------------------------------------------------------
// объявляем используемые функции
void inttostr(unsigned int tmp);
void init_(void);
unsigned int adc_Uout(void);
unsigned int adc_setIarc(void);
unsigned int adc_setIfors(void);
unsigned int adc_setIhot_start(void);
unsigned int adc_setUarc(void);
unsigned int adc_Tkey(void);
void port_leds(void);
//-----------------------------------------------------------
// объявляем глобальные переменные
unsigned char arr[4];
unsigned char PORT;
const unsigned char arr1[16]={63,6,91,79,102,
109,125,7,127,111,119,62,62,62,62,62
};// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, b, c, U, E, F==общий АНОД
volatile unsigned char count_r;
unsigned int count,count1;
double rez;
unsigned char setIarc; //регистр установок задания свар. тока
unsigned char setIfors; //регистр установок задания тока форсажа дуги
unsigned char setIhot_start; //регистр установок задания тока хот старта
unsigned int setUarc; //регистр установок задания напряжения дуги
unsigned char Tkey; //регистр температуры ключей
unsigned char set_ref;
unsigned char set_ind;
unsigned int Uout;
//-------------------
union{
struct {
unsigned d1 : 1;
unsigned d2 : 1;
unsigned d3 : 1;
unsigned d4 : 1;
unsigned e1 : 1;
unsigned e2 : 1;
unsigned e3 : 1;
unsigned e4 : 1;
}bt;
unsigned char led_port;
}un;
//-----------------
typedef union
{
struct {
unsigned char lo;
unsigned char hi;
}st;
unsigned int all;
}tun;
tun t;
//-------------------------------------------------------------
interrupt void _tmr0(void)// начало обработки прерывания
{
unsigned char temp,cnt;
if (T0IF & T0IE) // если срабатывание прерывания вызвано таймером
{
TMR0=240; //~920uS
T0IF=0;
switch (count_r)
{
case 0: break;
case 1: break;
case 2: // для 1 разряда
Lat_LED=0; // сбросили клок защелки
r4=1; // включили 1 разряд
r1=0; // выключили 4 разряд
cnt=0;
temp=arr[cnt];
//temp=arr[count_r]; // получили значение по 0 адресу
PORT=arr1[temp]; //получили образ числа
port_leds(); // и выдали на индикаторы
Lat_LED=1; // защелкнули регистры 595
break; // ушли
case 3: break;
case 4: break;
case 5:
Lat_LED=0;
r1=1;
r2=0;
cnt=1;
temp=arr[cnt];
//temp=arr[count_r];
PORT=arr1[temp];
port_leds();
Lat_LED=1;
break;
case 6: break;
case 7: break;
case 8:
Lat_LED=0;
r2=1;
r3=0;
cnt=2;
temp=arr[cnt];
//temp=arr[count_r];
PORT=arr1[temp];
port_leds();
Lat_LED=1;
break;
case 9: break;
case 10: break;
case 11:
Lat_LED=0;
r3=1;
r4=0;
cnt=3;
temp=arr[cnt];
//temp=arr[count_r];
PORT=119;
port_leds();
Lat_LED=1;
break;
}
count_r++; // добавили счетчик разрядов
if (count_r == 12) count_r=0; // если крайнее значение, обнуляем счетчик
} // выход обработки таймера
}// выход прерывания
//-----------------------------------------------------------
void main(){
init_();
while(1){
adc_setIarc();
set_ref = ((setIarc * k_ref)+Zmin); // масшабируем результат оцифровки потенциометра задания тока
PWM_REF = set_ref;
// и устанавливаем соответственнный К.зап. ШИМа ЦАПа задания тока
set_ind = ((setIarc * k_ind)+ind_Imin);//масшабируем результат оцифровки потенциометра задания тока // индицируем задание тока
inttostr(set_ind);
}// окончание бесконечного цикла
}
//--------------------------------------------------------------
void init_(void){
PORTA = 0;
PORTB = 0;
PORTC = 0;
count = 0;
PR2 = 100; // Длительность периода раб. частоты инвертора--20мксек @ 20Мгц ==50кГц.
PWM_ARC=0; //регистр длит. импульса ШИМ ключей обнулен
PWM_REF=0; //регистр длит. импульса ШИМ опоры компаратора обнулен
//----------------------------
CCP2CON=0B00001100; // Модуль ССР2 настроен, как однотактный ШИМ
CCP1CON=0B00001100; // Модуль ССР1 настроен, как однотактный ШИМ
//----------------------------
// настройка PWM1CON
PRSEN = 1; // Авторестарт модуля ШИМ после пропадания сигнала сброса
//----------------------------
// настройка ECCPAS
ECCPASE = 1; // Аппаратный сброс главного шима
ECCPAS0 = 0; // аппаратный сброс шима
ECCPAS1 = 1; // по высокому уровню
ECCPAS2 = 1; // любого из компараторов (С1 или С2)
PSSAC0 = 0; // В состоянии сброса выходы Р1А и Р1С
PSSAC1 = 0; // устанавливаются в "0"
PSSBD0 = 0; // В состоянии сброса выходы Р1B и Р1D
PSSBD1 = 0; // устанавливаются в "0"
//----------------------------
// настройка PSTRCON
STRA = 1; //Выход Р1А становлен, как выход ШИМ
//----------------------------
TRISA = 0;
TRISA6 = 1;
TRISA7 = 1;
TRISA0 = 1;
TRISB = 0;
TRISC = 0;
ANSEL = 0;
ANSELH = 0;
ANS0=1;
//----------------------------
// настройка ADСON1
VCFG0 = 0; //Vss
VCFG1 = 0; //Vdd
//----------------------------
// настройка ADСON0
// частота на 32
ADCS1 = 1;
ADCS0 = 0;
GODONE = 0;
ADON = 1; // включаем модуль АЦП
//----------------------------
TMR2ON = 1; // Таймер TMR2 включен
TMR1ON = 1; // Таймер TMR1 включен
// --------------------------
//таймер TMR0 установки
TMR0 = 240;
PSA = 0;
T0CS = 0;
T0SE = 0;// bit 4 TMR0 Source Edge Select bit: 0=low/high
//---------------------------
//SPI установки
CKE = 1; //слок в середине бита данных
CKP = 1; //
SSPSTAT = 0;
SSPM3 = 0; // делитель на 64
SSPM2 = 0;
SSPM1 = 0;
SSPM0 = 0;
SSPBUF = 0; // буфер очищен
SSPIF = 0; // флаг сброщен
SSPEN = 1; // SPI вкл
//---------------------------
//компараторы настройка
C1CH1 = 1; // С1 на C12IN2-
C1OE = 1; // C1OUT наружу
C1R = 1; // C1VIN+ внутри
C1RSEL = 1; // С1VIN+ на внутреннй цап VR1
C1ON = 1; // С1 вкл
C2ON = 1; // С2 вкл
//---------------------------
T0IE = 1; // разрешаем прерывания от TMR0
PEIE = 0; // прерывания от переферии невидимы
RBIE = 0; // прерывания от портаВ запрещены
INTE = 0; // прерывания по инт запрещены
GIE = 1; // разрешаем прерывания
PWM_ARC=45;
}
//-----------------------------------------------------------
void port_leds(void){
SSPIF = 0; // сбрасываем флаг окончания передачи SPI
SSPBUF = PORT; // сначала загружаем в буфер порт сегментов
while(!SSPIF); // ждем окончания передачи
SSPIF = 0;
SSPBUF = DIG; // и загружаем в буфер SPI маску нужного разряда
while(!SSPIF); // ждем окончания передачи
}
//------------------------------------------------
void inttostr(unsigned int tmp)
{
const unsigned int step[4]={100,10,1,1};
unsigned char i;
unsigned int val,temp,atemp;
val=tmp;
for (i=0; i<4; i++)
{
temp=step[i];
atemp=0;
while(val >= temp)
{
atemp++;
val-=temp;
}
arr[i]=atemp;
}
}
//-------------------------------------------------
unsigned int adc_setIarc(void)
{
ADFM = 0; // левое выравнивание
//----канал АN0
CHS3 = 0;
CHS2 = 0;
CHS1 = 0;
CHS0 = 0;
//------------
DelayUs(5);
GODONE=1;//запускаем преобразование
while (GODONE);//ждем завершения приобразования
setIarc = ADRESH;
}
//-------------------------------------------------
unsigned int adc_setIfors(void)
{
ADFM = 0; // левое выравнивание
//----канал АN0
CHS3 = 0;
CHS2 = 0;
CHS1 = 0;
CHS0 = 0;
//------------
DelayUs(5);
GODONE=1;//запускаем преобразование
while (GODONE);//ждем завершения приобразования
setIfors = ADRESH;
}
//-------------------------------------------------
unsigned int adc_setIhot_start(void)
{
ADFM = 0; // левое выравнивание
//----канал АN0
CHS3 = 0;
CHS2 = 0;
CHS1 = 0;
CHS0 = 0;
//------------
DelayUs(5);
GODONE=1;//запускаем преобразование
while (GODONE);//ждем завершения приобразования
setIfors = ADRESH;
}
//-------------------------------------------------
unsigned int adc_Tkey(void)
{
ADFM = 1; // правое выравнивание
//----канал АN0
CHS3 = 0;
CHS2 = 0;
CHS1 = 0;
CHS0 = 0;
//------------
DelayUs(5);
GODONE=1;//запускаем преобразование
while (GODONE);//ждем завершения приобразования
Tkey = ADRESH;
}
//-------------------------------------------------
unsigned int adc_Uout(void)
{
ADFM = 1; // правое выравнивание
//----канал АN0
CHS3 = 0;
CHS2 = 0;
CHS1 = 0;
CHS0 = 0;
//------------
DelayUs(5);
GODONE=1;//запускаем преобразование
while (GODONE);//ждем завершения приобразования
Uout = ADRESH;
}