kod źródłowy UDP - ethernet
#include<avr/io.h>
#include<avr/interrupt.h>
#include<avr/pgmspace.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include"ip_arp_udp_tcp.h"
#include"enc28j60.h"
#include"util/delay.h"
#include"net.h"
#include"LCD/lcd44780.h"
//---------------- definicje preprocesora ---------------------------------
#define LED1_DDR DDRB
#define LED1_PORT PORTB
#define LED1 (1<<PB1)
#define LED1_ON LED1_PORT &= ~LED1
#define LED1_OFF LED1_PORT |= LED1
#define LED1_TOG LED1_PORT ^= LED1
#define LED2_DDR DDRD
#define LED2_PORT PORTD
#define LED2 (1<<PD7)
#define LED2_ON LED2_PORT &= ~LED2
#define LED2_OFF LED2_PORT |= LED2
#define LED2_TOG LED2_PORT ^= LED2
#define KL_PORT PORTC
#define KL1 (1<<PC2)
#define KL2 (1<<PC3)
//--------------- definicje preprocesora ---------------------------------
//-------------------------------------------------------------------------
// ustalamy adres MAC
staticuint8_t mymac[6] = {0x00,'M','I','R','E','K'};
// ustalamy adres IP urządzenia
staticuint8_t myip[4] = {192,168,0,120};
// ustalamy porty UDP z jakich będziemy korzystać
// może ich być dowolna ilość
staticuint16_t myport[] = {1200,22700};
// ustalamy adres IP bramy domyślnej w sieci LAN
staticuint8_t gwip[4] = {192,168,0,1};
// ustalamy wielkość bufora dla ramek TCP/UDP
#define BUFFER_SIZE 650
staticuint8_t buf[BUFFER_SIZE+1];
// wskaźnik do funkcji zwrotnej własnego zdarzenia UDP_EVENT()
staticvoid (*mk_udp_event_callback)(uint8_t *peer_ip, uint16_t port,
uint16_t datapos, uint16_t len);
// funkcja do rejestracji funkcji zwrotnej w zdarzeniu UDP_EVENT()
void register_udp_event_callback(void (*callback)(uint8_t *peer_ip,
uint16_t port, uint16_t datapos, uint16_t len))
{
mk_udp_event_callback = callback;
}
//-----------------------------------------------------------------------
//------------------ deklaracje funkcji -------------------------------
void ping_callback(uint8_t *ip);
void SuperDebounce( volatileuint8_t *KPIN,
uint8_t key_mask, uint16_t rep_time, uint16_t rep_wait,
void (*push_proc)(uint8_t), void (*rep_proc)(uint8_t) );
void mk_send_udp(uint8_t nr_klawisza);
void udp_event_callback(uint8_t *peer_ip, uint16_t port,
uint16_t datapos, uint16_t len);
void UDP_EVENT(uint16_t *port);
void parse_set_led(char * buf);
void parse_get_led(char * s);
void parse_set_lcd(char * buf);
//------------- deklaracje funkcji -------------------------------
//--------- deklaracje zmiennych globalnych -------------------------------
// indeksy adresów IP w postaci przyjaznych nazw
enum ip_names {ip_pc, ip_sterownik1};
// adresy IP sterowników z którymi będziemy się komunikować
// za pomocą protokołu UDP
staticuint8_t farip[2][4] = { {192,168,0,49}, {192,168,0,180} };
// timer programowy na usługi funkcji SuperDebounce()
volatileuint8_t Timer1; /* timer programowy 100Hz */
// separator tokenów we własnych ramkach przesyłanych przez UDP
char sep[] = "^";
// przydzielenie kodów we własnych ramkach przesyłanych przez UDP
#define ILOSC_KOMEND 3
enum commands {set_led, get_led, set_lcd};
// tablica wskaźników do funkcji parsujących w pamięci FLASH
void (*parse_fun[ILOSC_KOMEND])(char *buf) PROGMEM = {
parse_set_led,
parse_get_led,
parse_set_lcd
};
//-------- deklaracje zmiennych globalnych -------------------------------
//======= main() ================================================
int main(void){
/********** inicjalizacja pinów/portów *********************/
// podświetlenie wyświetlacza LCD
DDRA |= (1<<PA7);
PORTA |= (1<<PA7);
// po resecie piny klawiszy są wejściami
// podciągnięcie wejść klawiszy do VCC
KL_PORT |= KL1|KL2;
// kierunki pinów diod LED jako wyjścia
LED1_DDR |= LED1;
LED2_DDR |= LED2;
// wyłączenie diod LED
LED1_OFF;
LED2_OFF;
/****** inicjalizacja modułów sprzętowych procesora *********************/
/* Timer2 – inicjalizacja przerwania co 10ms */
TCCR2 |= (1<<WGM21); // tryb pracy CTC
TCCR2 |= (1<<CS22)|(1<<CS21)|(1<<CS20); // preskaler = 1024
OCR2 = 108; // przerwanie porównania co 10ms (100Hz)
TIMSK = (1<<OCIE2); // Odblokowanie przerwania CompareMatch
/********** inicjalizacja funkcji bibliotecznych *********************/
lcd_init();
lcd_str("Start..");
/********** inicjalizacja funkcji obsługi stosu TCP *********************/
/*inicjalizacja układu enc28j60*/
enc28j60Init(mymac);
// konfiguracja diod LED w gnieździe RJ45
// zielona (LEDA) - link
// żółta (LEDB) - rx/tx
// enc28j60PhyWrite(PHLCON,0b0000 0100 0111 01 10);
enc28j60PhyWrite(PHLCON,0x476);
// inicjalizacja stosu TCP
init_ip_arp_udp_tcp(mymac,myip,80);
// inicjalizacja bramy domyślnej
// konieczne dla funkcji klienckich
client_set_gwip(gwip);
/********** inicjalizacja funkcji obsługi stosu TCP *********************/
// zarejestrowanie własnej procedury obsługi/reakcji na ping
register_ping_rec_callback(&ping_callback);
// zarejestrowanie własnej procedury obsługi/reakcji na
// przychodzące pakiety UDP
register_udp_event_callback(udp_event_callback);
/********** włączenie przerwań globalnych *********************/
sei();
/******************************************************/
/************ **********************/
/********** główna pętla programu *********************/
/*********** **********************/
/******************************************************/
while(1){
// zdarzenie sprawdzające czy są jakieś dane
// z sieci/układu ENC28j60
UDP_EVENT(myport);
// przykładowa obsługa klawiszy i wysyłanie
// własnych klienckich ramek UDP do wybranych urządzeń w sieci
SuperDebounce(&PINC, (1<<PC2), 100, 200, mk_send_udp, mk_send_udp);
SuperDebounce(&PINC, (1<<PC3), 20, 200, mk_send_udp, 0);
}