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.
2// Crystal: 11.0592Mhz
3
4#include <iom16v.h>
5#include <macros.h>
6
7// Address code
8#define ADDR_CODE 0x11
9
10void port_init(void);
11void init_devices(void);
12void delay(BYTE byTime);
13BYTE KeyPressed(void);
14BYTE KeyScan(void);
15void send_header(void);
16void send_0(void);
17void send_1(void);
18void Send(BYTE byValue);
19
20unsigned char g_bSend;
21
22
23void 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
37void port_init(void)
38{
39 PORTA = 0xFF;
40 DDRA = 0x00; // Key Input
41 PORTB = 0x00;
42 DDRB = 0x01;
43 PORTC = 0x00; // m103 output only
44 DDRC = 0x00;
45 PORTD = 0x00;
46 DDRD = 0x00;
47
48 return;
49}
50
51//call this routine to initialize all peripherals
52void init_devices(void)
53{
54 //stop errant interrupts until set up
55 CLI(); //disable all interrupts
56 port_init();
57 Serial_Init();
58
59 MCUCR = 0x00;
60 GICR = 0x00;
61 TIMSK = 0x00; //timer interrupt sources
62 SEI(); //re-enable interrupts
63 //all peripherals are now initialized
64
65 return;
66}
67
68void 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
82BYTE KeyPressed(void)
83{
84 BYTE key;
85 key = PINA;
86 key = key | 0xF0;
87
88 if (key == 0xFF)
89 {
90 return 0;
91 }
92 else
93 {
94 return 1;
95 }
96}
97
98BYTE 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 else
124 {
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:
141Header - Address(B) - ~Address(B) - Data(B) - ~Data(B)
142
143# encode:
144Header - (9+4.5) ms
1450 - (0.56+0.565) ms
1461 - (0.56+1.685) ms
147------------------------------------------------------*/
148void send_header(void)
149{
150 PORTB = 0x00;
151 Delay_us(9000); // 9 ms
152 PORTB = 0x01;
153 Delay_us(4500); // 4.5 ms
154
155 return;
156}
157
158void send_0(void)
159{
160 PORTB = 0x00;
161 Delay_us(560);
162 PORTB = 0x01;
163 Delay_us(565);
164
165 return;
166}
167
168void send_1(void)
169{
170 PORTB = 0x00;
171 Delay_us(560);
172 PORTB = 0x01;
173 Delay_us(1685);
174
175 return;
176}
177
178void Send(BYTE byValue)
179{
180 unsigned char byAddr = ADDR_CODE;
181 unsigned char bytemp = 0;
182 unsigned char i = 0;
183 // Boot code
184 send_header();
185
186 // Address code
187 for (i = 0; i < 8; i++)
188 {
189 if (byAddr & (1 << i))
190 {
191 // 1
192 send_1();
193 }
194 else
195 {
196 // 0
197 send_0();
198 }
199 }
200
201 // ~Address
202 bytemp = ~byAddr;
203 for (i = 0; i < 8; i++)
204 {
205 if (bytemp & (1 << i))
206 {
207 // 1
208 send_1();
209 }
210 else
211 {
212 // 0
213 send_0();
214 }
215 }
216
217 // Data code
218 for (i = 0; i < 8; i++)
219 {
220 if (byValue & (1 << i))
221 {
222 // 1
223 send_1();
224 }
225 else
226 {
227 // 0
228 send_0();
229 }
230 }
231
232 // ~Data code
233 bytemp = 0x00;
234 bytemp = ~byValue;
235 for (i = 0; i < 8; i++)
236 {
237 if (bytemp & (1 << i))
238 {
239 // 1
240 send_1();
241 }
242 else
243 {
244 // 0
245 send_0();
246 }
247 }
248
249 PORTB = 0x00;
250 Delay_us(100);
251 PORTB = 0x01;
252
253
254 return;
255}
256
257void 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.
2// Crystal: 8.0000Mhz
3
4#include <iom8v.h>
5#include <macros.h>
6
7#include "udt.h"
8#include "serial.h"
9
10/*----------------------------------------------------
11# frame format:
12Header - Address(B) - ~Address(B) - Data(B) - ~Data(B)
13
14# encode:
15Header - (9 + 4.5) ms
160 - (0.56+0.565) ms
171 - (0.56 + 1.685)ms
18------------------------------------------------------*/
19
20/*----------------- 8MHz晶振, 8分频 -------------------
21Header - 12.20ms 0x2FA6
220 - 1.0ms 0x03E7
231 - 2.1ms 0x0832
24error - 100us 0x0063
25------------------------------------------------------*/
26#define T_HEAD_L 0x2F43
27#define T_HEAD_H 0x3009
28#define T_0_L 0x0384
29#define T_0_H 0x044A
30#define T_1_L 0x07CF
31#define T_1_H 0x0895
32
33// Address code
34#define ADDR_CODE 0x11
35
36void port_init(void);
37void timer1_init(void);
38void init_devices(void);
39void parse_frame(void);
40
41//----------------------------------------------------
42unsigned char g_byBitCnt;
43unsigned int g_nAddr; // address code
44unsigned int g_nData; // data code
45unsigned char g_i = 0;
46
47
48//----------------------------------------------------
49void port_init(void)
50{
51 PORTB = 0xFF;
52 DDRB = 0x00;
53 PORTC = 0x00; //m103 output only
54 DDRC = 0x00;
55 PORTD = 0x00;
56 DDRD = 0x00;
57
58 return;
59}
60
61//TIMER1 initialize - prescale:Stop
62// WGM: 0) Normal, TOP=0xFFFF
63// desired value: 1Hz
64// actual value: Out of range
65void timer1_init(void)
66{
67 TCCR1B = 0x00; //stop
68 TCNT1H = 0x00 /*INVALID SETTING*/; //setup
69 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_CAPT
83void 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 byte
88
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) // 0
97 {
98 nTime = 0;
99 }
100 else if (nTime >= T_1_L && nTime <= T_1_H) // 1
101 {
102 nTime = 1;
103 }
104 else if (nTime >= T_HEAD_L && nTime <= T_HEAD_H) // Header
105 {
106 g_byBitCnt = 0;
107 g_nAddr = 0;
108 g_nData = 0;
109 g_i = 0;
110 return; // 返回,等待下次开始接收
111 }
112 else
113 {
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 else
127 {
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 else
144 {
145 g_nData &= ~(1 << g_i);
146 }
147
148 g_i++;
149
150 if (g_byBitCnt == 32)
151 {
152 // One frame received complete
153 g_i = 0;
154 check_frame();
155 }
156 }
157
158 return;
159}
160
161void 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 // Error
173 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 peripherals
183void init_devices(void)
184{
185 //stop errant interrupts until set up
186 CLI(); //disable all interrupts
187 port_init();
188 timer1_init();
189 Serial_Init();
190
191 MCUCR = 0x00;
192 GICR = 0x00;
193 TIMSK = 0x20; //timer interrupt sources
194 SEI(); //re-enable interrupts
195
196 //all peripherals are now initialized
197
198 return;
199}
200
201void 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!