Skip to content

Instantly share code, notes, and snippets.

@syusui-s
Created July 13, 2016 03:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save syusui-s/ec22039be7770b5c4e68b4feac5b05c1 to your computer and use it in GitHub Desktop.
Save syusui-s/ec22039be7770b5c4e68b4feac5b05c1 to your computer and use it in GitHub Desktop.
#define BAUD (9600)
#define STRLEN (256)
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/setbaud.h>
#include <util/delay.h>
#include <stdbool.h>
#include <string.h>
#include <limits.h>
#include <stdio.h>
#include <time.h>
volatile uint8_t countup10;
volatile uint64_t unix_time;
void USART_Init() {
UBRR0H = (uint8_t)UBRRH_VALUE;
UBRR0L = (uint8_t)UBRRL_VALUE;
// Data frame : 8bits, Stop bits : 2bits
UCSR0B = UCSR0B & (0b0 << UCSZ02);
UCSR0C = (0b11 << UCSZ00) | (1 << USBS0);
// Enable Tx/Rx
UCSR0B = (1 << RXEN0) | (1 << TXEN0);
}
void USART_Transmit(const unsigned char data) {
// wait for free of buffer
loop_until_bit_is_set(UCSR0A, UDRE0);
UDR0 = data;
}
unsigned char USART_Receive(void) {
loop_until_bit_is_set(UCSR0A, RXC0);
return UDR0;
}
#define usart_putc(c) USART_Transmit(c);
void usart_print(const char* str) {
for (uint8_t i = 0; str[i] != '\0'; i++) {
USART_Transmit(str[i]);
}
return;
}
void usart_puts(const char* str) {
usart_print(str);
USART_Transmit('\n');
return;
}
int usart_gets(char* str, const int len) {
int i;
for (i = 0; i < len; i++) {
char c = USART_Receive();
if (c == '\n' || c == '\0') {
str[i] = '\0';
break;
} else {
str[i] = c;
}
}
return i;
}
char* uint64_str(const uint64_t unix_time, char* buf, size_t len) {
char* start_ptr;
char* end_ptr;
uint64_t dived;
// convert uint64 to string
for (
dived = unix_time, end_ptr = buf;
dived != 0 && end_ptr < (buf + len);
dived /= 10, end_ptr++
) {
*end_ptr = dived % 10 + '0';
}
if (end_ptr >= (buf + len)) { // when over size of buf
return NULL;
} else if (end_ptr > buf) { // when some numbers are written in buf
*end_ptr = '\0';
for (
start_ptr = buf, end_ptr -= 1;
start_ptr < end_ptr;
start_ptr++, end_ptr--
) {
char tmp = *start_ptr;
*start_ptr = *end_ptr;
*end_ptr = tmp;
}
} else { // when buf has no numbers
buf[0] = '0';
buf[1] = '\0';
}
return buf;
}
void Timer1_Init() {
countup10 = 0;
unix_time = 1468377662ULL;
set_system_time((time_t)unix_time - UNIX_OFFSET);
// タイマ動作をCTCに設定, 64分周に設定
TCCR1B = (1 << WGM12) | (0b011 << CS10);
// タイマカウントを1秒周期に設定
OCR1A = (F_CPU / 64 / 10) - 1;
// 1Aの比較一致で割り込み発生
TIMSK1 = (1 << OCIE1A);
// 割り込み許可
sei();
}
void print_time() {
char output[STRLEN] = {'0'};
uint64_t real_unix_time = unix_time - (uint64_t)UNIX_OFFSET;
usart_print("Current Unix Time: ");
usart_print(ctime((time_t*)&real_unix_time));
usart_print(ctime((time_t*)time(NULL)));
usart_putc('(');
if (uint64_str(unix_time, output, STRLEN) != NULL) {
usart_print(output);
}
usart_putc(')');
usart_putc('\n');
}
ISR(TIMER1_COMPA_vect) {
if (countup10 >= 10) {
system_tick();
countup10 = 0;
unix_time++;
print_time();
}
countup10++;
}
int main(void) {
char str[] = "Hello. This is AVR ATmega88P-20PA.\nNice to meet you.\n";
char input[STRLEN] = {};
Timer1_Init();
USART_Init();
usart_puts(str);
int i = 0;
while (true) {
sprintf(input, "[%d] > ", i++);
usart_print(input);
usart_gets(input, STRLEN);
if (strcmp(input, "time") == 0) {
//char* tm = ctime((time_t)unix_time);
//sprintf(input, "Current Unix Time: %s\n", tm);
//usart_puts(input);
} else if (strcmp(input, "")){
usart_puts("Unknown Command Error!");
}
}
while (true) {
_delay_ms(5000UL);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment