📄 prog89s52-1.0.c
字号:
#include <sys/io.h>#include <sys/types.h>#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <fcntl.h>#include <stdarg.h>#include <string.h>#include <time.h>#include <math.h>#define VERSION "1.0"/* Port register locations */unsigned int portbase = 0x378 ;#define DATA portbase#define STATUS ((portbase)+1)#define CONTROL ((portbase)+2)/* Input pins to the port, Status register */#define ERR 8#define SELIN 16#define PE 32#define ACK 64#define BUS 128/* Output pins from the port, Control register */#define STR 1#define AF 2#define INI 4#define SELOUT 8#define IRQEN 16#define DIR 32/* Output pins from the port, Data register */#define D0 1#define D1 2#define D2 4#define D3 8#define D4 16#define D5 32#define D6 64#define D7 128/* Port pins as they relate to uC ISP pins (in and out relative to uC) */unsigned char din = D5 ;unsigned char dout = ACK ;unsigned char dclock = D6 ;unsigned char reset = D4 ;#define SET(register, bit) ( outb(inb(register) | bit, register) )#define CLEAR(register, bit) ( outb(inb(register) & (~bit), register) )#define ISSET(register, bit) (inb(register) & bit)int delay = 0 ; /* uS */#define pause(period) {if(period) usleep(period) ;}/* operations to be carried out */char doreadid = 0 ;char doreadlocks = 0 ;char doprogram = 0 ;char doerase = 0 ;char dosetlocks = 0 ;char doreadmem = 0 ;char donoerase = 0 ;char domock = 0 ;char domemfile = 0 ;char doreset = 0 ;char doprogramlocks = 0 ;char docopytomemfile = 0 ;char docopytohexfile = 0 ;char dowritelocks = 0 ; char *hexfilename ;/*--------------------------------------------------------------------------------------------------------------*//* memory map: for simulating (or coppying) the uC program memory in system RAM *//* the number of bytes displayed per line (must be a factor of 1024) */#define BLOCKSIZE 16typedef struct { unsigned int blocks ; /* the size of the data array is a multiple of BLOCKSIZE */ unsigned char *data ; /* memory data */ char *filename ; /* file to which this will be written */ } memmap ;memmap mapfromfile ; /* this map is populated with data from a read hex file */memmap mapfrompart ; /* this map is populated with data read from the part itself *//*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*//* Console messaging functions */int verbosity = 30 ;void msg(int msgverbosity, char *format, ...) { va_list argp ; va_start(argp, format) ; if(verbosity >= msgverbosity) { while(msgverbosity > 0) { putchar(' ') ; msgverbosity -= 10 ; } vprintf(format, argp) ; } va_end(argp) ; }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*//* Output brief syntax synopsis */void help(void) { printf("\prog89S52: Utility for programming the AT89S52 microcontroller.\n\n\Synopsis of options:\n\-d milliseconds\n\\tDelay between clock and data transitions.\n\-v verbosity\n\\t Verbosity as an integer between 0 and 100.\n\-a address\n\\t Parallel port address in hexadecimal and excluding the prefix 0x.\n\-r\n\\tReset part and exit.\n\-i\n\\tRead part identifiers.\n\-l\n\\tRead lockbits.\n\-L lockmode\n\\tProgram the specified lock mode.\n\-p hexfile\n\\tErase and program flash from the named file.\n\-e\n\\tErase the flash memory.\n\-n\n\\tNo erase when programming.\n\-s\n\\tSimulate, do not erase or write.\n\-m memfile\n\\tMemory dump program (from -p) to the specified file.\n\-g kilobytes memfile\n\\tGet integer number of killobytes from the part's flash,\n\\tand dump to specified file.\n\-G kilobytes hexfile\n\\tGet integer number of killobytes from the part's flash,\n\\tand write as a hex file.\n\-V\n\\tShow version information.\n\-h\n\\tDisplay this help message.\n\n\For more help, issue man prog89S52\n\") ; }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*//* Initialise a memmap strucrure. note that the file name is copied */int initmemmap(memmap *map, char *filename, int blocks) { int failure = 0 ; if(blocks) { if(!((*map).data = malloc(BLOCKSIZE * blocks))) { msg(0, "Failed to allocate %i bytes for memory map. Memory dump will not be performed\n", BLOCKSIZE * blocks) ; failure = 1 ; } } else { (*map).data = NULL ; } if((*map).data) (*map).blocks = blocks ; else (*map).blocks = 0 ; (*map).filename = strdup(filename) ; if(!(*map).filename) (*map).filename = "dump" ; return(failure) ; }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*//* Open the parallel port */void openport(void) { if(ioperm(portbase, 3 , 1)) { msg(0, "Failed to open the parallel port at 0x%X\n", portbase) ; perror("ioperm") ; exit(1) ; } { msg(50, "Opened the parallel port at 0x%X\n", portbase) ; } outb(0, DATA) ; ioperm(portbase, 3 , 1) ; }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*//* Close the parallel port */void closeport(void) { outb(0, DATA) ; ioperm(portbase, 3 , 0) ; }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*/#define PROGRAM 1#define RUN 0void mode(char state) { pause(delay) ; if(state == PROGRAM) { msg(100, "Setting reset (D4, p6)\n") ; SET(DATA, reset) ; } if(state == RUN) { msg(100, "Clearing reset (D4, p6)\n") ; CLEAR(DATA, reset) ; } pause(delay) ; }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*//* Transmit a single byte */byteout(unsigned char data) { char bitcount ; msg(80, "Transmitting %i (0x%02X)\n", data, data) ; for(bitcount = 7; bitcount >= 0; bitcount--) { /* Set data */ if((data >> bitcount) & 1) { /* bit is 1 */ msg(100, "Bit %i is 1. Setting MOSI (D5, p7)\n", bitcount) ; SET(DATA, din) ; } else { /* bit is 2 */ msg(100, "Bit %i is 0. Clearing MOSI (D5, p7)\n", bitcount) ; CLEAR(DATA, din) ; } /* Settle */ pause(delay) ; /* Strobe clock */ msg(100, "Setting clock (D6, p8)\n") ; SET(DATA, dclock) ; pause(delay) ; msg(100, "Clearing clock (D6, p8)\n") ; CLEAR(DATA, dclock) ; /* Settle */ pause(delay) ; } msg(100, "Byte transmission complete\n") ; }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*//* Recieve a single byte */unsigned char bytein(void) { char bitcount ; unsigned char data = 0 ; msg(100, "Clocking in 1 byte\n") ; for(bitcount = 7; bitcount >= 0; bitcount--) { /* Clock high */ msg(100, "Setting clock (D6, p8)\n") ; SET(DATA, dclock) ; /* Settle */ pause(delay) ; /* Read */ data <<= 1 ; msg(100, "Bit %i: ", bitcount) ; if(ISSET(STATUS, dout)) { /* bit is 1 */ data = data | 1 ; msg(100, "MISO (ACK, p10) is Set\n") ; } else { /* bit is 0 */ data = data & 254 ; msg(100, "MISO (ACK, p10) is Clear\n") ; } /* Clock low */ msg(100, "Clearing clock (D6, p8)\n") ; CLEAR(DATA, dclock) ; /* Settle */ pause(delay) ; } msg(80, "Recieved byte %i (0x%02X)\n", (int)data, (int)data) ; return(data) ; }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*//* Transmit the program enable code */int initprog(void) { unsigned char response ; msg(80, "Transmitting Programming Enable instruction\n") ; byteout(0xAC) ; byteout(0x53) ; byteout(0x00) ; response = bytein() ; if(response == 0x69) { /* OK */ msg(50, "Part successfully placed into Program mode\n") ; } else { /* Fail */ msg(0, "No valid response was recieved from the part (read value was %i)\n", (int)response) ; return(1) ; } return(0) ; }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*//* Read device ID bytes */int readid(void) { char id1, id2, id3 ; msg(80, "Reading device ID bytes\n") ; byteout(0x28) ; byteout(0x00) ; byteout(0x00) ; id1 = bytein() ; byteout(0x28) ; byteout(0x01) ; byteout(0x00) ; id2 = bytein() ; byteout(0x28) ; byteout(0x02) ; byteout(0x00) ; id3 = bytein() ; msg(20, "Atmel ID is %i (0x%X)\n", id1, id1) ; msg(20, "Device ID bytes are %i, %i (0x%X, 0x%X)\n", id2, id3, id2, id3) ; return(0) ; }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*/#define LB1 4#define LB2 8#define LB3 16/* Read the lock bits */int readlocks(void) { char response ; byteout(0x24) ; byteout(0x00) ; byteout(0x00) ; response = bytein() ; if(response & LB1) msg(20, "Lock bit 1 is Set\n") ; else msg(20, "Lock bit 1 is Clear\n") ; if(response & LB2) msg(20, "Lock bit 2 is Set\n") ; else msg(20, "Lock bit 2 is Clear\n") ; if(response & LB3) msg(20, "Lock bit 3 is Set\n") ; else msg(20, "Lock bit 3 is Clear\n") ; return(0) ; }/*--------------------------------------------------------------------------------------------------------------*//*--------------------------------------------------------------------------------------------------------------*/#define B2 1#define B1 2/* Set the lock bits */void writelocks(char lockmode) { if(domock) { msg(20, "Setting lock bits in Simulation mode: Nothing will be written to the part\n") ; return ; } else msg(20, "Setting lock mode %i\n", lockmode) ; switch(lockmode) { case 1: /* No lock. B1 and B2 = 0 */ byteout(0xAC) ; byteout(0xE0) ; byteout(0x00) ; byteout(0x00) ; break ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -