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.

  1// Target : M16
  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.

  1// Target : M8
  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!

原文地址:https://www.cnblogs.com/vsignsoft/p/1173505.html