Using AVR MCU to Encode & Decode the wireless data.
This artical reports how to use AVR mcu to encode & decode the wireless data.
The mode like this:
1. Encode
header - 9ms low + 4.5ms high
1 - 0.56ms low + 1.685ms high
0 - 0.56ms low + 0.565ms high
Frame Formt:
Header - Address(B) - ~Address(B) - Data(B) - ~Data(B)
The AVR Encoder just set one pin to keep long or short time to low or high, and then send it via the Wireless Sender.
2. Decode
The AVR Decoder just calculate how the received signal low and high times to confirm which is header, 1 or 0 signal.
Ok, about more details, please see the codes.
The Encoder:
PORTA to get the key command, PINB_0 which connected to the Wireless sender data in port to send wireless signal.
// Target : M162
// Crystal: 11.0592Mhz3

4
#include <iom16v.h>5
#include <macros.h>6

7
// Address code8
#define ADDR_CODE 0x119

10
void port_init(void);11
void init_devices(void);12
void delay(BYTE byTime);13
BYTE KeyPressed(void);14
BYTE KeyScan(void);15
void send_header(void);16
void send_0(void);17
void send_1(void);18
void Send(BYTE byValue);19

20
unsigned char g_bSend;21

22

23
void Delay_us(unsigned int nTime)24
{25
unsigned int i = 0;26
for (i = 0; i < nTime; i++)27
{28
asm("nop");29
asm("nop");30
asm("nop");31
asm("nop");32
}33

34
return;35
}36

37
void port_init(void)38
{39
PORTA = 0xFF;40
DDRA = 0x00; // Key Input41
PORTB = 0x00;42
DDRB = 0x01;43
PORTC = 0x00; // m103 output only44
DDRC = 0x00;45
PORTD = 0x00;46
DDRD = 0x00;47

48
return;49
}50

51
//call this routine to initialize all peripherals52
void init_devices(void)53
{54
//stop errant interrupts until set up55
CLI(); //disable all interrupts56
port_init();57
Serial_Init();58

59
MCUCR = 0x00;60
GICR = 0x00;61
TIMSK = 0x00; //timer interrupt sources62
SEI(); //re-enable interrupts63
//all peripherals are now initialized64

65
return;66
}67

68
void delay(BYTE byTime)69
{70
BYTE j;71
while ((byTime--) != 0)72
{73
for (j = 0; j < 125; j++)74
{75
;76
}77
}78

79
return;80
}81

82
BYTE KeyPressed(void)83
{84
BYTE key;85
key = PINA;86
key = key | 0xF0;87

88
if (key == 0xFF)89
{90
return 0;91
} 92
else93
{94
return 1;95
}96
}97

98
BYTE KeyScan(void)99
{100
BYTE key = 0;101
delay(50);102
if ((KeyPressed()))103
{104
key = PINA;105
key = key | 0xF0;106

107
if (key == 0xFE)108
{109
key = 1;110
} 111
else if (key == 0xFD)112
{113
key = 2;114
}115
else if (key == 0xFB)116
{117
key = 3;118
}119
else if (key == 0xF7)120
{121
key = 4;122
}123
else124
{125
key = 0;126
}127

128
do 129
{130
;131
} while(KeyPressed());132

133
delay(50);134
}135

136
return key;137
}138

139
/*----------------------------------------------------140
# frame format:141
Header - Address(B) - ~Address(B) - Data(B) - ~Data(B)142

143
# encode:144
Header - (9+4.5) ms145
0 - (0.56+0.565) ms146
1 - (0.56+1.685) ms147
------------------------------------------------------*/148
void send_header(void)149
{150
PORTB = 0x00;151
Delay_us(9000); // 9 ms152
PORTB = 0x01;153
Delay_us(4500); // 4.5 ms154

155
return;156
}157

158
void send_0(void)159
{160
PORTB = 0x00;161
Delay_us(560);162
PORTB = 0x01;163
Delay_us(565);164

165
return;166
}167

168
void send_1(void)169
{170
PORTB = 0x00;171
Delay_us(560);172
PORTB = 0x01;173
Delay_us(1685);174

175
return;176
}177

178
void Send(BYTE byValue)179
{180
unsigned char byAddr = ADDR_CODE;181
unsigned char bytemp = 0;182
unsigned char i = 0;183
// Boot code184
send_header();185

186
// Address code187
for (i = 0; i < 8; i++)188
{189
if (byAddr & (1 << i))190
{191
// 1192
send_1();193
} 194
else195
{196
// 0197
send_0();198
}199
}200

201
// ~Address202
bytemp = ~byAddr;203
for (i = 0; i < 8; i++)204
{205
if (bytemp & (1 << i))206
{207
// 1208
send_1();209
} 210
else211
{212
// 0213
send_0();214
}215
}216

217
// Data code218
for (i = 0; i < 8; i++)219
{220
if (byValue & (1 << i))221
{222
// 1223
send_1();224
} 225
else226
{227
// 0228
send_0();229
}230
}231

232
// ~Data code233
bytemp = 0x00;234
bytemp = ~byValue;235
for (i = 0; i < 8; i++)236
{237
if (bytemp & (1 << i))238
{239
// 1240
send_1();241
} 242
else243
{244
// 0245
send_0();246
}247
}248

249
PORTB = 0x00;250
Delay_us(100);251
PORTB = 0x01;252

253

254
return;255
}256

257
void main(void)258
{259
BYTE byKeyCode;260
BYTE byValue;261

262
init_devices();263

264

265
while (1)266
{267
if (KeyPressed())268
{269
byKeyCode = KeyScan();270

271
switch(byKeyCode)272
{273
case 0x01:274
g_bSend = 1;275
byValue = 1;276
break;277

278
case 0x02:279
g_bSend = 1;280
byValue = 2;281
break;282

283
case 0x03:284
g_bSend = 1;285
byValue = 3;286
break;287

288
case 0x04:289
g_bSend = 1;290
byValue = 4;291
break;292

293
default:294
g_bSend = 0;295
break;296
}297

298
}299

300
if (g_bSend)301
{302
Send(byValue);303
g_bSend = 0;304
}305

306
}307

308
return;309
}310

311

The Decoder:
Using AVR time capture function. when it correctly parse the signal, it send the data to the USART port. and you can see it from PC via RS-232.
// Target : M82
// Crystal: 8.0000Mhz3

4
#include <iom8v.h>5
#include <macros.h>6

7
#include "udt.h"8
#include "serial.h"9

10
/*----------------------------------------------------11
# frame format:12
Header - Address(B) - ~Address(B) - Data(B) - ~Data(B)13

14
# encode:15
Header - (9 + 4.5) ms16
0 - (0.56+0.565) ms17
1 - (0.56 + 1.685)ms18
------------------------------------------------------*/19

20
/*----------------- 8MHz晶振, 8分频 -------------------21
Header - 12.20ms 0x2FA622
0 - 1.0ms 0x03E723
1 - 2.1ms 0x083224
error - 100us 0x006325
------------------------------------------------------*/26
#define T_HEAD_L 0x2F4327
#define T_HEAD_H 0x300928
#define T_0_L 0x0384 29
#define T_0_H 0x044A30
#define T_1_L 0x07CF31
#define T_1_H 0x089532

33
// Address code34
#define ADDR_CODE 0x1135

36
void port_init(void);37
void timer1_init(void);38
void init_devices(void);39
void parse_frame(void);40

41
//----------------------------------------------------42
unsigned char g_byBitCnt;43
unsigned int g_nAddr; // address code44
unsigned int g_nData; // data code45
unsigned char g_i = 0;46

47

48
//----------------------------------------------------49
void port_init(void)50
{51
PORTB = 0xFF;52
DDRB = 0x00;53
PORTC = 0x00; //m103 output only54
DDRC = 0x00;55
PORTD = 0x00;56
DDRD = 0x00;57

58
return;59
}60

