Sample program for SU controllers

Below I present the source codes of an example program for the SU 1.2 driver and the SU 1.5 driver. The program was written in C, in the Atmel Studio 6 environment.

The program displays an inscription on the display and the status of digital outputs can be changed using the keys.

The entire program has been divided into three files:

  • the file „example_C_SU_12.c” contains the main program,
  • the „lcd.c” file contains procedures for operating the LCD display.
  • the file „procedures.c” contains the remaining procedures.

The main program was divided into three parts:

  • appropriate configuration of TIMER 0 and processor pins,
  • displaying the text on the LCD display,
  • in the main loop, the controller reads the pressed key and changes the state of the outputs accordingly.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <avr/io.h>
#include "avr/interrupt.h"
#include "procedury.h"
#include "global.h"
#include "avr/pgmspace.h"
#include "lcd.h"
 
#define KL_UP       0x02
#define KL_LEFT     0x03
#define KL_DOWN     0x04
#define KL_RIGHT    0x05
#define KL_OK       0x06
#define KL_ESC      0x07
 
volatile unsigned short ms, usx10;
volatile unsigned char KLAWISZ_P, KLSZ, KLAWISZ;
 
unsigned char const napis1[] PROGMEM=   {   "Sterownik SU 1.2á"};
unsigned char const napis2[] PROGMEM=   {   " firmy E-TRONIX á"};
     
int main(void)
{
    unsigned char wyjscie;
     
//poniżej konfiguracja TIMER-a 0,
// TIMER 0 wykorzystany jest do obsługi klawiatury 
    OCR0=91;
    TIFR=0;
    TCCR0=(1<<WGM01)|(0<<CS02)|(1<<CS01)|(0<<CS00);
     
    TIMSK=(1<<OCIE0);//załączenie przerwań od TIMER-a 0
 
    sei(); //globalne załączenie przerwań
 
    DDRB=0xff;      //magistrala danych jako wyjscie
    sbi(DDRD,4);    //aktywacja pinu wyswietlacza
    sbi(DDRC,6);    //aktywacja pinu ING1 odczytu wejsc cyfrowych
    sbi(DDRC,7);    //aktywacja pinu do sterowania wyjsc cyfrowych
    sbi(DDRA,4);    //aktywacja pinu /OE wyjsc cyfrowych
    sbi(PORTC,6);   //stan wysoki na ING1
    sbi(PORTC,7);   //stan wysoki na OUTG1
    cbi(PORTA,4);   //stan niski na /OE (sterowanie wyjsc cyfrowych mozliwe)
    sbi(PORTD,4);   //stan wysoki na DISPLAY
 
    LCD_init();     //inicjalizacja wyświetlacza LCD
    LCD_clear();    //wyczyszczenie wyświetlacza
    LCD_TXT(napis1);//wyświetlenie napisu pierwszego w wierszu pierwszym
    LCD_xy(1,2);
    LCD_TXT(napis2);//wyświetlenie napisu drugiego w wierszu drugim
    wyjscie=0;
    while(1)        //pętla główna programu
    {
        switch(KLAWISZ) // w zależności od naciśniętego klawisza sterowane
                        // jest wyjscie cyfrowe
        {
            case KL_UP:
            wyjscie=wyjscie^0b10000001; //wyjście przekaźnikowe nr 1
            KLAWISZ=0;
            break
 
            case KL_DOWN:
            wyjscie=wyjscie^0b01000010; //wyjście przekaźnikowe nr 2
            KLAWISZ=0;
            break;
 
            case KL_LEFT:
            wyjscie=wyjscie^0b00000100; //wyjście przekaźnikowe nr 3
            KLAWISZ=0;
            break;
 
            case KL_RIGHT:
            wyjscie=wyjscie^0b00001000; //wyjście przekaźnikowe nr 4
            KLAWISZ=0;
            break;
 
            case KL_ESC:
            wyjscie=wyjscie^0b00010000; //wyjście tranzystorowe nr 1
            KLAWISZ=0;
            break;
 
            case KL_OK:
            wyjscie=wyjscie^0b00100000; //wyjście tranzystorowe nr 2
            KLAWISZ=0;
            break;
 
        }
        PORTB=wyjscie;  //wystawienie danej na magistralę danych
        cbi(PORTC,7);   //zatrzaśnięcie z magistrali danych na wyjścia cyfrowe
        sbi(PORTC,7);              
    }
}

The „lcd.c” file contains procedures for operating the display:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#include "global.h"
#include <avr/io.h>
#include "procedury.h"
#include "avr/pgmspace.h"
 
/*
*************************************************
* Procedura zapisująca dane w wyświetlaczu LCD. *
*************************************************
*/
 
void LCD_clock(u08 data, u08 rs)
{
 
 MAGIST_DATA=((data&0x0f)<<4);
 
  if (rs==1)                        // linia RS wyświetlacza
    sbi(MAGIST_DATA,LCD_RS);        // ustaw linię RS wyświetlacza
    else cbi(MAGIST_DATA,LCD_RS);
 
 cbi(PORTB,1);
 sbi(DDRD,4);   
 
 sbi(MAGIST_DATA,LCD_EN);           // ustaw linię EN wyświetlacza
 
 wait(1);
 cbi(PORTD,4);                      // i wysłanie danych na szynę
 sbi(PORTD,4);
 
 wait(1);
 cbi(MAGIST_DATA,LCD_EN);           // skasuj linię EN wyświetlacza
 
 wait(1);
 cbi(PORTD,4);
 sbi(PORTD,4);
 
 wait(1);
 cbi(MAGIST_DATA,LCD_RS);           // skasuj liniŕ RS wyświetlacza
}
 
/*
*************************************************
* Wysyłanie danych lub komend do wyświetlacza.  *
*************************************************
*/
void LCD_send(u08 data, u08 rs)
{
  LCD_clock(data >> 4  , rs); // bardziej znacząca część
  LCD_clock(data & 0x0F, rs);   // mniej znacząca część
}
 
/*
*************************************************
* Procedura wysyłająca komendy do wyświetlacza. *
*************************************************
*/
void LCD_send_0(u08 ch)
{
  LCD_send(ch, 0);
}
 
/*
*************************************************
* Procedura wysyłająca dane do wyświetlacza LCD.*
*************************************************
*/
void LCD_send_1(u08 ch)
{
  LCD_send(ch, 1);
}
 
/*
*************************************************
* Procedura czyszcząca wyświetlacz LCD.         *
*************************************************
*/
void LCD_clear(void)
{
 LCD_send_0(0x01);  // wyczyść LCD
 
 wait(100);
}
 
/*
*************************************************
* Procedura inicjująca wyświetlacz LCD.         *
*************************************************
*/
void LCD_init(void)
{
 register unsigned char i;
 
 wait(1600);
  for(i=0;i<3;i++)
  {
    LCD_clock(0x03, 0); //reset LCD
    wait(40);
  }
  LCD_clock(0x02,0);    //operacje 4-bitowe
  LCD_send_0(0x2C);  
  LCD_send_0(0x08); //wylacz lcd, wylacz kursor, wlacz mruganie kursora
  LCD_clear();      //skasuj lcd, kursor do pozycji home
  LCD_send_0(0x06);     //przesuwaj kursor w prawo w trakcie wyswietlania
  LCD_send_0(0x0C);     //wlacz lcd i wyłącz kursor
}
 
/*
*************************************************
* Procedura wyświetlająca znak na wyświelaczu   *
* LCD.                                          *
*************************************************
*/
void LCD_putchar(char ch)
{
 
  LCD_send_1(ch);
 
}
 
 
/*
*************************************************
* Procedura wyświetlająca napis umieszczony     *
* w pamięci programu.                           *
*************************************************
*/
void LCD_TXT(unsigned char tablica[])
{
unsigned char x;
 x=0;
 for (x=0; pgm_read_byte(&tablica[x])!='á'; x++)
    {
     LCD_putchar(pgm_read_byte(&tablica[x]));
    }
 
}
 
/*
*************************************************
* Procedura umieszczająca kursor wyświetlacza   *
* na odpowiednich współrzędnych.                *
*************************************************
*/
void LCD_xy(u08 x, u08 y)
{
  switch(y)
  {
    case 1: y=0x00; break; // adres 1 znaku 1 wiersza
    case 2: y=0x40; break; // adres 1 znaku 2 wiersza
  }
  LCD_send_0(0x80+y+x-1);   // ustaw adres RAM
}

The „procedury.c” file contains, among others: TIMER 0 interrupt handling:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include "avr/interrupt.h"
#include "global.h"
#include "procedury.h"
#include "lcd.h"
#include "avr/pgmspace.h"
 
#define KL_UP       0x02
#define KL_LEFT     0x03
#define KL_DOWN     0x04
#define KL_RIGHT    0x05
#define KL_OK       0x06
#define KL_ESC      0x07
 
 
 
volatile extern unsigned char KLAWISZ_P, KLSZ, KLAWISZ;
volatile extern unsigned short ms, usx10;
 
/*
*****************************************************
*  Obsługa przerwania TIMER-a 0, przerwanie to      *
*  odpowiedzialne jest za obsługę klawiatury w
*  sterowniku.                                      *
*****************************************************
*/
ISR(TIMER0_COMP_vect)
 
{
 usx10++;
// if (us==8) us=0;
 ms++;
 if (ms==400)
    {
     ms=0;
     KLAWISZ_P=0;
     if (bit_is_clear(PINC,PC2)) KLAWISZ_P=KL_UP;
     if (bit_is_clear(PINC,PC3)) KLAWISZ_P=KL_LEFT;
     if (bit_is_clear(PINC,PC4)) KLAWISZ_P=KL_DOWN;
     if (bit_is_clear(PINC,PC5)) KLAWISZ_P=KL_RIGHT;
     if (bit_is_clear(PINA,PA6)) KLAWISZ_P=KL_ESC;
     if (bit_is_clear(PINA,PA7)) KLAWISZ_P=KL_OK;
     if (KLAWISZ_P!=0) KLSZ=KLAWISZ_P;
     if ((KLAWISZ_P==0)&&(KLSZ!=0))
        {
         KLAWISZ=KLSZ;
         KLSZ=0;
        }
    }
}
 
 
 
/*
*****************************************************
*  Porcedurka odmierzania czasu.                    *
*****************************************************
*/
void wait(unsigned short czas)
{
 usx10=0;
 while (usx10!=czas);
}

The effect of the program

Scroll to Top