16C84:ans i korthet:
- 1k EEPROM/FLASH
36 bytes RAM
1 MIPS @ 4 MHz
En 8-bit timer
En Compaq LTE 5000 med 75 MHz Pentium och 24 MB RAM, och Windows 98SE. Nu kan det roliga börja.
Pic Start Plus:en och laptopen har nästan samma beige färg, snyggt!
Kod: Markera allt
/******************************************************************************
* File: part1.c
* Platform: PIC16C84, MPLAB 5.70.40/CC5X
*
*
* Version history:
* 2014-02-10 1.0 Test av bitbangad UART
*
*******************************************************************************/
#include "inttypes.h"
#define FULLBIT 58
#define HALFBIT 152
#define TRUE 1
#define FALSE 0
#define DEBUG PORTA.0 = 1; nop2(); nop2(); PORTA.0 = 0
#define DEBUG1 PORTA.1 = !PORTA.1;
enum TASKS_T {LED1, LED2};
uint8_t tasks[LED2 + 1];
typedef enum {UWAIT,RSTART,RD1,RD2,RD3,RD4,RD5,RD6,RD7,RD8,RSTOP,
TSTART,TD1,TD2,TD3,TD4,TD5,TD6,TD7,TD8,TSTOP,RXEMPTY=0xF0} UART_E;
struct {
uint8_t rxbuffer;
uint8_t txbuffer;
UART_E status;
} uart;
#pragma location 0 //codepage 0
#include <INT16CXX.H>
#pragma origin 4
interrupt int_server(void)
{
static uint8_t tmp, rxtmp;
int_save_registers // W, STATUS (and PCLATH)
char sv_FSR = FSR;
if (INTF && INTE) { //edge on startbit detected
INTF = FALSE;
if (uart.status == UWAIT) {
INTE = FALSE;
TMR0 = HALFBIT;
uart.status = RSTART; //run receiver
}
}
if (T0IF && T0IE) {
TMR0 = FULLBIT;
//UART - bitbanged receiver
if (uart.status == UWAIT)
;
else if (uart.status == RSTART) {
++uart.status;
if (PORTB.0 != 0) { //startbit expected to be low
INTF = FALSE;
INTE = TRUE;
uart.status = UWAIT;
}
}
else if (uart.status > RSTART && uart.status < RSTOP) {
DEBUG;
tmp = PORTB.0;
tmp <<= 7;
rxtmp >>= 1;
rxtmp |= tmp; //save databit
++uart.status;
}
else if (uart.status == RSTOP) {
if (PORTB.0 == 1) //stopbit expected to be high
uart.rxbuffer = rxtmp;
else
uart.rxbuffer = RXEMPTY;
uart.status = UWAIT;
INTF = FALSE;
INTE = TRUE;
}
else if (uart.status == TSTART) { //UART - bitbanged transmitter
++uart.status;
PORTB.1 = 0; //make startbit
}
else if (uart.status > TSTART && uart.status < TSTOP) {
++uart.status;
tmp = uart.txbuffer & 0x01;
PORTB.1 = tmp; //databit to port
uart.txbuffer >>= 1;
}
else if (uart.status == TSTOP) {
++uart.status;
PORTB.1 = 1; //make stopbit
uart.status = UWAIT; //we are ready to send next char
}
//scheduler
for (tmp = 0; tmp < sizeof(tasks); ++tmp)
if (tasks[tmp])
--tasks[tmp];
}
FSR = sv_FSR;
int_restore_registers
T0IF = FALSE; //clear timerflag for next tick
}
#include <math16.h>
/******************************************************************************
* kbhit - Tecken mottaget?
*
*
******************************************************************************/
uint8_t kbhit(void) {
if (uart.rxbuffer != RXEMPTY)
return TRUE;
else
return FALSE;
}
/******************************************************************************
* putch - Skriv tecken till UART
*
*
******************************************************************************/
void putch(uint8_t c) {
while (uart.status != UWAIT)
;
uart.txbuffer = c;
uart.status = TSTART;
}
/******************************************************************************
* puts - Skriv sträng till UART
*
*
******************************************************************************/
void puts(const uint8_t *s) {
uint8_t c;
c = *s;
while (c) {
putch(c);
s++;
c = *s;
}
}
/******************************************************************************
* crlf - Gör radmatning
*
*
******************************************************************************/
void crlf(void) {
putch(0x0d);
putch(0x0a);
}
/******************************************************************************
* task_led1 - blinka LED 1
*
*
******************************************************************************/
void task_led1 (char p) {
if (PORTA.0) {
tasks[LED1] = 0xff - p;
PORTA.0 = FALSE;
}
else {
tasks[LED1] = p;
PORTA.0 = TRUE;
}
}
/******************************************************************************
* task_led2 - blinka LED 2
*
*
******************************************************************************/
void task_led2 (char p) {
if (PORTA.1) {
tasks[LED2] = 0xff - p;
PORTA.1 = FALSE;
}
else {
tasks[LED2] = p;
PORTA.1 = TRUE;
}
}
/******************************************************************************
* main -
*
*
******************************************************************************/
void main(void) {
uint8_t led1_speed;
TRISA = 0b0000.0000;
TRISB = 0b0000.0001;
OPTION_REG = 0b1100.0001;
INTEDG = FALSE;
INTF = FALSE;
INTE = TRUE;
TMR0 = FULLBIT;
T0IF = FALSE;
T0IE = TRUE;
RBIE = FALSE;
RBIF = FALSE;
PORTB.1 = 1;
GIE = TRUE;
uart.status = UWAIT;
while(1) {
if (kbhit() && uart.rxbuffer == 0x0A) {
uart.rxbuffer = RXEMPTY;
puts("Welcome to 16C84");
crlf(); puts("C84>");
}
if (!tasks[LED1])
task_led1(20);
if (!tasks[LED2])
task_led2(0xff-20);
}
}