You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
5.9 KiB
C

#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include "arduinolib.h"
/* First configure the pins of arduino and then
Initialize the LCD as described in the datasheet using the particular delays */
void Arduinolib__lcd_init_step(Arduinolib__lcd_init_out *out){
//control pins
LCD_E_DDR |= (1 << LCD_E_PIN);
LCD_RS_DDR |= (1 << LCD_RS_PIN);
//data pins
LCD_D4_DDR |= (1 << LCD_D4_PIN);
LCD_D5_DDR |= (1 << LCD_D5_PIN);
LCD_D6_DDR |= (1 << LCD_D6_PIN);
LCD_D7_DDR |= (1 << LCD_D7_PIN);
_delay_ms(50); //power delay more than 15ms
LCD_RS_PORT &= ~(1 << LCD_RS_PIN); //RS to low
LCD_E_PORT &= ~(1 << LCD_E_PIN); //E to low
// "reboot process"
Arduinolib__lcd_write_out *o1;
Arduinolib__lcd_write_step(LCD_FUNCTION_SET_8bit, o1);
_delay_ms(10); //more than 4.1ms
Arduinolib__lcd_write_out *o2;
Arduinolib__lcd_write_step(LCD_FUNCTION_SET_8bit,o2);
_delay_us(200); //more than 100us
Arduinolib__lcd_write_out *o3;
Arduinolib__lcd_write_step(LCD_FUNCTION_SET_8bit, o3);
_delay_us(200); //more than 100us
//set to 4bit
Arduinolib__lcd_write_out *o4;
Arduinolib__lcd_write_step(LCD_FUNCTION_SET_4bit, o4);
_delay_us(80); //more than 39us
Arduinolib__lcd_cmd_out *o5;
Arduinolib__lcd_cmd_step(LCD_FUNCTION_SET_4bit, o5);
_delay_us(80); //more than 39us
//send instructions
Arduinolib__lcd_cmd_out *o6;
Arduinolib__lcd_cmd_step(LCD_DISPLAY_OFF, o6);
_delay_us(80); //more than 39us
Arduinolib__lcd_cmd_out *o7;
Arduinolib__lcd_cmd_step(LCD_CLEAR, o7);
_delay_ms(3); //more than 1.53 ms
Arduinolib__lcd_cmd_out *o8;
Arduinolib__lcd_cmd_step(LCD_ENTRY_MODE, o8);
_delay_us(80); //more than 39us
Arduinolib__lcd_cmd_out *o9;
Arduinolib__lcd_cmd_step(LCD_DISPLAY_ON, o9);
_delay_us(80); //more than 39us
}
/* send an 8bit information to the LCD register in order to be written */
void Arduinolib__lcd_write_step(uint8_t info, Arduinolib__lcd_write_out *out){
if (info & 1<<4){
LCD_D4_PORT |= (1 << LCD_D4_PIN);
}
else {
LCD_D4_PORT &= ~(1 << LCD_D4_PIN);
}
if (info & 1<<5){
LCD_D5_PORT |= (1 << LCD_D5_PIN);
}
else {
LCD_D5_PORT &= ~(1 << LCD_D5_PIN);
}
if (info & 1<<6){
LCD_D6_PORT |= (1 << LCD_D6_PIN);
}
else {
LCD_D6_PORT &= ~(1 << LCD_D6_PIN);
}
if (info & 1<<7){
LCD_D7_PORT |= (1 << LCD_D7_PIN);
}
else {
LCD_D7_PORT &= ~(1 << LCD_D7_PIN);
}
//pulse the Enable pin to indicate we have written the data
LCD_E_PORT |= (1 << LCD_E_PIN); //high
_delay_us(1);
LCD_E_PORT &= ~(1 << LCD_E_PIN); //low
_delay_us(1);
}
/* send an 8bit instruction(command) to the LCD instruction register */
void Arduinolib__lcd_cmd_step(uint8_t cmd, Arduinolib__lcd_cmd_out *out){
LCD_RS_PORT &= ~(1 << LCD_RS_PIN); //low
LCD_E_PORT &= ~(1 << LCD_E_PIN); //low
Arduinolib__lcd_write_out *o1;
Arduinolib__lcd_write_step(cmd, o1); // write upper 4 bits
Arduinolib__lcd_write_out *o2;
Arduinolib__lcd_write_step(cmd << 4, o2); // write lower 4 bits
}
/* send an 8bit data character to the LCD register */
void Arduinolib__lcd_char_step(uint8_t char_data, Arduinolib__lcd_char_out *out){
LCD_RS_PORT |= (1 << LCD_RS_PIN); //high
LCD_E_PORT &= ~(1 << LCD_E_PIN); //low
Arduinolib__lcd_write_out *o1;
Arduinolib__lcd_write_step(char_data, o1); //write upper 4 bits
Arduinolib__lcd_write_out *o2;
Arduinolib__lcd_write_step(char_data << 4, o2); //write lower 4 bits
}
/* give a string to display to the LCD*/
void Arduinolib__lcd_string_step(uint8_t lstring[], int line, Arduinolib__lcd_string_out *out){
Arduinolib__lcd_cmd_out *o1;
Arduinolib__lcd_cmd_out *o2;
if (line == 1) {
Arduinolib__lcd_cmd_step(LCD_CURSOR_SET | LCD_START_LINE2, o1);
_delay_us(80); //more than 39us
} else {
Arduinolib__lcd_cmd_step(LCD_CURSOR_SET | LCD_START_LINE1, o2);
_delay_us(80); //more than 39us
}
volatile int i = 0;
for (i = 0; lstring[i] != 0 ; i++) {
Arduinolib__lcd_char_out *o3;
Arduinolib__lcd_char_step(lstring[i], o3);
_delay_us(80); //more than 39us
}
}
/* gice a number to display to the LCD */
void Arduinolib__lcd_int_step(int numb, int line, Arduinolib__lcd_int_out *out){
char lstring[80]; //buffer
itoa(numb, lstring, 10);
Arduinolib__lcd_string_out *o;
Arduinolib__lcd_string_step(lstring, line, o);
}
/* a general read pin function. it is assuming the user uses distinct pins to read/write */
void Arduinolib__dread_step(int p, Arduinolib__dread_out *out){
if (8 <= p && p <= 13){
int pin = p - 8;
DDRB &= ~(1 << pin);
if ((PINB & (1 << pin)) == (1 << pin) ) {
out -> v = 1; //pin high so it is pressed
}
else {
out -> v = 0; //pin low so it is not pressed
}
}
else if ( 0 <= p && p <= 7){
DDRD &= ~(1 << p);
if ((PIND & (1 << p)) == (1 << p) ) {
out -> v = 1; //pin high so it is pressed
} else {
out -> v = 0; //pin low so it is not pressed
}
}
else { //by default to pin 13 of arduino
DDRB &= ~(1 << 5);
if ((PINB & (1 << 5)) == (1 << 5) ) {
out -> v = 1; //pin high so it is pressed
}
else {
out -> v = 0; //pin low so it is not pressed
}
}
return;
}
void Arduinolib__dwrite_step(int p, int v, Arduinolib__dwrite_out *out){
if (8 <= p && p <= 13){
int pin = p - 8;
DDRB |= (1 << pin);
PORTB |= (1 << pin);
if (v == 0) PORTB &= ~(1 << pin);
}
else if ( 0 <= p && p <= 7){
DDRD |= (1 << p);
PORTD |= (1 << p);
if (v == 0) PORTD &= ~(1 << p);
}
else { //by default
DDRB |= (1 << 5);
PORTB |= (1 << 5);
if (v == 0) PORTB &= ~(1 << 5);
}
return;
}