Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.75/12: Рейтинг темы: голосов - 12, средняя оценка - 4.75
3 / 3 / 0
Регистрация: 29.06.2018
Сообщений: 1,249
1

Компиляция программы генератора на ATMEGA8A

06.06.2021, 01:52. Показов 2226. Ответов 75
Метки нет (Все метки)

При компиляции программы DDS-генератора на ATMEGA8A в WinAVR-20100110
не компилируется
C++
1
SG.acc= (uint32_t) SG.freq/RESOLUTION   ;
в двух подпрограммах (можно ли скомпилировать без мейкфайла и вставить ассемблерные вставки bat-файлом )
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
//
// File Name    : 'main.c'
// Title        : AVR DDS  signal generator
// Author       : Scienceprog.com - Copyright (C)  , modified for ATMEGA8
// Created      :  
// Revised      :  
// Version      :  
// Target MCU   : Atmel AVR series ATmega8a
//
// This code is distributed under the GNU Public License
//      which can be found at http://www.gnu.org/licenses/gpl.txt
 
 
#define F_CPU  16000000UL
#include <stdio.h>
#include <stdlib.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <inttypes.h>
 #include "lcd_lib.h"
#include <math.h>
//define R2R port
#define R2RPORT PORTD
#define R2RDDR DDRD
//define button port and dedicated pins
#define BPORT PORTB
#define BPIN PINB
#define BDDR DDRB
#define DOWN 0    //PORTB
#define LEFT 5       //PORTB
#define START  2    //PORTB
#define RIGHT 3    //PORTB
#define UP 4            //PORTB
//Define Highs Speed (HS) signal output
#define HSDDR DDRB
#define HSPORT PORTB
#define HS 1      //PB1
//define eeprom addresses
#define EEMODE 0
#define EEFREQ1 1
#define EEFREQ2 2
#define EEFREQ3 3
#define EEDUTY 4
#define EEINIT E2END
#define RESOLUTION 0.095367431640625  //    1/10,48576
#define MINFREQ 0  //minimum frequency
#define MAXFREQ 65000  //maximum DDS frequency
#define MN_No 9  // number of menu items
//function prototypes
void delay1s(void);
void Timer2_Init(void);
void Timer2_Start(void);
void Timer2_Stop(void);
void Main_Init(void);
void Menu_Update(uint8_t);
void Freq_Update(void);
void Timer1_Start(uint8_t);
void Timer1_Stop(void);
void static inline Signal_OUT(const uint8_t *, uint8_t, uint8_t, uint8_t);
static int LCDsendstream(char c, FILE *stream);
static FILE lcd_str = FDEV_SETUP_STREAM(LCDsendstream, NULL, _FDEV_SETUP_WRITE);
//Menu Strings in flash
const uint8_t MN000[] PROGMEM="      Sine      \0";//menu 1
const uint8_t MN100[] PROGMEM="     Square     \0";//menu 2
const uint8_t MN200[] PROGMEM="    Triangle    \0";//menu 3
const uint8_t MN300[] PROGMEM="    SawTooth    \0";//menu 4
const uint8_t MN400[] PROGMEM="  Rev SawTooth  \0";//menu 5
const uint8_t MN500[] PROGMEM="      TV Bars       \0";//menu 6
const uint8_t MN600[] PROGMEM="    Freq Step   \0";//menu 7
const uint8_t MN700[] PROGMEM="     Noise      \0";//menu 8
const uint8_t MN800[] PROGMEM="   High Speed   \0";
//Array of pointers to menu strings stored in flash
const uint8_t *MENU[]  ={
        MN000,  //
        MN100,  //menu 1 string
        MN200,  //menu 2 string
        MN300,  //menu 3 string
        MN400,  //menu 4 string
        MN500,  
        MN600,
        MN700,
        MN800
        }; 
//various LCD strings 
const uint8_t MNON[] PROGMEM="ON \0";//ON
const uint8_t MNOFF[] PROGMEM="OFF\0";//OFF
const uint8_t NA[] PROGMEM="       NA       \0";//Clear freq value
const uint8_t CLR[] PROGMEM="                \0";//Clear freq value 
const uint8_t MNClrfreq[] PROGMEM="           \0";//Clear freq value
const uint8_t TOEEPROM[] PROGMEM="Saving Settings\0";//saving to eeprom
const uint8_t ONEMHZ[] PROGMEM="      1MHz   \0";//saving to eeprom
const uint8_t welcomeln1[] PROGMEM="AVR SIGNAL\0";
const uint8_t RND[] PROGMEM="    Random\0";
//variables  
struct signal {
volatile uint8_t mode;      //signal
volatile uint8_t fr1;       //Frequency [0..7]
volatile uint8_t fr2;       //Frequency [8..15]
volatile int8_t fr3;        //Frequency [16..31]
volatile uint32_t freq;     //frequency value
volatile uint8_t flag;      //if "0"generator is OFF, "1" - ON
volatile uint32_t acc;      //accumulator
volatile uint8_t ON;
volatile uint8_t HSfreq;        //high speed frequency [1...4Mhz]
volatile uint32_t deltafreq;    //frequency step value
}SG;
//define signals
/* __attribute__ ((section (".MySection1"))) */
//sine 256 values
 
const uint8_t  sinewave[]  PROGMEM= 
{
0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,
0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,
0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,
0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,
0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51,
0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,
0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a,
0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c,
0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c
};
//square wave
const uint8_t squarewave[]  PROGMEM= 
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff 
};
 //sawtooth wave
const uint8_t sawtoothwave[] PROGMEM=
{
0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,
0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f,
0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f,
0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf,
0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf,
0xc0,0xc1,0xc2,0xc3,0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xcb,0xcc,0xcd,0xce,0xcf,
0xd0,0xd1,0xd2,0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xdb,0xdc,0xdd,0xde,0xdf,
0xe0,0xe1,0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,0xeb,0xec,0xed,0xee,0xef,
0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
};
 //reverse sawtooth wave
const uint8_t rewsawtoothwave[] PROGMEM=
{
0xff,0xfe,0xfd,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,0xf6,0xf5,0xf4,0xf3,0xf2,0xf1,0xf0,
0xef,0xee,0xed,0xec,0xeb,0xea,0xe9,0xe8,0xe7,0xe6,0xe5,0xe4,0xe3,0xe2,0xe1,0xe0,
0xdf,0xde,0xdd,0xdc,0xdb,0xda,0xd9,0xd8,0xd7,0xd6,0xd5,0xd4,0xd3,0xd2,0xd1,0xd0,
0xcf,0xce,0xcd,0xcc,0xcb,0xca,0xc9,0xc8,0xc7,0xc6,0xc5,0xc4,0xc3,0xc2,0xc1,0xc0,
0xbf,0xbe,0xbd,0xbc,0xbb,0xba,0xb9,0xb8,0xb7,0xb6,0xb5,0xb4,0xb3,0xb2,0xb1,0xb0,
0xaf,0xae,0xad,0xac,0xab,0xaa,0xa9,0xa8,0xa7,0xa6,0xa5,0xa4,0xa3,0xa2,0xa1,0xa0,
0x9f,0x9e,0x9d,0x9c,0x9b,0x9a,0x99,0x98,0x97,0x96,0x95,0x94,0x93,0x92,0x91,0x90,
0x8f,0x8e,0x8d,0x8c,0x8b,0x8a,0x89,0x88,0x87,0x86,0x85,0x84,0x83,0x82,0x81,0x80,
0x7f,0x7e,0x7d,0x7c,0x7b,0x7a,0x79,0x78,0x77,0x76,0x75,0x74,0x73,0x72,0x71,0x70,
0x6f,0x6e,0x6d,0x6c,0x6b,0x6a,0x69,0x68,0x67,0x66,0x65,0x64,0x63,0x62,0x61,0x60,
0x5f,0x5e,0x5d,0x5c,0x5b,0x5a,0x59,0x58,0x57,0x56,0x55,0x54,0x53,0x52,0x51,0x50,
0x4f,0x4e,0x4d,0x4c,0x4b,0x4a,0x49,0x48,0x47,0x46,0x45,0x44,0x43,0x42,0x41,0x40,
0x3f,0x3e,0x3d,0x3c,0x3b,0x3a,0x39,0x38,0x37,0x36,0x35,0x34,0x33,0x32,0x31,0x30,
0x2f,0x2e,0x2d,0x2c,0x2b,0x2a,0x29,0x28,0x27,0x26,0x25,0x24,0x23,0x22,0x21,0x20,
0x1f,0x1e,0x1d,0x1c,0x1b,0x1a,0x19,0x18,0x17,0x16,0x15,0x14,0x13,0x12,0x11,0x10,
0x0f,0x0e,0x0d,0x0c,0x0b,0x0a,0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x02,0x01,0x00 
};
 
//triangle wave
 
const uint8_t trianglewave[] PROGMEM = 
{
0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e,0x10,0x12,0x14,0x16,0x18,0x1a,0x1c,0x1e,
0x20,0x22,0x24,0x26,0x28,0x2a,0x2c,0x2e,0x30,0x32,0x34,0x36,0x38,0x3a,0x3c,0x3e,
0x40,0x42,0x44,0x46,0x48,0x4a,0x4c,0x4e,0x50,0x52,0x54,0x56,0x58,0x5a,0x5c,0x5e,
0x60,0x62,0x64,0x66,0x68,0x6a,0x6c,0x6e,0x70,0x72,0x74,0x76,0x78,0x7a,0x7c,0x7e,
0x80,0x82,0x84,0x86,0x88,0x8a,0x8c,0x8e,0x90,0x92,0x94,0x96,0x98,0x9a,0x9c,0x9e,
0xa0,0xa2,0xa4,0xa6,0xa8,0xaa,0xac,0xae,0xb0,0xb2,0xb4,0xb6,0xb8,0xba,0xbc,0xbe,
0xc0,0xc2,0xc4,0xc6,0xc8,0xca,0xcc,0xce,0xd0,0xd2,0xd4,0xd6,0xd8,0xda,0xdc,0xde,
0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xee,0xf0,0xf2,0xf4,0xf6,0xf8,0xfa,0xfc,0xfe,
0xff,0xfd,0xfb,0xf9,0xf7,0xf5,0xf3,0xf1,0xef,0xef,0xeb,0xe9,0xe7,0xe5,0xe3,0xe1,
0xdf,0xdd,0xdb,0xd9,0xd7,0xd5,0xd3,0xd1,0xcf,0xcf,0xcb,0xc9,0xc7,0xc5,0xc3,0xc1,
0xbf,0xbd,0xbb,0xb9,0xb7,0xb5,0xb3,0xb1,0xaf,0xaf,0xab,0xa9,0xa7,0xa5,0xa3,0xa1,
0x9f,0x9d,0x9b,0x99,0x97,0x95,0x93,0x91,0x8f,0x8f,0x8b,0x89,0x87,0x85,0x83,0x81,
0x7f,0x7d,0x7b,0x79,0x77,0x75,0x73,0x71,0x6f,0x6f,0x6b,0x69,0x67,0x65,0x63,0x61,
0x5f,0x5d,0x5b,0x59,0x57,0x55,0x53,0x51,0x4f,0x4f,0x4b,0x49,0x47,0x45,0x43,0x41,
0x3f,0x3d,0x3b,0x39,0x37,0x35,0x33,0x31,0x2f,0x2f,0x2b,0x29,0x27,0x25,0x23,0x21,
0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x11,0x0f,0x0f,0x0b,0x09,0x07,0x05,0x03,0x01
};
// TV bars ,fix
 
const uint8_t TVBars[] PROGMEM = 
{
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
    0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
    0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
    0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
    0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x60, 0x60, 0x60,
    0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60,
    0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
    0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
    0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
    0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0, 0xA0,
    0xA0, 0xA0, 0xA0, 0xA0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
    0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
    0xC0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0,
    0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xFF, 0xFF,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
};
 
/*array of pointers to signal tables*/
const uint8_t *SIGNALS[] ={
    sinewave,
     squarewave,
     trianglewave,
     sawtoothwave,
     rewsawtoothwave,
    TVBars
};
 
//adjust LCD stream fuinction to use with printf()
static int LCDsendstream(char c , FILE *stream)
{
LCDsendChar(c);
return 0;
}
 
void delay1s(void){ uint8_t i; for(i=0; i<100; i++){ _delay_ms(10); } }
 
//initialize Timer2 (used for button reading)
void Timer2_Init(void)
{
    TCNT2=0x00;
    sei();
} 
//start timer2
void Timer2_Start(void)
{
    TCCR2|=(1<<CS22)|(1<<CS21); //prescaller 256 ~122 interrupts/s
    TIMSK|=(1<<TOV2);//Enable Timer0 Overflow interrupts
}
//stop timer 2
void Timer2_Stop(void)
{
    TCCR0&=~((1<<CS22)|(1<<CS21)); //Stop timer0
    TIMSK&=~(1<<TOV2);//Disable Timer0 Overflow interrupts
}
 
/*Initial menu show initial signal and frequency generator is off*/
void Menu_Update(uint8_t on)
{
    LCDclr();
    CopyStringtoLCD(MENU[(SG.mode)], 0, 0 );
    LCDGotoXY(0, 1);
    if (SG.mode==6){ CopyStringtoLCD(CLR, 0, 1 ); LCDGotoXY(0, 1); printf("    %5uHz", (uint16_t)SG.deltafreq); }
    if (SG.mode==7){ CopyStringtoLCD(CLR, 0, 1 ); CopyStringtoLCD(RND, 0, 1 ); }
    if (SG.mode==8){ CopyStringtoLCD(CLR, 0, 1 ); LCDGotoXY(0, 1); printf(" %5uMHz", SG.HSfreq); }
    if((SG.mode==0)||(SG.mode==1)||(SG.mode==2)||(SG.mode==3)||(SG.mode==4)||(SG.mode==5))
        { CopyStringtoLCD(CLR, 0, 1 ); LCDGotoXY(0, 1); printf(" %5uHz", (uint16_t)SG.freq); }
    if (SG.mode!=6){ if(on==1) CopyStringtoLCD(MNON, 13, 1 );  else CopyStringtoLCD(MNOFF, 13, 1 ); }
}
 
