Network Light Dimmer with Slider Control
History
This project is one of many I have undertaken to control my house using a set of rules, a web interface, a logger and many more components. This project is a light dimmer which has multiple control interfaces such an RS485 network, an infrared remote control, a proximity touch slider or touch sensor.
It
is based on a ATMega8 and the well known Qprox QT401/QT110proximity
sensor. The Mega8 had lots of things to do: detect zero crossing of
phase, calculate the firing angle for the triac, manage the network
communications, check for a finger presence and position on the
proximity touch slider and detect and decode infrared coming from a
remote control. The device is powered from the RS485 network
connection which has +12, data+, data- and GND. On the schematic
you will see that there are two detectors, one is the slider, and
the other is a simple touch detector. It was done like this so that
non-dimmable loads can be driven by using the touch detector as the
control. That is why there are circuit pads on the board for two
sensors.
Features
|
|
Slider QProx sensor |
|
|
IR receiver |
|
|
RS485 interface |
|
|
Opto isolated |
|
|
Up to 500watts |
|
|
Network firmware upgradeable |
Pictures
Click to enlarge
|
Top side of the PCB Dimmer |
Original dimmer box cut to give more space in the wall box |
Mounting all together |
|
Down side of the PCB Dimmer |
Modification of the front plate |
All done |
|
Slider PCB |
Slider PCB with is cover |
All done with the IR receiver too! |
Sources codes & Schematics
-Schematic NetDimmer in PDF format
-Schematic of the Slider in PDF format
//*****************************************************************************
// NetDimmer
// Version 10.0 Nov 2005
//
// 10.0 -> New code for 9bit protocol
//
// Sylvain Bissonnette
//*****************************************************************************
// Editor : UltraEdit32
//*****************************************************************************
//
//
R E T U R N S T A C K 3 2
//
X T A L 16 MHZ
//
BootLoader of 512 word
//
//*****************************************************************************
//
//
F U S E B I T
//
//( )7 ( )6
(X)BL12 (X)BL11 ( )BL02 ( )BL01
( )Lock2 ( )Lock1
//( )RSTDIS ( )WDON (X)SPIEN(X)CKOPT
(X)EESAVE (X)BOOTSZ1 ( )BOOTSZ0 (X)BOOTRST
//(X)BODLEV (X)BODEN ( )SUT1 ( )SUT0
( )CKSEL3 ( )CKSEL2 ( )CKSEL1 ( )CKSEL0
//
//*****************************************************************************
//
P I N U S A G E
//
// PB0 -> IR input
// PB1 -> n/c VCC
// PB2 -> SPI SS / LED
// PB3 -> SPI MOSI
// PB4 -> SPI MISO
// PB5 -> SPI SCK
// PB6 -> Xtal
// PB7 -> Xtal
//
// PC0 -> Dip Switch Bit-0
// PC1 -> Dip Switch Bit-1
// PC2 -> Dip Switch Bit-2
// PC3 -> Dip Switch Bit-3
// PC4 -> Dip Switch Bit-4
// PC5 -> Dip Switch Bit-5
// PC6 -> RESET
//
// PD0 -> RS485 RX
// PD1 -> RS485 TX
// PD2 -> Triac Zero Crossing interrupt
input
// PD3 -> Option Jumper (Dimmer/Switch)Proximity
Detector
// PD4 -> RS485 TXE
// PD5 -> n/c vcc
// PD6 -> Triac Drive
// PD7 -> Proximity Detector
//
// ADC6-> n/c
// ADC7-> n/c
//
//*****************************************************************************
//
T I M E R U S A G E
//
// Timer 0 is use by TaskManager
// Timer 1 is use by triac and (IR remote
controle or Slider)
//
//*****************************************************************************
// NetWork Function
//-----------------------------------------------------------------------------
// Command
// 0xff
-> Get 16 bit software version
// 0xf5,0x55,0xaa -> Reset MCU
// 0xf0,0x55,L,V -> Write eeprom at L
value V
// 0xf1,0x55,L -> Read
eeprom at L
// 0x10
-> Set Light from 0 to 10 Byte[1]
// 0x20
-> Get Light from 0 to 10
// 0x21
-> Get Switch stat 0/1
// 0x22
-> Get IR Command
//-----------------------------------------------------------------------------
// EEprom
// 00@xx -> Not used
//*****************************************************************************
//*****************************************************************************
//
I N C L U D E
//*****************************************************************************
#include <iom8v.h>
#include <macros.h>
#include <stdlib.h>
#include <eeprom.h>
#include <shortnametype.h>
#include "TaskManager.h"
//*****************************************************************************
//
D E F I N E
//*****************************************************************************
#define VERSION
100
#define DEVICE
80
#define TRUE
1
#define FALSE
0
#define XTAL
16000000
#define LED
0x04
#define LED_DDR
DDRB
#define LED_PIN
PINB
#define LED_PORT
PORTB
#define PROX_DDR
DDRD
#define PROX_PIN
PIND
#define PROX_PORT
PORTD
#define PROX_DET
0x80
#define TRIAC_DDR
DDRD
#define TRIAC_PIN
PIND
#define TRIAC_PORT
PORTD
#define TRIAC_DRIVE
0x40
#define TRIAC_ZERO_CROSSING 0x04
#define TRIAC_OPTION
0x08
#define DIMMER_PROX
0
#define DIMMER_SLIDER
1
#define SWITCH
2
#define SPI_DDR
DDRB
#define SPI_PIN
PINB
#define SPI_PORT
PORTB
#define SPI_DOUT
0x08
#define SPI_DIN
0x10
#define SPI_SCLK
0x20
#define SPI_SS
0x04
#define SPI_DET
0x01
#define NET_ADDRESS_DDR
DDRC
#define NET_ADDRESS_PIN
PINC
#define NET_ADDRESS_PORT
PORTC
#define NET_DDR
DDRD
#define NET_PIN
PIND
#define NET_PORT &nbs¥þˆúbsp;
PORTD
#define NET_RX
0x01
#define NET_TX
0x02
#define NET_TXE
0x10
#define NET_UBRRH
UBRRH
#define NET_UBRRL
UBRRL
#define NET_UCSRA
UCSRA
#define NET_UCSRB
UCSRB
#define NET_UCSRC
UCSRC
#define NET_UDR
UDR
#define NET_RXBUFFER
10
#define NET_TXBUFFER
10
#define NET_GET_ADDRESS
NET_ADDRESS_PIN & 0x3f;
#define NET_SPEED
19200
#define BROADCASTDEVTYPE
0xf2
#define BROADCAST
0xff
#define IR_DDR
DDRB
#define IR_PIN
PINB
#define IR_PORT
PORTB
#define IR_INPUT
0x01
#define REMOTE_UP
20
#define REMOTE_DOWN
21
#define REMOTE_RIGHT
22
#define REMOTE_LEFT
23
#define REMOTE_MENU
24
#define REMOTE_STOP
30
#define REMOTE_PLAY
31
#define REMOTE_MUTE
32
#define REMOTE_REW
33
#define REMOTE_FFWD
34
#define REMOTE_PAUSE
35
#define REMOTE_POWER
40
//*****************************************************************************
//
P R O T O T Y P E
//*****************************************************************************
void main(void);
void _StackOverflowed(char
c);
int GetSwitchMode(void);
void LEDInit(void);
void LEDFlash(void);
void LightFlash(void);
void ProxInit(void);
void ProxCheckDimmer(void);
void ProxCheckSwitch(void);
void ProxSliderCheckDimmer(void);
void SPIInit(void);
ushort SPI(uint Write);
void SPISetSCLK(ushort
state);
void SPISetDOUT(ushort
state);
ushort SPIGetDIN(void);
void SPIWaitOnePulse(void);
void IRInit(void);
void IRLightChange(void);
void IRDecode(void);
void TriacInit(void);
void TriacFire(void);
void TriacZeroCrossing(void);
void NetInit(void);
void NetRxChar(void);
void NetAnalyseData(void);
void NetWrite(int
Value);
void NetTxByte(void);
void NetTxFinish(void);
void NetGetAddress(void);
//*****************************************************************************
//
G L O B A L V A R I A B L E
//*****************************************************************************
ushort NetAddress;
ushort NetRxData[NET_RXBUFFER];
ushort NetTxData[NET_TXBUFFER];
ushort *NetTxPtr;
short NetTxQte;
short NetBroadCast
= FALSE;
uint LatchedIrData =
0;
uint RemoteKey = -1;
ushort Light= 0;
ushort NetLight =
0;
ushort NetChange =
0;
ushort ChangeStat = FALSE;
ushort SwitchMode;
//*****************************************************************************
//
M A I N
//*****************************************************************************
void main()
{
int i;
WDR();
WDTCR = 0x0f;
// Enable WatchDog at 2.2 sec
TaskInit();
NetInit();
TriacInit();
IRInit();
LEDInit();
SPIInit();
ProxInit();
SEI();
TaskRegister(NetGetAddress,T1S,TRUE);
TaskRegister(IRLightChange,T100MS,TRUE);
switch (GetSwitchMode())
{
case SWITCH
:
TaskRegister(ProxCheckSwitch,T80MS,TRUE);
TaskRegister(LEDFlash,T100MS,TRUE);
break;
case DIMMER_PROX
:
TaskRegister(ProxCheckDimmer,T80MS,TRUE);
TaskRegister(LEDFlash,T500MS,TRUE);
break;
case DIMMER_SLIDER
:
TaskRegister(ProxSliderCheckDimmer,T10MS,TRUE);
break;
}
while (1)
{
WDR();
_StackCheck();
}
}
/******************************************************************************
Name:
void _StackOverflowed(char c)
Description: This function is
automaticaly called if
the stack crash.
Input:
none
Output:
PB2
Misc:
******************************************************************************/
void _StackOverflowed(char
c)
{
CLI();
while(1);
}
/******************************************************************************
Name:
void LightFlash(void)
Description: This function make the
Light Flashing
Input:
none
Output:
none
Misc:
******************************************************************************/
void LightFlash(void)
{
if (Light ==
0) Light
= 100;
else Light =
0;
}
/******************************************************************************
Name:
void GetSwitchMode(void)
Description: This function is to get
the switch mode
Input:
none
Output:
none
Misc:
******************************************************************************/
int GetSwitchMode(void)
{
int i;
for (i=0;i<500;i++)
SPIWaitOnePulse();
if ((TRIAC_PIN
& TRIAC_OPTION) == TRIAC_OPTION)
SwitchMode = SWITCH;
else
{
SwitchMode = DIMMER_PROX;
for (i=0;i<500;i++)
// Check 500ms for QT401
{
if ((PROX_PIN
& PROX_DET) !=
PROX_DET) SwitchMode
= DIMMER_SLIDER;
SPIWaitOnePulse();
}
}
return SwitchMode;
}
/******************************************************************************
Name:
void LEDInit(void)
Description: Init device for LED
Input:
none
Output:
none
Misc:
******************************************************************************/
void LEDInit(void)
{
LED_DDR |= LED;
// Pin as output
}
/******************************************************************************
Name:
void LEDFlash(void)
Description: This function make the
LED Flashing
Input:
none
Output:
none
Misc:
******************************************************************************/
void LEDFlash(void)
{
LED_PORT ^= LED;
}
/******************************************************************************
Name:
void ProxInit(void)
Description: Init device for
proximity functions
Input:
none
Output:
none
Misc:
******************************************************************************/
void ProxInit(void)
{
int i;
PROX_DDR &= ~PROX_DET;
// Pin as input
PROX_PORT |= PROX_DET;
// Pin as pullup
SPI(0x01);
while(!(PROX_PIN
& PROX_DET))
WDR();
SPI(0x02);
while(!(PROX_PIN
& PROX_DET))
WDR();
}
/******************************************************************************
Name:
void ProxCheckDimmer(void)
Description: This function is call
each 66ms to check
the key and set the light
Input:
none
Output:
none
Misc:
******************************************************************************/
void ProxCheckDimmer(void)
{
static ushort StillON
= FALSE;
static ushort OneShot
= FALSE;
static ushort DimUp
= 0x00;
static ushort Key
= 0;
static ushort Last
= 0x0a;
static ushort Debounce;
if (!(PROX_PIN
& PROX_DET)) Key++;
if (Key >
25) Key
= 25;
if ((PROX_PIN &
PROX_DET) && (Key
> 0) && (Key
< 5))
OneShot = TRUE;
else OneShot =
FALSE;
if (!(PROX_PIN
& PROX_DET) && (Key
> 4))
StillON = TRUE;
if ((PROX_PIN &
PROX_DET) && (StillON
== TRUE))
{
if (DimUp
== TRUE)
DimUp = FALSE;
else DimUp
= TRUE;
StillON = FALSE;
}
if (OneShot ==
TRUE)
{
OneShot = FALSE;
Key = 0;
if (Light
== 0)
{
Light = Last;
DimUp = FALSE;
}
else
{
Light =
0;
DimUp = TRUE;
}
}
if (StillON ==
TRUE)
{
OneShot = FALSE;
Key = 0;
if ((DimUp
== FALSE) && (Light
> 0))
Light-=5;
if ((DimUp
== TRUE) && (Light
< 100))
Light+=5;
if (Light
== 0)
DimUp = TRUE;
if (Light
== 100)
DimUp = FALSE;
Last = Light;
}
}
/******************************************************************************
Name:
void ProxCheckSwitch(void)
Description: This function is call
each 66ms to check
the key and set the light
Input:
none
Output:
none
Misc:
******************************************************************************/
void ProxCheckSwitch(void)
{
static ushort Debounce;
if ((!(PROX_PIN
& PROX_DET)) && (Debounce
== FALSE))
{
Debounce = TRUE;
ChangeStat = TRUE;
if (Light
== 0)
{
Light =
100;
}
else
{
Light =
0;
}
}
if (PROX_PIN &
PROX_DET) Debounce
= FALSE;
}
/******************************************************************************
Name:
void ProxSliderCheckDimmer(void)
Description: This function is call
each time the QT401 have
a valid value to give
Input:
none
Output:
none
Misc:
******************************************************************************/
void ProxSliderCheckDimmer(void)
{
static ushort DriftComp
= 0;
static ushort LastLightValue
= 10;
static int Count
= 0;
static int Error
= 0;
ushort byte;
int i;
if (DriftComp++
> 3)
// One drift compensation each 3 burst
{
SPI(0x03);
DriftComp =
0;
return;
}
else byte =
SPI(0x00);
// Check for sensor Error
if ((byte &
0x82) ==
0x02)
{
Error++;
if (Error
> 3)
{
ProxInit();
Error =
0;
return;
}
}
if ((byte &
0x82) ==
0x00)
Error = 0;
// if sensor is not touch exit
if ((PROX_PIN &
PROX_DET) != PROX_DET)
return;
// Check is the sensor is touch if yes increment
Count
if ((byte &
0x80) ==
0x80)
Count++;
else Count =
0;
// If touch for the frist time toggle light to
is last value
if (((byte &
0x80) ==
0x80) && (Count
== 2))
{
if (Light
== 0)
Light = LastLightValue;
else Light
= 0;
}
// If continously touch set the light value to
// the new value
if (Count >
25)
{
Count = 26;
if ((byte
& 0x80)
== 0x80)
{
i = (byte
& 0x7f)
* 100;
i = i
/ 127;
Light = i;
LastLightValue =
Light;
}
}
}
/******************************************************************************
Name:
void SPIInit(void)
Description: Init device for SPI
functions
Input:
none
Output:
none
Misc:
******************************************************************************/
void SPIInit(void)
{
int i;
SPI_DDR |= SPI_SCLK +
SPI_DOUT + SPI_SS;
// All those as output
SPI_DDR &= ~SPI_DIN;
// As input
SPI_PORT |= SPI_SCLK +
SPI_SS;
// Clock at 1
}
/******************************************************************************
Name:
void SPI(void)
Description: Write and read a byte
from the QT401
Input:
uint8 -> value to write to SPI
Output:
uint8 -> value read from SPI
Misc:
******************************************************************************/
ushort SPI(uint Write)
{
signed char i;
ushort Read = 0x00;
SPI_PORT &= ~SPI_SS;
SPIWaitOnePulse();
for (i=7;i!=-1;i--)
{
SPISetDOUT(Write&(1<<i));
SPISetSCLK(FALSE);
SPIWaitOnePulse();
SPISetSCLK(TRUE);
SPIWaitOnePulse();
Read = Read
<< 1;
if (SPIGetDIN())
Read |= 0x01;
}
SPIWaitOnePulse();
SPI_PORT |= SPI_SS;
return Read;
}
/******************************************************************************
Name:
void SPISetSCLK(ushort state)
Description: Set the SPI clock line
Input:
’ö!ˆr state -> 0 or 1
Output:
none
Misc:
******************************************************************************/
void SPISetSCLK(ushort
state)
{
if (state)
SPI_PORT |= SPI_SCLK;
else SPI_PORT
&= ~SPI_SCLK;
}
/******************************************************************************
Name:
void SPISetDOUT(ushort state)
Description: Set the SPI data in line
Input:
uchar state -> 0 or 1
Output:
none
Misc:
******************************************************************************/
void SPISetDOUT(ushort
state)
{
if (state)
SPI_PORT |= SPI_DOUT;
else SPI_PORT
&= ~SPI_DOUT;
}
/******************************************************************************
Name:
ushort SPIGetDIN(void)
Description: Get the SPI data in line
Input:
none
Output:
uchar state -> 0 or 1
Misc:
******************************************************************************/
ushort SPIGetDIN(void)
{
if ((SPI_PIN &
SPI_DIN)) return
1;
else return 0;
}
/******************************************************************************
Name:
void SPIWaitOnePulse(void)
Description: Clock & Data line delay
for 23khz
Input:
none
Output:
none
Misc:
******************************************************************************/
void SPIWaitOnePulse(void)
{
int i;
for (i=0;i<(XTAL/400000);i++)
WDR();
}
/******************************************************************************
Name:
void IRInit(void)
Description: Init device for IR
functions
Input:
none
Output:
none
Misc:
Share Timer 1 with Triac functions
******************************************************************************/
void IRInit(void)
{
IR_DDR &= ~IR_INPUT;
// ICP as input on PB0
IR_PORT |= IR_INPUT;
// Pull up on ICP pin
TCCR1B |= (1<<CS11);
// Timer1 / 8
TCCR1B |= (1<<ICES1);
// Rising edge on ICP
TIMSK |= (1<<TICIE1);
// Int on ICP
}
/******************************************************************************
Name:
void IRLightChange(void);
Description: Check the IR command
Change Light
Input:
none
Output:
none
Misc:
******************************************************************************/
void IRLightChange(void)
{
if ((SwitchMode
!= SWITCH) && (RemoteKey
== REMOTE_UP) &&
(Light <
96))
{
Light+=5;
if (Light
> 95)
Light = 100;
RemoteKey = -1;
}
else if ((SwitchMode
!= SWITCH) && (RemoteKey
== REMOTE_DOWN)
&& (Light >
4))
{
Light-=5;
if (Light
< 5)
Light = 0;
RemoteKey = -1;
}
else if ((SwitchMode
== SWITCH) && (RemoteKey
== REMOTE_UP))
{
Light =
100;
RemoteKey = -1;
}
else if ((SwitchMode
== SWITCH) && (RemoteKey
== REMOTE_DOWN))
{
Light = 0;
RemoteKey = -1;
}
}
/******************************************************************************
Name:
void IRDecode(void);
Description: This routine is called
whenever a rising edge (beginning
of valid IR signal) is received.
Input:
none
Output:
Global variable LatchedIrData
Misc:
Sony VCR protocol
******************************************************************************/
#pragma interrupt_handler IRDecode:6
void IRDecode(void)
{
static uint LastCapture;
uint PulseWidth;
static ushort IrPulseCount;
static uint IrData;
PulseWidth = ICR1 -
LastCapture;
LastCapture = ICR1;
if (PulseWidth
> (XTAL/4000))
{
IrPulseCount =
0;
IrData = 0;
}
else
{
IrData = IrData
>> 1;
if (PulseWidth
> (XTAL/5714))
IrData = IrData |
0x8000;
IrPulseCount++;
if (IrPulseCount
== 12)
{
LatchedIrData =
IrData >> 4;
switch(LatchedIrData)
{
case
2176 :
RemoteKey = 1;
break;
case
2177 :
RemoteKey = 2;
break;
case
2178 :
RemoteKey = 3;
break;
case
2179 :
RemoteKey = 4;
break;
case
2180 :
RemoteKey = 5;
break;
case
2181 :
RemoteKey = 6;
break;
case
2182 :
RemoteKey = 7;
break;
case
2183 :
RemoteKey = 8;
break;
case
2184 :
RemoteKey = 9;
break;
case
2208 :
RemoteKey = 0;
break;
case
2224 :
RemoteKey = REMOTE_REW;
break;
case
2227 :
RemoteKey = REMOTE_REW;
break;
case
2225 :
RemoteKey = REMOTE_FFWD;
break;
case
2228 :
RemoteKey = REMOTE_FFWD;
break;
case
2231 :
RemoteKey = REMOTE_UP;
break;
case
2238 :
RemoteKey = REMOTE_UP;
break;
case
2230 :
RemoteKey = REMOTE_DOWN;
break;
case
2237 :
RemoteKey = REMOTE_DOWN;
break;
case
2235 :
RemoteKey = REMOTE_RIGHT;
break;
case
2194 :
RemoteKey = REMOTE_RIGHT;
break;
case
2234 :
RemoteKey = REMOTE_LEFT;
break;
case
2195 :
RemoteKey = REMOTE_LEFT;
break;
case
2233 :
RemoteKey = REMOTE_PAUSE;
break;
case
2232 :
RemoteKey = REMOTE_STOP;
break;
case
2226 :
RemoteKey = REMOTE_PLAY;
break;
case
2271 :
RemoteKey = REMOTE_MUTE;
break;
case
2262 :
RemoteKey = REMOTE_MENU;
break;
case
2197 :
RemoteKey = REMOTE_POWER;
break;
default
: RemoteKey = -1;
break;
}
}
}
}
/******************************************************************************
Name:
void TriacInit(void)
Description: Init device for Triac
functions
Input:
none
Output:
none
Misc:
Timer 1
******************************************************************************/
void TriacInit(void)
{
TRIAC_DDR |= TRIAC_DRIVE;
// PD6 as output
TRIAC_DDR &= ~TRIAC_ZERO_CROSSING;
// PD2 as input for Int 0
TRIAC_DDR &= ~TRIAC_OPTION;
// PD3 as input
TRIAC_PORT |= TRIAC_OPTION;
// PD3 as pullup
// Int 0 on Low level
GICR |= (1<<INT0);
// Int 0 enable
TCCR1B |= (1<<CS11);
// Timer1 / 8
TIMSK |= (1<<OCIE1A);
// Int on compare match A
Light= 0;
}
/******************************************************************************
Name:
void TriacFire(void)
Description: This function is
automaticaly called
when the delay is expired and fire the
triac
Input:
none
Output:
none
Misc:
Timer 1 is also share with IR remote controle
******************************************************************************/
#pragma interrupt_handler TriacFire:7
void TriacFire(void)
{
int i;
if (SwitchMode
!= SWITCH)
{
if ((Light
> 0)
&& (Light <
100))
{
CLI();
TRIAC_PORT |=
TRIAC_DRIVE;
for (i=0;i<10;i++);
// 15us
TRIAC_PORT &= ~TRIAC_DRIVE;
SEI();
}
CLI();
if (Light
== 0)
TRIAC_PORT &= ~TRIAC_DRIVE;
if (Light
== 100)
TRIAC_PORT |= TRIAC_DRIVE;
SEI();
}
GICR |= (1<<INT0);
// Int 0 enable
}
/******************************************************************************
Name:
void TriacZeroCrossing(void)
Description: This function is
automaticaly called
each time the 110Vac cross 0 volt and
set up the delay to fire the triac later
delay from light 9 -> 0x05fa to
light 1 -> 0x0d6a
Input:
none
Output:
none
Misc:
******************************************************************************/
#pragma interrupt_handler TriacZeroCrossing:2
void TriacZeroCrossing(void)
{
static ushort Delay
= 0;
OCR1A = TCNT1 + ((100
- Light) *
120) +
3200;
GICR &= ~(1<<INT0);
// Int0 Disable
if (SwitchMode
!= SWITCH)
{
Delay++;
if (Delay
> 2)
{
Delay =
0;
if (NetChange
== TRUE)
{
if (NetLight
> Light)
Light++;
if (NetLight
< Light)
Light--;
if (NetLight
== Light)
NetChange = FALSE;
}
}
}
else
{
if (NetChange
== TRUE)
{
if (NetLight
== 0)
Light = 0;
else Light
= 10;
NetChange = FALSE;
}
CLI();
if (Light
== 0)
TRIAC_PORT &= ~TRIAC_DRIVE;
else TRIAC_PORT
|= TRIAC_DRIVE;
SEI();
}
}
//*****************************************************************************
//
N E T W O R K F U N C T I O N
//*****************************************************************************
/******************************************************************************
Name:
void NetInit(void)
Description: This function initialize
for NET network
Input:
None
Output:
None
Misc:
******************************************************************************/
void NetInit(void)
{
NET_UBRRH = ((XTAL / (16
* NET_SPEED)) -
1)>>8;
//set baud rate Ÿ™'úi>
NET_UBRRL = (XTAL / (16
* NET_SPEED)) -
1;
//set baud rate
NET_UCSRA = (1<<MPCM);
NET_UCSRB = (1<<UCSZ2)
+ (1<<RXCIE)+(1<<RXEN)+(1<<TXEN)+(1<<TXCIE);
NET_UCSRC = (1<<URSEL)+(1<<UCSZ1)
+ (1<<UCSZ0);
// 8 bit
NET_PORT &= ~NET_TXE;
// Switch NET in Rx mode
NET_PORT |= NET_RX;
// Pull up on RX
NET_DDR |= NET_TXE +
NET_TX;
NET_ADDRESS_DDR = 0x00;
// All port as input
NET_ADDRESS_PORT =
0xff;
// All port as pullup
NetGetAddress();
}
/******************************************************************************
Name:
void NetRxChar(void)
Description: This function is
automaticaly called each
time a char is received on the NET bus.
Input:
none
Output:
Data in NetRxData[]
Misc:
******************************************************************************/
#define RESET 0
#define QTE
1
#define DATA 2
#define CHECKSUM 3
#pragma interrupt_handler NetRxChar:12
void NetRxChar(void)
{
static ushort InByte;
static ushort Qte;
static ushort CheckSum;
static ushort *Ptr;
static ushort State;
if (NET_UCSRA &
((1<<FE)+(1<<DOR)))
{
InByte = NET_UDR;
return;
}
if (NET_UCSRB &
(1<<RXB8))
{
InByte = NET_UDR;
if (InByte
== NetAddress)
{
NET_UCSRA &= ~(1<<MPCM);
State = QTE;
NetBroadCast = FALSE;
return;
}
else if ((InByte
== BROADCASTDEVTYPE)
|| (InByte == BROADCAST))
{
NET_UCSRA &= ~(1<<MPCM);
State = QTE;
NetBroadCast = TRUE;
return;
}
else
{
NET_UCSRA |= (1<<MPCM);
State = RESET;
NetBroadCast = FALSE;
return;
}
}
InByte = NET_UDR;
switch (State)
{
case QTE
:
CheckSum =
0;
Ptr = &NetRxData[0];
Qte = InByte;
State = DATA;
break;
<