Доброго вечора. Проект цей доволі старий, тому реалізований був на Атмега8А. Проект передраний з другого контролера, який на тому підприємстві був встановлений. В квадратурного енкодера було використано тільки по одній ножці . Тобто даний контролер "не бачить" напрямку руху, і не бачить помилок енкодера при його поломці. Код виглядає так:
По одному каналу переривання ми зменшуємо амплітуду ЦАП:
// External Interrupt 0 service routine
interrupt [EXT_INT0] void ext_int0_isr(void)
{
// Place your code here
dp=1;
if(step_dac)
{
if(step_dac>=step_dac_dn)
{
step_dac=step_dac-step_dac_dn;
}
else if(step_dac){ step_dac=0; }
}
if(step_dac<0)step_dac=0;
timer_cnt=0; timer_res=0; // reset cnt data
}
По другому каналу переривання (другий енкодер) , ми збільшуємо амплітуду ЦАП:
// External Interrupt 1 service routine
interrupt [EXT_INT1] void ext_int1_isr(void)
{
// Place your code here
dp1=1;
if(step_dac<4095)step_dac=step_dac+step_dac_up;
if(step_dac>4095)step_dac=4095;
}
ЦАП у нас 12 біт, тому відлік в діапазоні від 0 до 4095. Це дорівнює значенню напруги на виході вже ОУ (після підсилення): від 0 до 10В.
Ідея зміщення різки цегли заключається в корекції амплітуди ЦАП (множення на коефіцієнт, який програмується з меню). Такий алгоритм дозволяє регулювати товщину цегли з кроком 10мм. А хочеться зробити точніше....
Програмування коефіцієнта з меню:
if(menu==2)
{
if(PLUS==0 && MINUS)
{
if(timer_button==0){if(step_dac_up<999)step_dac_up++; }
if(++timer_button>45){timer_button=42; if(step_dac_up<999)step_dac_up++;}
flags_butt=1;
}
else if(MINUS==0 && PLUS)
{
if(timer_button==0){if(step_dac_up>1)step_dac_up--; }
if(++timer_button>45){ timer_button=42; if(step_dac_up>1)step_dac_up--; }
flags_butt=1;
}
led_buff[3]=led_table[23];
led_out(step_dac_up);
}
else if(menu==1)
{
if(PLUS==0 && MINUS)
{
if(timer_button==0){if(step_dac_dn<999)step_dac_dn++; }
if(++timer_button>45){timer_button=42; if(step_dac_dn<999)step_dac_dn++;}
flags_butt=1;
}
else if(MINUS==0 && PLUS)
{
if(timer_button==0){if(step_dac_dn>1)step_dac_dn--; }
if(++timer_button>45){ timer_button=42; if(step_dac_dn>1)step_dac_dn--; }
flags_butt=1;
}
led_buff[3]=led_table[13];
led_out(step_dac_dn);
}
Оновлення даних відбувається в головному циклі так:
if(step_dac!=step_dac_buff)
{
SPI_MCP4921(step_dac);
step_dac_buff=step_dac;
timer_ovf=390;
}
Код вивода даних в ЦАП:
// === SPI DAC ======//
#define CLK PORTB.2
#define DATA PORTB.3
#define CS PORTB.4
void SPI_MCP4921(unsigned int data) // DAC
{
unsigned int mask=0b1000000000000000;
char x=0;
data = data | 0x3000;
CS=0;
delay_us(1);
for(x=0; x<16; x++)
{
if(data&mask) DATA=1;
else DATA=0;
delay_us(1);
CLK=1;
delay_us(1);
CLK=0;
delay_us(1);
mask>>=1;
}
delay_us(1);
CS=1;
}
Принципова схема пристроя:
https://drive.google.com/file/d/1S9SVnz … sp=sharing