/*update frequency value on LCD menu - more smooth display*/
void Freq_Update(void)
{
if (SG.mode==6){ LCDGotoXY(0, 1); printf("    %5uHz", (uint16_t)SG.deltafreq);}
if (SG.mode==8){ LCDGotoXY(0, 1); printf(" %5uMHz", SG.HSfreq); } //if HS signal
if((SG.mode==0)||(SG.mode==1)||(SG.mode==2)||(SG.mode==3)||(SG.mode==4)||(SG.mode==5))
  { LCDGotoXY(0, 1);printf(" %5uHz", (uint16_t)SG.freq);}
}
/*External interrupt0 service routine used to stop DDS depending on active menuany generator is stopped by setting flag value to 0
DDs generator which is inline ASM is stopped by setting */
/* CPHA bit in SPCR register */
 
 
ISR(INT0_vect)
{
SG.flag=0;   /* set flag to stop generator */
SPCR|=(1<<CPHA);/* using CPHA bit as stop mark */
//CopyStringtoLCD(MNOFF, 13, 1 );
SG.ON=0;/* set off in LCD menu */
loop_until_bit_is_set(BPIN, START);//wait for button release
}
 
  //uint32_t getAcc( uint32_t  Sfreq) {   return 0x0000;//(uint32_t) Sfreq/RESOLUTION; }
 
/* timer overflow interrupt service tourine  checks all button status and if button is pressed
value is updated */
 
ISR(TIMER2_OVF_vect)
{
/*Button UP increments value which selects previous signal mode if first mode is reached - jumps to last */
if (bit_is_clear(BPIN, UP)){ if (SG.mode==0){ SG.mode=MN_No-1;} else { SG.mode--; } 
                 Menu_Update(SG.ON); //Display menu item
    loop_until_bit_is_set(BPIN, UP); }
/*Button Down decrements value which selects next signal mode if last mode is reached - jumps to first*/
if ( bit_is_clear(BPIN, DOWN) ){
    if (SG.mode<(MN_No-1)) { SG.mode++; } else{ SG.mode=0; } //Display menu item
    Menu_Update(SG.ON);
    loop_until_bit_is_set(BPIN, DOWN); }
//frequency increment   
if (bit_is_clear(BPIN, RIGHT)){
    if(SG.mode==6){ if(SG.deltafreq==10000) { SG.deltafreq=1; } else {SG.deltafreq=(SG.deltafreq*10); }
            Freq_Update();
            loop_until_bit_is_set(BPIN, RIGHT); }
                    //ifhigh speed signal
     if (SG.mode==8){ if(SG.HSfreq==8) { SG.HSfreq=1; } else { SG.HSfreq=(SG.HSfreq<<1); }
            Freq_Update();
            loop_until_bit_is_set(BPIN, RIGHT); }
     if((SG.mode==0)||(SG.mode==1)||(SG.mode==2)||(SG.mode==3)||(SG.mode==4)||(SG.mode==5)){
            if ((0xFFFF-SG.freq)>=SG.deltafreq) SG.freq+=SG.deltafreq;
            Freq_Update();
            uint8_t ii=0;
            //press button and wait for long press (~0.5s)
            do{ _delay_ms(2); ii++; } while((bit_is_clear(BPIN, RIGHT))&&(ii<=250));//wait for button release
             if(ii>=250){
                                                     do{ if ((0xFFFF-SG.freq)>=SG.deltafreq) { SG.freq+=SG.deltafreq; } Freq_Update();} 
                                                       while(bit_is_clear(BPIN, RIGHT));  }   //wait for button release
                
       }}
//frequency decrement
if (bit_is_clear(BPIN, LEFT)){
    if(SG.mode==6){ if(SG.deltafreq==1) {SG.deltafreq=10000; } else {SG.deltafreq=(SG.deltafreq/10);}
            Freq_Update(); loop_until_bit_is_set(BPIN, LEFT); }
                  //ifhigh speed signal
    if (SG.mode==8){ if(SG.HSfreq==1) { SG.HSfreq=8;} else {SG.HSfreq=(SG.HSfreq>>1) ;} 
            Freq_Update(); loop_until_bit_is_set(BPIN, LEFT); }
     if ((SG.mode==0)||(SG.mode==1)||(SG.mode==2)||(SG.mode==3)||(SG.mode==4)||(SG.mode==5)){
        if (SG.freq>=SG.deltafreq) SG.freq-=SG.deltafreq;
                Freq_Update();
                uint8_t ii=0;
                /* press button and wait for long press (~0.5s) */
                do{ _delay_ms(2); ii++; } while((bit_is_clear(BPIN, LEFT))&&(ii<=250));/* wait for button release */
                if(ii>=250){ do{ if (SG.freq>=SG.deltafreq) {SG.freq-=SG.deltafreq;} 
                                                                        Freq_Update(); } while(bit_is_clear(BPIN, LEFT)); }/*wait for button release*/
                 
            } }
 
if (bit_is_clear(BPIN, START)) {
     if(SG.mode!=6){
        /*saving last configuration*/
        SG.fr1=(uint8_t)(SG.freq);
        SG.fr2=(uint8_t)(SG.freq>>8);
        SG.fr3=(uint8_t)(SG.freq>>16); 
        //Calculate frequency value from restored EEPROM values
        SG.freq=(((uint32_t)(SG.fr3)<<16)|((uint32_t)(SG.fr2)<<8)|((uint32_t)(SG.fr1)));
        //calculate accumulator value
    //                               SG.acc=  SG.freq/ RESOLUTION   ; //warning  *****************************
        // SG.acc=  (uint32_t)( SG.freq/ RESOLUTION)    ; //warning
                                   //   SG.acc= (uint32_t)SG.freq* 10.48576;  
 
         SG.flag=1; //set flag to start generator
         SG.ON=1; //set ON on LCD menu
         SPCR&=~(1<<CPHA); //clear CPHA bit in SPCR register to allow DDS
        //Stop timer2 - menu inactive
         Timer2_Stop();
        //display ON on LCD
         Menu_Update(SG.ON);
             }
    loop_until_bit_is_set(BPIN, START);  //wait for button release
    }
}
 
/*DDS signal generation function
Original idea is taken from
http://www.myplace.nu/avr/minidds/index.htm
small modification is made - added additional command which
checks if CPHA bit is set in SPCR register if yes - exit function
*/
void static inline Signal_OUT(const uint8_t *signal, uint8_t ad2, uint8_t ad1, uint8_t ad0)
{ 
asm volatile(   "eor r18, r18   ;r18<-0"    "\n\t"
                "eor r19, r19   ;r19<-0"    "\n\t"
                "1:"                        "\n\t"
                "add r18, %0    ;1 cycle"           "\n\t"
                "adc r19, %1    ;1 cycle"           "\n\t"  
                "adc %A3, %2    ;1 cycle"           "\n\t"
                "lpm            ;3 cycles"  "\n\t"
                "out %4, __tmp_reg__    ;1 cycle"   "\n\t"
                "sbis %5, 2     ;1 cycle if no skip" "\n\t"
                "rjmp 1b        ;2 cycles. Total 10 cycles" "\n\t"
                :
                :"r" (ad0),"r" (ad1),"r" (ad2),"e" (signal),"I" (_SFR_IO_ADDR(PORTD)), "I" (_SFR_IO_ADDR(SPCR))
                :"r18", "r19" 
    ); 
}
 
void Timer1_Start(uint8_t FMHz)
{
    if(FMHz==1){ OCR1A=7; } else  //start high speed (1MHz) signal
    if(FMHz==2){ OCR1A=3; } else //2MHz
    if(FMHz==4){ OCR1A=1; } else //4MHz     
    if(FMHz==8){ OCR1A=0; } else //8MHz 
        OCR1A=7;//default 1MHz
    
    //Output compare toggles OC1A pin
    TCCR1A=0x40;
    //start timer without prescaler
    TCCR1B=0b00001001;
}
void Timer1_Stop(void){ TCCR1B=0x00; }//timer off
void Main_Init(void){
//stderr = &lcd_str;
stdout = &lcd_str;
//--------init LCD----------
LCDinit();
LCDclr();
LCDcursorOFF();
// const uint8_t welcomeln1[] PROGMEM ="AVR LCD DEMO\0";
 //CopyStringtoLCD(welcomeln1, 3, 1);
//return;
 
//-------EEPROM initial values----------
//if (eeprom_read_byte((uint8_t*)EEINIT)!='T')
//{
//eeprom_write_byte((uint8_t*)EEMODE,0x00);//initial mode 0 – OUT~~~~;
//eeprom_write_byte((uint8_t*)EEFREQ1,0xE8);//initial frequency 1kHz
//eeprom_write_byte((uint8_t*)EEFREQ2,0x03);
//eeprom_write_byte((uint8_t*)EEFREQ3,0x00);
//eeprom_write_byte((uint8_t*)EEINIT,'T');//marks once that eeprom init is done
//once this procedure is held, no more initialization is performed
//}
//------restore last saved values from EEPROM------
SG.mode=0x00; //eeprom_read_byte((uint8_t*)EEMODE);
SG.fr1=0xE8;//eeprom_read_byte((uint8_t*)EEFREQ1);
SG.fr2=0x03;//eeprom_read_byte((uint8_t*)EEFREQ2);
SG.fr3=0x00;//eeprom_read_byte((uint8_t*)EEFREQ3);
SG.freq=(((uint32_t)(SG.fr3)<<16)|((uint32_t)(SG.fr2)<<8)|((uint32_t)(SG.fr1)));
             //SG.acc= (uint32_t) ( SG.freq* 10.48576); 
             //SG.acc= (uint32_t) SG.freq/RESOLUTION    ; //warning  RESOLUTION= 0.095367431640625 
// SG.acc= (uint32_t) SG.freq/RESOLUTION    ; //fix ***********************
SG.flag=0;
//default 1MHz HS signal freq
SG.HSfreq=1;
SG.deltafreq=100;
//------------init DDS output-----------
R2RPORT=0x00;//set initial zero values
R2RDDR=0xFF;//set A port as output
//-------------set ports pins for buttons----------
BDDR&=~(_BV(START)|_BV(UP)|_BV(DOWN)|_BV(RIGHT)|_BV(LEFT));
BPORT|=(_BV(START)|_BV(UP)|_BV(DOWN)|_BV(RIGHT)|_BV(LEFT));
//---------set ports pins for HS output---------
HSDDR|=_BV(HS);//configure as output
//-----------Menu init--------------
SG.ON=0;//default signal is off
Menu_Update(SG.ON);
//-----------Timer Init-------------
Timer2_Init();
//Start Timer with overflow interrupts
Timer2_Start();
}
 
int main(void)
{
//Initialize
Main_Init();
while(1)  {
    if (SG.flag==1)
        {
        GICR|=(1<<INT0);//set external interrupt to enable stop
        if (SG.mode==7)
            {
            //Noise
            do { R2RPORT=rand();} while(SG.flag==1);
            //set signal level to 0
            R2RPORT=0x00;
            //display generator OFF
            Menu_Update(SG.ON);
            //stop external interrupt
            GICR&=~(1<<INT0);
            //start timer menu active
            Timer2_Start();
            }
        else if (SG.mode==6)
            {
            //freq step
            while((SG.flag==1))
            {
            //not implemented
            CopyStringtoLCD(NA, 0, 1 );
            }
            //set signal level to 0
            R2RPORT=0x00;
            //display generator OFF
            Menu_Update(SG.ON); 
            GICR&=~(1<<INT0);//|(1<<INT1);//stop external interrupt
            //start timer menu active
            Timer2_Start();
            }
 
        else if (SG.mode==8)
            {
            //High speed signal
            Timer1_Start(SG.HSfreq);
            while((SG.flag==1)) { CopyStringtoLCD(MNON, 13, 1 ); }//not implemented
            Timer1_Stop();//timer off
            //set HS pin to LOW
            HSPORT&=~(1<<HS);
            //display generator OFF
            Menu_Update(SG.ON); 
            GICR&=~(1<<INT0);//|(1<<INT1);//stop external interrupt
            //start timer menu active
            Timer2_Start();
            }
        else
            {
            //start DDS
            Signal_OUT(  SIGNALS[SG.mode], (uint8_t) ((uint32_t) SG.acc>>16), (uint8_t)((uint32_t) SG.acc>>8),(uint8_t)SG.acc);
            //set signal level to 0
            R2RPORT=0x00;
            //display generator OFF
            Menu_Update(SG.ON);
            GICR&=~(1<<INT0);//|(1<<INT1);
                                                      //stop external interrupt
            //start timer menu active
            Timer2_Start();
            }
        }
    }
return 0;    
}
 
/*
 for ATMEGA8A 
 
 PB0  down
 PB1(OC1A) HS
 PB2(OC1B/nSS)START (and anodes of the diodes, nSS )
 PB3(OC2) RIGHT 
 PB4 UP
 PB5 LEFT
 
 16 MHz XTAL(9,10),
 21,20 not used 
 
 44780
 RW- to GND
 PC0 RS pin 4 LCD
 PC1 EN pin 6 LCD
 PC2 D4 pin 11 LCD
 PC3 D5 pin 12 LCD
 PC4 D6 pin 13 LCD
 PC5 D7 pin 14 LCD
 
 R-2R DAC bus
 PD0 DD0
 PD1 DD1
 PD2(INT0) DD2
 PD3(INT1) DD3
 PD4 DD4
 PD5 DD5
 PD6 DD6
 PD7 DD7
 
 pin 1 MCU to Vcc using R=10 k
 
 fuses
 
 LOCKBITS =0xFF
 
  RSTDISBL =1
  WDTON  =1
  SPIEN =0
  CKOPT =1
  EESAVE =1
  BOOTSZ1 =0
  BOOTSZ0 =0 
  BOOTRST =1
  
  BODLEVEL =1
  BODEN =1
  SUT1 =1
  SUT0 =1
  CKSEL3...1 =111
  CKSEL0=0
  
 */
 
 
 
/*
-Wl,-section-start=.MySection1=0x3A00
-Wl,-section-start=.MySection2=0x3B00
-Wl,-section-start=.MySection3=0x3C00
-Wl,-section-start=.MySection4=0x3D00
-Wl,-section-start=.MySection5=0x3E00
-Wl,-section-start=.MySection6=0x3F00
 
 
Resolution=fCPU/2^24
fOUT=PhAccumulator*Resolution;
 
 
 build.bat:
 
 
path C:\WinAVR-20100110\bin;%path%
 rem avr-gcc  -mmcu=atmega8  -Wall  -Os  -lm   -o   main.elf   main.c
 rem  avr-objcopy -O ihex  main.o   main.hex
 
 
in the AVRStudio4  may be 
fix problem 
avr-gcc  -mmcu=atmega8 -Wall -gdwarf-2 -std=gnu99 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT main.o -MF main.o.d  -c  main.c
avr-objcopy -O ihex  main.o   main.hex
 
pause 0;
*/
0
Вложения
Тип файла: zip ddsmega8test_bugs.zip (54.0 Кб, 2 просмотров)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.06.2021, 01:52
Ответы с готовыми решениями:

Динамическая компиляция (компиляция программы в программе)
Привет форумчане, встретился с такой проблемой,мне в курсовой работе сказали сделать чтобы с...

Не могу понять почему выскакивает ошибка при компиляции программы для МК atmega8a
Уважаемые господа программисты. Помогите мне пожалуйста . С паяльником я дружу с 12 лет и восновном...

Разработка программы Генератора Псевдослучайной Последовательности
Всем привет! Есть задача: написать программу Генератора Псевдослучайной Последовательности (ГПСП)...

Генератор карты высот (часть программы-генератора G кода)
Наверное прийдётся сделать длинное вступление (все-же пишут чего и зачем, у кого сессия, у кого...

75
3 / 3 / 0
Регистрация: 29.06.2018
Сообщений: 1,249
06.06.2021, 01:58  [ТС] 2
Схема для альтернативной версии Soir DDS .
0
3 / 3 / 0
Регистрация: 29.06.2018
Сообщений: 1,249
06.06.2021, 02:04  [ТС] 3
Проблема с линковкой математики . Хочу проверить, возможно ли это на этом процессоре (хотя бы некоторые версии на ассемблере в интернете у некоторых авторов получались).
Масштабирование ,возможно, табличное или на ассемблерных вставках .
С седьмой Атмел студией билдится. но в файле ерунда, пока с багами, не работает.
Прототип на ATMEGA16(A) AVR DDS 2.0 circuit (Scienceprog.com) в аттаче.
0
Вложения
Тип файла: 7z m16.7z (26.0 Кб, 0 просмотров)
3 / 3 / 0
Регистрация: 29.06.2018
Сообщений: 1,249
06.06.2021, 02:42  [ТС] 4
В интернете есть другой вариант вычисления фазы сигнала для аккумулятора фазы с другой распиновкой и схемой (на радиокоте встречал ):
0
Вложения
Тип файла: 7z 03.7z (2.93 Мб, 2 просмотров)
3 / 3 / 0
Регистрация: 29.06.2018
Сообщений: 1,249
06.06.2021, 03:39  [ТС] 5
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdint.h>
 
 #define RESOLUTION 0.095367431640625 //    1/10,48576
 
int main(void)
{
  
FILE *fp;
char name[80];
 
 
 
if((fp=fopen("data.txt", "a")) == NULL) {printf("Cannot open directory file."); exit(1);}
 for(int i=0; i<65536;i++)
{
int freq=(uint32_t)i;
 uint32_t phase=( uint32_t )freq/ RESOLUTION;
 
fprintf(fp,"%d %d   \n",  (int) freq, (int) phase);
 
 
 
 
 
 
 
}
fclose(fp);
return 0;
}
0
Вложения
Тип файла: 7z data.7z (97.3 Кб, 0 просмотров)
3 / 3 / 0
Регистрация: 29.06.2018
Сообщений: 1,249
06.06.2021, 03:43  [ТС] 6
f=65535 -->687184 ->( 00) 0A 7С 50
0
3 / 3 / 0
Регистрация: 29.06.2018
Сообщений: 1,249
06.06.2021, 03:46  [ТС] 7
В седьмой атмел студии (программа пока с багами, см. листинг ):
0
Вложения
Тип файла: 7z dds8app.7z (81.5 Кб, 0 просмотров)
3 / 3 / 0
Регистрация: 29.06.2018
Сообщений: 1,249
06.06.2021, 04:00  [ТС] 8
В четвертой с AVR Toolchain
Код
Build started 6.6.2021 at 03:52:18
avr-gcc  -mmcu=atmega8 -Wall -gdwarf-2 -std=gnu99     -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT main.o -MF dep/main.o.d  -c  ../main.c
avr-gcc -mmcu=atmega8 -Wl,-Map=proj1.map main.o     -o proj1.elf
c:/program files (x86)/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.5.1/../../../../avr/bin/ld.exe: proj1.elf section `.text' will not fit in region `text'
c:/program files (x86)/atmel/avr tools/avr toolchain/bin/../lib/gcc/avr/4.5.1/../../../../avr/bin/ld.exe: region `text' overflowed by 1672 bytes
collect2: ld returned 1 exit status
make: *** [proj1.elf] Error 1
Добавлено через 1 минуту
Примерно также, как и с WinAVR(якобы не помещается).

Добавлено через 4 минуты
Можно ли это сделать на сдвигах и ассемблерных вставках ?
В смысле
C++
1
2
3
4
5
6
#define RESOLUTION 0.095367431640625  //    1/10,48576
 
uint32_t SG.acc= (uint32_t) ((uint32_t)SG.freq/RESOLUTION );
//SG.acc-фаза сигнала , 3 байта 
//SG.freq частота 
//RESOLUTION для 16 МГц и ассемблерной вставки
0
3 / 3 / 0
Регистрация: 29.06.2018
Сообщений: 1,249
06.06.2021, 22:22  [ТС] 9
Исходная теория

https://scienceprog.com/avr-dd... explained/
https://scienceprog.com/avr-dd... rator-v10/

Добавлено через 12 минут
Для атмега8 бывает другой параметр RESOLUTION (проверить )
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#define RESOLUTION 0.1059638129340278
//#define RESOLUTION F_CPU/(9*16777216);
 
void static inline signalOUT(const uint8_t *signal, uint8_t ad2, uint8_t ad1, uint8_t ad0)
{
asm volatile(   "eor r18, r18   ;r18<-0"    "\n\t"
                "eor r19, r19   ;r19<-0"    "\n\t"
                "1:"                        "\n\t"
                "add r18, %0    ;1 cycle"           "\n\t"
                "adc r19, %1    ;1 cycle"           "\n\t"  
                "adc %A3, %2    ;1 cycle"           "\n\t"
                "lpm            ;3 cycles"  "\n\t"
                "out %4, __tmp_reg__    ;1 cycle"   "\n\t"
                "rjmp 1b        ;2 cycles. Total 9 cycles"  "\n\t"
                :
                :"r" (ad0),"r" (ad1),"r" (ad2),"e" (signal),"I" (_SFR_IO_ADDR(PORTD))
                :"r18", "r19" 
    );
}
 
...
frequency=(((uint32_t)(freq3)<<16)|((uint32_t)(freq2)<<8)|((uint32_t)(freq1)));
temp=frequency/RESOLUTION;
tfreq1=(uint8_t)(temp);
tfreq2=(uint8_t)(temp>>8);
tfreq3=(uint8_t)(temp>>16);
0
Вложения
Тип файла: zip firmware.zip (98.3 Кб, 0 просмотров)
3 / 3 / 0
Регистрация: 29.06.2018
Сообщений: 1,249
06.06.2021, 23:02  [ТС] 10
Если мега8 , то 9 циклов и 0.1059638129340278 или F_CPU/(9*16777216)

Добавлено через 18 минут
Для остановки кнопкой будет 10 циклов (с учетом условия) и
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//#define RESOLUTION F_CPU/NCYCLES/2^24= 16000000/(10*16 777 216)=0,095367431640625 
//or 1/10,48576
#define RESOLUTION 0.095367431640625 //    1/10,48576
 
void static inline Signal_OUT(const uint8_t *signal, uint8_t ad2, uint8_t ad1, uint8_t ad0)
{ 
asm volatile(   "eor r18, r18   ;r18<-0"    "\n\t"
                "eor r19, r19   ;r19<-0"    "\n\t"
                "1:"                        "\n\t"
                "add r18, %0    ;1 cycle"           "\n\t"
                "adc r19, %1    ;1 cycle"           "\n\t"  
                "adc %A3, %2    ;1 cycle"           "\n\t"
                "lpm            ;3 cycles"  "\n\t"
                "out %4, __tmp_reg__    ;1 cycle"   "\n\t"
                "sbis %5, 2     ;1 cycle if no skip" "\n\t"
                "rjmp 1b        ;2 cycles. Total 10 cycles" "\n\t"
                :
                :"r" (ad0),"r" (ad1),"r" (ad2),"e" (signal),"I" (_SFR_IO_ADDR(PORTD)), "I" (_SFR_IO_ADDR(SPCR))
                :"r18", "r19" 
    ); 
}
0
3 / 3 / 0
Регистрация: 29.06.2018
Сообщений: 1,249
07.06.2021, 02:02  [ТС] 11
Проект в VMLAB (пока без подпрограммы, линкерные опции две нижние точки (минимальные), математика, гну99 ): происходит сбой при выборке массива строчек (где-то неадекватные типы или метод линковки(компиляции)).
0
Вложения
Тип файла: zip vm.zip (138.5 Кб, 0 просмотров)
Тип файла: rar VM-LAB.rar (4.34 Мб, 0 просмотров)
3 / 3 / 0
Регистрация: 29.06.2018
Сообщений: 1,249
07.06.2021, 03:35  [ТС] 12
В CodeVisoinAVR 3.32 evaluation cvavreval.zip

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>
#include <stdlib.h>
//#include <avr/io.h>
//#include <avr/pgmspace.h>
//#include <avr/eeprom.h>
//#include <avr/interrupt.h>
//#include <util/delay.h>
#include <io.h>
#include <pgmspace.h>
#include <eeprom.h>
#include <interrupt.h>
#include <delay.h>
 
//  _delay_ms(1); -->   delay_ms(1);
 
 
//adjust LCD stream fuinction to use with printf()
static int LCDsendstream(char c  , FILE *stream )
{
LCDsendChar(c);
return 0;
}
 
 // stdout = stdin = &uart_str;
 // stderr = &lcd_str;
 
static FILE lcd_str = FDEV_SETUP_STREAM(LCDsendstream, NULL, _FDEV_SETUP_WRITE); 
// stdout = &lcd_str;
void static inline Signal_OUT(const uint8_t *, uint8_t, uint8_t, uint8_t);
C++
1
static int LCDsendstream(char c  , FILE *stream )
дает ошибку C:\cvpr\Lcddemo.c(101): declaration syntax error
C++
1
2
3
    for(i=0; (uint8_t) pgm_read_byte(&FlashLoc[i])  ; i++)  
 
дает небезопасное преобразование указателя
некоторые элементы библиотеки индикатора глючат или не используются
0
Вложения
Тип файла: zip cvpr.zip (40.9 Кб, 0 просмотров)
3 / 3 / 0
Регистрация: 29.06.2018
Сообщений: 1,249
07.06.2021, 10:58  [ТС] 13
Там еще что-то с нумерацией таймеров (0 или 2 и название регистров), переход от 16-й к 8-й меге.

Добавлено через 18 минут
Плохо компилируется CopyStringtoLCD


C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
...
 
//initialize Timer2 (used for button reading)
void Timer2_Init(void)
{
    TCNT2=0x00;
    sei();
}
//start timer2
void Timer2_Start(void)
{
 //     TIMSK|=(1<<CS22)|(1<<CS21);
//  TCCR2|=(1<<CS22)|(1<<CS21); //prescaller 256 ~122 interrupts/s
//  TIMSK|=(1<<TOV2);//Enable Timer0 Overflow interrupts     ?2
//  TIFR|=(1<<TOV2);//Enable Timer0 Overflow interrupts2
    
}
//stop timer 2
void Timer2_Stop(void)
{   //TCCR0?
//  TCCR2&=~((1<<CS22)|(1<<CS21)); //Stop timer0    ? 2
//  TIMSK&=~((1<<CS22)|(1<<CS21)); //Stop timer0    ?2
//  TIMSK&=~(1<<TOV2);//Disable Timer0 Overflow interrupts
   //   TIFR&=~(1<<TOV2);
}
 
 
 
...
void Menu_Update(uint8_t on)
{
    LCDclr();
//  int i=   (int)(SG.mode);
//  CopyStringtoLCD(  MENU[i], 0, 0 );
    
//  CopyStringtoLCD(  MENU[(SG.mode)], 0, 0 );
    
    LCDGotoXY(0, 1);
return; //для диагностики , так не "блуждает" по памяти, но не будет работать 
    
//  if (SG.mode==6){ CopyStringtoLCD(CLR, 0, 1 ); LCDGotoXY(0, 1); printf("    %5uHz", (uint16_t)SG.deltafreq); }
//  if (SG.mode==7){ CopyStringtoLCD(CLR, 0, 1 ); CopyStringtoLCD(RND, 0, 1 ); }
//  if (SG.mode==8){ CopyStringtoLCD(CLR, 0, 1 ); LCDGotoXY(0, 1); printf(" %5uMHz", SG.HSfreq); }
//if((SG.mode==0)||(SG.mode==1)||(SG.mode==2)||(SG.mode==3)||(SG.mode==4)||(SG.mode==5))
//  { CopyStringtoLCD(CLR, 0, 1 ); LCDGotoXY(0, 1); printf(" %5uHz", (uint16_t)SG.freq); }
        
//  if (SG.mode!=6){ if(on==1) CopyStringtoLCD(MNON, 13, 1 );  else CopyStringtoLCD(MNOFF, 13, 1 ); }
}
Добавлено через 1 час 27 минут
test.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdint.h>
 
 #define RESOLUTION 0.095367431640625 //    1/10,48576
 #define NTICKS 10
 #define FCPU 16000000UL  //F4 2400
//  #define RESOLUTION  FCPU/NTICKS/2^24    16 777 216   (0x100 0000   1 0000 0000 0000 0000 0000 0000  ) (1<<24)
 
 //10=5*2
 //FCPU/10=FCPU/5/2=(FCPU>>1)/5
 
 //((FCPU>>1)/(5*  (1<<24))
 //((FCPU)/(10*  (1<<24)) 
 
 //2^n 2 << (n-1);
 //m-тую степень 2  n << m;
 
 //freq/ RESOLUTION
 //freq*10*(1<<24)/16000000
 //freq*10*(16777216)/16000000
 //freq*2*5*(16777216)/2*8000000           16000000
 //freq*5*(16777216)/8000000
//16000000/2^10 1 024=15625   10
 
// 2^10  --> (1<<10)
//(uint32_t) (((uint64_t)freq<<24)/(15625*(1<<10));
//(uint32_t) (((uint64_t)  freq<<(24-10))*10/(15625 );
//(uint32_t) (((uint64_t)  freq<<14 )*10/(15625 );  15625 =5^6
 
 
int main(void)
{
  
FILE *fp;
char name[80];
 
 
 
if((fp=fopen("data.txt", "w")) == NULL) {printf("Cannot open directory file."); exit(1);}
 for(int i=0; i<65536;i++)
{
int freq=(uint32_t)i;
 uint32_t phase=( uint32_t )freq/ RESOLUTION;
 
 //uint32_t ph1=(uint32_t) (((uint64_t)freq<<24)/1600000);
 
  uint32_t ph1= (uint32_t) ( (uint64_t) ((uint32_t) (freq<<15)) /3125) ;
  
  //uint32_t ph2= (uint32_t) ( (uint32_t) ((uint32_t) (freq<<15)) /3125) ;
  //3125=5^5 5 callings of the sub. dib by 5 
  uint32_t ph2= (uint32_t) ( (uint32_t) ((uint32_t) (freq<<15))   ) ;
  for(uint8_t i1=0; i1<5;i1++){    ph2/=5 ;      }
   
  
 
fprintf(fp,"f= %d    ph=%d    ph1(64bit)=%d   ph2(32bit)=%d \n",  (int) freq, (int) phase, (int) ph1,  (int) ph2);
 
 
 
}
fclose(fp);
return 0;
}
Добавлено через 46 минут
https://www.avrfreaks.net/foru... 16a?page=1

Добавлено через 13 минут
вариант тестовой программы с делением на 5 (медленно работает)
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdint.h>
 
 #define RESOLUTION 0.095367431640625 //    1/10,48576
 #define NTICKS 10
 #define FCPU 16000000UL  //F4 2400
//  #define RESOLUTION  FCPU/NTICKS/2^24    16 777 216   (0x100 0000   1 0000 0000 0000 0000 0000 0000  ) (1<<24)
 
 //10=5*2
 //FCPU/10=FCPU/5/2=(FCPU>>1)/5
 
 //((FCPU>>1)/(5*  (1<<24))
 //((FCPU)/(10*  (1<<24)) 
 
 //2^n 2 << (n-1);
 //m-тую степень 2  n << m;
 
 //freq/ RESOLUTION
 //freq*10*(1<<24)/16000000
 //freq*10*(16777216)/16000000
 //freq*2*5*(16777216)/2*8000000           16000000
 //freq*5*(16777216)/8000000
//16000000/2^10 1 024=15625   10
 
// 2^10  --> (1<<10)
//(uint32_t) (((uint64_t)freq<<24)/(15625*(1<<10));
//(uint32_t) (((uint64_t)  freq<<(24-10))*10/(15625 );
//(uint32_t) (((uint64_t)  freq<<14 )*10/(15625 );  15625 =5^6
 
 
 
 
uint32_t  div_5( uint32_t N   )
{
int32_t Q=0;
int32_t R=(int32_t ) N; 
while(R>=0x0005){ Q++; R-=0x0005; }
//printf ("\nN=%ld R=%ld  Q=%ld  ",N,R,Q ); 
return  (uint32_t)Q;
}
 
 
 
 
 
 
 
int main(void)
{
  
FILE *fp;
char name[80];
 
 
 
if((fp=fopen("data.txt", "w")) == NULL) {printf("Cannot open directory file."); exit(1);}
 for(int i=0; i<65536;i++)
{
int freq=(uint32_t)i;
 uint32_t phase=( uint32_t )freq/ RESOLUTION;
 
 //uint32_t ph1=(uint32_t) (((uint64_t)freq<<24)/1600000);
 
  uint32_t ph1= (uint32_t) ( (uint64_t) ((uint32_t) (freq<<15)) /3125) ;
  
  //uint32_t ph2= (uint32_t) ( (uint32_t) ((uint32_t) (freq<<15)) /3125) ;
  //3125=5^5 5 callings of the sub. dib by 5 
  uint32_t ph2= (uint32_t) ( (uint32_t) ((uint32_t) (freq<<15))   ) ;
  for(uint8_t i1=0; i1<5;i1++){    ph2=div_5( ph2  ) ;      }
   
  
 
fprintf(fp,"f= %d    ph=%d    ph1(64bit)=%d   ph2(32bit)=%d \n",  (int) freq, (int) phase, (int) ph1,  (int) ph2);
 
 
 
}
fclose(fp);
return 0;
}
Добавлено через 39 минут
Еще один вариант
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdint.h>
 
 #define RESOLUTION 0.095367431640625 //    1/10,48576
 #define NTICKS 10
 #define FCPU 16000000UL  //F4 2400
//  #define RESOLUTION  FCPU/NTICKS/2^24    16 777 216   (0x100 0000   1 0000 0000 0000 0000 0000 0000  ) (1<<24)
 
 //10=5*2
 //FCPU/10=FCPU/5/2=(FCPU>>1)/5
 
 //((FCPU>>1)/(5*  (1<<24))
 //((FCPU)/(10*  (1<<24)) 
 
 //2^n     2<<(n-1)    =    1<<n;
 //m-тую степень 2  n << m;
 
 //freq/ RESOLUTION=freq *10*(2^24)/ 16000000=freq *(2^24)/ 1600000
 //freq*10*(1<<24)/16000000
 //freq*10*(16777216)/16000000
 //freq*2*5*(16777216)/2*8000000           16000000
 //freq*5*(16777216)/8000000
//16000000/2^10    (or  1024) =15625   
 
// 2^10  --> (1<<10)
//(uint32_t) (((uint64_t)freq<<24)/(15625*(1<<10));
//(uint32_t) (((uint64_t)  freq<<(24-10))*10/(15625 );
//(uint32_t) (((uint64_t)  freq<<14 )*10/(15625 );  15625 =5^6
//(uint32_t) (((uint64_t)  freq<<14 )*2*5/(15625 /5);  15625 =5^6
 
 
 
uint32_t  div_5( uint32_t N   )
{
int32_t Q=0;
int32_t R=(int32_t ) N; 
while(R>=0x00000005){ Q++; R-=0x00000005; }
//printf ("\nN=%ld R=%ld  Q=%ld  ",N,R,Q ); 
return  (uint32_t)Q;
}
 
 
 
//uint32_t  div_10( uint32_t N   )
//{
//int32_t Q=0;
//int32_t R=(int32_t ) N; 
//while(R>=10UL){ Q++; R-=10UL; }
//printf ("\nN=%ld R=%ld  Q=%ld  ",N,R,Q ); 
//return  (uint32_t)Q;
//}
 
uint32_t  div_3125( uint32_t N   )
{
int32_t Q=0;
int32_t R=(int32_t ) N; 
while(R>=0x00000C35){ Q++; R-=0x00000C35; }
//printf ("\nN=%ld R=%ld  Q=%ld  ",N,R,Q ); 
return  (uint32_t)Q;
}
 
 
int main(void)
{
  
FILE *fp;
char name[80];
 
 
 
if((fp=fopen("data.txt", "w")) == NULL) {printf("Cannot open directory file."); exit(1);}
 for(int i=0; i<65536;i++)
{
int freq=(uint32_t)i;
 uint32_t phase=( uint32_t )freq/ RESOLUTION;
 
 //uint32_t ph1=(uint32_t) (((uint64_t)freq<<24)/1600000);
 
  uint32_t ph1= (uint32_t) ( (uint64_t) ((uint32_t) (freq<<15)) /3125) ;
  
  //uint32_t ph2= (uint32_t) ( (uint32_t) ((uint32_t) (freq<<15)) /3125) ;
  //3125=5^5 5 callings of the sub. dib by 5 
    uint32_t ph2= (uint32_t) ( (uint32_t) ((uint32_t) (freq<<15))   ) ;
    ph2=div_3125( ph2  );
 
 
 //   ph2=div_5( ph2  ) ;
 //   ph2=div_5( ph2  ) ;
 //   ph2=div_5( ph2  ) ;
 //   ph2=div_5( ph2  ) ;
 //   ph2=div_5( ph2  ) ;*/
 //  for(uint8_t i1=0; i1<5;i1++){    ph2=div_5( ph2  ) ;  }
 
 
 
fprintf(fp,"f= %d    ph=%d    ph1(64bit)=%d   ph2(32bit)=%d \n",  (int) freq, (int) phase, (int) ph1,  (int) ph2);
 
 
 
}
fclose(fp);
return 0;
}
Добавлено через 1 час 31 минуту
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
void delay1s(void){ uint8_t i; for(i=0; i<100; i++){ _delay_ms(10); } }
 
//initialize Timer2 (used for button reading)
void Timer2_Init(void)
{
    TCNT2=0x00;
    sei();
} 
//start timer2
void Timer2_Start(void)
{
    TCCR2|=(1<<CS22)|(1<<CS21); //prescaller 256 ~122 interrupts/s
    //TIMSK|=(1<<TOV2);//Enable Timer2 Overflow interrupts
                  
    TIMSK |=  (1<<TOIE2);//Enable Timer2 Overflow interrupts
                  //   TIFR|=(1<<TOV2);//Enable Timer2 Overflow interrupts  
}
//stop timer 2
void Timer2_Stop(void)
{
 
 
        TIMSK &= ~(1<< TOIE2); //Disable Timer2 Overflow interrupts
    TCCR2&=~((1<<CS22)|(1<<CS21)); //Stop timer0
        
    //TIMSK&=~(1<<TOV2);//Disable Timer2 Overflow interrupts?
                         
         //TIFR|=(1<<TOV2);//Disable Timer2 Overflow interrupts
 
}
 
 
 
uint32_t  div_5( uint32_t N   )
{
int32_t Q=0;
int32_t R=(int32_t ) N; 
while(R>=0x00000005){ Q++; R-=0x00000005; }
return  (uint32_t)Q;
}
/*
uint32_t  div_3125( uint32_t N   )
{
int32_t Q=0;
int32_t R=(int32_t ) N; 
while(R>=0x00000C35){ Q++; R-=0x00000C35; }
return  (uint32_t)Q;
}
*/
 
void UpdateACC(void)
{
 
   //SG.acc=   SG.freq /RESOLUTION; 
SG.acc=  (uint32_t) ( (uint32_t) ((uint32_t) (SG.freq <<15))   ) ; 
//SG.acc=div_3125( SG.acc );
uint8_t i1;
for( i1=0; i1<5; i1++ ){    SG.acc=div_5( SG.acc  ) ;  }
 
 
 return;    
}
Добавлено через 1 минуту
VMLAB ,WinAVR плохо справляются с отладкой при PROGMEM .

Добавлено через 1 час 44 минуты
В Windows 10 плохо билдится с секциями
C++
1
2
3
4
5
6
const uint8_t squarewave[]  PROGMEM= 
//const uint8_t squarewave[] __attribute__ ((section ("MySection2")))/* PROGMEM*/= 
//const uint8_t squarewave[] __attribute__ ((section (".MySection2")))/* PROGMEM*/= 
{
...
}
если задать с адресов 0x01A0,0x01B0, 0x01C0, 0x01E0,0x01F0 по 256 байт (и с точкой1 и без ).

Добавлено через 1 минуту
С PROGMEM что-то получается, но в последнее время (после сервис-паков и обновлений винды ) стало глючить.

Добавлено через 1 минуту
Код
rm -rf main.o  proj1.elf dep/* proj1.hex proj1.eep proj1.lss proj1.map
Build succeeded with 0 Warnings...
avr-gcc  -mmcu=atmega8 -Wall -gdwarf-2 -std=gnu99                 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT main.o -MF dep/main.o.d  -c  ../main.c
avr-gcc -mmcu=atmega8 -Wl,-Map=proj1.map -Wl,-section-start=MySection1=0x3400 -Wl,-section-start=MySection2=0x3600 -Wl,-section-start=.MySection3=0x3800 -Wl,-section-start=.MySection4=0x3a00 -Wl,-section-start=.MySection5=0x3c00 -Wl,-section-start=.MySec
tion6=0x3e00 main.o     -o proj1.elf

avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature  proj1.elf proj1.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex proj1.elf proj1.eep || exit 0
avr-objdump -h -S proj1.elf > proj1.lss
выдает но не размещает правильно в файле прошивки.

Добавлено через 1 минуту
Код
rm -rf main.o  proj1.elf dep/* proj1.hex proj1.eep proj1.lss proj1.map
Build succeeded with 0 Warnings...
avr-gcc  -mmcu=atmega8 -Wall -gdwarf-2 -std=gnu99 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT main.o -MF dep/main.o.d  -c  ../main.c
avr-gcc -mmcu=atmega8 -Wl,-Map=main.map main.o     -o main.elf
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature  main.elf main.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex main.elf main.eep || exit 0
avr-objdump -h -S main.elf > main.lss

AVR Memory Usage
----------------
Device: atmega8

Program:    6748 bytes (82.4% Full)
(.text + .data + .bootloader)

Data:         99 bytes (9.7% Full)
(.data + .bss + .noinit)
для PROGMEM, но ,кажется, сбоит по выборке из на массивов
0
3 / 3 / 0
Регистрация: 29.06.2018
Сообщений: 1,249
07.06.2021, 11:15  [ТС] 14
В WinAVR с внешним батником стало компилироваться с секциями , но там баги
0
Вложения
Тип файла: zip example_bat.zip (174.7 Кб, 0 просмотров)
3 / 3 / 0
Регистрация: 29.06.2018
Сообщений: 1,249
07.06.2021, 11:24  [ТС] 15
но с
Код
path C:\WinAVR-20100110\bin;%path%


  rm -rf main.o  proj1.elf   proj1.hex proj1.eep proj1.lss proj1.map

avr-gcc  -mmcu=atmega8 -Wall -gdwarf-2 -std=gnu99                 -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT main.o -MF  main.o.d  -c   main.c
avr-gcc -mmcu=atmega8 -Wl,-Map=proj1.map -Wl,-section-start=MySection1=0x1A00 -Wl,-section-start=MySection2=0x1B00 -Wl,-section-start=MySection3=0x1C00 -Wl,-section-start=MySection4=0x1D00 -Wl,-section-start=MySection5=0x1E00 -Wl,-section-start=MySection6=0x1F00 main.o     -o proj1.elf

avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature  proj1.elf proj1.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex proj1.elf proj1.eep || exit 0
avr-objdump -h -S proj1.elf > proj1.lss
pause 0
размещается правильно (не удваивать адрес).

Добавлено через 2 минуты
А в 4-й "студии" удваивается адрес в сравнении с окном .
В программаторе avrdudeshell.exe последний адрес флэшки программ 0x1FFF
0
Вложения
Тип файла: zip testhexmapping.zip (178.8 Кб, 0 просмотров)
3 / 3 / 0
Регистрация: 29.06.2018
Сообщений: 1,249
07.06.2021, 11:50  [ТС] 16
Пример компиляции проекта простого генератора функций с секцией на порт D ,Atmega8A, 16MHz (WinAVR)
0
Вложения
Тип файла: zip genfun.zip (7.5 Кб, 0 просмотров)
3 / 3 / 0
Регистрация: 29.06.2018
Сообщений: 1,249
07.06.2021, 18:46  [ТС] 17
С предустановками
Код
Flash MySection1 0xd00 (01A00/2)
Flash MySection1 0xd80 (01B00/2)
Flash MySection1 0xe00 (01C00/2)
Flash MySection1 0xe80 (01D00/2)
Flash MySection1 0xf00 (01D00/2)
Flash MySection1 0xf80 (01D00/2)
с тулчейном дает
Код
rm -rf main.o  proj1.elf dep/* proj1.hex proj1.eep proj1.lss proj1.map
Build succeeded with 0 Warnings...
avr-gcc  -mmcu=atmega8 -Wall -gdwarf-2 -std=gnu99                                             -DF_CPU=16000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT main.o -MF dep/main.o.d  -c  ../main.c
avr-gcc -mmcu=atmega8 -Wl,-Map=proj1.map -Wl,-section-start=MySection1=0x1a00 -Wl,-section-start=MySection2=0x1b00 -Wl,-section-start=MySection3=0x1c00 -Wl,-section-start=MySection4=0x1d00 -Wl,-section-start=MySection5=0x1e00 -Wl,-section-start=MySection6=
0x1f00 main.o     -o proj1.elf

avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature  proj1.elf proj1.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O ihex proj1.elf proj1.eep || exit 0
avr-objdump -h -S proj1.elf > proj1.lss

AVR Memory Usage
----------------
Device: atmega8

Program:    5108 bytes (62.4% Full)
(.text + .data + .bootloader)

Data:         99 bytes (9.7% Full)
(.data + .bss + .noinit)


Build succeeded with 0 Warnings...
Добавлено через 1 час 12 минут
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
uint32_t  div_3125( uint32_t N   )
{
int32_t Q=0;
int32_t R=(int32_t ) N; 
while(R>=0x0C35){ Q++; R-=0x0C35; }
return  (uint32_t)Q;
}
 
 
void UpdateACC(void)
{
 //SG.acc=(uint32_t) ((  float)  SG.freq * (  float) 10.48576);
  // SG.acc=(uint32_t)   SG.freq /RESOLUTION;
    SG.acc=  (uint32_t) ( (uint32_t) ((uint32_t) (SG.freq <<15))   ) ; 
SG.acc=div_3125( SG.acc );
//uint8_t i1;
// for( i1=0; i1<5; i1++ ){    SG.acc=div_5( SG.acc  ) ;  }
 
 return;    
}
может работать быстрее чем с делением на 5

Добавлено через 2 часа 24 минуты
Проба с и таймером 0 (редко опрос кнопок вместо Int0, как использовать nSS для остановки генерации на инлайновом коде )) и 2 (перепрограммируется в режиме ШИМ) и битом 6 регистра SREG
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
 
 
 ...
 
void delay1s(void){ uint8_t i; for(i=0; i<100; i++){ _delay_ms(10); } }
 
//initialize Timer2 (used for button reading)
void Timer2_Init(void)
{
    TCNT2=0x00;
    sei();
} 
//start timer2
void Timer2_Start(void)
{
TCCR2|=(1<<CS22)|(1<<CS21)|(1<<CS20); //prescaller 256 ~122 interrupts/s    
TIMSK |=  (1<<TOIE2);//Enable Timer2 Overflow interrupts
// TIFR|=(1<<TOV2);//Enable Timer2 Overflow interrupts  
}
//stop timer 2
void Timer2_Stop(void)
{
TIMSK &= ~(1<< TOIE2); //Disable Timer2 Overflow interrupts
TCCR2&=~((1<<CS22)|(1<<CS21)|(1<<CS20)); //Stop timer0
//TIFR|=(1<<TOV2);//Disable Timer2 Overflow interrupts
 
}
 
 
 /*
uint32_t  div_5( uint32_t N   )
{
int32_t Q=0;
int32_t R=(int32_t ) N; 
while(R>=5){ Q++; R-=5; }
return  (uint32_t)Q;
}
*/
uint32_t  div_3125( uint32_t N   )
{
int32_t Q=0;
int32_t R=(int32_t ) N; 
while(R>=0x0C35){ Q++; R-=0x0C35; }
return  (uint32_t)Q;
}
 
 
void UpdateACC(void)
{
 //SG.acc=(uint32_t) ((  float)  SG.freq * (  float) 10.48576);
  // SG.acc=(uint32_t)   SG.freq /RESOLUTION;
    SG.acc=  (uint32_t) ( (uint32_t) ((uint32_t) (SG.freq <<15))   ) ; 
SG.acc=div_3125( SG.acc );
//uint8_t i1;
// for( i1=0; i1<5; i1++ ){    SG.acc=div_5( SG.acc  ) ;  }
 
 return;    
}
 
/*Initial menu show initial signal and frequency generator is off*/
void Menu_Update(uint8_t on)
{
    LCDclr();
    CopyStringtoLCD(  MENU[(SG.mode)], 0, 0 );
    LCDGotoXY(0, 1);
    if (SG.mode==6){ CopyStringtoLCD(CLR, 0, 1 ); LCDGotoXY(0, 1); printf("    %5uHz", (uint16_t)SG.deltafreq); }
    if (SG.mode==7){ CopyStringtoLCD(CLR, 0, 1 ); CopyStringtoLCD(RND, 0, 1 ); }
    if (SG.mode==8){ CopyStringtoLCD(CLR, 0, 1 ); LCDGotoXY(0, 1); printf(" %5uMHz", SG.HSfreq); }
    if((SG.mode==0)||(SG.mode==1)||(SG.mode==2)||(SG.mode==3)||(SG.mode==4)||(SG.mode==5))
        { CopyStringtoLCD(CLR, 0, 1 ); LCDGotoXY(0, 1); printf(" %5uHz", (uint16_t)SG.freq); }
    if (SG.mode!=6){ if(on==1) CopyStringtoLCD(MNON, 13, 1 );  else CopyStringtoLCD(MNOFF, 13, 1 ); }
}
 
/*update frequency value on LCD menu - more smooth display*/
void Freq_Update(void)
{
if (SG.mode==6){ LCDGotoXY(0, 1); printf("    %5uHz", (uint16_t)SG.deltafreq);}
if (SG.mode==8){ LCDGotoXY(0, 1); printf(" %5uMHz", SG.HSfreq); } //if HS signal
if((SG.mode==0)||(SG.mode==1)||(SG.mode==2)||(SG.mode==3)||(SG.mode==4)||(SG.mode==5))
  { LCDGotoXY(0, 1);printf(" %5uHz", (uint16_t)SG.freq);}
}
 
 
/*External interrupt0 service routine used to stop DDS depending on active menuany generator is stopped by setting flag value to 0
DDs generator which is inline ASM is stopped by setting */
/* CPHA bit in SPCR register */
 
 
 
 
 
 
 
ISR(INT0_vect)
{
 
SG.flag=0;   /* set flag to stop generator */
SPCR|=(1<<CPHA);/* using CPHA bit as stop mark */
 
//CopyStringtoLCD(MNOFF, 13, 1 );
SG.ON=0;/* set off in LCD menu */
SREG|=(_BV(6));
loop_until_bit_is_set(BPIN, START);//wait for button release
return;
}
 
//TIMSK =(1<<TOIE0);  // timer0 enable
//TCCR0 = (1<<CS02) | (1<<CS00); // prescaler 1/1024
  
void CheckButtonStop()
 
{
  if (bit_is_clear(BPIN, START))  { TIMSK &=~(1<<TOIE0);
  if (SG.flag==1){ SG.flag=0; SPCR|=(1<<CPHA);     SG.ON=0; SREG|=(_BV(6));  
   loop_until_bit_is_set(BPIN, START);   } 
 }
 
 
}
 
ISR(TIMER0_OVF_vect)
{
CheckButtonStop();
return;
}
 
 
 
/* timer overflow interrupt service tourine  checks all button status and if button is pressed
value is updated */
 
 
 
void CheckButtons(void)
{
/*Button UP increments value which selects previous signal mode if first mode is reached - jumps to last */
if (bit_is_clear(BPIN, UP)){ if (SG.mode==0){ SG.mode=MN_No-1;} else { SG.mode--; } 
                 Menu_Update(SG.ON); //Display menu item
    loop_until_bit_is_set(BPIN, UP); return; }
/*Button Down decrements value which selects next signal mode if last mode is reached - jumps to first*/
 
if ( bit_is_clear(BPIN, DOWN) ){
    if (SG.mode<(MN_No-1)) { SG.mode++; } else{ SG.mode=0; } //Display menu item
    Menu_Update(SG.ON);
    loop_until_bit_is_set(BPIN, DOWN); return;}
 
//frequency increment   
if (bit_is_clear(BPIN, RIGHT)){
    if(SG.mode==6){ if(SG.deltafreq==10000) { SG.deltafreq=1; } else {SG.deltafreq=(SG.deltafreq*10); }
            Freq_Update();
            loop_until_bit_is_set(BPIN, RIGHT); }
                    //ifhigh speed signal
     if (SG.mode==8){ if(SG.HSfreq==8) { SG.HSfreq=1; } else { SG.HSfreq=(SG.HSfreq<<1); }
            Freq_Update();
            loop_until_bit_is_set(BPIN, RIGHT); }
     if((SG.mode==0)||(SG.mode==1)||(SG.mode==2)||(SG.mode==3)||(SG.mode==4)||(SG.mode==5)){
            if ((0xFFFF-SG.freq)>=SG.deltafreq) SG.freq+=SG.deltafreq;
            Freq_Update();
            //uint8_t ii=0;
            //press button and wait for long press (~0.5s)
                          // do{ _delay_ms(2); ii++; } while((bit_is_clear(BPIN, RIGHT))&&(ii<=250));//wait for button release
                          //  if(ii>=250){
                                                      //    do{ if ((0xFFFF-SG.freq)>=SG.deltafreq) { SG.freq+=SG.deltafreq; } Freq_Update();} 
                                                      //   while(bit_is_clear(BPIN, RIGHT));  }   //wait for button release
                
       }   return; }
 
//frequency decrement
if (bit_is_clear(BPIN, LEFT)){
    if(SG.mode==6){ if(SG.deltafreq==1) {SG.deltafreq=10000; } else {SG.deltafreq=(SG.deltafreq/10);}
            Freq_Update(); loop_until_bit_is_set(BPIN, LEFT); }
                  //ifhigh speed signal
    if (SG.mode==8){ if(SG.HSfreq==1) { SG.HSfreq=8;} else {SG.HSfreq=(SG.HSfreq>>1) ;} 
            Freq_Update(); loop_until_bit_is_set(BPIN, LEFT); }
     if ((SG.mode==0)||(SG.mode==1)||(SG.mode==2)||(SG.mode==3)||(SG.mode==4)||(SG.mode==5)){
        if (SG.freq>=SG.deltafreq) SG.freq-=SG.deltafreq;
                Freq_Update();
            //  uint8_t ii=0;
                /* press button and wait for long press (~0.5s) */
            //  do{ _delay_ms(2); ii++; } while((bit_is_clear(BPIN, LEFT))&&(ii<=250));/* wait for button release */
            //  if(ii>=250){ do{ if (SG.freq>=SG.deltafreq) {SG.freq-=SG.deltafreq;} Freq_Update();
                                                                        //} while(bit_is_clear(BPIN, LEFT)); }/*wait for button release*/
                 
            } return ;}
 
 
if (bit_is_clear(BPIN, START)) {
     if(SG.mode!=6){
        /*saving last configuration*/
        SG.fr1=(uint8_t)(SG.freq);
        SG.fr2=(uint8_t)(SG.freq>>8);
        SG.fr3=(uint8_t)(SG.freq>>16);
     
        //Calculate frequency value from restored EEPROM values
        SG.freq=(((uint32_t)(SG.fr3)<<16)|((uint32_t)(SG.fr2)<<8)|((uint32_t)(SG.fr1)));
        //calculate accumulator value
     UpdateACC();
                   // #define RES  ((16000000/9/0x1000000)*0x10000)  
                  //SG.acc=((uint64_t)SG.freq << 16) / RES;
 
    //#define RES1 (F_CPU/NUM_CYCLES/2/0x100)
    
    //SG.acc=((uint64_t)SG.freq << 16) / RES1;
                   //SG.acc=  SG.freq/ RESOLUTION   ; //warning
     //  SG.acc=  (uint32_t)( SG.freq/ RESOLUTION)    ; //warning
                                   //   SG.acc= (uint32_t)SG.freq* 10.48576;  
 
         SG.flag=1; //set flag to start generator
         SG.ON=1; //set ON on LCD menu
         SPCR&=~(1<<CPHA); //clear CPHA bit in SPCR register to allow DDS
         SREG&=~(_BV(6));  
        //Stop timer2 - menu inactive
         Timer2_Stop();
         
        //display ON on LCD
         Menu_Update(SG.ON);
            
             }
    loop_until_bit_is_set(BPIN, START);  //wait for button release
    TIMSK|=(1<<TOIE0);
 
    return;
    }
 
 
 
}
 
 
 
 
ISR(TIMER2_OVF_vect)
{
CheckButtons();
return;
}
 
 
/*DDS signal generation function
Original idea is taken from
http://www.myplace.nu/avr/minidds/index.htm
small modification is made - added additional command which
checks if CPHA bit is set in SPCR register if yes - exit function  //SREG,6(T)
*/
 
 
 
void static inline Signal_OUT(const uint8_t *signal, uint8_t ad2, uint8_t ad1, uint8_t ad0)
{ 
asm volatile(   "eor r18, r18   ;r18<-0"    "\n\t"
                "eor r19, r19   ;r19<-0"    "\n\t"
                "1:"                        "\n\t"
                "add r18, %0    ;1 cycle"           "\n\t"
                "adc r19, %1    ;1 cycle"           "\n\t"  
                "adc %A3, %2    ;1 cycle"           "\n\t"
                "lpm            ;3 cycles"  "\n\t"
                "out %4, __tmp_reg__    ;1 cycle"   "\n\t"
                "sbis %5, 2     ;1 cycle if no skip skip if  SPCR.CPHA" "\n\t"    
                "rjmp 1b        ;2 cycles. Total 10 cycles" "\n\t"
                :
                :"r" (ad0),"r" (ad1),"r" (ad2),"e" (signal),"I" (_SFR_IO_ADDR(PORTD)), "I" (_SFR_IO_ADDR(SPCR))
                :"r18", "r19" 
    ); 
}
 
 
 
/*
void static inline Signal_OUT(const uint8_t *signal, uint8_t ad2, uint8_t ad1, uint8_t ad0)
{ 
asm volatile(   "eor r18, r18   ;r18<-0"    "\n\t"
                "eor r19, r19   ;r19<-0"    "\n\t"
                "1:"                        "\n\t"
                "add r18, %0    ;1 cycle"           "\n\t"
                "adc r19, %1    ;1 cycle"           "\n\t"  
                "adc %A3, %2    ;1 cycle"           "\n\t"
                "lpm            ;3 cycles"  "\n\t"
                "out %4, __tmp_reg__    ;1 cycle"   "\n\t"
                "sbis %5, 6     ;1 cycle if no skip skip if  SPCR.CPHA" "\n\t"    
                "rjmp 1b        ;2 cycles. Total 10 cycles" "\n\t"
                :
                :"r" (ad0),"r" (ad1),"r" (ad2),"e" (signal),"I" (_SFR_IO_ADDR(PORTD)), "I" (_SFR_IO_ADDR(SREG))
                :"r18", "r19" 
    ); 
}
 
 
 
*/
 
void Timer1_Start(uint8_t FMHz)
{
    if(FMHz==1){ OCR1A=7; } else  //start high speed (1MHz) signal
    if(FMHz==2){ OCR1A=3; } else //2MHz
    if(FMHz==4){ OCR1A=1; } else //4MHz     
    if(FMHz==8){ OCR1A=0; } else //8MHz 
        OCR1A=7;//default 1MHz
    
    //Output compare toggles OC1A pin
    TCCR1A=0x40;
    //start timer without prescaler
    TCCR1B=0b00001001;
}
void Timer1_Stop(void){ TCCR1B=0x00; }//timer off
 
 
 
void Main_Init(void)
{
//stderr = &lcd_str;
stdout = &lcd_str;
//--------init LCD----------
LCDinit();
LCDclr();
LCDcursorOFF();
 
CopyStringtoLCD(welcomeln1, 3, 0);
CopyStringtoLCD(welcomeln1, 3, 1);
 _delay_ms(50);
 
 
 
 
 
 
SG.mode=0x00; //eeprom_read_byte((uint8_t*)EEMODE);
SG.fr1=0xE8;//eeprom_read_byte((uint8_t*)EEFREQ1);
SG.fr2=0x03;//eeprom_read_byte((uint8_t*)EEFREQ2);
SG.fr3=0x00;//eeprom_read_byte((uint8_t*)EEFREQ3);
SG.freq=(((uint32_t)(SG.fr3)<<16)|((uint32_t)(SG.fr2)<<8)|((uint32_t)(SG.fr1)));
 
UpdateACC();
               //SG.acc= (uint32_t) ( SG.freq* 10.48576); 
               //SG.acc= (uint32_t) SG.freq/RESOLUTION    ; //warning  RESOLUTION= 0.095367431640625 
               //SG.acc=   SG.freq/RESOLUTION    ; //fix ***********************
SG.flag=0;
//default 1MHz HS signal freq
SG.HSfreq=1;
SG.deltafreq=100;
//------------init DDS output-----------
R2RPORT=0x00;//set initial zero values
R2RDDR=0xFF;//set A port as output
//-------------set ports pins for buttons----------
BDDR&=~(_BV(START)|_BV(UP)|_BV(DOWN)|_BV(RIGHT)|_BV(LEFT));
BPORT|=(_BV(START)|_BV(UP)|_BV(DOWN)|_BV(RIGHT)|_BV(LEFT));
//---------set ports pins for HS output---------
HSDDR|=_BV(HS);//configure as output
//-----------Menu init--------------
SG.ON=0;//default signal is off
 
//return;
Menu_Update(SG.ON);
//-----------Timer Init-------------
Timer2_Init();
//Start Timer with overflow interrupts
Timer2_Start();
}
 
 
 
 
 
 
//const uint8_t welcomeln1[] PROGMEM ="AVR LCD DEMO\0";
int main(void)
{
//Initialize
Main_Init();
     
//GICR |= (1<<INT0);  
 
TCCR0 = (1<<CS02) | (1<<CS00);
TIMSK&=~(1<<TOIE0);
while(1)  {
 
 
 
 
    if (SG.flag==1)
        {  //fix 
 
 
        //GICR|=(1<<INT0);//set external interrupt to enable stop
        if (SG.mode==7)
            {
            //Noise
            do { R2RPORT=rand();} while(SG.flag==1);
            //set signal level to 0
            R2RPORT=0x00;
            //display generator OFF
            Menu_Update(SG.ON);
            //stop external interrupt
            GICR&=~(1<<INT0);
            TIMSK&=~(1<<TOIE0);     
 
            //start timer menu active
            Timer2_Start();
            }
        else if (SG.mode==6)
            {
            //freq step
            while((SG.flag==1))
            {
            //not implemented
            CopyStringtoLCD(NA, 0, 1 );
            }
            //set signal level to 0
            R2RPORT=0x00;
            //display generator OFF
            Menu_Update(SG.ON); 
            GICR&=~(1<<INT0);//|(1<<INT1);//stop external interrupt
            TIMSK&=~(1<<TOIE0);
            //start timer menu active
            Timer2_Start();
            }
 
        else if (SG.mode==8)
            {
            //High speed signal
            Timer1_Start(SG.HSfreq);
            while((SG.flag==1)) { CopyStringtoLCD(MNON, 13, 1 ); }//not implemented
            Timer1_Stop();//timer off
            //set HS pin to LOW
            HSPORT&=~(1<<HS);
            //display generator OFF
            Menu_Update(SG.ON); 
            GICR&=~(1<<INT0);//|(1<<INT1);//stop external interrupt
             TIMSK&=~(1<<TOIE0);
            //start timer menu active
            Timer2_Start();
            }
        else
            {
            //start DDS
            SREG|=(_BV(6));
            Signal_OUT(  SIGNALS[SG.mode], (uint8_t) ((uint32_t) SG.acc>>16), (uint8_t)((uint32_t) SG.acc>>8),(uint8_t)SG.acc);
            //set signal level to 0
            R2RPORT=0x00;
            //display generator OFF
            Menu_Update(SG.ON);
            GICR&=~(1<<INT0);//|(1<<INT1);
            TIMSK&=~(1<<TOIE0);
                                                      //stop external interrupt
            //start timer menu active
            Timer2_Start();
            }
        }
 
 
//CheckButtons();
 
    }
return 0;    
}
0
3 / 3 / 0
Регистрация: 29.06.2018
Сообщений: 1,249
07.06.2021, 18:47  [ТС] 18
Проба с и таймером 0 (редко опрос кнопок вместо Int0, как использовать nSS для остановки генерации на инлайновом коде )) и 2 (перепрограммируется в режиме ШИМ) и битом 6 регистра SREG
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
 
 
 ...
 
void delay1s(void){ uint8_t i; for(i=0; i<100; i++){ _delay_ms(10); } }
 
//initialize Timer2 (used for button reading)
void Timer2_Init(void)
{
    TCNT2=0x00;
    sei();
} 
//start timer2
void Timer2_Start(void)
{
TCCR2|=(1<<CS22)|(1<<CS21)|(1<<CS20); //prescaller 256 ~122 interrupts/s    
TIMSK |=  (1<<TOIE2);//Enable Timer2 Overflow interrupts
// TIFR|=(1<<TOV2);//Enable Timer2 Overflow interrupts  
}
//stop timer 2
void Timer2_Stop(void)
{
TIMSK &= ~(1<< TOIE2); //Disable Timer2 Overflow interrupts
TCCR2&=~((1<<CS22)|(1<<CS21)|(1<<CS20)); //Stop timer0
//TIFR|=(1<<TOV2);//Disable Timer2 Overflow interrupts
 
}
 
 
 /*
uint32_t  div_5( uint32_t N   )
{
int32_t Q=0;
int32_t R=(int32_t ) N; 
while(R>=5){ Q++; R-=5; }
return  (uint32_t)Q;
}
*/
uint32_t  div_3125( uint32_t N   )
{
int32_t Q=0;
int32_t R=(int32_t ) N; 
while(R>=0x0C35){ Q++; R-=0x0C35; }
return  (uint32_t)Q;
}
 
 
void UpdateACC(void)
{
 //SG.acc=(uint32_t) ((  float)  SG.freq * (  float) 10.48576);
  // SG.acc=(uint32_t)   SG.freq /RESOLUTION;
    SG.acc=  (uint32_t) ( (uint32_t) ((uint32_t) (SG.freq <<15))   ) ; 
SG.acc=div_3125( SG.acc );
//uint8_t i1;
// for( i1=0; i1<5; i1++ ){    SG.acc=div_5( SG.acc  ) ;  }
 
 return;    
}
 
/*Initial menu show initial signal and frequency generator is off*/
void Menu_Update(uint8_t on)
{
    LCDclr();
    CopyStringtoLCD(  MENU[(SG.mode)], 0, 0 );
    LCDGotoXY(0, 1);
    if (SG.mode==6){ CopyStringtoLCD(CLR, 0, 1 ); LCDGotoXY(0, 1); printf("    %5uHz", (uint16_t)SG.deltafreq); }
    if (SG.mode==7){ CopyStringtoLCD(CLR, 0, 1 ); CopyStringtoLCD(RND, 0, 1 ); }
    if (SG.mode==8){ CopyStringtoLCD(CLR, 0, 1 ); LCDGotoXY(0, 1); printf(" %5uMHz", SG.HSfreq); }
    if((SG.mode==0)||(SG.mode==1)||(SG.mode==2)||(SG.mode==3)||(SG.mode==4)||(SG.mode==5))
        { CopyStringtoLCD(CLR, 0, 1 ); LCDGotoXY(0, 1); printf(" %5uHz", (uint16_t)SG.freq); }
    if (SG.mode!=6){ if(on==1) CopyStringtoLCD(MNON, 13, 1 );  else CopyStringtoLCD(MNOFF, 13, 1 ); }
}
 
/*update frequency value on LCD menu - more smooth display*/
void Freq_Update(void)
{
if (SG.mode==6){ LCDGotoXY(0, 1); printf("    %5uHz", (uint16_t)SG.deltafreq);}
if (SG.mode==8){ LCDGotoXY(0, 1); printf(" %5uMHz", SG.HSfreq); } //if HS signal
if((SG.mode==0)||(SG.mode==1)||(SG.mode==2)||(SG.mode==3)||(SG.mode==4)||(SG.mode==5))
  { LCDGotoXY(0, 1);printf(" %5uHz", (uint16_t)SG.freq);}
}
 
 
/*External interrupt0 service routine used to stop DDS depending on active menuany generator is stopped by setting flag value to 0
DDs generator which is inline ASM is stopped by setting */
/* CPHA bit in SPCR register */
 
 
 
 
 
 
 
ISR(INT0_vect)
{
 
SG.flag=0;   /* set flag to stop generator */
SPCR|=(1<<CPHA);/* using CPHA bit as stop mark */
 
//CopyStringtoLCD(MNOFF, 13, 1 );
SG.ON=0;/* set off in LCD menu */
SREG|=(_BV(6));
loop_until_bit_is_set(BPIN, START);//wait for button release
return;
}
 
//TIMSK =(1<<TOIE0);  // timer0 enable
//TCCR0 = (1<<CS02) | (1<<CS00); // prescaler 1/1024
  
void CheckButtonStop()
 
{
  if (bit_is_clear(BPIN, START))  { TIMSK &=~(1<<TOIE0);
  if (SG.flag==1){ SG.flag=0; SPCR|=(1<<CPHA);     SG.ON=0; SREG|=(_BV(6));  
   loop_until_bit_is_set(BPIN, START);   } 
 }
 
 
}
 
ISR(TIMER0_OVF_vect)
{
CheckButtonStop();
return;
}
 
 
 
/* timer overflow interrupt service tourine  checks all button status and if button is pressed
value is updated */
 
 
 
void CheckButtons(void)
{
/*Button UP increments value which selects previous signal mode if first mode is reached - jumps to last */
if (bit_is_clear(BPIN, UP)){ if (SG.mode==0){ SG.mode=MN_No-1;} else { SG.mode--; } 
                 Menu_Update(SG.ON); //Display menu item
    loop_until_bit_is_set(BPIN, UP); return; }
/*Button Down decrements value which selects next signal mode if last mode is reached - jumps to first*/
 
if ( bit_is_clear(BPIN, DOWN) ){
    if (SG.mode<(MN_No-1)) { SG.mode++; } else{ SG.mode=0; } //Display menu item
    Menu_Update(SG.ON);
    loop_until_bit_is_set(BPIN, DOWN); return;}
 
//frequency increment   
if (bit_is_clear(BPIN, RIGHT)){
    if(SG.mode==6){ if(SG.deltafreq==10000) { SG.deltafreq=1; } else {SG.deltafreq=(SG.deltafreq*10); }
            Freq_Update();
            loop_until_bit_is_set(BPIN, RIGHT); }
                    //ifhigh speed signal
     if (SG.mode==8){ if(SG.HSfreq==8) { SG.HSfreq=1; } else { SG.HSfreq=(SG.HSfreq<<1); }
            Freq_Update();
            loop_until_bit_is_set(BPIN, RIGHT); }
     if((SG.mode==0)||(SG.mode==1)||(SG.mode==2)||(SG.mode==3)||(SG.mode==4)||(SG.mode==5)){
            if ((0xFFFF-SG.freq)>=SG.deltafreq) SG.freq+=SG.deltafreq;
            Freq_Update();
            //uint8_t ii=0;
            //press button and wait for long press (~0.5s)
                          // do{ _delay_ms(2); ii++; } while((bit_is_clear(BPIN, RIGHT))&&(ii<=250));//wait for button release
                          //  if(ii>=250){
                                                      //    do{ if ((0xFFFF-SG.freq)>=SG.deltafreq) { SG.freq+=SG.deltafreq; } Freq_Update();} 
                                                      //   while(bit_is_clear(BPIN, RIGHT));  }   //wait for button release
                
       }   return; }
 
//frequency decrement
if (bit_is_clear(BPIN, LEFT)){
    if(SG.mode==6){ if(SG.deltafreq==1) {SG.deltafreq=10000; } else {SG.deltafreq=(SG.deltafreq/10);}
            Freq_Update(); loop_until_bit_is_set(BPIN, LEFT); }
                  //ifhigh speed signal
    if (SG.mode==8){ if(SG.HSfreq==1) { SG.HSfreq=8;} else {SG.HSfreq=(SG.HSfreq>>1) ;} 
            Freq_Update(); loop_until_bit_is_set(BPIN, LEFT); }
     if ((SG.mode==0)||(SG.mode==1)||(SG.mode==2)||(SG.mode==3)||(SG.mode==4)||(SG.mode==5)){
        if (SG.freq>=SG.deltafreq) SG.freq-=SG.deltafreq;
                Freq_Update();
            //  uint8_t ii=0;
                /* press button and wait for long press (~0.5s) */
            //  do{ _delay_ms(2); ii++; } while((bit_is_clear(BPIN, LEFT))&&(ii<=250));/* wait for button release */
            //  if(ii>=250){ do{ if (SG.freq>=SG.deltafreq) {SG.freq-=SG.deltafreq;} Freq_Update();
                                                                        //} while(bit_is_clear(BPIN, LEFT)); }/*wait for button release*/
                 
            } return ;}
 
 
if (bit_is_clear(BPIN, START)) {
     if(SG.mode!=6){
        /*saving last configuration*/
        SG.fr1=(uint8_t)(SG.freq);
        SG.fr2=(uint8_t)(SG.freq>>8);
        SG.fr3=(uint8_t)(SG.freq>>16);
     
        //Calculate frequency value from restored EEPROM values
        SG.freq=(((uint32_t)(SG.fr3)<<16)|((uint32_t)(SG.fr2)<<8)|((uint32_t)(SG.fr1)));
        //calculate accumulator value
     UpdateACC();
                   // #define RES  ((16000000/9/0x1000000)*0x10000)  
                  //SG.acc=((uint64_t)SG.freq << 16) / RES;
 
    //#define RES1 (F_CPU/NUM_CYCLES/2/0x100)
    
    //SG.acc=((uint64_t)SG.freq << 16) / RES1;
                   //SG.acc=  SG.freq/ RESOLUTION   ; //warning
     //  SG.acc=  (uint32_t)( SG.freq/ RESOLUTION)    ; //warning
                                   //   SG.acc= (uint32_t)SG.freq* 10.48576;  
 
         SG.flag=1; //set flag to start generator
         SG.ON=1; //set ON on LCD menu
         SPCR&=~(1<<CPHA); //clear CPHA bit in SPCR register to allow DDS
         SREG&=~(_BV(6));  
        //Stop timer2 - menu inactive
         Timer2_Stop();
         
        //display ON on LCD
         Menu_Update(SG.ON);
            
             }
    loop_until_bit_is_set(BPIN, START);  //wait for button release
    TIMSK|=(1<<TOIE0);
 
    return;
    }
 
 
 
}
 
 
 
 
ISR(TIMER2_OVF_vect)
{
CheckButtons();
return;
}
 
 
/*DDS signal generation function
Original idea is taken from
http://www.myplace.nu/avr/minidds/index.htm
small modification is made - added additional command which
checks if CPHA bit is set in SPCR register if yes - exit function  //SREG,6(T)
*/
 
 
 
void static inline Signal_OUT(const uint8_t *signal, uint8_t ad2, uint8_t ad1, uint8_t ad0)
{ 
asm volatile(   "eor r18, r18   ;r18<-0"    "\n\t"
                "eor r19, r19   ;r19<-0"    "\n\t"
                "1:"                        "\n\t"
                "add r18, %0    ;1 cycle"           "\n\t"
                "adc r19, %1    ;1 cycle"           "\n\t"  
                "adc %A3, %2    ;1 cycle"           "\n\t"
                "lpm            ;3 cycles"  "\n\t"
                "out %4, __tmp_reg__    ;1 cycle"   "\n\t"
                "sbis %5, 2     ;1 cycle if no skip skip if  SPCR.CPHA" "\n\t"    
                "rjmp 1b        ;2 cycles. Total 10 cycles" "\n\t"
                :
                :"r" (ad0),"r" (ad1),"r" (ad2),"e" (signal),"I" (_SFR_IO_ADDR(PORTD)), "I" (_SFR_IO_ADDR(SPCR))
                :"r18", "r19" 
    ); 
}
 
 
 
/*
void static inline Signal_OUT(const uint8_t *signal, uint8_t ad2, uint8_t ad1, uint8_t ad0)
{ 
asm volatile(   "eor r18, r18   ;r18<-0"    "\n\t"
                "eor r19, r19   ;r19<-0"    "\n\t"
                "1:"                        "\n\t"
                "add r18, %0    ;1 cycle"           "\n\t"
                "adc r19, %1    ;1 cycle"           "\n\t"  
                "adc %A3, %2    ;1 cycle"           "\n\t"
                "lpm            ;3 cycles"  "\n\t"
                "out %4, __tmp_reg__    ;1 cycle"   "\n\t"
                "sbis %5, 6     ;1 cycle if no skip skip if  SPCR.CPHA" "\n\t"    
                "rjmp 1b        ;2 cycles. Total 10 cycles" "\n\t"
                :
                :"r" (ad0),"r" (ad1),"r" (ad2),"e" (signal),"I" (_SFR_IO_ADDR(PORTD)), "I" (_SFR_IO_ADDR(SREG))
                :"r18", "r19" 
    ); 
}
 
 
 
*/
 
void Timer1_Start(uint8_t FMHz)
{
    if(FMHz==1){ OCR1A=7; } else  //start high speed (1MHz) signal
    if(FMHz==2){ OCR1A=3; } else //2MHz
    if(FMHz==4){ OCR1A=1; } else //4MHz     
    if(FMHz==8){ OCR1A=0; } else //8MHz 
        OCR1A=7;//default 1MHz
    
    //Output compare toggles OC1A pin
    TCCR1A=0x40;
    //start timer without prescaler
    TCCR1B=0b00001001;
}
void Timer1_Stop(void){ TCCR1B=0x00; }//timer off
 
 
 
void Main_Init(void)
{
//stderr = &lcd_str;
stdout = &lcd_str;
//--------init LCD----------
LCDinit();
LCDclr();
LCDcursorOFF();
 
CopyStringtoLCD(welcomeln1, 3, 0);
CopyStringtoLCD(welcomeln1, 3, 1);
 _delay_ms(50);
 
 
 
 
 
 
SG.mode=0x00; //eeprom_read_byte((uint8_t*)EEMODE);
SG.fr1=0xE8;//eeprom_read_byte((uint8_t*)EEFREQ1);
SG.fr2=0x03;//eeprom_read_byte((uint8_t*)EEFREQ2);
SG.fr3=0x00;//eeprom_read_byte((uint8_t*)EEFREQ3);
SG.freq=(((uint32_t)(SG.fr3)<<16)|((uint32_t)(SG.fr2)<<8)|((uint32_t)(SG.fr1)));
 
UpdateACC();
               //SG.acc= (uint32_t) ( SG.freq* 10.48576); 
               //SG.acc= (uint32_t) SG.freq/RESOLUTION    ; //warning  RESOLUTION= 0.095367431640625 
               //SG.acc=   SG.freq/RESOLUTION    ; //fix ***********************
SG.flag=0;
//default 1MHz HS signal freq
SG.HSfreq=1;
SG.deltafreq=100;
//------------init DDS output-----------
R2RPORT=0x00;//set initial zero values
R2RDDR=0xFF;//set A port as output
//-------------set ports pins for buttons----------
BDDR&=~(_BV(START)|_BV(UP)|_BV(DOWN)|_BV(RIGHT)|_BV(LEFT));
BPORT|=(_BV(START)|_BV(UP)|_BV(DOWN)|_BV(RIGHT)|_BV(LEFT));
//---------set ports pins for HS output---------
HSDDR|=_BV(HS);//configure as output
//-----------Menu init--------------
SG.ON=0;//default signal is off
 
//return;
Menu_Update(SG.ON);
//-----------Timer Init-------------
Timer2_Init();
//Start Timer with overflow interrupts
Timer2_Start();
}
 
 
 
 
 
 
//const uint8_t welcomeln1[] PROGMEM ="AVR LCD DEMO\0";
int main(void)
{
//Initialize
Main_Init();
     
//GICR |= (1<<INT0);  
 
TCCR0 = (1<<CS02) | (1<<CS00);
TIMSK&=~(1<<TOIE0);
while(1)  {
 
 
 
 
    if (SG.flag==1)
        {  //fix 
 
 
        //GICR|=(1<<INT0);//set external interrupt to enable stop
        if (SG.mode==7)
            {
            //Noise
            do { R2RPORT=rand();} while(SG.flag==1);
            //set signal level to 0
            R2RPORT=0x00;
            //display generator OFF
            Menu_Update(SG.ON);
            //stop external interrupt
            GICR&=~(1<<INT0);
            TIMSK&=~(1<<TOIE0);     
 
            //start timer menu active
            Timer2_Start();
            }
        else if (SG.mode==6)
            {
            //freq step
            while((SG.flag==1))
            {
            //not implemented
            CopyStringtoLCD(NA, 0, 1 );
            }
            //set signal level to 0
            R2RPORT=0x00;
            //display generator OFF
            Menu_Update(SG.ON); 
            GICR&=~(1<<INT0);//|(1<<INT1);//stop external interrupt
            TIMSK&=~(1<<TOIE0);
            //start timer menu active
            Timer2_Start();
            }
 
        else if (SG.mode==8)
            {
            //High speed signal
            Timer1_Start(SG.HSfreq);
            while((SG.flag==1)) { CopyStringtoLCD(MNON, 13, 1 ); }//not implemented
            Timer1_Stop();//timer off
            //set HS pin to LOW
            HSPORT&=~(1<<HS);
            //display generator OFF
            Menu_Update(SG.ON); 
            GICR&=~(1<<INT0);//|(1<<INT1);//stop external interrupt
             TIMSK&=~(1<<TOIE0);
            //start timer menu active
            Timer2_Start();
            }
        else
            {
            //start DDS
            SREG|=(_BV(6));
            Signal_OUT(  SIGNALS[SG.mode], (uint8_t) ((uint32_t) SG.acc>>16), (uint8_t)((uint32_t) SG.acc>>8),(uint8_t)SG.acc);
            //set signal level to 0
            R2RPORT=0x00;
            //display generator OFF
            Menu_Update(SG.ON);
            GICR&=~(1<<INT0);//|(1<<INT1);
            TIMSK&=~(1<<TOIE0);
                                                      //stop external interrupt
            //start timer menu active
            Timer2_Start();
            }
        }
 
 
//CheckButtons();
 
    }
return 0;    
}
0
3 / 3 / 0
Регистрация: 29.06.2018
Сообщений: 1,249
10.06.2021, 04:12  [ТС] 19
Может, через бит T (бит 6 SREG) и таймер 0 попробовать (немного дает шум )

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void static inline Signal_OUT(const uint8_t *signal, uint8_t ad2, uint8_t ad1, uint8_t ad0)
{ 
asm volatile(   "eor r18, r18   ;r18<-0"    "\n\t"
                "eor r19, r19   ;r19<-0"    "\n\t"
                "1:"                        "\n\t"
                "add r18, %0    ;1 cycle"           "\n\t"
                "adc r19, %1    ;1 cycle"           "\n\t"  
                "adc %A3, %2    ;1 cycle"           "\n\t"
                "lpm            ;3 cycles"  "\n\t"
                "out %4, __tmp_reg__    ;1 cycle"   "\n\t"
                "sbis %5, 6     ;1 cycle if no skip skip if  SPCR.CPHA" "\n\t"    
                "rjmp 1b        ;2 cycles. Total 10 cycles" "\n\t"
                :
                :"r" (ad0),"r" (ad1),"r" (ad2),"e" (signal),"I" (_SFR_IO_ADDR(PORTD)), "I" (_SFR_IO_ADDR(SREG))
                :"r18", "r19" 
    ); 
}
На меге 16 с прерываниями удобнее
0
Вложения
Тип файла: zip examplecheckT.zip (232.6 Кб, 0 просмотров)
3 / 3 / 0
Регистрация: 29.06.2018
Сообщений: 1,249
12.06.2021, 00:33  [ТС] 20
С такой инициализацией не выдает в ємуляторе произвольные символы в начале
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
//lcd_lib.h
 
#define F_CPU  16000000UL
 #include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <math.h>
/*
44780 compatible
LCD pin 2 Vss
LCD pin 1 Vdd
LCD pin 3 Vee
 
 
PC0 RS LCD pin 4
GND to RW  pin 5
PC1 EN LCD pin 6
LCD pin 7-10 mot used 
PC2 D4 LCD pin 11
PC3 D5 LCD pin 12
PC4 D6 LCD pin 13
PC5 D7 LCD pin 14
 
 
 
*/
 
 
 
//Uncomment this if LCD 4 bit interface is used
//******************************************
#define LCD_4bit
//***********************************************
 
#define LCD_RS  0   //define MCU pin connected to LCD RS
//#define LCD_RW    0   //define MCU pin connected to LCD R/W ,not used , fix 
#define LCD_E   1   //define MCU pin connected to LCD E
 
//D0-D3 not used for 4 bit mode 
//#define LCD_D0    2   //define MCU pin connected to LCD D0
//#define LCD_D1    3   //define MCU pin connected to LCD D1
//#define LCD_D2    4   //define MCU pin connected to LCD D2
//#define LCD_D3    5   //define MCU pin connected to LCD D3
 
#define LCD_D4  2   //define MCU pin connected to LCD D4
#define LCD_D5  3   //define MCU pin connected to LCD D5
#define LCD_D6  4   //define MCU pin connected to LCD D6
#define LCD_D7  5   //define MCU pin connected to LCD D7
 
 
#define LDP PORTC   //define MCU port connected to LCD data pins
#define LCP PORTC   //define MCU port connected to LCD control pins
#define LDDR DDRC   //define MCU direction register for port connected to LCD data pins
#define LCDR DDRC   //define MCU direction register for port connected to LCD control pins
 
#define LCD_CLR             0   //DB0: clear display
#define LCD_HOME            1   //DB1: return to home position
#define LCD_ENTRY_MODE      2   //DB2: set entry mode
#define LCD_ENTRY_INC       1   //DB1: increment
#define LCD_ENTRY_SHIFT     0   //DB2: shift
#define LCD_ON_CTRL         3   //DB3: turn lcd/cursor on
#define LCD_ON_DISPLAY      2   //DB2: turn display on
#define LCD_ON_CURSOR       1   //DB1: turn cursor on
#define LCD_ON_BLINK        0   //DB0: blinking cursor
#define LCD_MOVE            4   //DB4: move cursor/display
#define LCD_MOVE_DISP       3   //DB3: move display (0-> move cursor)
#define LCD_MOVE_RIGHT      2   //DB2: move right (0-> left)
#define LCD_FUNCTION        5   //DB5: function set
#define LCD_FUNCTION_8BIT   4   //DB4: set 8BIT mode (0->4BIT mode)
#define LCD_FUNCTION_2LINES 3   //DB3: two lines (0->one line)
#define LCD_FUNCTION_10DOTS 2   //DB2: 5x10 font (0->5x7 font)
#define LCD_CGRAM           6   //DB6: set CG RAM address
#define LCD_DDRAM           7   //DB7: set DD RAM address
// reading:
#define LCD_BUSY            7   //DB7: LCD is busy
#define LCD_LINES           2   //visible lines
#define LCD_LINE_LENGTH     16  //line length (in characters)
// cursor position to DDRAM mapping
#define LCD_LINE0_DDRAMADDR     0x00
#define LCD_LINE1_DDRAMADDR     0x40
//#define LCD_LINE2_DDRAMADDR       0x14
//#define LCD_LINE3_DDRAMADDR       0x54
// progress bar defines
#define PROGRESSPIXELS_PER_CHAR 6
 
 
void LCDsendChar(uint8_t ch)        //Sends Char to LCD
{
 
 
    //4 bit part
    LDP=(ch&0b11110000);
    LCP|=1<<LCD_RS;
    LCP|=1<<LCD_E;      
    _delay_ms(1);
    LCP&=~(1<<LCD_E);   
    LCP&=~(1<<LCD_RS);
    _delay_ms(1);
    LDP=((ch&0b00001111)<<4);
    LCP|=1<<LCD_RS;
    LCP|=1<<LCD_E;      
    _delay_ms(1);
    LCP&=~(1<<LCD_E);   
    LCP&=~(1<<LCD_RS);
    _delay_ms(1);
 
}
void LCDsendCommand(uint8_t cmd)    //Sends Command to LCD
{
    
    //4 bit part
 
    LDP=(cmd&0b11110000);
    LCP|=1<<LCD_E;      
    _delay_ms(1);
    LCP&=~(1<<LCD_E);
    _delay_ms(1);
    LDP=((cmd&0b00001111)<<4);  
    LCP|=1<<LCD_E;      
    _delay_ms(1);
    LCP&=~(1<<LCD_E);
    _delay_ms(1);
 
 
 
}
 
 
 
/*
void LCDsendCommand( unsigned char cmnd )
{
    LDP = (LDP & 0x0F) | (cmnd & 0xF0);
    LCP &= ~ (1<<LCD_RS);
    LCP |= (1<<LCD_E);
    _delay_us(1);
    LDP &= ~ (1<<LCD_E);
    _delay_us(200);
    LDP = (LDP & 0x0F) | (cmnd << 4);
    LCP |= (1<<LCD_E);
    _delay_us(1);
    LCP &= ~ (1<<LCD_E);
    _delay_ms(2);
}
 
 
*/
 
 
 
 
 
void LCDinit (void)
{
    LDP=0x00;
    LCP=0x00;
    //LCDR|=1<<LCD_E |1<<LCD_RS ;/*|1<<LCD_RW*/ 
    //LDDR|=1<<LCD_D7|1<<LCD_D6|1<<LCD_D5|1<<LCD_D4;
    LDDR|=1<<LCD_D7|1<<LCD_D6|1<<LCD_D5|1<<LCD_D4|1<<LCD_E |1<<LCD_RS ;
      // LDP |=1<<LCD_E |1<<LCD_RS ; 
 
 
 
    //LDP = 0xFF;       //Control LCD Pins (D4-D7)
    _delay_ms(15);      //Wait before LCD activation
    LCDsendCommand(0x02);   //4-Bit Control
    LCDsendCommand(0x28);       //Control Matrix @ 4-Bit
    LCDsendCommand(0x0c);       //Disable Cursor
    LCDsendCommand(0x06);       //Move Cursor
    LCDsendCommand(0x01);       //Clean LCD
    _delay_ms(2);
}
void LCDclr(void){  LCDsendCommand(1<<LCD_CLR); }//Clears LCD
void LCDhome(void){ LCDsendCommand(1<<LCD_HOME); }//LCD cursor home
 
void LCDstring(uint8_t* data, uint8_t nBytes)   //Outputs string to LCD
{
register uint8_t i;
    // check to make sure we have a good pointer
    if (!data) return;
    // print data
    for(i=0; i<nBytes; i++){ LCDsendChar(data[i]);}
}
void LCDGotoXY(uint8_t x, uint8_t y)    //Cursor to X Y position
{
    register uint8_t DDRAMAddr;
    // remap lines into proper order
    switch(y)
    {
    case 0: DDRAMAddr = LCD_LINE0_DDRAMADDR+x; break;
    case 1: DDRAMAddr = LCD_LINE1_DDRAMADDR+x; break;
//  case 2: DDRAMAddr = LCD_LINE2_DDRAMADDR+x; break;
//  case 3: DDRAMAddr = LCD_LINE3_DDRAMADDR+x; break;
    default: DDRAMAddr = LCD_LINE0_DDRAMADDR+x;
    }
    // set data address
    LCDsendCommand(1<<LCD_DDRAM | DDRAMAddr);
    
}
//Copies string from flash memory to LCD at x y position
//const uint8_t welcomeln1[] PROGMEM="AVR LCD DEMO\0";
//CopyStringtoLCD(welcomeln1, 3, 1);    
void CopyStringtoLCD(const uint8_t *FlashLoc, uint8_t x, uint8_t y)
{
    uint8_t i;
    LCDGotoXY(x,y);
    for(i=0;(uint8_t)pgm_read_byte(&FlashLoc[i]);i++)
    {
        LCDsendChar((uint8_t)pgm_read_byte(&FlashLoc[i]));
    }
}
//defines char symbol in CGRAM
/*
const uint8_t backslash[] PROGMEM= 
{
0b00000000,//back slash
0b00010000,
0b00001000,
0b00000100,
0b00000010,
0b00000001,
0b00000000,
0b00000000
};
LCDdefinechar(backslash,0);
*/
void LCDdefinechar(const uint8_t *pc,uint8_t char_code){
    uint8_t a, pcc;
    uint16_t i;
    a=(char_code<<3)|0x40;
    for (i=0; i<8; i++){
        pcc=pgm_read_byte(&pc[i]);
        LCDsendCommand(a++);
        LCDsendChar(pcc);
        }
}
 
void LCDshiftLeft(uint8_t n) { uint8_t i; for ( i=0; i<n; i++){ LCDsendCommand(0x1E); }}//Scrol n of characters Right
void LCDshiftRight(uint8_t n){ uint8_t i;for ( i=0;i<n;i++){ LCDsendCommand(0x18);}}//Scrol n of characters Left
void LCDcursorOn(void){ LCDsendCommand(0x0E); } //displays LCD cursor
void LCDcursorOnBlink(void) { LCDsendCommand(0x0F); } //displays LCD blinking cursor
void LCDcursorOFF(void) {   LCDsendCommand(0x0C); } //turns OFF cursor
void LCDblank(void)     {   LCDsendCommand(0x08); } //blanks LCD
void LCDvisible(void){  LCDsendCommand(0x0C);}//Shows LCD
void LCDcursorLeft(uint8_t n) { uint8_t i;for (  i=0;i<n;i++){  LCDsendCommand(0x10); }}//Moves cursor by n poisitions left
void LCDcursorRight(uint8_t n)  {uint8_t i; for (  i=0;i<n;i++){ LCDsendCommand(0x14); }}//Moves cursor by n poisitions left
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.06.2021, 00:33

Помощь в написании контрольных, курсовых и дипломных работ здесь.

компиляция программы
Здравствуйте, подскажите пожалуйста, не судите строго, это у меня первое творение. Есть проект...

Компиляция программы
Привет форумчане! Вот задание: Написать программу, которая вводит с клавиатуры одномерный массив из...

Компиляция программы
При компиляции терминал выдал следующее java Example Exception in thread &quot;main&quot;...

C++ компиляция программы
Необходимо скомпилировать программу из документа В документе имеется: текст программы...

Компиляция программы
У меня вот такая проблема, я вот как два часа учусь программировать на это потрясающем языке, и...

Компиляция программы
У меня есть полный текст программы. Но не удаётся её скомпилировать. Программа мне нужна срочно для...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.