Last active
June 2, 2020 00:14
-
-
Save KGrzeg/07c4053d6a679388ea9691e3c39731a7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <Atmel/AT89X52.h> | |
| #include <absacc.h> | |
| #include <stdio.h> | |
| #include "LCD_lib.c" | |
| #define CS55A 0xFF28 // write | |
| #define CS55B 0xFF29 // read | |
| #define CS55D 0xFF2B // setup | |
| #define CSKB0 0xF021 | |
| #define CSKB1 0xF022 | |
| #define INTERVAL 1000 | |
| #define MAX_PEOPLE 50 | |
| typedef enum { false, true } bool; | |
| char text_max[] = "Brak wolnych\nmiejsc", text[] = "Osoby: \n"; | |
| struct { | |
| unsigned char occupied; | |
| unsigned char max; | |
| unsigned char input_gates; | |
| unsigned char output_gates; | |
| } gates_data; | |
| void lcd_print(const char *str) { | |
| unsigned char i = 0; | |
| while (str[i]) | |
| lcd(str[i++]); | |
| } | |
| void lcd_print_number(int num) { | |
| char digits[3] = {0}; | |
| sprintf(digits, "%d", num); | |
| lcd_print(digits); | |
| } | |
| bool reach_max() { return gates_data.max <= gates_data.occupied; } | |
| bool empty() { return gates_data.occupied == 0; } | |
| void setup_input_gate(unsigned char id) { gates_data.input_gates |= 1 << id; } | |
| void setup_input_gates_raw(unsigned char d) { gates_data.input_gates |= d; } | |
| void reset_input_gates() { gates_data.input_gates = 0; } | |
| void setup_output_gate(unsigned char id) { gates_data.output_gates |= 1 << id; } | |
| void setup_output_gates_raw(unsigned char d) { gates_data.output_gates |= d; } | |
| void reset_output_gates() { gates_data.output_gates = 0; } | |
| void initialize_gates() { | |
| gates_data.max = MAX_PEOPLE; | |
| gates_data.occupied = 0; | |
| reset_input_gates(); | |
| reset_output_gates(); | |
| XBYTE[CS55D] = 0x82; | |
| lcd_init(); | |
| lcd_clr(); | |
| } | |
| void display_status() { | |
| if (reach_max()) { | |
| lcd_print(text_max); | |
| } else { | |
| lcd_print(text); | |
| lcd_print_number(gates_data.occupied); | |
| lcd('/'); | |
| lcd_print_number(gates_data.max); | |
| } | |
| } | |
| void add_person() { gates_data.occupied += reach_max() ? 0 : 1; } | |
| void sub_person() { gates_data.occupied -= empty() ? 0 : 1; } | |
| unsigned int count_high_bits(unsigned int n) { | |
| unsigned int count = 0; | |
| while (n) { | |
| count += n & 1; | |
| n >>= 1; | |
| } | |
| return count; | |
| } | |
| unsigned char detect_rises(char last, char current) { | |
| char result = (last ^ current) & current; | |
| return count_high_bits(result); | |
| } | |
| void update_system() { | |
| static unsigned char last_input_state = 0, last_output_state = 0; | |
| unsigned char input_state, output_state, people, current_state; | |
| current_state = XBYTE[CS55B]; | |
| // check in gates | |
| input_state = current_state & gates_data.input_gates; | |
| people = detect_rises(last_input_state, input_state); | |
| while (people--) { | |
| add_person(); | |
| } | |
| // check out gates | |
| output_state = current_state & gates_data.output_gates; | |
| people = detect_rises(last_output_state, output_state); | |
| while (people--) { | |
| sub_person(); | |
| } | |
| last_input_state = input_state; | |
| last_output_state = output_state; | |
| } | |
| void live_setup() { | |
| unsigned char nums, status; | |
| nums = ~XBYTE[CSKB0]; | |
| status = ~XBYTE[CSKB1]; | |
| switch (status) { | |
| case 0: { | |
| return; | |
| break; | |
| } | |
| case 128: { //'F' - reset amount of people | |
| gates_data.occupied = 0; | |
| break; | |
| } | |
| case 4: { // A - input gates | |
| setup_input_gates_raw(nums); | |
| break; | |
| } | |
| case 8: { // B - output gates | |
| setup_output_gates_raw(nums); | |
| break; | |
| } | |
| case (16 + 4): { // C+A - reset input gates | |
| reset_input_gates(); | |
| break; | |
| } | |
| case (16 + 8): { // C+B - reset output gates | |
| reset_output_gates(); | |
| break; | |
| } | |
| } | |
| } | |
| void main() { | |
| initialize_gates(); | |
| setup_output_gate(0); | |
| setup_output_gate(1); | |
| setup_output_gate(2); | |
| setup_output_gate(3); | |
| setup_input_gate(4); | |
| setup_input_gate(5); | |
| setup_input_gate(6); | |
| while (1) { | |
| P1_7 = 0; | |
| wait(80); | |
| P1_7 = 1; | |
| update_system(); | |
| live_setup(); | |
| display_status(); | |
| wait(INTERVAL); | |
| lcd_clr(); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment