📄 absolute_pos_encoder.c
字号:
/*===============================================
(C) Easy Soft 07/2001
C code for Programable Signal Controller
- - - - - - - - - - - - - - - - - - - - - - - -
Raisonance RC-51, version 6.4.16
oscillator freq.22.1184 MHz
controller AT89S8252
================================================ */
/* This is part of big program. You can use it like an example of absolute position encoder reading.
I have been using Siemens' encoder 6FX2001-5FS12 with RS485 interface */
#pragma SMALL
#include <reg52.h>
/* characters pattern defintions table */
char code CGRom1[65] = {0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55, // "hash" 0x00
0xFF,0xFF,0xF9,0xF3,0xE7,0xF3,0xF9,0xFF, // left 0x01
0xFF,0xFF,0xF3,0xF9,0xFC,0xF9,0xF3,0xFF, // right 0x02
0xFF,0xFF,0xFB,0xF1,0xE4,0xEE,0xFF,0xFF, // up 0x03
0xFF,0xFF,0xFF,0xEE,0xE4,0xF1,0xFB,0xFF, // down 0x04
0xC0,0xC0,0xFF,0xF1,0xF1,0xF1,0xFF,0xC0, // empty box 0x05
0xC0,0xC0,0xFF,0xFF,0xFF,0xFF,0xFF,0xC0, // filled box 0x06
0xE0,0xFF,0xFF,0xFF,0xE0,0xE0,0xE0,0xE0, // line 0x07
0x00};
/* position to degree factor */
#define FACTOR 11.38
/* LCD display is working like external memory,0x00 is its base address */
at 0x00 pdata char LcdCtrlRegister, LcdVideoRam, LcdReadCtrl, LcdRead;
unsigned int POS; // absolute encoder position 12-bit Gray encoded
int ZERO = 0; // calibration of encoder
/************************** EXTERNAL ROUTINES IN ASSEMBLER LANGUAGE ******************************/
/* encoder position reading; clock signal must be within range from 100kHz up to 1MHz */
extern unsigned int PositionRead(void);
/************************************* "C" ROUTINES **********************************************/
/* 12 bit Gray to Binary conversion */
unsigned int Gray2Bin(unsigned int N)
{
char i;
unsigned int A = N;
for (i = 1; i != 13; i++) N = N^(A >> i);
return (N);
}
/* changing absolute position in binary to degree */
unsigned int DPE(void)
{
int N;
N = Gray2Bin(PositionRead());
N = N / FACTOR;
N = N - ZERO;
if (N < 0) N = N + 360;
return(N);
}
/* delay about 1 ms for 22.1184MHz crystal */
void delay (unsigned int k)
{
unsigned int i,j;
for ( j = 0; j < k; j++)
for (i = 0; i <= 148;) {
i++;
}
}
/* wait if LCD is busy */
void LcdWait (void)
{
while (LcdReadCtrl & 0x80);
}
/* write a byte to LCD's controll register */
void WriteToLcdCtrlRegister(char X)
{
LcdCtrlRegister = X;
LcdWait();
}
/* direct byte writing to LCD */
void LcdWrite(char X)
{
LcdVideoRam = X;
LcdWait();
}
/* clear LCD screen */
void LcdClrScr(void)
{
LcdCtrlRegister = 0x01;
LcdWait();
}
/* LCD initializing */
void LcdInitialize(void)
{
delay(15);
LcdCtrlRegister = 0x30;
delay(10);
LcdCtrlRegister = 0x30;
delay(10);
WriteToLcdCtrlRegister(0x30);
WriteToLcdCtrlRegister(0x3C);
WriteToLcdCtrlRegister(0x08);
WriteToLcdCtrlRegister(0x01);
WriteToLcdCtrlRegister(0x06);
WriteToLcdCtrlRegister(0x0C);
}
/* set cursor position at X, Y coordinates */
void GotoXY(char x, char y)
{
char addr;
switch (y) {
case 0:
addr = 0x80+x;
break;
case 1:
addr = 0xC0+x;
break;
case 2:
addr = 0x94+x;
break;
case 3:
addr = 0xD4+x;
break;
}
LcdCtrlRegister = addr;
LcdWait();
}
/* routine displays text at X, Y coordinates */
void WriteTextXY(char x, char y, char code *S)
{
while (*S) {
GotoXY(x, y);
LcdWrite(*S);
x++;
S++;
if (x > 19) {
x = 0;
y++;
}
}
}
/* routine defines yourown characters */
void DefineSpecialCharacters(char *ptr)
{
LcdCtrlRegister = 0x40; // set cgram definition mode
LcdWait();
while (*ptr != 0x00) {
LcdWrite(*ptr);
ptr++;
}
LcdCtrlRegister = 0x80; // switch to normal mode
LcdWait();
}
/* Bin to Dec conversion & writing the number in X, Y coordinates */
void DisplayDegree(char x, char y, int N)
{
int l=0, D;
if (N > 359) {
WriteTextXY(x, y, "---");
} else {
GotoXY(x, y);
if (N < 0) {
LcdWrite(0x2D);
N = -N;
}
D = N;
if (N >= 100) {
l = D/100;
LcdWrite(l+0x30);
D = D - 100*l;
}
if (N >= 10) {
l = D/10;
LcdWrite(l+0x30); // 10
D = D - 10*l;
}
l = D;
LcdWrite(l+0x30); // 1
LcdWrite(0xDF); // degree character
LcdWrite(0x20); // 2 blank spaces
LcdWrite(0x20);
}
}
// main programm
void main(void)
{
LcdInitialize(); // inicjowanie wy渨ietlacza lcd (tryb 8-bit體)
DefineSpecialCharacters(CGRom1);
while (1) {
POS = DPE();
DisplayDegree(0, 0, POS);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -