From b6b79e7fcf2790795e99d24a70401278333d64fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20Proch=C3=A1zka?= Date: Fri, 19 Sep 2025 15:27:19 +0200 Subject: [PATCH] Vandalized the example even more --- example.c | 452 +++++++++++++++++++++++++----------------------------- 1 file changed, 207 insertions(+), 245 deletions(-) diff --git a/example.c b/example.c index e6fe64f..e65d92d 100644 --- a/example.c +++ b/example.c @@ -3,362 +3,324 @@ //*** *** //*** K O P Y T O V1.1 *** //*** *** -//*** vandalizoval Michal Procházka *** +//*** vandalized by Michal Procházka *** //*** *** //********************************************************************** //********************************************************************** -#include <8051.h> +#include #include #include -#define TickPerSec 100 -#define NPER (0x10000-(20000000L/12/TickPerSec)) +#define TICK_RATE 100 +#define NPER (0x10000 - (20000000 / 12 / TICK_RATE)) -// Definice vstupu a vystupu -#define _P0 0x80 -#define _P1 0x90 -#define _P2 0xa0 -#define _P3 0xb0 -#define _P4 0xc0 +// Missing port definitions +__sbit __at (0xC4) P4_4; +__sbit __at (0xC3) P4_3; +__sbit __at (0xC2) P4_2; +__sbit __at (0xC1) P4_1; +__sbit __at (0xC0) P4_0; -#define Tlac1 P3_2 -#define Tlac2 P3_3 -#define Buzzer P3_6 -#define LED1 P4_2 -#define LED2 P4_3 -#define LED3 P4_4 +// I/O definitions +#define BUTTON_1 P3_2 +#define BUTTON_2 P3_3 +#define PIEZO P3_6 + +#define LED_RED P4_2 +#define LED_YELLOW P4_3 +#define LED_GREEN P4_4 #define POT P1_0 -#define SMT P1_1 -#define ZAR P1_2 -#define LB_Data P1_3 -#define LB_SCK P1_4 -#define LB_SCL P1_5 -#define LB_RCK P1_6 -#define LB_OE P1_7 +#define THERM P1_1 +#define BULB P1_2 -// TIMER se odecita v casovem preruseni -volatile uint16_t TIMER; -uint8_t LCD_Pos; - -/*************************************************************************\ -* LCD - Liquid Crystal Display * -*-------------------------------------------------------------------------* -* Description : Header file for programming of LCD display based on * -* HITACHI controller HD44780. * -*-------------------------------------------------------------------------* -* Author : Ceba & www.HW.cz Email : ceba@hw.cz * -* Developed : 06.02.2002 Last Update : 12.04.2003 * -* Version : 0.1.0 * -*-------------------------------------------------------------------------* -* Compiler : ANY Version: ANY * -* Source file : LCD.H * -*-------------------------------------------------------------------------* -* Target system : Charon II. - ATmega128, Quartz 14.7456 MHz * -* LCD SC1602A - 4.bit mode * -*-------------------------------------------------------------------------* -* Instruction D7 D6 D5 D4 D3 D2 D1 D0 * -* ============================================== * -* Display clear 0 0 0 0 0 0 0 1 * -* Cursor home 0 0 0 0 0 0 1 * * -* Entry Mode Set 0 0 0 0 0 1 I/D S * -* Display On/Off 0 0 0 0 1 D C B * -* Curs/Disp shift 0 0 0 1 S/C R/L * * * -* Function Set 0 0 1 DL N F * * * -* CG RAM addr set 0 1 ---------Acg--------- * -* DD RAM addr set 1 -------------Add--------- * -* * -* Meaning: * -* * - nonvalid bit * -* Acg - CG RAM address (CHARACTER GENERATOR) * -* Add - DD RAM address (DATA DISPLAY) * -* AC - adress counter * -* * -* I/D - 1-increment, 0-decrement * -* S - 1-display shift, 0-no display shift * -* D - 1-display ON, 0-display OFF * -* C - 1-cursor ON, 0-cursor OFF * -* B - 1-blink ON, 0-blink OFF * -* S/C - 1-display shift, 0-cursor movement * -* R/L - 1-right shift, 0-left shift * -* DL - 1-8 bits data transfer, 0-4 bits data transfer * -* N - 1-1/16 duty, 0-1/8 or 1/11 duty * -* F - 1-5x10 dot matrix, 0-5x7 dot matrix * -* BF - 1-internal operation in progress, 0-display ready * -* * -\*************************************************************************/ +#define BAR_DAT P1_3 +#define BAR_SCK P1_4 +#define BAR_SCL P1_5 +#define BAR_RCK P1_6 +#define BAR_OE P1_7 #define LCD_RS_PIN P2_4 #define LCD_RW_PIN P2_5 #define LCD_EN_PIN P2_6 -#define LCD_RS 0x10 /* rgister select */ -#define LCD_RW 0x20 /* read/write */ -#define LCD_EN 0x40 /* chip enable */ +#define KEY_COL_1 P0_0 +#define KEY_COL_2 P0_1 +#define KEY_COL_3 P0_2 +#define KEY_COL_4 P0_3 -/* --- LCD commands --- */ +#define KEY_ROW_1 P0_4 +#define KEY_ROW_2 P0_5 +#define KEY_ROW_3 P0_6 +#define KEY_ROW_4 P0_7 -#define cmd_lcd_init 0x38 +volatile uint16_t TIMER; -#define cmd_lcd_clear 0x01 -#define cmd_lcd_home 0x02 - -#define cmd_cur_shift_on 0x06 -#define cmd_cur_shift_off 0x07 - -#define cmd_lcd_on 0x0E -#define cmd_lcd_off 0x0A - -#define cmd_cur_on 0x0E -#define cmd_cur_off 0x0C - -#define cmd_cur_blink_on 0x0F -#define cmd_cur_blink_off 0x0E - -#define cmd_cur_left 0x10 -#define cmd_cur_right 0x14 - -#define cmd_scr_left 0x18 -#define cmd_scr_right 0x1C - -#define cmd_set_cgram_addr 0x40 -#define cmd_set_ddram_addr 0x80 - -void Delay(int pause) { +// Timer-based delay, waits for pause * 10 ms +void delay(int pause) { TIMER = 1 + pause; while(TIMER); } -void LCD_Pause(void) { - // Hnus, ale funguje to +uint8_t lcd_pos; + +#define LCD_RS 0x10 /* rgister select */ +#define LCD_RW 0x20 /* read/write */ +#define LCD_EN 0x40 /* chip enable */ + +// Quick'n'dirty CPU pause, just enough for the LCD to stabilize. +void lcd_pause(void) { int i = 30; while(i--); } -uint8_t LCD_State(void) { +// Reads the status register from the LCD. +uint8_t lcd_read_status(void) { uint8_t temp; - LCD_Pause(); + lcd_pause(); P2 = LCD_RW | 0x0F; - LCD_Pause(); + lcd_pause(); LCD_EN_PIN = 1; - LCD_Pause(); + lcd_pause(); temp = (P2 & 0x0F) << 4; LCD_EN_PIN = 0; - LCD_Pause(); + lcd_pause(); LCD_EN_PIN = 1; - LCD_Pause(); + lcd_pause(); temp = temp + (P2 & 0x0F); LCD_EN_PIN = 0; return temp; } -void LCD_SendCmd( uint8_t val ) +// Writes a command to the LCD. +void lcd_send_cmd( uint8_t val ) { - LCD_Pause(); + lcd_pause(); P2 = (val >> 4) & 0x0F; - LCD_Pause(); + lcd_pause(); LCD_EN_PIN = 1; - LCD_Pause(); + lcd_pause(); LCD_EN_PIN = 0; - LCD_Pause(); + lcd_pause(); P2 = (val & 0x0F); - LCD_Pause(); + lcd_pause(); LCD_EN_PIN = 1; - LCD_Pause(); + lcd_pause(); LCD_EN_PIN = 0; - while(LCD_State() & 0x80); + while(lcd_read_status() & 0x80); } -void LCD_SendData(uint8_t val) { - LCD_Pause(); +// Writes a data value to the LCD. +void lcd_send_data(uint8_t val) { + lcd_pause(); P2 = LCD_RS | ((val >> 4) & 0x0F); - LCD_Pause(); + lcd_pause(); LCD_EN_PIN = 1; - LCD_Pause(); + lcd_pause(); LCD_EN_PIN = 0; - LCD_Pause(); + lcd_pause(); P2 = LCD_RS | (val & 0x0F); - LCD_Pause(); + lcd_pause(); LCD_EN_PIN = 1; - LCD_Pause(); + lcd_pause(); LCD_EN_PIN = 0; - while(LCD_State() & 0x80); + while(lcd_read_status() & 0x80); } -void LCD_Clear(void) { - LCD_SendCmd(0x01); /* display clear */ - LCD_Pos=0; +// Clears the LCD. +void lcd_clear(void) { + lcd_send_cmd(0x01); /* display clear */ + lcd_pos = 0; } -void LCD_Init(void) { +// Initializes the LCD. +void lcd_init(void) { P2 = 0; /* set RS, RW and EN low */ /* all delays are vital */ - Delay(50); /* power on delay - wait more than 15 ms */ + delay(50); /* power on delay - wait more than 15 ms */ for(uint8_t i = 0; i < 3; i++) { P2 = 0x03; /* lce enable low */ - Delay(1); /* wait more than 100us */ + delay(1); /* wait more than 100us */ P2 = LCD_EN | 0x03; /* lcd enable high */ - Delay(1); /* wait more than 100us */ + delay(1); /* wait more than 100us */ P2 = 0x03; /* lce enable low */ - Delay(5); /* wait more than 4.1 ms */ + delay(5); /* wait more than 4.1 ms */ } P2 = 0x02; /* lcd enable low */ - Delay(1); /* wait more than 100us */ + delay(1); /* wait more than 100us */ P2 = LCD_EN | 0x02; /* lcd enable high */ - Delay(1); /* wait more than 100us */ + delay(1); /* wait more than 100us */ P2 = 0x02; /* lcd enable low */ - Delay(5); /* wait more than 100us */ + delay(5); /* wait more than 100us */ - LCD_SendCmd(0x28); /* 4 bit mode, 1/16 duty, 5x8 font */ - LCD_SendCmd(0x08); /* display off */ - LCD_Clear(); - LCD_SendCmd(0x06); /* entry mode */ - LCD_SendCmd(0x0C); /* display on, blinking cursor off */ + lcd_send_cmd(0x28); /* 4 bit mode, 1/16 duty, 5x8 font */ + lcd_send_cmd(0x08); /* display off */ + lcd_clear(); + lcd_send_cmd(0x06); /* entry mode */ + lcd_send_cmd(0x0C); /* display on, blinking cursor off */ } -int putchar(int c) { +// Puts a character to the LCD. Correctly handles '\n'. +void lcd_putchar(char c) { if(c == 10) { - while((LCD_Pos != 0) && (LCD_Pos != 40)) { - LCD_SendData(32); - LCD_Pos++; - if(LCD_Pos == 80) LCD_Pos=0; + while((lcd_pos != 0) && (lcd_pos != 40)) { + lcd_send_data(32); + lcd_pos++; + if(lcd_pos == 80) lcd_pos=0; } } else { - LCD_SendData(c); - LCD_Pos++; - if(LCD_Pos == 80) LCD_Pos=0; + lcd_send_data(c); + lcd_pos++; + if(lcd_pos == 80) lcd_pos=0; + } +} + +// Initializes the background tick timer (for delays). +void timer_init(void) { + // Initialize timer 0 as 16-bit countdown, timer 1 as 8-bit auto-reload countdown + + TMOD = 0x21; + TCON = 0x50; + + // Initialize timer 0 for 100 Hz + + TL0 = (uint8_t)NPER; + TH0 = (uint8_t)(NPER >> 8); + + // Enable interrupts only for timer 0 + + IE = 0x82; +} + +// Initializes the serial port (along with timer 2). +void serial_init(void) { + // Initialize timer 2 as 312500 Hz as the baud rate generator (for tulflash) + + RCAP2H = 0xFF; + RCAP2L = 0xFE; + T2CON = 0x34; + + // Initialize serial I/O + + SCON = 0x50; + TI = 1; +} + +// Writes a character to the serial port. +void serial_putchar(char c) { + while(TI == 0); + SBUF = c; +} + +__bit stdout_to_lcd = 0; +__bit stdout_to_serial = 0; + +// Writes a character to standard output (LCD, serial or both). +int putchar(int c) { + if(stdout_to_lcd) { + lcd_putchar(c); + } + + if(stdout_to_serial) { + serial_putchar(c); } return 0; } -/***************************************** - ** Nastaveni preruseni ** - *****************************************/ - -/* Seriove preruseni a timer1 jsou nastaveny - na 115200bps, timer0 se nastavuje pomoci TH0.*/ -void init_interrupts(void) { - TMOD=0x21; - TCON=0x50; - PCON=0x80; - TL0=(uint8_t)NPER; - TH0=(uint8_t)(NPER >> 8); - IE=0x82; -} - -/***************************************** - ** Obsluha LED baru ** - *****************************************/ -/* -__sbit __at _P1+3 LB_Data; -__sbit __at _P1+4 LB_SCK; -__sbit __at _P1+5 LB_SCL; RESET -__sbit __at _P1+6 LB_RCK; PREPIS -__sbit __at _P1+7 LB_OE; -*/ - -void SetLedBar(uint16_t n) { +// Writes a 10-bit value to the LED bar. Bit 0 = bottom LED, bit 9 = top LED. +void led_bar_set(uint16_t n) { uint8_t i; - LB_RCK = 0; - LB_SCL = 0; - LB_SCL = 1; - LB_SCK = 0; + BAR_RCK = 0; + BAR_SCL = 0; + BAR_SCL = 1; + BAR_SCK = 0; for(i = 0; i < 10; i++) { - LB_Data = !(n & 1); + BAR_DAT = !(n & 1); n >>= 1; // n = n >> 1 - LB_SCK = 1; - LB_SCK = 0; + BAR_SCK = 1; + BAR_SCK = 0; } - LB_RCK = 1; - LB_OE = 0; + BAR_RCK = 1; + BAR_OE = 0; } -/***************************************** - ** Obsluha Klavesnice ** - *****************************************/ - -#define KEY_C_1 P0_0 -#define KEY_C_2 P0_1 -#define KEY_C_3 P0_2 -#define KEY_C_4 P0_3 - -#define KEY_R_1 P0_4 -#define KEY_R_2 P0_5 -#define KEY_R_3 P0_6 -#define KEY_R_4 P0_7 - -char GetKeyboard(void) { +// Reads a character from the keypad. +char keypad_read(void) { P0 = 0xFF; - KEY_R_1 = 0; - LCD_Pause(); - if (!KEY_C_1) return '1'; - if (!KEY_C_2) return '2'; - if (!KEY_C_3) return '3'; - if (!KEY_C_4) return 'A'; + KEY_ROW_1 = 0; + lcd_pause(); + if (!KEY_COL_1) return '1'; + if (!KEY_COL_2) return '2'; + if (!KEY_COL_3) return '3'; + if (!KEY_COL_4) return 'A'; P0 = 0xFF; - KEY_R_2 = 0; - LCD_Pause(); - if (!KEY_C_1) return '4'; - if (!KEY_C_2) return '5'; - if (!KEY_C_3) return '6'; - if (!KEY_C_4) return 'B'; + KEY_ROW_2 = 0; + lcd_pause(); + if (!KEY_COL_1) return '4'; + if (!KEY_COL_2) return '5'; + if (!KEY_COL_3) return '6'; + if (!KEY_COL_4) return 'B'; P0 = 0xFF; - KEY_R_3 = 0; - LCD_Pause(); - if (!KEY_C_1) return '7'; - if (!KEY_C_2) return '8'; - if (!KEY_C_3) return '9'; - if (!KEY_C_4) return 'C'; + KEY_ROW_3 = 0; + lcd_pause(); + if (!KEY_COL_1) return '7'; + if (!KEY_COL_2) return '8'; + if (!KEY_COL_3) return '9'; + if (!KEY_COL_4) return 'C'; P0 = 0xFF; - KEY_R_4 = 0; - LCD_Pause(); - if (!KEY_C_1) return '*'; - if (!KEY_C_2) return '0'; - if (!KEY_C_3) return '#'; - if (!KEY_C_4) return 'D'; + KEY_ROW_4 = 0; + lcd_pause(); + if (!KEY_COL_1) return '*'; + if (!KEY_COL_2) return '0'; + if (!KEY_COL_3) return '#'; + if (!KEY_COL_4) return 'D'; return -1; } -/***************************************** - ** Hlavni program ** - *****************************************/ - void main(void) { - init_interrupts(); - LCD_Init(); + timer_init(); + lcd_init(); + serial_init(); - int i = 0; + stdout_to_serial = 1; + stdout_to_lcd = 1; + + int i = 1; while(1) { - LCD_Clear(); - printf("hellOwOrld! %d", ++i); - Delay(TickPerSec); + lcd_clear(); + printf("hellOwOrld! %d\n", i); + led_bar_set(i); + + LED_RED = !(i & 1); + LED_YELLOW = !(i & 2); + LED_GREEN = !(i & 4); + BULB = !(i & 8); + + i++; + + delay(TICK_RATE); } } -/***************************************** - ** Obsluha casovace 0 ** - *****************************************/ - - -void timer0(void) __interrupt(1) { +void timer0_handler(void) __interrupt(1) { // Reload, 10ms - TL0=(uint8_t)NPER; - TH0=(uint8_t)(NPER >> 8); - if(TIMER!=0) TIMER--; + TL0 = (uint8_t)NPER; + TH0 = (uint8_t)(NPER >> 8); + if(TIMER != 0) TIMER--; }