61
//TIMER1 initialize - prescale:Stop62
// WGM: 0) Normal, TOP=0xFFFF63
// desired value: 1Hz64
// actual value: Out of range65
void timer1_init(void)66
{67
TCCR1B = 0x00; //stop68
TCNT1H = 0x00 /*INVALID SETTING*/; //setup69
TCNT1L = 0x00 /*INVALID SETTING*/;70
OCR1AH = 0x00 /*INVALID SETTING*/;71
OCR1AL = 0x00 /*INVALID SETTING*/;72
OCR1BH = 0x00 /*INVALID SETTING*/;73
OCR1BL = 0x00 /*INVALID SETTING*/;74
ICR1H = 0x00 /*INVALID SETTING*/;75
ICR1L = 0x00 /*INVALID SETTING*/;76
TCCR1A = 0x00;77
TCCR1B = 0x82; //start Timer 8分频78

79
return;80
}81

82
#pragma interrupt_handler timer1_capt_isr:iv_TIM1_CAPT83
void timer1_capt_isr(void)84
{85
//timer 1 input capture event, read (int)value in ICR1 using;86
// value=ICR1L; //Read low byte first (important)87
// value|=(int)ICR1H << 8; //Read high byte and shift into top byte88

89

90
static unsigned int nOldTime;91
unsigned int nTime, nNewTime; 92
nNewTime = ICR1; 93
nTime = nNewTime - nOldTime;94
nOldTime = nNewTime;95
96
if (nTime >= T_0_L && nTime <= T_0_H) // 097
{98
nTime = 0;99
} 100
else if (nTime >= T_1_L && nTime <= T_1_H) // 1101
{102
nTime = 1;103
} 104
else if (nTime >= T_HEAD_L && nTime <= T_HEAD_H) // Header105
{106
g_byBitCnt = 0;107
g_nAddr = 0;108
g_nData = 0;109
g_i = 0;110
return; // 返回,等待下次开始接收111
}112
else113
{ 114
// 干扰信号115
return;116
}117

118
g_byBitCnt++;119

120
if (g_byBitCnt <= 16)121
{122
if (nTime)123
{124
g_nAddr |= (1 << g_i);125
} 126
else127
{128
g_nAddr &= ~(1 << g_i);129
}130

131
g_i++;132
}133
else if (g_byBitCnt <= 32)134
{135
if (g_i == 16)136
{137
g_i = 0;138
}139
if (nTime)140
{141
g_nData |= (1 << g_i);142
} 143
else144
{145
g_nData &= ~(1 << g_i);146
}147

148
g_i++;149

150
if (g_byBitCnt == 32)151
{152
// One frame received complete153
g_i = 0;154
check_frame();155
}156
}157
158
return;159
}160

161
void check_frame(void)162
{163
unsigned char byAddr_0 = (unsigned char)g_nAddr;164
unsigned char byAddr_1 = (unsigned char)(g_nAddr >> 8);165
unsigned char byData_0 = (unsigned char)g_nData;166
unsigned char byData_1 = (unsigned char)(g_nData >> 8);167

168
// byAddr_0 = ~byAddr_1;169
// byData_0 = ~byData_1;170
if ( (byAddr_0 + byAddr_1 != 0xFF) || (byData_0 + byData_1 != 0xFF) || (byAddr_0 != ADDR_CODE))171
{172
// Error173
g_nAddr = 0;174
g_nData = 0;175
g_byBitCnt = 0;176
g_i = 0;177
}178

179
return;180
}181

182
//call this routine to initialize all peripherals183
void init_devices(void)184
{185
//stop errant interrupts until set up186
CLI(); //disable all interrupts187
port_init();188
timer1_init();189
Serial_Init();190

191
MCUCR = 0x00;192
GICR = 0x00;193
TIMSK = 0x20; //timer interrupt sources194
SEI(); //re-enable interrupts195
196
//all peripherals are now initialized197

198
return;199
}200

201
void main(void)202
{203
init_devices();204

205
while (1)206
{207
if (g_byBitCnt >= 32)208
{209
unsigned char byValue = (unsigned char)(g_nData);210
Serial_Send(&byValue, 1);211
g_byBitCnt = 0;212
} 213
}214

215
return;216
}217

218

that's all, fine day!



浙公网安备 33010602011771号