📄 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... */
void
InitPeripherals(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 */
void
MessageFunc(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 */
void
LedPanelFunc(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
*/
void
PushButtonFunc(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
}
void
SwitchFunc(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 */
void
SerialFunc(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);
}
void
main(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 + -