📄 demo18.c
字号:
/************************************************** * HI-TIDE PICC-18 Demonstration * * Demonstrates LCD, LED's, Push buttons, Switches, * Serial I/O * * Microchip PIC 18C452 Wiring: * * 20 x 4 LCD * RS --> PORTA.3 * E --> PORTA.1 * D0 --> PORTD.0 * D1 --> PORTD.1 * D2 --> PORTD.2 * D3 --> PORTD.3 * D4 --> PORTD.4 * D5 --> PORTD.5 * D6 --> PORTD.6 * D7 --> PORTD.7 * * Switch 1 --> PORTB.4 * Switch 2 --> PORTB.5 * * Push Button 1 --> PORTB.6 * Push Button 2 --> PORTB.7 * * LED PANEL 1: * LED0 --> PORTC.0 * LED1 --> PORTC.1 * LED2 --> PORTC.2 * LED3 --> PORTC.3 * LED4 --> PORTC.4 * LED5 --> PORTC.5 * * LED PANEL 2: * LED0 --> PORTC.7 * LED1 --> PORTC.6 * LED2 --> PORTC.5 * LED3 --> PORTC.4 * LED4 --> PORTC.3 * LED5 --> PORTC.2 * **************************************************/#include <pic18.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include "demo18.h"#include "delay.h"#include "lcd.h"#include "serial.h"/* Scrolling LCD message: */const unsigned char Message[] = " ---***** HI-TECH PICC-18 Demostration. *****--- " "HI-TIDE can simulate virtual I/O devices for PIC18 " "processors running with real-time execution speed on " "Windows and Linux!!! "; /* status variables */volatile unsigned char status, port_stat; /* button counter */signed char buttons; /* switch states */unsigned char sw1, sw2; /* circular serial I/O buffer */unsigned char serial_buf[SERIAL_BUFFER+1]; /* serial I/O buffer head/tail pointers */unsigned char serial_head,serial_tail;/* General initialization of ports, etc... */voidInitPeripherals(void) { WDTCON = 0; init_comms(); printf("\n\n\nStarting HI-TIDE PICC18 demo program..."); /* configure ports */ ADCON1 = 0x6; //set to output bits not used by serial. TRISC = 0x80; TRISD = OUTPUT_DATA; PSPMODE = 0; LATA = LATB = LATC = LATD = 0; TRISA0 = OUTPUT_PIN; TRISA1 = OUTPUT_PIN; TRISB = 0; TRISB4 = INPUT_PIN; TRISB5 = INPUT_PIN; TRISB6 = INPUT_PIN; TRISB7 = INPUT_PIN; /* initialize the LCD */ lcd_init(EIGHTBIT_MODE); // Initialize the LCD display /* configure timers/interrupts */ di(); IPEN = 0; TMR0IP = 1; // timer 0 TMR0IE = 1; TMR0ON = 1; T1CON &= 0xFD; T0CS = 0; INT0IE = 0; RBIP = 0; // interrupt on PORTB change RBIE = 1; RCIP = 1; // Serial I/O receive interrupt RCIF = 0; RCIE = 1; IPEN = 0; PEIE = 1; printf("OK.\n\n\nType Something.\nIt will be shown on the LCD:\n\nDEMO> "); ei(); // start interrupts}/* The scrolling message function */voidMessageFunc(void) { static unsigned char line_buf[LCD_WIDTH+10]; static unsigned char msg_buf[LCD_WIDTH+10]; static const unsigned char *msg_ptr = Message; unsigned char *ptr,count; if (!msg_buf[0]) // first time run? clear the buffer { for (count=0; count < LCD_WIDTH; ++count) msg_buf[count] = ' '; // clear with spaces } if (CHK_STATUS(SCROLL_MESSAGE)) // time to scroll message? { for (ptr = msg_buf; ptr < &msg_buf[LCD_WIDTH-1]; ++ptr) *ptr = *(ptr+1); if (*msg_ptr) // Add the next character msg_buf[LCD_WIDTH-1] = *msg_ptr++; else msg_ptr = Message; // end of message, start again lcd_goto(MESSAGE_LINE); lcd_puts(msg_buf); // display message on LCD CLR_STATUS(SCROLL_MESSAGE); // message scroll completed } if (CHK_STATUS(BUTTON_MESSAGE)) { sprintf(line_buf,"Button counter: %d ",buttons); lcd_goto(BUTTON_LINE); lcd_puts(line_buf); // show button count CLR_STATUS(BUTTON_MESSAGE); } if (CHK_STATUS(SW_MESSAGE)) // do we need to update the switch states? { sprintf(line_buf,"SW 1: %s SW 2: %s",sw1?"ON ":"OFF",sw2?"ON ":"OFF"); lcd_goto(SW_LINE); lcd_puts(line_buf); // show switch states CLR_STATUS(SW_MESSAGE); }}/* The LED Panel function - shows a flashing LED */voidLedPanelFunc(void){ static near unsigned char flash=0x1; static near bit direction; if (flash & 0x21) // are we at the end? direction = !direction; // then change direction if (direction) flash <<= 1; // shift the 'on' led else flash >>= 1; //leave the two most significant bits of the //LED_PANEL unchanged because the are used //by the serial i/o. LED_PANEL = (LED_PANEL & 0xC0) + ((~flash) & 0x3F); // display on the LED panel CLR_STATUS(LEDS);}/* The Push Button Function - Increments or decrements a value depending on which button is pressed */voidPushButtonFunc(void){ if (CHK_STATUS(BUTTON_1)) // Was button 1 pressed? { CLR_STATUS(BUTTON_1); ++buttons; // increase the count } if (CHK_STATUS(BUTTON_2)) // was button 2 pressed? { CLR_STATUS(BUTTON_2); --buttons; // descrease the button count } SET_STATUS(BUTTON_MESSAGE); // now we need to update the LCD message}voidSwitchFunc(void){ sw1 = port_stat & SWITCH1; sw2 = port_stat & SWITCH2; CLR_STATUS(SWITCHES); SET_STATUS(SW_MESSAGE);}void interrupt ISR(void) // The main ISR routine{ if (TMR0IE && TMR0IF) // did the timer cause the interrupt? { SET_STATUS(SCROLL_MESSAGE | LEDS); TMR0 = 0xF000; TMR0IF = 0; } if (RBIE && RBIF) // did something on PORTB change? { port_stat = PORTB; if (port_stat & BUT1) // was button 1 pressed? SET_STATUS(BUTTON_1); else if (port_stat & BUT2) // was button 2 pressed SET_STATUS(BUTTON_2); else // a switch must have changed SET_STATUS(SWITCHES); RBIF = 0; } if (RCIE && RCIF) // did we receive serial I/O { SET_STATUS(SERIAL_REC); serial_buf[serial_head] = RCREG; // add to circular buffer serial_head = (serial_head +1) % SERIAL_BUFFER; RCIF = 0; }}/* The serail I/O function */voidSerialFunc(void){ char ch; char serial_msg[LCD_WIDTH+1]; ch = serial_buf[serial_tail]; serial_tail = (serial_tail + 1) % SERIAL_BUFFER; putch(ch); // echo the typed character if (ch == '\r') // was ENTER pressed? ->clear buffer, display prompt { printf("\nDEMO> "); // display a prompt for (ch=0; ch < SERIAL_BUFFER; ++ch) // clear buffer serial_buf[ch] = ' '; serial_head = serial_tail = 0; } lcd_goto(SERIAL_LINE); sprintf(serial_msg,"Serial:%s",serial_buf); lcd_puts(serial_msg); CLR_STATUS(SERIAL_REC);}voidmain(void){ InitPeripherals(); // initialize peripherals status = 0xff; CLR_STATUS(SERIAL_REC); while(1) { if (CHK_STATUS(BUTTON_1 | BUTTON_2)) // was a button pressed? PushButtonFunc(); if (CHK_STATUS(SWITCHES)) // did the switches change state? SwitchFunc(); if (CHK_STATUS(LEDS)) // time to update leds? LedPanelFunc(); if (CHK_STATUS(SCROLL_MESSAGE | BUTTON_MESSAGE | SW_MESSAGE)) // time to update LCD? MessageFunc(); if (CHK_STATUS(SERIAL_REC)) // did we receive serial data? SerialFunc(); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -