First commit

This commit is contained in:
Dawid Pietrykowski 2024-04-16 20:18:18 +02:00
commit 8749f5e3a9
20 changed files with 1625 additions and 0 deletions

View File

@ -0,0 +1,38 @@
#include <avr/io.h>
#include <avr/interrupt.h>
volatile uint8_t current_led = 3;
volatile uint8_t reverse = 0;
ISR(ANALOG_COMP_vect){
uint8_t next = current_led + 1;
if (next > 3){
next = 0;
reverse = (reverse + 1) % 2;
}
if (!reverse){
PORTC |= (1<<next);
}else{
PORTC &= ~(1<<next);
}
current_led = next;
}
int main(void){
// ustawienie C0-C3 jako wyjscie
DDRC |= 0b00001111;
// wylaczenie interrupow
cli();
// wlaczenie interrupu na komparator
ACSR |= (1<<ACIE);
// wlaczenie interrupow
sei();
for(;;);
return 1;
}

View File

@ -0,0 +1,46 @@
#include <avr/io.h>
#include <avr/interrupt.h>
volatile uint8_t current_led = 3;
// czyscimy czy zapalamy
volatile uint8_t reverse = 0;
void update_led(){
// przesuwamy wybrany led
uint8_t next = current_led + 1;
if (next > 3){
next = 0;
reverse = (reverse + 1) % 2;
}
if (!reverse){
// zapalamy kolejna
PORTC |= (1<<next);
}else{
// gasimy kolejna
PORTC &= ~(1<<next);
}
current_led = next;
}
int main(void){
// ustawienie C0-C3 jako wyjscie
DDRC |= 0b00001111;
uint8_t last_state = ACSR & (1<<ACO);
for(;;){
// pobieramy stan komparatora
uint8_t comparator_state = ACSR & (1<<ACO);
// jesli stan sie zmienil na wysoki to przesun ledy
if (comparator_state != last_state && last_state == 0){
update_led();
}
// zaktualizuj ostatni stan
last_state = comparator_state;
}
return 1;
}

View File

@ -0,0 +1,35 @@
#include<avr/io.h>
#include<avr/interrupt.h>
volatile uint8_t dioda = 0;
// Przerwanie ktore wykonuje sie przy zmianie stanu kompratora
ISR(ANALOG_COMP_vect) {
if(dioda == 0) dioda = 1;
else dioda = 0;
}
int main(void) {
// Ustawienie portu C0 i C1 jako wyjscie
DDRC |= (1<<PC0) | (1<<PC1);
// Wlaczenie interrupt na toggle stanu komparatora
cli();
ACSR |= (1<<ACIE);
sei();
while(1) {
// Zmiana na bezposrednie zczytanie stanu
// B2 - AIN0
// B3 - AIN1
uint8_t AIN0_wieksze_od_AIN1 = ACSR & (1<<ACO);
if(AIN0_wieksze_od_AIN1) PORTC |= (1<<PC0);
else PORTC &= ~(1<<PC0);
// Zmiana na interrupt
if(dioda == 0) PORTC &= ~(1<<PC1);
else PORTC |= (1<<PC1);
}
return 0;
}

590
lectures/LCD_lib/HD44780.c Normal file
View File

@ -0,0 +1,590 @@
#include "HD44780.h"
//----- Auxiliary data --------------------------//
#define _Byte2Ascii(Value) (Value = Value + '0')
#if (LCD_Size == 801)
#define __LCD_Rows 1
#define __LCD_Columns 8
#define __LCD_LineStart_1 0x00
#elif (LCD_Size == 802)
#define __LCD_Rows 2
#define __LCD_Columns 8
#define __LCD_LineStart_1 0x00
#define __LCD_LineStart_2 0x40
#elif (LCD_Size == 1601)
#define __LCD_Rows 1
#define __LCD_Columns 16
#define __LCD_LineStart_1 0x00
#if (LCD_Type == B)
#define __LCD_LINESTART_1B 0x40
#endif
#elif (LCD_Size == 1602)
#define __LCD_Rows 2
#define __LCD_Columns 16
#define __LCD_LineStart_1 0x00
#define __LCD_LineStart_2 0x40
#elif (LCD_Size == 1604)
#define __LCD_Rows 4
#define __LCD_Columns 16
#define __LCD_LineStart_1 0x00
#define __LCD_LineStart_2 0x40
#define __LCD_LineStart_3 0x10
#define __LCD_LineStart_4 0x50
#elif (LCD_Size == 2001)
#define __LCD_Rows 1
#define __LCD_Columns 20
#define __LCD_LineStart_1 0x00
#elif (LCD_Size == 2002)
#define __LCD_Rows 2
#define __LCD_Columns 20
#define __LCD_LineStart_1 0x00
#define __LCD_LineStart_2 0x40
#elif (LCD_Size == 2004)
#define __LCD_Rows 4
#define __LCD_Columns 20
#define __LCD_LineStart_1 0x00
#define __LCD_LineStart_2 0x40
#define __LCD_LineStart_3 0x14
#define __LCD_LineStart_4 0x54
#elif (LCD_Size == 4001)
#define __LCD_Rows 1
#define __LCD_Columns 40
#define __LCD_LineStart_1 0x00
#elif (LCD_Size == 4002)
#define __LCD_Rows 2
#define __LCD_Columns 40
#define __LCD_LineStart_1 0x00
#define __LCD_LineStart_2 0x40
#endif
//-----------------------------------------------//
//----- Prototypes ----------------------------//
static void LCD_SendCommandHigh(uint8_t Command);
static void LCD_Send(uint8_t Data);
static uint8_t LCD_Read(void);
static inline void Pulse_En(void);
static void Int2bcd(int32_t Value, char *BCD);
//---------------------------------------------//
//----- Functions -------------//
//Setup LCD.
void LCD_Setup(void)
{
//LCD pins = Outputs
PinMode(LCD_D4, Output);
PinMode(LCD_D5, Output);
PinMode(LCD_D6, Output);
PinMode(LCD_D7, Output);
PinMode(LCD_RS, Output);
PinMode(LCD_RW, Output);
PinMode(LCD_EN, Output);
//LCD pins = 0
DigitalWrite(LCD_D4, Low);
DigitalWrite(LCD_D5, Low);
DigitalWrite(LCD_D6, Low);
DigitalWrite(LCD_D7, Low);
DigitalWrite(LCD_RS, Low);
DigitalWrite(LCD_RW, Low);
DigitalWrite(LCD_EN, Low);
//----- Soft reset -----
//1. Wait for more than 15ms
_delay_ms(__LCD_Delay_1);
//2. Command 32: LCD 8-bit mode
LCD_SendCommandHigh(__LCD_CMD_FunctionSet | __LCD_CMD_8BitMode);
//3. Wait for more than 4.1ms
_delay_ms(__LCD_Delay_2);
//4. Command 32: LCD 8-bit mode
LCD_SendCommandHigh(__LCD_CMD_FunctionSet | __LCD_CMD_8BitMode);
//5. Wait for more than 100us
_delay_ms(__LCD_Delay_3);
//6. Command 32: LCD 8-bit mode, for the 3rd time
LCD_SendCommandHigh(__LCD_CMD_FunctionSet | __LCD_CMD_8BitMode);
//7. Wait for more than 100us
_delay_ms(__LCD_Delay_4);
//----- Initialization -----
//1. Command 32: LCD mode
LCD_SendCommandHigh(__LCD_CMD_FunctionSet | __LCD_CMD_4BitMode);
//2. Command 32: LCD mode and size
LCD_SendCommand(__LCD_CMD_FunctionSet | __LCD_CMD_4BitMode | __LCD_CMD_2Line | __LCD_CMD_5x8Dots);
//3. Command 8: Display On, Cursor off, Blinking Off
LCD_SendCommand(__LCD_CMD_DisplayControl | __LCD_CMD_DisplayOn | __LCD_CMD_CursorOff | __LCD_CMD_BlinkOff);
//4. Command 4: Auto increment, No shifting
LCD_SendCommand(__LCD_CMD_EntryModeSet | __LCD_CMD_EntryIncrement | __LCD_CMD_EntryNoShift);
//5. Command 1: Clear display, cursor at home
LCD_SendCommand(__LCD_CMD_ClearDisplay);
}
//Send command to LCD.
void LCD_SendCommand(uint8_t Command)
{
LCD_WaitBusy();
DigitalWrite(LCD_RS, Low);
LCD_Send(Command);
}
//Send data to LCD.
void LCD_SendData(char c)
{
LCD_WaitBusy();
DigitalWrite(LCD_RS, High);
LCD_Send((uint8_t)(c));
}
//Wait until busy flag is cleared.
void LCD_WaitBusy(void)
{
uint8_t busy = 0;
PinMode(LCD_D4, Input); //D7:D4 = Inputs
PinMode(LCD_D5, Input);
PinMode(LCD_D6, Input);
PinMode(LCD_D7, Input);
DigitalWrite(LCD_RS, Low); //RS=0
DigitalWrite(LCD_RW, High); //RW=1
do
{
//High nibble comes first
DigitalWrite(LCD_EN, High);
_delay_us(__LCD_Pulse_us);
busy &= ~(1<<__LCD_BusyFlag);
busy |= (DigitalRead(LCD_D7)<<__LCD_BusyFlag);
DigitalWrite(LCD_EN, Low);
//Low nibble follows
Pulse_En();
}
while(BitCheck(busy, __LCD_BusyFlag));
PinMode(LCD_D4, Output); //D7:D4 = Outputs
PinMode(LCD_D5, Output);
PinMode(LCD_D6, Output);
PinMode(LCD_D7, Output);
DigitalWrite(LCD_RW, Low); //RW = 0
}
//Build character in LCD CGRAM from data in SRAM.
void LCD_BuildChar(char *Data, uint8_t Position)
{
if (Position < 0)
return;
if (Position >= 8)
return;
Point_t p = LCD_GetP();
uint8_t i;
//Every character in CGRAM needs 8bytes
LCD_SendCommand(__LCD_CMD_SetCGRAMAddress | (Position<<3));
//Save the character byte-by-byte
for (i = 0 ; i < 8 ; i++)
LCD_SendData(Data[i]);
//Return to the DDRAM position
LCD_GotoXY(p.X, p.Y);
}
//Build character in LCD CGRAM from data in Flash memory.
void LCD_BuildChar_P(const char *Data, uint8_t Position)
{
if (Position < 0)
return;
if (Position >= 8)
return;
Point_t p = LCD_GetP();
uint8_t i;
//Every character in CGRAM needs 8bytes
LCD_SendCommand(__LCD_CMD_SetCGRAMAddress | (Position<<3));
//Save the character byte-by-byte
for (i = 0 ; i < 8 ; i++)
LCD_SendData(pgm_read_byte(Data[i]));
//Return to the DDRAM position
LCD_GotoXY(p.X, p.Y);
}
//Clear display.
void LCD_Clear(void)
{
LCD_SendCommand(__LCD_CMD_ClearDisplay);
}
//Clear line.
void LCD_ClearLine(uint8_t Line)
{
uint8_t i = 0;
LCD_GotoXY(0, Line);
while(i <= __LCD_Columns)
{
LCD_SendData(' ');
i++;
}
}
//Go to specified position.
void LCD_GotoXY(uint8_t X, uint8_t Y)
{
if ((X < __LCD_Columns) && (Y < __LCD_Rows))
{
uint8_t addr = 0;
switch (Y)
{
#if ((defined(__LCD_LineStart_4)) || (defined(__LCD_LineStart_3)) || (defined(__LCD_LineStart_2)) || (defined(__LCD_LineStart_1)))
case (0):
addr = __LCD_LineStart_1;
#if ((LCD_Size == 1601) && (LCD_Type == B))
if (X >= (__LCD_Columns>>1))
{
X -= __LCD_Columns>>1;
addr = __LCD_LINESTART_1B;
}
#endif
break;
#endif
#if ((defined(__LCD_LineStart_4)) || (defined(__LCD_LineStart_3)) || (defined(__LCD_LineStart_2)))
case (1):
addr = __LCD_LineStart_2;
break;
#endif
#if ((defined(__LCD_LineStart_4)) || (defined(__LCD_LineStart_3)))
case (2):
addr = __LCD_LineStart_3;
break;
#endif
#if (defined(__LCD_LineStart_4))
case (3):
addr = __LCD_LineStart_4;
break;
#endif
}
addr = __LCD_CMD_SetDDRAMAddress | (addr | X);
LCD_SendCommand(addr);
}
}
//Get current position.
Point_t LCD_GetP(void)
{
Point_t p;
p.X = LCD_Read();
p.Y = 0;
#if (__LCD_Rows == 1)
#if ((LCD_Size == 1601) && (LCD_Type == B))
if (p.X >= __LCD_LINESTART_1B)
p.X = p.X - __LCD_LINESTART_1B + (__LCD_Columns>>1);
#endif
#elif (__LCD_Rows == 2)
if (p.X >= __LCD_LineStart_2)
{
p.X -= __LCD_LineStart_2;
p.Y = 1;
}
#elif (__LCD_Rows == 3)
if (p.X >= __LCD_LineStart_2)
{
p.X -= __LCD_LineStart_2;
p.Y = 1;
}
else if (p.X >= __LCD_LineStart_3)
{
p.X -= __LCD_LineStart_3;
p.Y = 2;
}
#elif (__LCD_Rows == 4)
if (p.X >= __LCD_LineStart_4)
{
p.X -= __LCD_LineStart_4;
p.Y = 3;
}
else if (p.X >= __LCD_LineStart_2)
{
p.X -= __LCD_LineStart_2;
p.Y = 1;
}
else if (p.X >= __LCD_LineStart_3)
{
p.X -= __LCD_LineStart_3;
p.Y = 2;
}
#endif
return p;
}
//Get X position.
uint8_t LCD_GetX(void)
{
return LCD_GetP().X;
}
//Get Y position.
uint8_t LCD_GetY(void)
{
return LCD_GetP().Y;
}
//Print character.
void LCD_PrintChar(char Character)
{
LCD_SendData(Character);
}
//Print string from SRAM.
void LCD_PrintString(char *Text)
{
while(*Text)
LCD_SendData(*Text++);
}
//Print string from Flash memory.
void LCD_PrintString_P(const char *Text)
{
char r = pgm_read_byte(Text++);
while(r)
{
LCD_SendData(r);
r = pgm_read_byte(Text++);
}
}
//Print integer.
void LCD_PrintInteger(int32_t Value)
{
if (Value == 0 )
{
LCD_PrintChar('0');
}
else if ((Value > INT32_MIN ) && (Value <= INT32_MAX))
{
//int32_max + sign + null = 12 bytes
char arr[12] = { '\0' };
//Convert integer to array (returns in reversed order)
Int2bcd(Value, arr);
//Print
LCD_PrintString(arr);
}
}
//Print double.
void LCD_PrintDouble(double Value, uint32_t Tens)
{
if (Value == 0)
{
//Print characters individually so no string is stored into RAM.
LCD_PrintChar('0');
LCD_PrintChar('.');
LCD_PrintChar('0');
}
else if ((Value >= (-2147483647)) && (Value < 2147483648))
{
//Print sign
if (Value < 0)
{
Value = -Value;
LCD_PrintChar('-');
}
//Print integer part
LCD_PrintInteger(Value);
//Print dot
LCD_PrintChar('.');
//Print decimal part
LCD_PrintInteger((Value - (uint32_t)(Value)) * Tens);
}
}
//Send only high nibble to LCD.
static void LCD_SendCommandHigh(uint8_t Data)
{
DigitalWrite(LCD_RS, Low);
//Send the high nibble
DigitalWrite(LCD_D4, BitCheck(Data, 4));
DigitalWrite(LCD_D5, BitCheck(Data, 5));
DigitalWrite(LCD_D6, BitCheck(Data, 6));
DigitalWrite(LCD_D7, BitCheck(Data, 7));
Pulse_En();
}
//Send data to LCD.
static void LCD_Send(uint8_t Data)
{
//Send the high nibble
DigitalWrite(LCD_D4, BitCheck(Data, 4));
DigitalWrite(LCD_D5, BitCheck(Data, 5));
DigitalWrite(LCD_D6, BitCheck(Data, 6));
DigitalWrite(LCD_D7, BitCheck(Data, 7));
Pulse_En();
//Low nibble comes after
DigitalWrite(LCD_D4, BitCheck(Data, 0));
DigitalWrite(LCD_D5, BitCheck(Data, 1));
DigitalWrite(LCD_D6, BitCheck(Data, 2));
DigitalWrite(LCD_D7, BitCheck(Data, 3));
Pulse_En();
}
//Read status from LCD.
static uint8_t LCD_Read(void)
{
uint8_t status = 0;
LCD_WaitBusy();
PinMode(LCD_D4, Input); //D7:D4 = Inputs
PinMode(LCD_D5, Input);
PinMode(LCD_D6, Input);
PinMode(LCD_D7, Input);
DigitalWrite(LCD_RS, Low); //RS = 0
DigitalWrite(LCD_RW, High); //RW = 1
//High nibble comes first
DigitalWrite(LCD_EN, High);
_delay_us(__LCD_Pulse_us);
status |= DigitalRead(LCD_D4)<<4;
status |= DigitalRead(LCD_D5)<<5;
status |= DigitalRead(LCD_D6)<<6;
DigitalWrite(LCD_EN, Low);
//Low nibble follows
DigitalWrite(LCD_EN, High);
_delay_us(__LCD_Pulse_us);
status |= DigitalRead(LCD_D4);
status |= DigitalRead(LCD_D5)<<1;
status |= DigitalRead(LCD_D6)<<2;
status |= DigitalRead(LCD_D7)<<3;
DigitalWrite(LCD_EN, Low);
PinMode(LCD_D4, Output); //D7:D4 = Outputs
PinMode(LCD_D5, Output);
PinMode(LCD_D6, Output);
PinMode(LCD_D7, Output);
DigitalWrite(LCD_RW, Low); //RW = 0
return status;
}
//Sends pulse to PIN_EN of LCD.
static inline void Pulse_En(void)
{
DigitalWrite(LCD_EN, High);
_delay_us(__LCD_Pulse_us);
DigitalWrite(LCD_EN, Low);
}
//Converts integer value to BCD.
static void Int2bcd(int32_t Value, char BCD[])
{
uint8_t isNegative = 0;
BCD[0] = BCD[1] = BCD[2] =
BCD[3] = BCD[4] = BCD[5] =
BCD[6] = BCD[7] = BCD[8] =
BCD[9] = BCD[10] = '0';
if (Value < 0)
{
isNegative = 1;
Value = -Value;
}
while (Value > 1000000000)
{
Value -= 1000000000;
BCD[1]++;
}
while (Value >= 100000000)
{
Value -= 100000000;
BCD[2]++;
}
while (Value >= 10000000)
{
Value -= 10000000;
BCD[3]++;
}
while (Value >= 1000000)
{
Value -= 1000000;
BCD[4]++;
}
while (Value >= 100000)
{
Value -= 100000;
BCD[5]++;
}
while (Value >= 10000)
{
Value -= 10000;
BCD[6]++;
}
while (Value >= 1000)
{
Value -= 1000;
BCD[7]++;
}
while (Value >= 100)
{
Value -= 100;
BCD[8]++;
}
while (Value >= 10)
{
Value -= 10;
BCD[9]++;
}
while (Value >= 1)
{
Value -= 1;
BCD[10]++;
}
uint8_t i = 0;
//Find first non zero digit
while (BCD[i] == '0')
i++;
//Add sign
if (isNegative)
{
i--;
BCD[i] = '-';
}
//Shift array
uint8_t end = 10 - i;
uint8_t offset = i;
i = 0;
while (i <= end)
{
BCD[i] = BCD[i + offset];
i++;
}
BCD[i] = '\0';
}
//-----------------------------//

View File

@ -0,0 +1,95 @@
#ifndef HD44780_H_INCLUDED
#define HD44780_H_INCLUDED
/*
||
|| Filename: HD44780.h
|| Title: HD44780 Driver
|| Author: Efthymios Koktsidis
|| Email: efthymios.ks@gmail.com
|| Compiler: AVR-GCC
|| Description:
|| This library can drive HD44780 based LCD.
|| The LCD is driven exclusively in 4-bit mode.
||
*/
//----- Headers ------------//
#include <inttypes.h>
#include <util/delay.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include "IO_Macros.h"
#include "HD44780_Settings.h"
//--------------------------//
//----- Auxiliary data ---------------------------//
#define __LCD_Pulse_us 1
#define __LCD_Delay_1 20
#define __LCD_Delay_2 10
#define __LCD_Delay_3 1
#define __LCD_Delay_4 1
#define __LCD_CMD_ClearDisplay 0x01
#define __LCD_CMD_ReturnHome 0x02
#define __LCD_CMD_EntryModeSet 0x04
#define __LCD_CMD_DisplayControl 0x08
#define __LCD_CMD_CursorShift 0x10
#define __LCD_CMD_FunctionSet 0x20
#define __LCD_CMD_SetCGRAMAddress 0x40
#define __LCD_CMD_SetDDRAMAddress 0x80
#define __LCD_CMD_EntryIncrement 0x02
#define __LCD_CMD_EntryDecrement 0x00
#define __LCD_CMD_EntryShift 0x01
#define __LCD_CMD_EntryNoShift 0x00
#define __LCD_CMD_DisplayOn 0x04
#define __LCD_CMD_DisplayOff 0x00
#define __LCD_CMD_CursonOn 0x02
#define __LCD_CMD_CursorOff 0x00
#define __LCD_CMD_BlinkOn 0x01
#define __LCD_CMD_BlinkOff 0x00
#define __LCD_CMD_DisplayMove 0x08
#define __LCD_CMD_CursorMove 0x00
#define __LCD_CMD_MoveRight 0x04
#define __LCD_CMD_MoveLeft 0x00
#define __LCD_CMD_8BitMode 0x10
#define __LCD_CMD_4BitMode 0x00
#define __LCD_CMD_2Line 0x08
#define __LCD_CMD_1Line 0x00
#define __LCD_CMD_5x10Dots 0x04
#define __LCD_CMD_5x8Dots 0x00
#define __LCD_BusyFlag 7
typedef struct
{
uint8_t X,Y;
}Point_t;
//------------------------------------------------//
//----- Prototypes ------------------------------------------------------------//
void LCD_Setup(void);
void LCD_SendCommand(uint8_t Command);
void LCD_SendData(char Character);
void LCD_WaitBusy(void);
void LCD_BuildChar(char *Data, uint8_t Position);
void LCD_BuildChar_P(const char *Data, uint8_t Position);
void LCD_Clear(void);
void LCD_ClearLine(uint8_t Line);
void LCD_GotoXY(uint8_t X, uint8_t Y);
Point_t LCD_GetP(void);
uint8_t LCD_GetX(void);
uint8_t LCD_GetY(void);
void LCD_PrintChar(char Character);
void LCD_PrintString(char *Text);
void LCD_PrintString_P(const char *Text);
void LCD_PrintInteger(int32_t Value);
void LCD_PrintDouble(double Value, uint32_t Tens);
//-----------------------------------------------------------------------------//
#endif

View File

@ -0,0 +1,43 @@
#ifndef HD44780_SETTINGS_H_INCLUDED
#define HD44780_SETTINGS_H_INCLUDED
/*
||
|| Filename: HD44780_Settings.h
|| Title: HD44780 Driver Settings
|| Author: Efthymios Koktsidis
|| Email: efthymios.ks@gmail.com
|| Compiler: AVR-GCC
|| Description:
|| Settings for the HD44780 driver. Pick a size and the
|| desirable pins. 16x1 needs testing.
||
|| Size Code | Size Code | Size Code | Size Code |
||------------------------------------------------------------------|
|| 8x1 - 801 | * 16x1 - 1601 * | 20x1 - 2001 | 40x1 - 4001 |
|| 8x2 - 802 | 16x2 - 1602 | 20x2 - 2002 | 40x2 - 4002 |
|| | 16x4 - 1604 | 20x4 - 2004 | |
||
||*If LCD size is 16x1, choose variant A or B
|| Type Row DDRAM Address Details
|| ? 0x00->0x0F Row uses consequtive block addresses.
|| ? 0x00->0x07 + 0x40->0x47 Row is split into two sections.
||
*/
//----- Configuration --------------------------//
//LCD size
#define LCD_Size 1602
//If LCD size is 16x1, define type A or B
#define LCD_Type A
//LCD pins PORT, PIN
#define LCD_D4 D, 4
#define LCD_D5 D, 5
#define LCD_D6 D, 6
#define LCD_D7 D, 7
#define LCD_RS D, 1
#define LCD_RW D, 2
#define LCD_EN D, 3
//----------------------------------------------//
#endif

View File

@ -0,0 +1,60 @@
#ifndef IO_MACROS_H_INCLUDED
#define IO_MACROS_H_INCLUDED
/*
||
|| Filename: IO_Macros.h
|| Title: IO manipulation macros
|| Author: Efthymios Koktsidis
|| Email: efthymios.ks@gmail.com
|| Compiler: AVR-GCC
|| Description: This library contains macros for
|| easy port manipulation (similar
|| to Arduino).
||
|| Demo:
|| 1. #define LED A, 0 || 6. PinModeToggle(BUTTON);
|| 2. #define BUTTON A, 1 || 7. DigitalWrite(LED, LOW);
|| 3. || 8. DigitalWrite(LED, HIGH);
|| 4. PinMode(BUTTON, OUTPUT); || 9. DigitalLevelToggle(LED);
|| 5. PinMode(LED, OUTPUT); ||10. int a = DigitalRead(BUTTON);
||
*/
#include <avr/io.h>
//----- I/O Macros -----
//Macros to edit PORT, DDR and PIN
#define PinMode( x, y) ( y ? _SET(DDR, x) : _CLEAR(DDR, x) )
#define DigitalWrite( x, y) ( y ? _SET(PORT, x) : _CLEAR(PORT, x) )
#define DigitalRead( x) ( _GET(PIN, x) )
#define PinModeToggle( x) ( _TOGGLE(DDR, x) )
#define DigitalLevelToggle( x) ( _TOGGLE(PORT, x) )
//General use bit manipulating commands
#define BitSet( x, y) ( x |= (1UL<<y) )
#define BitClear( x, y) ( x &= (~(1UL<<y)) )
#define BitToggle( x, y) ( x ^= (1UL<<y) )
#define BitCheck( x, y) ( x & (1UL<<y) ? 1 : 0 )
//Access PORT, DDR and PIN
#define PORT( port) (_PORT( port))
#define DDR( port) (_DDR( port))
#define PIN( port) (_PIN( port))
#define _PORT( port) (PORT## port)
#define _DDR( port) (DDR## port)
#define _PIN( port) (PIN## port)
#define _SET( type, port, bit) ( BitSet( (type##port), bit) )
#define _CLEAR( type, port, bit) ( BitClear( (type##port), bit) )
#define _TOGGLE(type, port, bit) ( BitToggle( (type##port), bit) )
#define _GET( type, port, bit) ( BitCheck( (type##port), bit) )
//Definitions
#define Input 0
#define Output !Input
#define Low 0
#define High !Low
#define False 0
#define True !False
//------------------
#endif

View File

@ -0,0 +1,22 @@
#include"HD44780.h"
int main(void) {
uint8_t linia;
char Znak1[] = {0x04, 0x0E, 0x04, 0x1F, 0x04, 0x0E, 0x04, 0x04};
char Znak2[] = {0x00, 0x00, 0x00, 0x1F, 0x1F, 0x00, 0x00, 0x00};
LCD_Setup();
LCD_BuildChar(Znak1, 0);
LCD_BuildChar(Znak2, 1);
for(linia = 0; linia < 2; linia++) {
LCD_GotoXY(0, linia);
LCD_PrintString("Linia 1");
LCD_PrintInteger(LCD_GetY());
LCD_SendData(linia);
LCD_PrintDouble(3.14, 100);
}
while(1);
return 0;
}

View File

@ -0,0 +1,250 @@
#include<avr/io.h>
#include<util/delay.h>
#define HD44780_CLEAR 0x01
#define HD44780_HOME 0x02
#define HD44780_ENTRY_MODE 0x04
#define HD44780_EM_SHIFT_CURSOR 0
#define HD44780_EM_SHIFT_DISPLAY 1
#define HD44780_EM_DECREMENT 0
#define HD44780_EM_INCREMENT 2
#define HD44780_DISPLAY_ONOFF 0x08
#define HD44780_DISPLAY_OFF 0
#define HD44780_DISPLAY_ON 4
#define HD44780_CURSOR_OFF 0
#define HD44780_CURSOR_ON 2
#define HD44780_CURSOR_NOBLINK 0
#define HD44780_CURSOR_BLINK 1
#define HD44780_DISPLAY_CURSOR_SHIFT 0x10
#define HD44780_SHIFT_CURSOR 0
#define HD44780_SHIFT_DISPLAY 8
#define HD44780_SHIFT_LEFT 0
#define HD44780_SHIFT_RIGHT 4
#define HD44780_FUNCTION_SET 0x20
#define HD44780_FONT5x7 0
#define HD44780_FONT5x10 4
#define HD44780_ONE_LINE 0
#define HD44780_TWO_LINE 8
#define HD44780_4_BIT 0
#define HD44780_8_BIT 16
#define HD44780_CGRAM_SET 0x40
#define HD44780_DDRAM_SET 0x80
#define PORT(x) XPORT(x)
#define XPORT(x) (PORT##x)
#define PIN(x) XPIN(x)
#define XPIN(x) (PIN##x)
#define DDR(x) XDDR(x)
#define XDDR(x) (DDR##x)
#define LCD_DATA_PORT D
#define LCD_RS_PORT D
#define LCD_RW_PORT D
#define LCD_E_PORT D
#define LCD_D4_PIN 4
#define LCD_D5_PIN 5
#define LCD_D6_PIN 6
#define LCD_D7_PIN 7
#define LCD_RS_PIN 1
#define LCD_RW_PIN 2
#define LCD_E_PIN 3
void LCD_init(void);
void LCD_clear(void);
void LCD_goto(uint8_t x, uint8_t y);
void LCD_write_text(char * text);
int main(void) {
DDRC |= (1<<PC0);
PORTC |= (1<<PC0);
LCD_init();
LCD_clear();
LCD_goto(1,0);
LCD_write_text("TEST!TEST!TEST!");
while(1);
return 0;
}
uint8_t LCD_in_bits(void)
{
uint8_t tmp = 0;
if(((PIN(LCD_DATA_PORT) >> LCD_D4_PIN) & 0x01) != 0)
tmp |= (1 << 0);
if(((PIN(LCD_DATA_PORT) >> LCD_D5_PIN) & 0x01) != 0)
tmp |= (1 << 1);
if(((PIN(LCD_DATA_PORT) >> LCD_D6_PIN) & 0x01) != 0)
tmp |= (1 << 2);
if(((PIN(LCD_DATA_PORT) >> LCD_D7_PIN) & 0x01) != 0)
tmp |= (1 << 3);
return tmp;
}
uint8_t LCD_read(void)
{
uint8_t tmp = 0;
DDR(LCD_DATA_PORT) &=
~((1<<LCD_D4_PIN)|(1<<LCD_D5_PIN)|(1<<LCD_D6_PIN)|(1<<LCD_D7_PIN));
PORT(LCD_RW_PORT) |= (1<<LCD_RW_PIN);
PORT(LCD_E_PORT) |= (1<<LCD_E_PIN);
tmp |= (LCD_in_bits() << 4);
PORT(LCD_E_PORT) &= ~(1<<LCD_E_PIN);
_delay_ms(1);
PORT(LCD_E_PORT) |= (1<<LCD_E_PIN);
tmp |= LCD_in_bits();
PORT(LCD_E_PORT) &= ~(1<<LCD_E_PIN);
return tmp;
}
uint8_t LCD_ReadStatus(void)
{
PORT(LCD_RS_PORT) &= ~(1<<LCD_RS_PIN);
return LCD_read();
}
void LCD_out_bits(uint8_t bits_to_write)
{
if(bits_to_write & 0x01)
PORT(LCD_DATA_PORT) |= (1<<LCD_D4_PIN);
else
PORT(LCD_DATA_PORT) &= ~(1<<LCD_D4_PIN);
if(bits_to_write & 0x02)
PORT(LCD_DATA_PORT) |= (1<<LCD_D5_PIN);
else
PORT(LCD_DATA_PORT) &= ~(1<<LCD_D5_PIN);
if(bits_to_write & 0x04)
PORT(LCD_DATA_PORT) |= (1<<LCD_D6_PIN);
else
PORT(LCD_DATA_PORT) &= ~(1<<LCD_D6_PIN);
if(bits_to_write & 0x08)
PORT(LCD_DATA_PORT) |= (1<<LCD_D7_PIN);
else
PORT(LCD_DATA_PORT) &= ~(1<<LCD_D7_PIN);
}
void LCD_write(uint8_t data_to_write)
{
DDR(LCD_DATA_PORT) |=
((1<<LCD_D4_PIN)|(1<<LCD_D5_PIN)|(1<<LCD_D6_PIN)|(1<<LCD_D7_PIN));
PORT(LCD_RW_PORT) &= ~(1<<LCD_RW_PIN);
PORT(LCD_E_PORT) |= (1<<LCD_E_PIN);
LCD_out_bits(data_to_write >> 4);
PORT(LCD_E_PORT) &= ~(1<<LCD_E_PIN);
_delay_ms(1);
PORT(LCD_E_PORT) |= (1<<LCD_E_PIN);
LCD_out_bits(data_to_write);
PORT(LCD_E_PORT) &= ~(1<<LCD_E_PIN);
_delay_ms(1);
while(LCD_ReadStatus() & 0x80);
}
void LCD_just_write(uint8_t data_to_write)
{
DDR(LCD_DATA_PORT) |=
((1<<LCD_D4_PIN)|(1<<LCD_D5_PIN)|(1<<LCD_D6_PIN)|(
1<<LCD_D7_PIN));
PORT(LCD_RW_PORT) &= ~(1<<LCD_RW_PIN);
PORT(LCD_E_PORT) |= (1<<LCD_E_PIN);
LCD_out_bits(data_to_write >> 4);
PORT(LCD_E_PORT) &= ~(1<<LCD_E_PIN);
_delay_ms(1);
PORT(LCD_E_PORT) |= (1<<LCD_E_PIN);
LCD_out_bits(data_to_write);
PORT(LCD_E_PORT) &= ~(1<<LCD_E_PIN);
_delay_ms(1);
}
void LCD_just_write_command(uint8_t commandToWrite)
{
PORT(LCD_RS_PORT) &= ~(1<<LCD_RS_PIN);
LCD_just_write(commandToWrite);
}
void LCD_just_write_data(uint8_t data_to_write)
{
PORT(LCD_RS_PORT) |= (1<<LCD_RS_PIN);
LCD_just_write(data_to_write);
}
uint8_t LCD_NotBusy(void)
{
if(LCD_ReadStatus() != 0x80)
return 1;
else
return 0;
}
void LCD_write_command(uint8_t commandToWrite)
{
PORT(LCD_RS_PORT) &= ~(1<<LCD_RS_PIN);
LCD_write(commandToWrite);
}
void LCD_write_data(uint8_t data_to_write)
{
PORT(LCD_RS_PORT) |= (1<<LCD_RS_PIN);
LCD_write(data_to_write);
}
uint8_t LCD_read_data(void)
{
PORT(LCD_RS_PORT) |= (1<<LCD_RS_PIN);
return LCD_read();
}
void LCD_write_text(char * text)
{
while(*text != '\0' && *text != 0)
LCD_write_data(*text++);
}
void LCD_goto(uint8_t x, uint8_t y)
{
LCD_write_command(HD44780_DDRAM_SET | (x + (0x40 * y)));
}
void LCD_clear(void)
{
LCD_write_command(HD44780_CLEAR);
_delay_ms(2);
}
void LCD_home(void)
{
LCD_write_command(HD44780_HOME);
_delay_ms(2);
}
void LCD_init(void)
{
uint8_t i;
DDR(LCD_DATA_PORT) |=
((1<<LCD_D4_PIN)|(1<<LCD_D5_PIN)|(1<<LCD_D6_PIN)|(1<<LCD_D7_PIN));
DDR(LCD_RS_PORT) |= (1<<LCD_RS_PIN);
DDR(LCD_RW_PORT) |= (1<<LCD_RW_PIN);
DDR(LCD_E_PORT) |= (1<<LCD_E_PIN);
_delay_ms(15);
PORT(LCD_RS_PORT) &= ~(1<<LCD_RS_PIN);
PORT(LCD_E_PORT) &= ~(1<<LCD_E_PIN);
PORT(LCD_RW_PORT) &= ~(1<<LCD_RW_PIN);
for(i = 0; i < 3; i++)
{
PORT(LCD_E_PORT) |= (1<<LCD_E_PIN);
LCD_out_bits(0x03);
PORT(LCD_E_PORT) &= ~(1<<LCD_E_PIN);
_delay_ms(5);
}
PORT(LCD_E_PORT) |= (1<<LCD_E_PIN);
LCD_out_bits(0x02);
PORT(LCD_E_PORT) &= ~(1<<LCD_E_PIN);
_delay_ms(1);
LCD_write_command(HD44780_FUNCTION_SET | HD44780_FONT5x7 | HD44780_TWO_LINE |
HD44780_4_BIT);
LCD_write_command(HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_OFF);
LCD_write_command(HD44780_CLEAR);
LCD_write_command(HD44780_ENTRY_MODE | HD44780_EM_SHIFT_CURSOR |
HD44780_EM_INCREMENT);
LCD_write_command(HD44780_DISPLAY_ONOFF | HD44780_DISPLAY_ON | HD44780_CURSOR_OFF |
HD44780_CURSOR_NOBLINK);
}

View File

@ -0,0 +1,79 @@
#include <avr/io.h>
#include <avr/interrupt.h>
volatile uint8_t button_reset_counter;
volatile uint8_t main_count;
volatile uint8_t current_segment = 0;
const uint8_t digits[] = {0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90};
const uint8_t segments[] = {0x0E, 0x0D, 0x0B, 0x07};
// decrease reset_counter until 0
ISR(TIMER2_OVF_vect)
{
PORTC &= 0xF0;
PORTC |= segments[current_segment];
int count_disp[4];
int count_copy = main_count;
for(int i = 0; i < 4; i++){
count_disp[i] = count_copy % 10;
count_copy /= 10;
}
PORTA = digits[count_disp[current_segment]];
current_segment = (current_segment + 1) % 4;
button_reset_counter -= button_reset_counter == 0 ? 0 : 1;
}
// update press_counter on interrupt if reset == 0
ISR(PCINT2_vect){
if (button_reset_counter == 0){
main_count++;
button_reset_counter = 255;
}
}
int main(void) {
DDRA = 0xFF;
// C7 as input for external interrupt
DDRC &= ~_BV(DDC7);
PORTC |= _BV(PORTC7);
// C0:3 as segment out
DDRC = 0x0F;
// TIMER 2 setup
TCCR2B |= _BV(CS22);// | _BV(CS21) | _BV(CS20);
TIMSK2 |= _BV(TOIE2);
cli();
// rising edge interrupt on INT2
EICRA |= _BV(ISC20);
EIMSK |= _BV(INT2);
// enable external interrupt for pin 23 - PC7
PCMSK2 |= _BV(PCINT23);
PCICR |= _BV(PCIE2);
sei();
while(1) {
// if(przyciskZablokowany1 && (PIND & (1<<PD2))) przyciskZablokowany1++;
// if(!przyciskZablokowany2 && !(PIND & (1<<PD1))) {
// if(dioda2 == 0)
// dioda2 = 1;
// else dioda2 = 0;
// przyciskZablokowany2 = 1;
// }
// else if(przyciskZablokowany2 && (PIND & (1<<PD1))) przyciskZablokowany2++;
// if(!przyciskZablokowany3 && !(PIND & (1<<PD0))) {
// liczba = (liczba + 1) % 10;
// przyciskZablokowany3 = 1;
// }
// else if(przyciskZablokowany3 && (PIND & (1<<PD0))) przyciskZablokowany3++;
}
return 0;
}

19
lectures/Timer/FastPWM.c Normal file
View File

@ -0,0 +1,19 @@
#include <avr/io.h>
int main(void) {
DDRD |= _BV(PD5);
PORTD &= ~_BV(PORTD5);
// FAST PWM
TCCR1A |= _BV(COM1A1) | _BV(WGM11);
TCCR1B |= _BV(WGM13) | _BV(WGM12);
TCCR1B |= _BV(CS10) | _BV(CS11);
ICR1 = 0xFFFF;
OCR1A = 0x0FFF;
for(;;);
return 0;
}

View File

@ -0,0 +1,18 @@
#include <avr/io.h>
int main(void) {
DDRD |= _BV(PD5);
PORTD &= ~_BV(PORTD5);
TCCR1A |= _BV(COM1A1) | _BV(WGM11);
TCCR1B |= _BV(WGM13);
TCCR1B |= _BV(CS10) | _BV(CS11);
ICR1 = 0xFFFF;
OCR1A = 0x2FFF;
for(;;);
return 0;
}

View File

@ -0,0 +1,51 @@
#include<avr/io.h>
#include <avr/interrupt.h>
volatile uint8_t id;
volatile uint8_t state;
volatile int8_t dir = -1;
ISR(TIMER2_OVF_vect)
{
if(state == 0){
PORTC &= ~(1<<id);
}else{
PORTC |= (1<<id);
id = (id + dir) % 8;
}
state = (state+1) % 2;
}
ISR(PCINT1_vect){
if(dir == 1)
dir = -1;
else
dir = 1;
}
int main(void) {
DDRC = (0xff);
PORTC = (0xff);
DDRB &= ~_BV(DDB0);
PORTB |= _BV(PORTB0);
// timer int
TCCR2B |= _BV(CS22) | _BV(CS21) | _BV(CS20);
TIMSK2 |= _BV(TOIE2);
EICRA |= _BV(ISC11) | _BV(ISC10);
EIMSK |= _BV(INT1);
// enable for pin 8 - PB0
PCMSK1 |= _BV(PCINT8);
PCICR |= _BV(PCIE1);
sei();
for(;;);
return 0;
}

View File

@ -0,0 +1,56 @@
#include <avr/io.h>
#include <avr/interrupt.h>
volatile uint8_t button_reset_counter;
volatile uint8_t button_press_count;
// decrease reset_counter until 0
ISR(TIMER2_OVF_vect)
{
button_reset_counter -= button_reset_counter == 0 ? 0 : 1;
}
// update press_counter on interrupt if reset == 0
ISR(PCINT2_vect){
if (button_reset_counter == 0){
button_press_count++;
button_reset_counter = 20;
if(button_press_count % 2 == 0){
PORTD &= ~(1<<5);
}else{
PORTD |= (1<<5);
}
}
}
int main(void) {
// C7 as input for external interrupt
DDRC &= ~_BV(DDC7);
PORTC |= _BV(PORTC7);
// D5 as output
DDRD = _BV(PD5);
PORTD = _BV(PD5);
// TIMER 2 setup
TCCR2B |= _BV(CS22) | _BV(CS21) | _BV(CS20);
TIMSK2 |= _BV(TOIE2);
cli();
// rising edge interrupt on INT2
EICRA |= _BV(ISC20);
EIMSK |= _BV(INT2);
// enable external interrupt for pin 23 - PC7
PCMSK2 |= _BV(PCINT23);
PCICR |= _BV(PCIE2);
sei();
for(;;){}
return 0;
}

View File

@ -0,0 +1,51 @@
#include<avr/io.h>
#include <avr/interrupt.h>
volatile uint8_t id;
volatile uint8_t state;
volatile int8_t dir = -1;
ISR(TIMER2_OVF_vect)
{
if(state == 0){
PORTC &= ~(1<<id);
}else{
PORTC |= (1<<id);
id = (id + dir) % 8;
}
state = (state+1) % 2;
}
ISR(PCINT1_vect){
if(dir == 1)
dir = -1;
else
dir = 1;
}
int main(void) {
DDRC = (0xff);
PORTC = (0xff);
DDRB &= ~_BV(DDB0);
PORTB |= _BV(PORTB0);
// timer int
TCCR2B |= _BV(CS22) | _BV(CS21) | _BV(CS20);
TIMSK2 |= _BV(TOIE2);
EICRA |= _BV(ISC11) | _BV(ISC10);
EIMSK |= _BV(INT1);
// enable for pin 8 - PB0
PCMSK1 |= _BV(PCINT8);
PCICR |= _BV(PCIE1);
sei();
for(;;);
return 0;
}

View File

@ -0,0 +1,44 @@
#include<avr/io.h>
#include<util/delay.h>
#include <avr/interrupt.h>
#define DELAY_TIME 150
volatile uint8_t id;
volatile uint8_t state;
ISR(TIMER2_OVF_vect, ISR_NAKED)
{
if(state == 0){
PORTC &= ~(1<<id);
state++;
}else{
PORTC |= (1<<id);
state = 0;
id++;
if(id == 8)
id = 0;
}
reti();
}
void set_led(int id){
PORTC &= ~(1<<id);
_delay_ms(DELAY_TIME);
PORTC |= (1<<id);
_delay_ms(DELAY_TIME);
}
int main(void) {
DDRC = (0xff);
PORTC = (0xff);
TCCR2B |= (0b111);
TIMSK2 |= 0b1;
sei();
for(;;);
return 0;
}

View File

@ -0,0 +1,58 @@
#include<avr/io.h>
#include <avr/interrupt.h>
volatile uint8_t id;
volatile uint8_t state;
volatile int8_t dir = -1;
// ISR(TIMER2_OVF_vect)
// {
// if(state == 0){
// PORTC &= ~(1<<id);
// }else{
// PORTC |= (1<<id);
// id = (id + dir) % 8;
// }
// state = (state+1) % 2;
// }
// ISR(PCINT1_vect){
// if(dir == 1)
// dir = -1;
// else
// dir = 1;
// }
int main(void) {
// DDRC = (0xff);
// PORTC = (0xff);
DDRB |= _BV(DDB3);
PORTB &= ~_BV(PORTB3);
// timer int
// TCCR2B |= _BV(CS22) | _BV(CS21) | _BV(CS20);
// TIMSK2 |= _BV(TOIE2);
// EICRA |= _BV(ISC11) | _BV(ISC10);
// EIMSK |= _BV(INT1);
// enable for pin 8 - PB0
// PCMSK1 |= _BV(PCINT8);
// PCICR |= _BV(PCIE1);
// sei();
TCCR0A |= _BV(COM0A0);
TCCR0A &= ~_BV(COM0A1);
TCCR0B |= _BV(CS02) | _BV(CS00);
TCCR0B &= ~_BV(CS01);
for(;;);
return 0;
}

16
lectures/Timer/timerCMP.c Normal file
View File

@ -0,0 +1,16 @@
#include<avr/io.h>
int main(void) {
DDRB |= _BV(DDB7);
PORTB &= ~_BV(PORTB7);
TCCR3A |= _BV(COM3B0);
TCCR3A &= ~_BV(COM3A1);
TCCR3B |= _BV(CS32) | _BV(CS30) | _BV(WGM32);
OCR3A = 0x0FFF;
for(;;);
return 0;
}

View File

@ -0,0 +1,36 @@
#include <avr/io.h>
#include <avr/interrupt.h>
volatile uint8_t state;
volatile uint8_t count;
ISR(TIMER0_OVF_vect)
{
if(++count == 100){
count = 0;
state = (state+1) % 2;
if(state){
PORTC &= ~(1<<PC0);
}
else{
PORTC |= (1<<PC0);
}
}
}
int main(void) {
DDRC |= _BV(PC0);
PORTC &= ~_BV(PORTC0);
TCCR0A |= (1<<COM0A0);
TCCR0B |= _BV(CS02) | _BV(CS00);
TIMSK0 |= _BV(TOIE0);
sei();
for(;;);
return 0;
}

View File

@ -0,0 +1,18 @@
#include <avr/io.h>
int main(void) {
DDRD |= _BV(PD5);
PORTD &= ~_BV(PORTD5);
TCCR1A |= _BV(COM1A1) | _BV(WGM11);
TCCR1B |= _BV(WGM13);
TCCR1B |= _BV(CS10) | _BV(CS11);
ICR1 = 0xFFFF;
OCR1A = 0x2FFF;
for(;;);
return 0;
}