initial stc rpn calculator project
This commit is contained in:
270
src/lcd.c
Normal file
270
src/lcd.c
Normal file
@ -0,0 +1,270 @@
|
||||
//#define DEBUG
|
||||
|
||||
#include "stc15.h"
|
||||
#include "utils.h"
|
||||
#include "lcd.h"
|
||||
|
||||
|
||||
#define LCDINC 2
|
||||
#define LCDDEC 0
|
||||
#define LCDSHIFT 1
|
||||
#define LCDNOSHIFT 0
|
||||
#define LCDCURSOR 2
|
||||
#define LCDNOCURSOR 0
|
||||
#define LCDBLINK 1
|
||||
#define LCDNOBLINK 0
|
||||
#define LCDSCROLL 8
|
||||
#define LCDNOSCROLL 0
|
||||
#define LCDLEFT 0
|
||||
#define LCDRIGHT 4
|
||||
#define LCD2LINE 8
|
||||
#define LCD1LINE 0
|
||||
#define LCD10DOT 4
|
||||
#define LCD7DOT 0
|
||||
|
||||
#define CR 13 // \r
|
||||
#define TAB 9 // \n
|
||||
#define LF 10 // \r
|
||||
|
||||
|
||||
|
||||
static int row, col;
|
||||
static int OpenFlag = 0;
|
||||
static int ErrorTimeout = 0;
|
||||
static int Error = 0;
|
||||
|
||||
#define CLEAR_BIT(port, bit) (port &= ~(_BV(bit)))
|
||||
#define CLEAR_BITS(port, bits) (port &= ~(bits))
|
||||
#define SET_BIT(port, bit) (port |= _BV(bit))
|
||||
|
||||
//#define DISABLE_INTERRUPTS() __critical{
|
||||
//#define ENABLE_INTERRUPTS() }
|
||||
#define DISABLE_INTERRUPTS() {
|
||||
#define ENABLE_INTERRUPTS() }
|
||||
|
||||
#define LCD_E P3_5
|
||||
#define LCD_RW P3_6
|
||||
#define LCD_RS P3_7
|
||||
#define LCD_BUSY P2_7 //LCD D7
|
||||
|
||||
static void outCsrBlindNibble(unsigned char command);
|
||||
static void outCsrBlind(unsigned char command);
|
||||
static void outCsr(unsigned char command);
|
||||
static char readBusy(void);
|
||||
static void wait_busy(void);
|
||||
static void to_row(unsigned char row_to);
|
||||
static void LCD_OutChar(unsigned char c);
|
||||
|
||||
static void outCsrBlindNibble(unsigned char command) {
|
||||
// CLEAR_BITS(PORTC, _BV(LCD_E) | _BV(LCD_RS) | _BV(LCD_RW));
|
||||
P3 &= ~(0x7 << 5); //clear LCD_E, LCD_RS, LCD_RW
|
||||
_delay_us(50);
|
||||
P2 = ((command & 0xf) << 4);
|
||||
//CLEAR_BIT(PORTC, LCD_E); //E = 0
|
||||
//CLEAR_BIT(PORTC, LCD_RS); //control
|
||||
//CLEAR_BIT(PORTC, LCD_RW); //write
|
||||
_delay_us(100);
|
||||
LCD_E = 1;
|
||||
_delay_us(100);
|
||||
LCD_E = 0;
|
||||
}
|
||||
|
||||
static void outCsrBlind(unsigned char command) {
|
||||
outCsrBlindNibble(command >> 4); // ms nibble, E=0, RS=0
|
||||
_delay_us(100);
|
||||
outCsrBlindNibble(command); // ls nibble, E=0, RS=0
|
||||
_delay_us(100); // blind cycle 90 us wait
|
||||
}
|
||||
|
||||
static void outCsr(unsigned char command) {
|
||||
DISABLE_INTERRUPTS();
|
||||
outCsrBlindNibble(command >> 4); // ms nibble, E=0, RS=0
|
||||
outCsrBlindNibble(command); // ls nibble, E=0, RS=0
|
||||
ENABLE_INTERRUPTS();
|
||||
wait_busy();
|
||||
}
|
||||
|
||||
#define SET_BUSY_IN() do {P2M1 |= (1<<7); P2M0 &= ~(1<<7);} while(0)
|
||||
#define SET_BUSY_OUT() do {P2M1 &= ~(1<<7); P2M0 |= (1<<7); } while(0)
|
||||
|
||||
//returns 1 if busy, 0 otherwise
|
||||
static char readBusy() {
|
||||
unsigned char oldP2 = P2;
|
||||
__bit busy;
|
||||
|
||||
LCD_RS = 0; //control
|
||||
LCD_RW = 1; //read
|
||||
LCD_E = 1;
|
||||
SET_BUSY_IN();
|
||||
|
||||
//wait
|
||||
_delay_us(100); // blind cycle 100us wait
|
||||
//read busy flag
|
||||
busy = LCD_BUSY;
|
||||
SET_BUSY_OUT();
|
||||
LCD_E = 0;
|
||||
LCD_E = 1;
|
||||
//wait
|
||||
_delay_us(100); // blind cycle 100us wait
|
||||
LCD_E = 0;
|
||||
P2 = oldP2;
|
||||
|
||||
return busy;
|
||||
}
|
||||
|
||||
//sets ErrorTimeout flag if busy signal not cleared in time
|
||||
static void wait_busy() {
|
||||
unsigned int i;
|
||||
for (i = 0; i < 100; i++){
|
||||
if (!readBusy()){
|
||||
return;
|
||||
}
|
||||
_delay_ms(1);
|
||||
}
|
||||
|
||||
ErrorTimeout = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
static void LCD_OutChar(unsigned char c) {
|
||||
unsigned char lower = (c & 0x0f);
|
||||
DISABLE_INTERRUPTS();
|
||||
wait_busy();
|
||||
//output upper 4 bits:
|
||||
LCD_E = 0;
|
||||
LCD_RS = 1; //data
|
||||
LCD_RW = 0; //write
|
||||
P2 = ((c & 0xf0));
|
||||
LCD_E = 1;
|
||||
_delay_us(100);
|
||||
LCD_E = 0;
|
||||
//output lower 4 bits:
|
||||
P2 = ((c & 0xf) << 4);
|
||||
LCD_E = 1;
|
||||
_delay_us(100);
|
||||
LCD_E = 0;
|
||||
ENABLE_INTERRUPTS();
|
||||
wait_busy();
|
||||
}
|
||||
|
||||
void LCD_Open(void) {
|
||||
static int open_error = 0;
|
||||
if (!OpenFlag) {
|
||||
//set ports to output
|
||||
//P2
|
||||
P2M1 = 0;
|
||||
P2M0 = 0xff;
|
||||
//P3
|
||||
P3M1 &= ~(0xfe);
|
||||
P3M0 |= (0xfe);
|
||||
|
||||
_delay_ms(30); // to allow LCD powerup
|
||||
outCsrBlindNibble(0x03); // (DL=1 8-bit mode)
|
||||
_delay_ms(5); // blind cycle 5ms wait
|
||||
outCsrBlindNibble(0x03); // (DL=1 8-bit mode)
|
||||
_delay_us(100); // blind cycle 100us wait
|
||||
outCsrBlindNibble(0x03); // (DL=1 8-bit mode)
|
||||
_delay_us(100); // blind cycle 100us wait (not called for, but do it anyway)
|
||||
outCsrBlindNibble(0x02); // DL=1 switch to 4 bit mode (only high 4 bits are sent)
|
||||
_delay_us(100); // blind cycle 100 us wait
|
||||
//set increment, no shift
|
||||
outCsrBlind(0x4 + LCDINC + LCDNOSHIFT);
|
||||
#ifdef DEBUG
|
||||
//set display on, cursor on, blink on:
|
||||
outCsrBlind(0x0c + LCDCURSOR + LCDBLINK);
|
||||
#else
|
||||
//set display on, cursor and blink off:
|
||||
outCsrBlind(0x0c + LCDNOCURSOR + LCDNOBLINK);
|
||||
#endif
|
||||
//set display shift on and to the right
|
||||
outCsrBlind(0x10 + LCDNOSCROLL + LCDRIGHT);
|
||||
//set 4-bit mode, 2 line, 5x7 display:
|
||||
outCsrBlind(0x20 + LCD2LINE + LCD7DOT);
|
||||
//clear display
|
||||
LCD_Clear();
|
||||
_delay_ms(50);
|
||||
if (!readBusy()) {
|
||||
OpenFlag = 1;
|
||||
} else {
|
||||
open_error = 1;
|
||||
}
|
||||
} else { //display already open
|
||||
open_error = 1;
|
||||
}
|
||||
}
|
||||
|
||||
//row and columns indexed from 0
|
||||
void LCD_GoTo(unsigned int row_to, unsigned int col_to) {
|
||||
if (row_to < MAX_ROWS && col_to < MAX_CHARS_PER_LINE) {
|
||||
outCsr(0x80 + 0x40 * row_to + col_to); //set ddram address to position
|
||||
row = row_to;
|
||||
col = col_to;
|
||||
} else {
|
||||
Error = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void to_row(unsigned char row_to) {
|
||||
if (row_to == 0) {
|
||||
outCsr(0x80);//set address to start of row 0
|
||||
row = 0;
|
||||
} else {
|
||||
outCsr(0xc0);// set address to row 1
|
||||
row = 1;
|
||||
}
|
||||
col = 0;
|
||||
}
|
||||
|
||||
//row indexed from 0
|
||||
void LCD_SingleLineGoTo(unsigned int spot_to) {
|
||||
LCD_GoTo(spot_to / MAX_CHARS_PER_LINE, spot_to % MAX_CHARS_PER_LINE);
|
||||
}
|
||||
|
||||
void LCD_OutString(const char *string) {
|
||||
const char *s;
|
||||
for (s = string; *s; s++) {
|
||||
TERMIO_PutChar(*s);
|
||||
}
|
||||
}
|
||||
|
||||
short TERMIO_PutChar(unsigned char letter) {
|
||||
if (letter == CR || letter == '\n') {
|
||||
LCD_Clear();
|
||||
} else if (letter == TAB || letter == '\t') {
|
||||
if (row == 0) {
|
||||
to_row(1);
|
||||
} else {
|
||||
to_row(0);
|
||||
}
|
||||
} else {
|
||||
if (col > MAX_CHARS_PER_LINE) {
|
||||
if (row == 0) {
|
||||
to_row(1);
|
||||
} else {
|
||||
to_row(0);
|
||||
}
|
||||
}
|
||||
col++;
|
||||
LCD_OutChar(letter);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void LCD_Clear() {
|
||||
if (OpenFlag) {
|
||||
outCsr(0x01);
|
||||
} else {
|
||||
outCsrBlind(0x01);
|
||||
}
|
||||
row = 0;
|
||||
col = 0;
|
||||
}
|
||||
|
||||
unsigned char LCD_Timeout_Error(void) {
|
||||
if (ErrorTimeout != 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
20
src/lcd.h
Normal file
20
src/lcd.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef LCD_H
|
||||
#define LCD_H
|
||||
|
||||
|
||||
#define MAX_CHARS_PER_LINE 15
|
||||
#define MAX_ROWS 2
|
||||
|
||||
void LCD_Open(void);
|
||||
void LCD_Clear(void);
|
||||
void LCD_GoTo(unsigned int row, unsigned int col);
|
||||
void LCD_SingleLineGoTo(unsigned int row_to);
|
||||
|
||||
void LCD_OutString(const char* string);
|
||||
short TERMIO_PutChar(unsigned char letter);
|
||||
|
||||
unsigned char LCD_Timeout_Error(void);
|
||||
|
||||
|
||||
#endif
|
||||
|
62
src/main.c
Normal file
62
src/main.c
Normal file
@ -0,0 +1,62 @@
|
||||
//
|
||||
// STC15 RPN calculator
|
||||
//
|
||||
|
||||
#include "stc15.h"
|
||||
#include <stdint.h>
|
||||
#include "lcd.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define FOSC 11059200
|
||||
|
||||
// clear wdt
|
||||
#define WDT_CLEAR() (WDT_CONTR |= 1 << 4)
|
||||
void timer0_isr() __interrupt 1 __using 1
|
||||
{
|
||||
P3_1 ^= 1;
|
||||
}
|
||||
|
||||
|
||||
// Call timer0_isr() 10000/sec: 0.0001 sec
|
||||
// Initialize the timer count so that it overflows after 0.0001 sec
|
||||
// THTL = 0x10000 - FOSC / 12 / 10000 = 0x10000 - 92.16 = 65444 = 0xFFA4
|
||||
void Timer0Init(void) //100us @ 11.0592MHz
|
||||
{
|
||||
// TMOD = 0; // default: 16-bit auto-reload
|
||||
// AUXR = 0; // default: traditional 8051 timer frequency of FOSC / 12
|
||||
// Initial values of TL0 and TH0 are stored in hidden reload registers: RL_TL0 and RL_TH0
|
||||
TL0 = 0xA4; // Initial timer value
|
||||
TH0 = 0xFF; // Initial timer value
|
||||
TF0 = 0; // Clear overflow flag
|
||||
TR0 = 1; // Timer0 start run
|
||||
ET0 = 1; // Enable timer0 interrupt
|
||||
EA = 1; // Enable global interrupt
|
||||
}
|
||||
|
||||
|
||||
char buf[17];
|
||||
|
||||
/*********************************************/
|
||||
int main()
|
||||
{
|
||||
uint32_t i;
|
||||
Timer0Init(); // display refresh & switch read
|
||||
LCD_Open();
|
||||
P3_4 = 0; //turn on led backlight
|
||||
LCD_OutString("Hello world !!!!");
|
||||
LCD_GoTo(1,0);
|
||||
LCD_OutString(".......");
|
||||
|
||||
i = 0;
|
||||
// LOOP
|
||||
while (1)
|
||||
{
|
||||
LCD_GoTo(1,7);
|
||||
LCD_OutString(u32str(i, buf, 10));
|
||||
i++;
|
||||
|
||||
WDT_CLEAR();
|
||||
}
|
||||
}
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
179
src/stc15.h
Normal file
179
src/stc15.h
Normal file
@ -0,0 +1,179 @@
|
||||
#ifndef _STC15_H_
|
||||
#define _STC15_H_
|
||||
|
||||
#include <8051.h>
|
||||
|
||||
#ifdef REG8051_H
|
||||
#undef REG8051_H
|
||||
#endif
|
||||
|
||||
/* P4 */
|
||||
__sfr __at (0xC0) P4 ;
|
||||
__sbit __at (0xC0) P4_0 ;
|
||||
__sbit __at (0xC1) P4_1 ;
|
||||
__sbit __at (0xC2) P4_2 ;
|
||||
__sbit __at (0xC3) P4_3 ;
|
||||
__sbit __at (0xC4) P4_4 ;
|
||||
__sbit __at (0xC5) P4_5 ;
|
||||
__sbit __at (0xC6) P4_6 ;
|
||||
__sbit __at (0xC7) P4_7 ;
|
||||
|
||||
__sfr __at 0x94 P0M0;
|
||||
__sfr __at 0x93 P0M1;
|
||||
__sfr __at 0x92 P1M0;
|
||||
__sfr __at 0x91 P1M1;
|
||||
__sfr __at 0x96 P2M0;
|
||||
__sfr __at 0x95 P2M1;
|
||||
__sfr __at 0xB2 P3M0;
|
||||
__sfr __at 0xB1 P3M1;
|
||||
__sfr __at 0xB4 P4M0;
|
||||
__sfr __at 0xB3 P4M1;
|
||||
__sfr __at 0xCA P5M0;
|
||||
__sfr __at 0xC9 P5M1;
|
||||
__sfr __at 0xCC P6M0;
|
||||
__sfr __at 0xCB P6M1;
|
||||
__sfr __at 0xE2 P7M0;
|
||||
__sfr __at 0xE1 P7M1;
|
||||
|
||||
__sfr __at 0x8E AUXR;
|
||||
__sfr __at 0xA2 AUXR1;
|
||||
__sfr __at 0xA2 P_SW1;
|
||||
__sfr __at 0x97 CLK_DIV;
|
||||
__sfr __at 0xA1 BUS_SPEED;
|
||||
__sfr __at 0x9D P1ASF;
|
||||
__sfr __at 0xBA P_SW2;
|
||||
|
||||
/* IE */
|
||||
__sbit __at 0xAE ELVD;
|
||||
__sbit __at 0xAD EADC;
|
||||
|
||||
/* IP */
|
||||
__sbit __at 0xBF PPCA;
|
||||
__sbit __at 0xBE PLVD;
|
||||
__sbit __at 0xBD PADC;
|
||||
|
||||
__sfr __at 0xAF IE2;
|
||||
__sfr __at 0xB5 IP2;
|
||||
__sfr __at 0x8F INT_CLKO;
|
||||
|
||||
__sfr __at 0xD1 T4T3M;
|
||||
__sfr __at 0xD1 T3T4M;
|
||||
__sfr __at 0xD2 T4H;
|
||||
__sfr __at 0xD3 T4L;
|
||||
__sfr __at 0xD4 T3H;
|
||||
__sfr __at 0xD5 T3L;
|
||||
__sfr __at 0xD6 T2H;
|
||||
__sfr __at 0xD7 T2L;
|
||||
__sfr __at 0xAA WKTCL;
|
||||
__sfr __at 0xAB WKTCH;
|
||||
__sfr __at 0xC1 WDT_CONTR;
|
||||
|
||||
__sfr __at 0x9A S2CON;
|
||||
__sfr __at 0x9B S2BUF;
|
||||
__sfr __at 0xAC S3CON;
|
||||
__sfr __at 0xAD S3BUF;
|
||||
__sfr __at 0x84 S4CON;
|
||||
__sfr __at 0x85 S4BUF;
|
||||
__sfr __at 0xA9 SADDR;
|
||||
__sfr __at 0xB9 SADEN;
|
||||
|
||||
//ADC
|
||||
__sfr __at 0xBC ADC_CONTR;
|
||||
__sfr __at 0xBD ADC_RES;
|
||||
__sfr __at 0xBE ADC_RESL;
|
||||
|
||||
//SPI
|
||||
__sfr __at 0xCD SPSTAT;
|
||||
__sfr __at 0xCE SPCTL;
|
||||
__sfr __at 0xCF SPDAT;
|
||||
|
||||
//IAP/ISP
|
||||
__sfr __at 0xC2 IAP_DATA;
|
||||
__sfr __at 0xC3 IAP_ADDRH;
|
||||
__sfr __at 0xC4 IAP_ADDRL;
|
||||
__sfr __at 0xC5 IAP_CMD;
|
||||
__sfr __at 0xC6 IAP_TRIG;
|
||||
__sfr __at 0xC7 IAP_CONTR;
|
||||
|
||||
//PCA/PWM
|
||||
__sfr __at 0xD8 CCON;
|
||||
__sbit __at 0xDF CF;
|
||||
__sbit __at 0xDE CR;
|
||||
__sbit __at 0xDA CCF2;
|
||||
__sbit __at 0xD9 CCF1;
|
||||
__sbit __at 0xD8 CCF0;
|
||||
|
||||
__sfr __at 0xD9 CMOD;
|
||||
__sfr __at 0xE9 CL;
|
||||
__sfr __at 0xF9 CH;
|
||||
__sfr __at 0xDA CCAPM0;
|
||||
__sfr __at 0xDB CCAPM1;
|
||||
__sfr __at 0xDC CCAPM2;
|
||||
__sfr __at 0xEA CCAP0L;
|
||||
__sfr __at 0xEB CCAP1L;
|
||||
__sfr __at 0xEC CCAP2L;
|
||||
__sfr __at 0xF2 PCA_PWM0;
|
||||
__sfr __at 0xF3 PCA_PWM1;
|
||||
__sfr __at 0xF4 PCA_PWM2;
|
||||
__sfr __at 0xFA CCAP0H;
|
||||
__sfr __at 0xFB CCAP1H;
|
||||
__sfr __at 0xFC CCAP2H;
|
||||
|
||||
__sfr __at 0xE6 CMPCR1;
|
||||
__sfr __at 0xE7 CMPCR2;
|
||||
|
||||
//PWM
|
||||
__sfr __at 0xf1 PWMCFG;
|
||||
__sfr __at 0xf5 PWMCR;
|
||||
__sfr __at 0xf6 PWMIF;
|
||||
__sfr __at 0xf7 PWMFDCR;
|
||||
|
||||
#define PWMC (*(unsigned int volatile xdata *)0xfff0)
|
||||
#define PWMCH (*(unsigned char volatile xdata *)0xfff0)
|
||||
#define PWMCL (*(unsigned char volatile xdata *)0xfff1)
|
||||
#define PWMCKS (*(unsigned char volatile xdata *)0xfff2)
|
||||
#define PWM2T1 (*(unsigned int volatile xdata *)0xff00)
|
||||
#define PWM2T1H (*(unsigned char volatile xdata *)0xff00)
|
||||
#define PWM2T1L (*(unsigned char volatile xdata *)0xff01)
|
||||
#define PWM2T2 (*(unsigned int volatile xdata *)0xff02)
|
||||
#define PWM2T2H (*(unsigned char volatile xdata *)0xff02)
|
||||
#define PWM2T2L (*(unsigned char volatile xdata *)0xff03)
|
||||
#define PWM2CR (*(unsigned char volatile xdata *)0xff04)
|
||||
#define PWM3T1 (*(unsigned int volatile xdata *)0xff10)
|
||||
#define PWM3T1H (*(unsigned char volatile xdata *)0xff10)
|
||||
#define PWM3T1L (*(unsigned char volatile xdata *)0xff11)
|
||||
#define PWM3T2 (*(unsigned int volatile xdata *)0xff12)
|
||||
#define PWM3T2H (*(unsigned char volatile xdata *)0xff12)
|
||||
#define PWM3T2L (*(unsigned char volatile xdata *)0xff13)
|
||||
#define PWM3CR (*(unsigned char volatile xdata *)0xff14)
|
||||
#define PWM4T1 (*(unsigned int volatile xdata *)0xff20)
|
||||
#define PWM4T1H (*(unsigned char volatile xdata *)0xff20)
|
||||
#define PWM4T1L (*(unsigned char volatile xdata *)0xff21)
|
||||
#define PWM4T2 (*(unsigned int volatile xdata *)0xff22)
|
||||
#define PWM4T2H (*(unsigned char volatile xdata *)0xff22)
|
||||
#define PWM4T2L (*(unsigned char volatile xdata *)0xff23)
|
||||
#define PWM4CR (*(unsigned char volatile xdata *)0xff24)
|
||||
#define PWM5T1 (*(unsigned int volatile xdata *)0xff30)
|
||||
#define PWM5T1H (*(unsigned char volatile xdata *)0xff30)
|
||||
#define PWM5T1L (*(unsigned char volatile xdata *)0xff31)
|
||||
#define PWM5T2 (*(unsigned int volatile xdata *)0xff32)
|
||||
#define PWM5T2H (*(unsigned char volatile xdata *)0xff32)
|
||||
#define PWM5T2L (*(unsigned char volatile xdata *)0xff33)
|
||||
#define PWM5CR (*(unsigned char volatile xdata *)0xff34)
|
||||
#define PWM6T1 (*(unsigned int volatile xdata *)0xff40)
|
||||
#define PWM6T1H (*(unsigned char volatile xdata *)0xff40)
|
||||
#define PWM6T1L (*(unsigned char volatile xdata *)0xff41)
|
||||
#define PWM6T2 (*(unsigned int volatile xdata *)0xff42)
|
||||
#define PWM6T2H (*(unsigned char volatile xdata *)0xff42)
|
||||
#define PWM6T2L (*(unsigned char volatile xdata *)0xff43)
|
||||
#define PWM6CR (*(unsigned char volatile xdata *)0xff44)
|
||||
#define PWM7T1 (*(unsigned int volatile xdata *)0xff50)
|
||||
#define PWM7T1H (*(unsigned char volatile xdata *)0xff50)
|
||||
#define PWM7T1L (*(unsigned char volatile xdata *)0xff51)
|
||||
#define PWM7T2 (*(unsigned int volatile xdata *)0xff52)
|
||||
#define PWM7T2H (*(unsigned char volatile xdata *)0xff52)
|
||||
#define PWM7T2L (*(unsigned char volatile xdata *)0xff53)
|
||||
#define PWM7CR (*(unsigned char volatile xdata *)0xff54)
|
||||
|
||||
#endif
|
||||
|
47
src/utils.c
Normal file
47
src/utils.c
Normal file
@ -0,0 +1,47 @@
|
||||
#include <stdint.h>
|
||||
|
||||
void _delay_ms(uint8_t ms)
|
||||
{
|
||||
// delay function, tuned for 11.092 MHz clock
|
||||
// optimized to assembler
|
||||
ms; // keep compiler from complaining?
|
||||
__asm;
|
||||
; dpl contains ms param value
|
||||
delay$:
|
||||
mov b, #8 ; i
|
||||
outer$:
|
||||
mov a, #243 ; j
|
||||
inner$:
|
||||
djnz acc, inner$
|
||||
djnz b, outer$
|
||||
djnz dpl, delay$
|
||||
__endasm;
|
||||
}
|
||||
|
||||
char* u32str(uint32_t x, char* buf, uint8_t base)
|
||||
{
|
||||
int i = 0, j;
|
||||
//corner case
|
||||
if (x == 0){
|
||||
buf[i] = '0';
|
||||
}
|
||||
//get reversed string
|
||||
while(x > 0){
|
||||
buf[i] = (x % base) + '0';
|
||||
x /= base;
|
||||
i++;
|
||||
}
|
||||
//add terminator
|
||||
buf[i] = '\0';
|
||||
i--; //back to last digit
|
||||
//reverse string
|
||||
for (j = 0; j < i; j++, i--){
|
||||
char tmp;
|
||||
tmp = buf[j];
|
||||
buf[j] = buf[i];
|
||||
buf[i] = tmp;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
21
src/utils.h
Normal file
21
src/utils.h
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* utils.h
|
||||
*
|
||||
* Created on: Mar 10, 2019
|
||||
*/
|
||||
|
||||
#ifndef SRC_UTILS_H_
|
||||
#define SRC_UTILS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void _delay_ms(uint8_t ms);
|
||||
|
||||
//TODO
|
||||
#define _delay_us(x) _delay_ms(1)
|
||||
|
||||
char* u32str(uint32_t x, char* buf, uint8_t base);
|
||||
|
||||
|
||||
#endif /* SRC_UTILS_H_ */
|
||||
|
Reference in New Issue
Block a user