📄 data_logger_rtc.c
字号:
//-----------------------------------------------------------------------------
// FLASH_ByteWrite
//-----------------------------------------------------------------------------
//
// This routine writes <dat> to the FLASH byte addressed by <dest>.
//
void FLASH_ByteWrite (unsigned long dest, char dat)
{
char SFRPAGE_SAVE = SFRPAGE; // Preserve current SFR page
char PSBANK_SAVE = PSBANK; // Preserve current code bank
bit EA_SAVE = EA; // Preserve interrupt state
ULong temp_dest; // Temporary ULong
char xdata * idata pwrite; // FLASH write/erase pointer
temp_dest.ULong = dest; // copy <dest> to a byte
// addressable unsigned long
// Check if data byte being written is 0xFF
// There is no need to write 0xFF to FLASH since erased
// FLASH defaults to 0xFF.
if(dat != 0xFF){
// Extract address information from <dest>
pwrite = (char xdata *) temp_dest.Int[1];
// Extract code bank information from <addr>
PSBANK &= ~COBANK; // Clear the COBANK bits
if( temp_dest.Char[1] == 0x00){ // If the address is less than
// 0x10000, the Common area and
PSBANK |= COBANK1; // Bank1 provide a 64KB linear
// address space
} else { // Else, Bank2 and Bank3 provide
// a 64KB linear address space
if (temp_dest.Char[2] & 0x80){// If bit 15 of the address is
// a '1', then the operation should
PSBANK |= COBANK3; // target Bank3, else target Bank2
} else {
PSBANK |= COBANK2;
temp_dest.Char[2] |= 0x80;
pwrite = (char xdata *) temp_dest.Int[1];
}
}
SFRPAGE = LEGACY_PAGE;
EA = 0; // Disable interrupts
FLSCL |= 0x01; // Enable FLASH writes/erases
PSCTL = 0x01; // MOVX writes FLASH byte
*pwrite = dat; // Write FLASH byte
FLSCL &= ~0x01; // Disable FLASH writes/erases
PSCTL = 0x00; // MOVX targets XRAM
}
EA = EA_SAVE; // Restore interrupt state
PSBANK = PSBANK_SAVE; // Restore current code bank
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
}
//-----------------------------------------------------------------------------
// FLASH_Read
//-----------------------------------------------------------------------------
//
// This routine copies <numbytes> from FLASH addressed by <src> to <dest>.
//
void FLASH_Read ( char* dest, unsigned long src, unsigned int numbytes)
{
unsigned int i; // Software Counter
for (i = 0; i < numbytes; i++) {
*dest++ = FLASH_ByteRead(src++);
}
}
//-----------------------------------------------------------------------------
// FLASH_ByteRead
//-----------------------------------------------------------------------------
//
// This routine returns to the value of the FLASH byte addressed by <addr>.
//
unsigned char FLASH_ByteRead (unsigned long addr)
{
char SFRPAGE_SAVE = SFRPAGE; // Preserve current SFR page
char PSBANK_SAVE = PSBANK; // Preserve current code bank
ULong temp_addr; // Temporary ULong
char temp_char; // Temporary char
char code * idata pread; // FLASH read pointer
temp_addr.ULong = addr; // copy <addr> to a byte addressable
// unsigned long
// Extract address information from <addr>
pread = (char code *) temp_addr.Int[1];
// Extract code bank information from <addr>
PSBANK &= ~COBANK; // Clear the COBANK bits
if( temp_addr.Char[1] == 0x00){ // If the address is less than
// 0x10000, the Common area and
PSBANK |= COBANK1; // Bank1 provide a 64KB linear
// address space
} else { // Else, Bank2 and Bank3 provide
// a 64KB linear address space
if (temp_addr.Char[2] & 0x80){ // If bit 15 of the address is
// a '1', then the operation should
PSBANK |= COBANK3; // target Bank3, else target Bank2
} else {
PSBANK |= COBANK2;
temp_addr.Char[2] |= 0x80;
pread = (char code *) temp_addr.Int[1];
}
}
temp_char = *pread; // Read FLASH byte
PSBANK = PSBANK_SAVE; // Restore current code bank
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
return temp_char;
}
//-----------------------------------------------------------------------------
// Support Routines
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// print_menu
//-----------------------------------------------------------------------------
//
// This routine uses prints the command menu to the UART.
//
void print_menu(void)
{
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
SFRPAGE = UART0_PAGE;
printf("\n\nC8051F12x Data Logging Example\n");
printf("---------------------------------------\n");
printf("1. Start Logging\n");
printf("2. Stop Logging\n");
printf("3. Erase Log\n");
printf("4. Print Log (one page at a time - Press CTRL+C to stop)\n");
printf("5. Print Log (all at once - Press CTRL+C to stop)\n");
printf("6. Print Elapsed Time Since Last Reset\n");
printf("?. Print Command List\n");
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
}
//-----------------------------------------------------------------------------
// print_time
//-----------------------------------------------------------------------------
//
// This routine uses prints the elapsed time since the last reset to the UART.
//
void print_time(void)
{
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
bit EA_SAVE = EA; // Preserve interrupt state
SFRPAGE = UART0_PAGE;
EA = 0;
printf ("%05u:%02bu:%02bu\n", HOURS, MINUTES, SECONDS);
EA = EA_SAVE;
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
}
//-----------------------------------------------------------------------------
// find_current_record
//-----------------------------------------------------------------------------
//
//
unsigned long find_current_record(void)
{
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
bit EA_SAVE = EA; // Preserve interrupt state
unsigned long pRead = LOG_START; // Pointer used to read from FLASH
unsigned int i; // Software counter
bit record_erased; // Temporary flag
// Keep skipping records until an uninitialized record is found or
// until the end of the log is reached
while( pRead < LOG_END ){
EA = 0;
// Skip all records that have been initialized
if(FLASH_ByteRead(pRead) == START_OF_RECORD ){
// increment pRead to the next record
pRead += RECORD_LEN;
EA = EA_SAVE;
continue;
}
// Verify that the Record is uninitialized, otherwise keep
// searching for an uninitialized record
record_erased = 1;
for(i = 0; i < RECORD_LEN; i++){
if( FLASH_ByteRead(pRead+i) != 0xFF ){
record_erased = 0;
}
}
if(!record_erased){
// increment pRead to the next record
pRead += RECORD_LEN;
EA = EA_SAVE;
continue;
}
EA = EA_SAVE;
// When this code is reached, <pRead> should point to the beginning
// of an uninitialized (erased) record;
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
return pRead;
}
// This code is reached only when there are no uninitialized records
// in the LOG. Erase the first FLASH page in the log and return
// a pointer to the first record in the log.
EA = 0;
FLASH_PageErase(LOG_START); // Erase the first page of the LOG
EA = EA_SAVE;
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
return LOG_START;
}
//-----------------------------------------------------------------------------
// LOG_erase
//-----------------------------------------------------------------------------
//
//
void LOG_erase(void)
{
unsigned long pWrite = LOG_START; // pointer used to write to FLASH
bit EA_SAVE = EA; // save interrupt status
// Keep erasing pages until <pWrite> reaches the end of the LOG.
while( pWrite < LOG_END ){
EA = 0;
FLASH_PageErase(pWrite);
EA = EA_SAVE;
pWrite += FLASH_PAGESIZE;
}
LOG_ERASED = 1; // flag that LOG has been erased
}
//-----------------------------------------------------------------------------
// LOG_print
//-----------------------------------------------------------------------------
//
//
void LOG_print(char all_at_once)
{
char SFRPAGE_SAVE = SFRPAGE; // Save Current SFR page
bit EA_SAVE = EA; // save interrupt status
unsigned long pRead = LOG_START; // Pointer used to read from FLASH
Record temp_rec; // Temporary record
// Keep printing records until the end of the log is reached
while( pRead < LOG_END ){
// Copy a record from at <pRead> from the LOG into the local
// Record structure <temp_rec>
EA = 0;
FLASH_Read( (char*) &temp_rec, pRead, RECORD_LEN);
EA = EA_SAVE;
// Validate Record
if(temp_rec.start != ':'){
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
return;
}
// Print the Record
SFRPAGE = UART0_PAGE;
RI0 = 0; // Clear UART Receive flag
// to later check for the
// user pressing CTRL+C
EA = 0; // disable interrupts
// print the time and ADC reading
printf ("%05u:%02bu:%02bu ADC = 0x%04X\n", temp_rec.hours,
temp_rec.minutes,
temp_rec.seconds,
temp_rec.ADC_result);
EA = EA_SAVE; // restore interrupts
// any pending interrupts will
// be handled immediatly
// check if we need to continue
// if printing all data at once do not stop printing unless
// the user presses CTRL+C, otherwise print 16 records and
// then prompt user to press any key
if(all_at_once){
// Check if user has pressed CTRL+C
if(RI0 && SBUF0 == 0x03){
RI0 = 0;
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
return;
}
// pause every 16 lines
} else if( (pRead & ((RECORD_LEN*16)-1)) == 0 &&
pRead > (LOG_START + RECORD_LEN)) {
// wait for a key to be pressed then check if user has
// pressed CTRL+C (0x03)
printf("\npress any key to continue\n");
if(_getkey() == 0x03) {
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
return;
}
}
// increment pRead to the next record
pRead += RECORD_LEN;
SFRPAGE = SFRPAGE_SAVE; // Restore SFR page
}
}
//-----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -