Привет, Хабр!
Как то раз была у меня «работа» — нужно было сделать управление кассовым аппаратом Штрих-ФР-К. Так как моя карьера начиналась с ремонта ККТ, то решил взяться за эту работу.

Так выглядит сама касса и пробное изображение моего коллеги:

Так же по мимо управления движками и термоголовкой в аппарате пришлось написать небольшой скрипт на питоне с использованием библиотеки OpenCV. Итак, поехали.
Все началось с изучения рем. дока. к данной кассе и последующего подключения логического анализатора на пины термоголовки. Я отправил на печать, через штриховый тест драйвер букву «С». И вот что у меня получилось:

По DATA значение точек (всего 432 точки в строке), SCK — cинхросигнал, STB0, STB1, STB2 — стробы для нагрева термоголовки, LATCH — защелкивание данных. Строчку вбил в сдвиговый регистр, прожег, пошел дальше.
Следующий этап был доработка платы для ускорения процесса разработки.

Теперь перейдем к коду.
Есть две схемы управления шаговым двигателем для этой кассы. 4-шаговый и 8-шаговым. Я выбрал 8, так как движки работали лучше.
Код отправки данных в термоголовку. Термоголовка работает как сдвиговый регистр. Как она работает я писал выше.
Функция печати и прожига строк.
Основная функция, которая крутится в вечном вайле. Когда приходит буква «P» я включаю вход в режим печати. Далее все остальные символы начинают набиваться в буфер. Далее когда буфер набивается 54 байтами (или 432 бита), то печатаем строку и отправляем по УСАРТ слово PRINTED.
Ну вот и все с железной частью. В следующей части я распишу про программную часть, а именно про программу на питоне. Исходники.

Как то раз была у меня «работа» — нужно было сделать управление кассовым аппаратом Штрих-ФР-К. Так как моя карьера начиналась с ремонта ККТ, то решил взяться за эту работу.

Так выглядит сама касса и пробное изображение моего коллеги:

Так же по мимо управления движками и термоголовкой в аппарате пришлось написать небольшой скрипт на питоне с использованием библиотеки OpenCV. Итак, поехали.
Все началось с изучения рем. дока. к данной кассе и последующего подключения логического анализатора на пины термоголовки. Я отправил на печать, через штриховый тест драйвер букву «С». И вот что у меня получилось:

По DATA значение точек (всего 432 точки в строке), SCK — cинхросигнал, STB0, STB1, STB2 — стробы для нагрева термоголовки, LATCH — защелкивание данных. Строчку вбил в сдвиговый регистр, прожег, пошел дальше.
Следующий этап был доработка платы для ускорения процесса разработки.

Теперь перейдем к коду.
void go(int n, int shag) { switch (shag) { case 0: PORTA=0b10001000; PORTD|=(1<<2); dela(n); PORTD&=0b11111011; PORTA=0; PORTD|=(1<<2); PORTD&=0b11111011; break; case 1: PORTA=0b10101010; PORTD|=(1<<2); dela(n); PORTD&=0b11111011; PORTA=0; PORTD|=(1<<2); PORTD&=0b11111011; break; case 2: PORTA=0b00100010; PORTD|=(1<<2); dela(n); PORTD&=0b11111011; PORTA=0; PORTD|=(1<<2); PORTD&=0b11111011; break; case 3: PORTA=0b01100110; PORTD|=(1<<2); dela(n); PORTD&=0b11111011; PORTA=0; PORTD|=(1<<2); PORTD&=0b11111011; break; case 4: PORTA=0b01000100; PORTD|=(1<<2); dela(n); PORTD&=0b11111011; PORTA=0; PORTD|=(1<<2); PORTD&=0b11111011; break; case 5: PORTA=0b01010101; PORTD|=(1<<2); dela(n); PORTD&=0b11111011; PORTA=0; PORTD|=(1<<2); PORTD&=0b11111011; break; case 6: PORTA=0b00010001; PORTD|=(1<<2); dela(n); PORTD&=0b11111011; PORTA=0; PORTD|=(1<<2); PORTD&=0b11111011; break; case 7: PORTA=0b10011001; PORTD|=(1<<2); dela(n); PORTD&=0b11111011; PORTA=0; PORTD|=(1<<2); PORTD&=0b11111011; break; } }
Есть две схемы управления шаговым двигателем для этой кассы. 4-шаговый и 8-шаговым. Я выбрал 8, так как движки работали лучше.
#define DATA 2 #define SCK 1 #define LATCH 3 #define STB0 2 #define STB1 3 #define STB2 4 #define DATA_IN PORTB #define STB_IN PORTE int sck() { _delay_us(3); DATA_IN|= (1<<SCK); DATA_IN&= 0b11111101; } int x; int bit; void bait(int bait1) { x=0; while(x<8) { bit|= (1<<x); bit =bait1&bit; if (bit>0) { DATA_IN|=(1<<DATA); } else {DATA_IN&=0b11111011;} sck(); x++; } } void latch() { DATA_IN&=0b11110111; DATA_IN|=(1<<LATCH); }
Код отправки данных в термоголовку. Термоголовка работает как сдвиговый регистр. Как она работает я писал выше.
void print_all_pixel() { while(n<55) { print_stroka(str[n]); _delay_us(3); n++; } latch(); n=0; STB_IN&=0b11111011; _delay_us(500); STB_IN|=(1<<STB0); STB_IN&=0b11110111; _delay_us(500); STB_IN|=(1<<STB1); STB_IN&=0b11101111; _delay_us(500); STB_IN|=(1<<STB2); //vpered(300); //n=0; //_delay_ms(100); //vpered(100); }
Функция печати и прожига строк.
void recieve() { ///while(f); if ((com==0x50)&&(rezhim==0))/// P { //USART_Transmit('X'); com=0; USART_Transmit('B'); rezhim=1; } if ((rezhim==1)&&(send!=0)) { str[iFF]=com; send=0; iFF++; if (send == 1) { USART_Transmit('B'); } if (iFF==54) { USART_Transmit('P'); USART_Transmit('R'); USART_Transmit('I'); USART_Transmit('N'); USART_Transmit('T'); USART_Transmit('E'); USART_Transmit('D'); PORTB|=1<<0; _delay_ms(1); print_all_pixel(); //print_all_pixel(); go1(1500,ggg); rezhim=0; iFF=0; ggg++; if (ggg==8) { ggg=0; } } } if ((com==0x52)&&(rezhim==0))///R { com=0; go1(1000,ggg); rezhim=0; iFF=0; ggg++; if (ggg==8) { ggg=0; } USART_Transmit('O'); USART_Transmit('K'); //vpered(300); } }
Основная функция, которая крутится в вечном вайле. Когда приходит буква «P» я включаю вход в режим печати. Далее все остальные символы начинают набиваться в буфер. Далее когда буфер набивается 54 байтами (или 432 бита), то печатаем строку и отправляем по УСАРТ слово PRINTED.
Ну вот и все с железной частью. В следующей части я распишу про программную часть, а именно про программу на питоне. Исходники.

