Примеры CodeVisionAVR

Автор: Internet. Опубліковано в Початківцям з CV AVR

Зміст статті

адочный CodeVisionAVR,   небольшие примеры кода, для осваивающихся.

Кусочки кода которые и программой то нельзя назвать , так пара строк , примитив :))  .

Всё на примерах изучается, здесь просто примеры без комментариев и обсуждения, только простые примеры.

Если у вас, есть показать какой либо небольшой пример в CodeVision ; мигалки , .... будильника, измерителя или что там еще,  милости прошу, это будет очень полезно и интересно      

ATtiny2313.pdf (RUS_datasheet) 2.61 Mb

ATmega 8.pdf   (Eng_datasheet) 3.06 Mb

ATmega 16. pdf (Eng_datasheet) 3.44 Mb
ATmega 32. pdf (Eng_datasheet) 2.15 Mb
ATmega 128.pdf (RUS_datasheet) 2.54 Mb 
DS1307_rus.pdf  299.3 Kb
DS18b20 rus.pdf  1.0 Mb

 

программатор
 

 


 Тип    Размер байт  Диапазон 
  bit (бит)    1/8    0,1 
  char(символ)   1   -128 ... 127 
  unsigned char (символ без знака)   1    0 ... 255 
  int (целое)    2   -32768 ... 32767
  unsigned int (целое без знака)    2    0 ... 65535
  long int (длинное целое)    4   -2147483648 ... 2147483647 
  unsigned long int (длинное целое без знака)  4    0 ... 4294967295 
  float (с плавающей точкой)    4   ±1,175е-38... ±3,402е38

       

       

  


Небольшие примеры, как помигать светодиодом с помощью кнопки, вот тут  несколько вариантов.....

Смотрим в протеусе, нажимаем на кнопку (можно кое-где и придержать её), смотрим как реагирует светодиод, ..... если интересно как это заработало, смотрим в код, вносим изменения, редактируем, комплимируем. .....

Code
/*****************************************************
Version : Кнопки и светодиоды 
Company : c2.at.ua 
Chip type : ATmega8
Clock frequency : 4,000000 MHz
*****************************************************/ 
#include <mega8.h> // библиотека ввода вывода микроконтроллера
#include <delay.h> // библиотека задержки
unsigned char kR, temp; // обьявляем переменные
void main(void) // Declare your global variables here

PORTB=0b11111111; // Port B initialization
DDRB=0b00000000; 
PORTC=0b01000000; // Port C initialization
DDRC=0b00111111;
PORTD=0b00000000; // Port D initialization
DDRD=0b111111111;

while(1) // бесконечный цикл 
{
PORTD.0=~PINB.0; // =======№1 Упр. 1 порт 1 кнопка 

if (PINB.1==0) // ==== №2 кнопка

PORTD.1=1;
delay_ms(600);
PORTD.1=0;
delay_ms(300); 

if (PINB.2==0) // ==== №3 кнопка

PORTD ^= 1<<2;
delay_ms(500); 

if (PINB.3==0) // ==== №4 кнопка

PORTD.3= 1;
delay_ms(5000); 
PORTD.3= 0; 

if (PINB.4==0 && kR!=1) // === №5 кнопка

delay_ms(10); // 10мс для "анти-дребезга"
PORTD.4 = ~PORTD.4;
kR = 1; //
}
if (PINB.5==0 && kR!=1)

delay_ms(10); // 10мс для "анти-дребезга"
PORTD.5 = ~PORTD.5;
kR = 1;
}
if (PINB.4==1 && PINB.5==1)
{
kR = 0;

//========== №6 МИГАЛКА 
while (PINB.6==0) // проверяем если кнопка нажата (замкнута), то выполняем цикл мигалки
{
PORTD.6=1; // зажигаем красный светодиод
delay_ms(200); //ждем 100 миллисекунд
PORTD.6=0; //гасим его
delay_ms(200); //ждем 100 миллисекунд
PORTD.6=1; //зажигаем
delay_ms(200); //ждем
PORTD.6=0; //гасим
PORTD.7=1; //зажигаем синий светодиод
delay_ms(200); //ждем
PORTD.7=0; //гасим
delay_ms(200); //ждем
PORTD.7=1; //зажигаем
delay_ms(200); //ждем
PORTD.7=0; //гасим
} // как только отпустим кнопку программа дойдет до конца цикла
// и будет ждать пока не нажмем заново 

//========== №-7 Переключаем по кольцу
if (PINB.7==0){ //если кнопка нажата выполнить следующее
delay_ms(100);
if (PINB.7==0){
temp++;
if(temp==6) { 
temp=0;
}
while (PINB.7==0); // ждем пока кнопка будет отжата
}
}

if (temp==0) { // если темп равен 0 вывести в порт следующее 
PORTC=0b00000001; 
delay_ms(10); 

if (temp==1) { 
PORTC=0b00000010; 
delay_ms(10); 
}
if (temp==2) { 
PORTC=0b00000100;
delay_ms(10); 
}
if (temp==3) { 
PORTC=0b00001000;
delay_ms(10); 
}
if (temp==4) { 
PORTC=0b00010000;
delay_ms(10); 
}
if (temp==5) { 
PORTC=0b00100000;
delay_ms(10); 
}
}; // закрываем бесконечный цикл

Скачать архив проекта; исходный код, прошивка,  proteus.

Остается только добавить что в железе реакция светодиодов  на кнопки 100% соответствует работе схемы в   proteus'е.  

Небольшая программа с управлением кнопками, результат   управления кнопок можно сохранять в eeprom.


Code
/*****************************************************
Version : Кнопки и led знак, .. пишем в flash-память. 
Company : c2.at.ua 
Chip type : ATmega8
Clock frequency : 4,000000 MHz
*****************************************************/ 
#include <mega8.h>
#include <delay.h>

flash unsigned char led[11]={ 
0b10000000,
0b00000110, 0b01011011,
0b01001111, 0b01100110,
0b01101101, 0b01111101,
0b00000111, 0b01111111, 
0b01101111, 0b00111111}; // Массив "led" во flash-памяти,
eeprom unsigned char eep;
unsigned char i,a; // переменная 
void main(void)
{
PORTB=0b11111111; // Port B initialization
DDRB=0b00000000; 
PORTC=0b01000000; // Port C initialization
DDRC=0b00111111;
PORTD=0b00000000; // Port D initialization
DDRD=0b011111111;
a=eep;
start:
while (1)
{
if (a==11) a=1;
if (a==0) a=10;
i=a;
PORTD=led[i];
delay_ms(400);
if (PINB.0==0) {a++; goto start;} 
if (PINB.1==0) {a--; goto start;}
if (PINB.2==0) goto zap;
};
zap:
eep=a;
PORTD=0;
delay_ms(400);
goto start; 
  }

Скачать архив проекта; исходный код, прошивка, proteus.

 


  Подключение одного датчика .

Программная часть. 

Подключим один датчик к микроконтроллеру ATmega8. Программная часть.

Подключаем к основному коду программы заголовочный файл.h


#include <ds18b20.h>

Чтобы начать работать с одним датчиком, достаточно воспользоваться двумя функциями:

Функция инициализации

ds18b20_init( адрес датчика, нижний порог Т, верхний порог Т, разрешающая способность );

функция чтения температуры

ds18b20_temperature( адрес датчика );

Код программы.

Code
#include                                                      // библиотека ввода вывода микроконтроллера
#asm
  .equ __w1_port=0x18 ;PORTB                                       // сообщаем куда подключен датчик
.equ __w1_bit=0
#endasm
#include <1wire.h>                                                        // библиотека работы с 1Wire
#include                                                    // библиотека для работы с датчиком ds18b20
#asm
  .equ __lcd_port=0x12 ;PORTD                                       // сообщаем куда подключён экран
#endasm
#include                                                            // библиотека для LCD
#include                                                        // библиотека задержки
#include                                                         // стандартная библиотека вывода символов на экран 
unsigned char devices;                                                    // переменная в которой количество присоеденённых датчиков
int temp;                                                                        // переменная для хранения температуры  
unsigned char lcd_buffer[16]; 
void main(void)                                                              // Declare your global variables here

PORTB=0b00000000;                                                      // Port B initialization
 DDRB=0b00000000;                                                      // 0b в таком виде легче представить состояние портов
PORTC=0b10000000;                                                      // Port C initialization
DDRC=0b00000000;
PORTD=0b00000000;                                                      // Port D initialization
DDRD=0b00000000;
ACSR=0x80;                                                                  // Analog Comparator: Off
lcd_init(16);                                                                   // инициилизация LCD, и говорим что он на 16 символов
devices=w1_init();                                                          // ищим датчики
while(devices>0)                                                            // бесконечный цикл, если датчик подключон
{
  temp=ds18b20_temperature(0);                                    // читаем температуру  
  if (temp>1000){                                                           // если датчик выдаёт больше 1000
  temp=4096-temp;                                                        // отнимаем от данных 4096
  temp=-temp;                                                               // и ставим знак "минус"
}
  sprintf(lcd_buffer,"t=%i.%u xdfC",temp,temp%1);          // записуем в масив показания на экран 
  lcd_clear();                                                                  // чистим дисплей перед выводом
  lcd_puts(lcd_buffer);                                                     // выводим масив на LCD
  delay_ms(500);                                                            // ждём 500мс
};

Проект использования одного датчика ds18b20

Еще один пример если необходимо выводить значение температуры с точностью до одной сотой,

Код программы.

Code
#include                                              // библиотека ввода вывода микроконтроллера
#asm
  .equ __w1_port=0x18 ;PORTB                               // сообщаем куда подключен датчик
  .equ __w1_bit=0                                                   // 1 Wire Bus functions
#endasm
#include                                            // библиотека для работы с датчиком ds18b20
#include                                                // библиотека задержки
#define MAX_DS18B20 8
unsigned char ds18b20_devices;
unsigned char ds18b20_rom_codes[MAX_DS18B20][9];
#asm 
  .equ __lcd_port=0x12 ;PORTD                               // сообщаем куда подключён экран
#endasm 
#include                                                    // библиотека для LCD
#include                                                 // библиотека для LCD
float temper;                                                          // переменная в которой количество 
int temp_0,temper_fl,min=0;                                   // обьявляем перменные
char lcd_buffer[16];                                                // масив с данными для экрана
void temperature(void)                                           // функция по работе с термо-датчиком
{
temper=ds18b20_temperature(&ds18b20_rom_codes[0][0]);
  temp_0=temper;                                                  // отбор целой части от температуры 
  if(temper<0)                                                        // при отрицательной температуре  
{
  temper_fl=(temper-temp_0-0.0625)*10;                // дробная часть 
  temp_0=-((temp_0*10)+temper_fl);                      // температура*10 
  min=1;                                                                // минус
  }else                                                                   // при положительной 
{
  min=0;                                                                // плюс 
  temper_fl=(temper-temp_0)*10;                           // дробная часть 
  temp_0=(temp_0*10)+temper_fl;                          // температура*10 

  if ((temp_0 < 1300) & (temp_0 > 0))                      // установим порог 
temp_0= temp_0;
else
{
temp_0 =0; 

}
void main(void)                                                      //основная функция
{
 char *_str=" c2.at.ua";                                  //Создаем информ. строку 
char *_str1="Tepјoјeїp 0.1 x60C"; 

PORTB=0b00000000;                                              // «WzAVR «Port B initialization
 DDRB=0b00000000;                                              // 0b в таком виде легче представить состояние портов

PORTC=0b10000000;                                              // «WzAVR «Port C initialization
DDRC=0b00000000;

PORTD=0b00000000;                                              // «WzAVR «Port D initialization
DDRD=0b00000000;

ACSR=0x80;                                                          // «Analog Comparator: Off
ds18b20_devices=w1_search(0xf0,ds18b20_rom_codes); 
 ds18b20_init(0,-35,35,DS18B20_12BIT_RES);          // переключения термометра в 12 битный режим 
  w1_init();                                                             // 1 Wire Bus initialization
  lcd_init(16);                                                          // Инициализация ЖКИ на 16 символов 
  lcd_gotoxy(0, 0);                                                  // Переводим курсор на первый символ первой строки 
  lcd_puts(_str);                                                      // Выводим строку _str на дисплей ЖКИ  
  lcd_gotoxy(0, 1);                                                  // Переводим курсор на первый символ первой строки 
  lcd_puts(_str1);                                                    // Выводим строку _str на дисплей ЖКИ 
  delay_ms(900);                                                    // ждём 900мс  
  lcd_clear();                                                          // чистим дисплей перед выводом  
lcd_init(16);                                                           // «WzAVR « Инициализация ЖКИ на 16 символов
while (1)                                                                // бесконечный цикл, если датчик подключон  
{
delay_ms(50);
  temperature();                                                     // вызываем функцию температуры
  lcd_clear();                                                          // очищаем LCD
if(min==1)
{
  sprintf(lcd_buffer,"t=-%u.%u x60C ",temp_0/10,temp_0%10); //вывод отрицательной температуры 
}else
{
  sprintf(lcd_buffer,"t=+%i.%d x60C ",temp_0/10,temp_0%10); // вывод положительной
}
  lcd_puts(lcd_buffer);                                             // вывод на дисплей
};
}


Проект использования одного датчика ds18b20    с точностью до  0.1°C

Подключение двух датчиков.


При подключении более одного датчика ds18b20 на линию 1-wire, необходимо выполнять чтение ROM каждого датчика, чтоб обращаться к каждому индивидуально. Используя функцию w1_search, производим поиск устройств 1-wire, тем самым выясняем их количество на линии и производим чтение ROM данных каждого датчика:

unsigned char devices;

unsigned char rom_code[2][9];

Код программы.

Code
#include                                              // библиотека ввода вывода микроконтроллера
#asm
  .equ __w1_port=0x18 ;PORTB                               //сообщаем куда подключен датчик
.equ __w1_bit=0
#endasm
#include                                             //библиотека для работы с датчиком ds18b20
unsigned char rom_code[4][9];                                //масив с адресами найденых датчиков
#define MAX_DS18B20 8
#asm 
  .equ __lcd_port=0x12 ;PORTD                               //сообщаем куда подключён экран
#endasm 
#include                                                    //библиотека для LCD
#include                                                 //библиотека для LCD
#include                                                //библиотека задержки
unsigned char i,devices;                                          //переменная в которой количество 
int temp1,temp2;                                                    //обьявляем перменные
unsigned char lcd_buffer_1[16];                               //масив с данными для экрана
unsigned char lcd_buffer_2[16];                               //масив с данными для экрана 
void main(void)                                                      // Declare your global variables here
{
 char *_str=" c2.at.ua";                                  //Создаем информ. строку 
char *_str1="2 Tepјoјeїpa 1 x60C"; 

PORTB=0b00000000;                                              // «WzAVR «Port B initialization
 DDRB=0b00000000;                                              // 0b в таком виде легче представить состояние портов

PORTC=0b10000000;                                              // «WzAVR «Port C initialization
DDRC=0b00000000;

PORTD=0b00000000;                                              // «WzAVR «Port D initialization
DDRD=0b00000000;
devices=w1_search(DS18B20_SEARCH_ROM_CMD,rom_code); //определим сколько устройств подключено к шине 1-Wire 

ACSR=0x80;                                                          // «Analog Comparator: Off
 ds18b20_init(0,-35,35,DS18B20_12BIT_RES);          // переключения термометра в 12 битный режим 
  w1_init();                                                             // Wire Bus initialization
  lcd_init(16);                                                         // Инициализация ЖКИ на 16 символов 
  lcd_gotoxy(0, 0);                                                  // Переводим курсор на первый символ первой строки 
  lcd_puts(_str);                                                      // Выводим строку _str на дисплей ЖКИ  
  lcd_gotoxy(0, 1);                                                  // Переводим курсор на первый символ первой строки 
  lcd_puts(_str1);                                                    // Выводим строку _str на дисплей ЖКИ 
  delay_ms(900);                                                    // ждём 900мс  
  lcd_clear();                                                          // чистим дисплей перед выводом  
lcd_init(16);                                                            // Инициализация ЖКИ на 16 символов
while(devices>0)                                                     // бесконечный цикл, если датчик подключон  
{                                                                           // Place your code here
  temp1 = ds18b20_temperature(&rom_code[0][0]);  // читаем температуру с выбранного датчика
//if( temp1 > 1000 ) { temp1 = 4096 - temp1; temp1 = -temp1; }
  if ((temp1 < 130) & (temp1 > -60))                        // установим границу диапазон 
temp1= temp1;
else
{
  temp1 =0;                                                            // если выходит за границу тогда 0
}
sprintf(lcd_buffer_1," t%u=%i.%u xdfC ",i+1,temp1,temp1%1);
  lcd_gotoxy(0,0);                                                   // указали место на дисплее
lcd_puts(lcd_buffer_1); // выводим масив на LCD
  temp2 = ds18b20_temperature( &rom_code[1][0] ); //читаем температуру с выбранного датчика  
//if( temp2 > 1000 ) { temp2 = 4096-temp2; temp2 = -temp2; }
  if ((temp2 < 130) & (temp2 > -60))                        // установим границу диапазон 
temp2= temp2;
else
{
  temp2 =0;                                                           // если выходит за границу тогда 0
}
sprintf(lcd_buffer_2," t%u=%i.%u xdfC ",i+2,temp2,temp2%1); 
lcd_gotoxy(0,1);
  lcd_puts(lcd_buffer_2);                                          // выводим масив на LCD
  delay_ms(30);                                                      // ждём 
};

}

Проект использования двух датчиков ds18b20

Пример проекта где можно подключать датчики "десятками". :)

Код программы.

Code
/*****************************************************
CodeWizardAVR 
Project : Ver. 1.6.0
Version : Термометр 1°С
Date : 04.02.2012 
Company : c2.at.ua 
Chip type : ATmega8
Program type : Application
Clock frequency : 4,000000 MHz
*****************************************************/ 
#include <mega8.h> // библиотека ввода вывода микроконтроллера
#asm
.equ __w1_port=0x18 ;PORTB //сообщаем куда подключен датчик
.equ __w1_bit=0
#endasm
#include <ds18b20.h> //библиотека для работы с датчиком ds18b20
#define MAX_DS18B20 8
#asm 
.equ __lcd_port=0x12 ;PORTD //сообщаем куда подключён экран
#endasm 
#include <lcd.h> //библиотека для LCD
#include <stdio.h> //библиотека для LCD
#include <delay.h> //библиотека задержки
unsigned char rom_code[16][9]; //масив с адресами найденых датчиков
char lcd_buffer[16]; //масив с данными для экрана
unsigned char devices=9, iw=0; //переменная в которой количество присоеденённых датчиков, и номер выбранного датчика
int temp; //переменная для хранения температуры
void main(void) 

PORTB=0b00000010; // Port B initialization
DDRB=0b00000000; // 
PORTC=0b11000000; // Port C initialization
DDRC=0b00000000;
PORTD=0b00000000; // Port D initialization
DDRD=0b00000000;
ACSR=0x80; // Analog Comparator: Off
lcd_init(16); //инициилизация LCD, и говорим что он на 16 символов
devices=w1_search(0xf0,rom_code); //ищим датчики, и записуем их адреса в масив
while(devices>0) //бесконечный цикл, если датчик подключон

if (PINB.1==1 ) { //Если нажата кнопка
iw++; //Увиличиваем переменную "i" на 1
delay_ms(300); //Ждём 300мс для "анти-дребезга"
}
if(iw>=devices){ 
delay_ms(5); //Если "iw" больше или равно найденым датчикам
iw=0; //тогда "i" равно нулю
}
temp=ds18b20_temperature(&rom_code[iw][0]); //читаем температуру с выбранного датчика
if (temp>1000){ //если датчик выдаёт больше 1000
temp=4096-temp; //отнимаем от данных 4096
temp=-temp; //и ставим знак "минус"
};
if (temp > -1000) // установим порог если обрыв датчика 
temp= temp;
else
{
temp =0; // выводим ноль

sprintf(lcd_buffer,"t%i=%i.%u xdfC", iw,temp,temp%1); //записуемв масив для экрана температуру и всё такое
lcd_clear(); //чистим дисплей перед выводом
lcd_puts(lcd_buffer); //выводим масив на LCD
delay_ms(50); //ждём 500мс
};
}


Проект такого подключения датчиков ds18b20  

Fuse бит , при прошивке МК выставить так


Таймер обратного отсчёта ,  интервал времени в диапазоне от 1 секунды до 24 часов.

Простая схема, источник   http://cxema.at.ua Author : Katran

 
Code

Chip type : ATmega8
Program type : Application
AVR Core Clock frequency: 4,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*****************************************************/
#include <mega8.h>
#asm
.equ __lcd_port=0x12 ;PORTD
#endasm
#include <lcd.h>
#include <delay.h>
unsigned char a=0, b=0, c=0, d=0, e=0, f=0, help=0; // ab : cd : ef
char hours, minuts, seconds;
#define SIGNAL PORTD.3
#define ON 1
#define OFF 0
#define MPLUS PINB.2
#define MMINUS PINB.3
#define SPLUS PINB.4
#define SMINUS PINB.5
#define PUSK PINC.0
#define STOP PINC.2
// ФУНКЦИЯ ОТОБРАЖЕНИЯ ВРЕМЕНИ
void time(void) // Подготовка регистров для заполнения данными
{
a = 0;
b = 0;
c = 0;
d = 0;
e = 0;
f = 0;
//=============================================================================
help = hours; // Разложение значения ЧАСов по разрядам ab : __ : __
while (help > 9)
{
help -= 10;
a++;
};
b = help;
//=============================================================================
help = minuts; // Разложение значения МИНут по разрядам __ : cd : __
while (help > 9)
{
help -= 10;
c++;
};
d = help;
//=============================================================================
help = seconds; // Разложение значения СЕКунд по разрядам __ : __ : ef
while (help > 9)
{
help -= 10;
e++;
};
f = help;
//=============================================================================
// ОТОБРАЖЕНИЕ НА ДИСПЛЕЕ ВРЕМЕНИ В СООТВЕТСТВИИ с местрположением
// ab : cd : ef
// Alrm gh : ij
lcd_gotoxy(0,0);
lcd_putchar(a+0x30);
lcd_putchar(b+0x30);
lcd_putsf(":");
lcd_putchar(c+0x30);
lcd_putchar(d+0x30);
lcd_putsf(":");
lcd_putchar(e+0x30);
lcd_putchar(f+0x30);
lcd_gotoxy(0,1);
lcd_putsf("<<<<>>>>");
};
// Timer 1 overflow interrupt service routine
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
// Reinitialize Timer 1 value
TCNT1H=0xBDC >> 8;
TCNT1L=0xBDC & 0xff;
// Place your code here
seconds--; // Инкремент таймера +1СЕК
if (seconds > 59) // условия при которых таймер ведет себя как часы
{
seconds = 59;
minuts--;
if (minuts > 59)
{
minuts = 59;
hours--;
if (hours > 23)
{
hours = 23;
};
};
};
// В данные часы включена функция включения нагрузки с 8 до 23,

//поэтому проверяем условие и делаем вывод
time(); // обновление дисплея
}
// Declare your global variables here
void main(void)
{
// Declare your local variables here

PORTB=0b00111111;
DDRB=0b00000000; //
PORTC=0b11111111; // «WzAVR «Port C initialization
DDRC=0b00000000; //
PORTD=0b00000000; // «WzAVR «Port D initialization
DDRD=0b00001000;
TCCR0=0x00;
TCNT0=0x00;
TCCR1A=0x00;
TCCR1B=0x03;
TCNT1H=0x0B;
TCNT1L=0xDC;
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
MCUCR=0x00;
TIMSK=0x04;
ACSR=0x80;
SFIOR=0x00;
// LCD module initialization
lcd_init(16);
// НАЧАЛЬНАЯ ИНИЦИАЛИЗАЦИЯ
timing:
while (PUSK == 1)
{
if (MPLUS == 0)
{
minuts++;
if (minuts > 59)
{
minuts = 0;
hours++;
if (hours > 23)
{
hours = 0;
};
};
}
if (MMINUS == 0)
{
minuts--;
if (minuts > 59)
{
minuts = 59;
hours--;
if (hours > 23)
{
hours = 23;
};
};
};
if (SPLUS == 0)
{
seconds++;
if (seconds > 59) seconds = 0;
};
if (SMINUS == 0)
{
seconds--;
if (seconds > 59) seconds = 59;
};
delay_ms(100);
time();
};
// Global enable interrupts
#asm("sei")
while (1)
{
// проводим сравнение для включения нагрузки
if (STOP == 0)
{
#asm("cli")
SIGNAL = OFF;
goto timing;
};
if (hours == 0)
{
if (minuts == 0)
{
if (seconds == 0)
{
#asm("cli")
SIGNAL = ON;
}
}
}

};
}

Скачать архив проекта; исходный код, прошивка,  proteus.

Секундомер  на МК ATtiny2313 6 знаков. 

Code
/*****************************************************
This program was produced by the
CodeWizardAVR V2.04.4a Advanced
Automatic Program Generator
© Copyright 1998-2009 Pavel Haiduc, HP InfoTech s.r.l.
c2.at.ua
 Chip type : ATtiny2313
AVR Core Clock frequency: 8,000000 MHz
Memory model : Tiny
External RAM size : 0
Data Stack size : 32
*****************************************************/
#include <tiny2313.h>
#include <delay.h>
unsigned char razrad=0b00100000; 
bit start=0; 
unsigned char cloc[6]={0,0,0,0,0,0};
unsigned char tik=0;
unsigned char des_tik=0;
unsigned char sec=0;
unsigned char des_sec=0;
unsigned char min=0; 
unsigned char des_min=0;
unsigned char x=0;
unsigned char znak [10] = {0b00111111, 0b00000110, 0b01011011, 0b01001111, 0b01100110, 0b01101101, 0b01111101, 0b00000111, 0b01111111, 0b01101111};//знакогенератор OA.
//unsigned char znak [10] = {0b11000000, 0b11111001, 0b10100100, 0b10110000, 0b10011001, 0b10010010, 0b10000010, 0b11111000, 0b10000000, 0b10010000};//знакогенератор OK.
//****************************** динамическая индикация ************************************
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
PORTD = razrad^0xFF ;
// PORTD = razrad; 
PORTB = znak [cloc[x]];
if ((x==2) | | (x==4)) {PORTB.7 =1;} else PORTB.7 =0;
razrad>>= 1; x++; 
if (x==6) {x=0; razrad=0b00100000;} 
// if (x==4) {x=0; razrad=0b0001000;} 
}
//******************************** отсчет времени ************************************
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
if (start==0) goto m1;
tik++;
if (tik==10) {tik=0; des_tik++;}
if (des_tik==10) {des_tik=0; sec++;}
if (sec==10) {sec=0; des_sec++;}
if (des_sec==6) {des_sec=0; min++;}
if (min==10) {min=0; des_min++;}
if (des_min==10) {des_min=0;}
cloc[0] = tik;
cloc[1] = des_tik;
cloc[2] = sec;
cloc[3] = des_sec;
cloc[4] = min; 
cloc[5] = des_min; 

m1:
}
void main(void)
{
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
PORTA=0x00;DDRA=0x00;
PORTB=0x00;DDRB=0xFF;
PORTD=0x40;DDRD=0x3F;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x03;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
// Mode: CTC top=OCR1A
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x0B;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x04;
OCR1AL=0xE2;
OCR1BH=0x00;
OCR1BL=0x00;
TIMSK=0x42;
ACSR=0x80;
#asm("sei")
while (1)
{
while (PIND.6!=0) {};
start++; delay_ms(200);
while (PIND.6!=1) {};
};
}

Скачать архив проекта секудомера; исходный код  , прошивка,  proteus.


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

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

 

Приступим!

Для начала нужно отконфигурировать подключение дисплея в мастере начального кода CVAVR. Там ничего, требующего какого-либо описания нет.

Перечень самых ходовых команд:

Очистка дисплея: lcd_clear();
Размещение надписи на дисплее задается функцией lcd_gotoxy(2,0); где цифра 2 означает что первый слева символ надписи будет выводиться в третью по счету ячейку дисплея слева, имеющую порядковый номер 1, так как счет ячеек идет с цифры 0.
Цифра 0 означает что надпись выводится в первую строчку сверху, 1 соответственно будет значить размещение надписи во второй строке, и.т.д.
Чтобы просто написать что-то на дисплее латиницей, достаточно применить следующий код;
lcd_gotoxy(1,0); // задаем положение первого символа
lcd_putsf("Radiokot");
В итоге на дисплей будет выведена надпись Radiokot

Вывод содержимого текстовых массивов

Можно создать текстовый массив в оперативной памяти контроллера или в памяти программ. В данном случае массивы, сидящие в разных типах памяти выводятся разными командами.
К примеру создадим текстовый массив в памяти программ:
flash char text_mass[] = "Radiokot.ru";
Для вывода его содержимого нужно воспользоваться функцией lcd_putsf
пример: lcd_putsf(text_mass);
На дисплей будет выведено: Radiokot.ru
Если же массив вписан в оперативную память контроллера:
char text_mass[] = "Radiokot.ru";
то его вывод осуществляется аналогично функцией lcd_puts(text_mass);
(без буквы f)
Чтобы просто вывести один символ, достаточно ввести команду:
lcd_putchar('D'); // Будет выведена просто буква D

Вывод произвольного символа из таблицы знакогенератора.

Для вывода какого-либо символа из таблицы знакогенератора дисплея, нужно посмотреть его номер в кодовой странице 0 в даташите.


Рисунок 1 Фрагмент таблицы 0 знакогенератора.

Мне захотелось вывести подряд два символа, первый символ - что помечен сиреневым цветом, и второй- тот, что помечен зеленым. Сиреневый символ имеет код в шестнадцатеричном виде xD1, зеленый символ имеет код x83, выводятся они на дисплей  следующим образом:
lcd_putsf(" xD1 x83");

Вывод русских символов.

Можно конечно, поизвращаться как указано строкой выше, а можно пойти более легким путем:
Были предложены разные варианты, такие как специальная функция-перекодировщик, и еще один вариант с прагмами.
Первый – лишнее утяжеление программы.
Второй вариант не работает во второй версии CVAVR.
Я остановился на варианте, предложенным Aheir-ом. Он поделился маленькой программкой, которая перекодирует символы кириллицы.
Вот скриншот:


                Рисунок 2 Скриншот полезной программки.

Вводим слово Радиокот, нажимаем Convert, получаем крякозабры, те что выделены в нижнем окне, копируем их в строчку для отображения, и на дисплее нормально отображается надпись на русском. По-моему это гораздо проще и легче, нежели изобретать велосипед.

А теперь самое интересное:

Работа с функцией sprintf , позволяющей в частности, отображать значения переменных вперемешку с выводом других символов. Все ниже написанное вытекло из изучения содержимого проектов в папке C: cvavr examples. Я объясню основу, то что удалось
накопать так же в просторах сети.

Для начала немного описания функции sprintf:

Функция sprintf( ) (прототип содержится в файле stdio.h) обеспечивает форматированный вывод в строку. Ее можно записать в следующем формальном виде:
sрrintf ("управляющая строка", аргумент _1, аргумент _2,...);
Управляющая строка содержит компоненты трех типов: обычные символы, которые просто копируются в стандартный выходной поток (выводятся на экран дисплея); спецификации преобразования, каждая из которых вызывает вывод на экран очередного аргумента из последующего списка; управляющие символьные константы.
Каждая спецификация преобразования начинается со знака % и заканчивается некоторым символом, задающим преобразование. Между знаком % и символом преобразования могут встречаться другие знаки в соответствии со следующим форматом:
% [признаки] [ширина_поля] [точность] [F |N |h |l |L] c_n
Все параметры в квадратных скобках не являются обязательными.
На месте параметра c_n (символ преобразования) могут быть записаны:

с - значением аргумента является символ;
d или i - значением аргумента является десятичное целое число;
е - значением аргумента является вещественное десятичное число в экспоненциальной форме вида 1.23e+2;
Е - значением аргумента является вещественное десятичное число в экспоненциальной форме вида 1.23E+2;
f - значением аргумента является вещественное десятичное число с плавающей точкой;
g (или G) - используется, как е или f, и исключает вывод незначащих нулей;
о - значением аргумента является восьмеричное целое число;
s - значением аргумента является строка символов (символы строки выводятся до тех пор, пока не встретится символ конца строки или же не будет, выведено число символов, заданное точностью);
u - значением аргумента является беззнаковое целое число;
х - значением аргумента является шестнадцатеричное целое число с цифрами 0,...,
9, а, b, с, d, е, f;
X - значением аргумента является шестнадцатеричное целое число с цифрами 0,...,
9, А, В, С, О, Е, F;
р - значением аргумента является указатель;
n - применяется в операциях форматирования.

Аргумент, соответствующий этому символу спецификации, должен быть указателем на целое. В него возвращается номер позиции строки (отображаемой на экране), в которой записана спецификация %n.

Необязательные параметры в спецификации преобразования:

· признак минус (-) указывает, что преобразованный параметр должен быть выровнен влево в своем поле;
· признак плюс (+) требует вывода результата со знаком;
· строка цифр, задающая минимальный размер поля (ширина поля). Здесь может так же использоваться символ *, который тоже позволяет задать минимальную ширину поля и точность представления выводимого числа;
· точка (.), отделяющая размер поля от последующей строки цифр;
· строка цифр, задающая максимальное число выводимых символов, или же количество цифр, выводимых справа от десятичной точки в значениях типов float или double (точность);
· символ F, определяющий указатель типа far;
· символ N, определяющий указатель типа near;
· символ h, определяющий аргумент типа short int (используется вместе с символами преобразования d, i, о, u, х, Х);
· символ l, указывающий, что соответствующий аргумент имеет тип long (в случае символов преобразования d, i, о, u, х, X) или double (в случае символов преобразования е, Е, f, g, G);
· символ L, указывающий, что соответствующий аргумент имеет тип long double (используется вместе с символами преобразований е, Е, f, g, G);
· символ #, который может встречаться перед символами преобразования g, f, е и перед символом х. В первом случае всегда будет выводиться десятичная точка, а во втором - префикс 0x перед соответствующим шестнадцатеричным числом.
Если после знака % записан не символ преобразования, то он выводится на экран. Таким образом, строка %% приводит к выводу на экран знака %.
Функция sprintf( ) использует управляющую строку, чтобы определить, сколько всего аргументов и каковы их типы. Аргументами могут быть переменные, константы, выражения, вызовы функций; главное, чтобы их значения соответствовали заданной
спецификации.
При наличии ошибок, например, в числе аргументов или типе преобразования, результаты будут неверными.
Среди управляющих символьных констант наиболее часто используются следующие:

а - для кратковременной подачи звукового сигнала;
b - для перевода курсора влево на одну позицию;
f - для подачи формата;
n - для перехода на новую строку;
r - для возврата каретки;
t - горизонтальная табуляция;
v - вертикальная табуляция;
- вывод символа ;
' - вывод символа ' ;
" - вывод символа ";
? - вывод символа ?.

Например, в результате вызова функции:
sprintf(" tComputer n%d n", i);
сначала выполняется горизонтальная табуляция ( t), т.е. курсор сместится от края экрана, затем на экран будет выведено слово Computer, после этого курсор переместится в начало следующей строки ( n), затем будет выведено целое число i по формату %d (десятичное целое), и, окончательно, курсор перейдет в начало новой строки ( n).
Напечатать строку символов можно и так: sprintf("Это строка символов");

Спецификатор формата Тип данных
%d, %i целое десятичное число
%s текстовая строка
%c один символ
%e, %E число с плавающей точкой в экспоненциальной форме
%f число с плавающей точкой в десятичной записи
%u целое десятичное число без знака
%o целое восьмеричное число без знака
%x, %X целое шестнадцатиричное число без знака
%g, %G либо %e, либо %f в зависимости от того, запись в каком формате короче
%p значение указателя
%n число символов

Много – то как всего… На практике проще:

Разберем пример THERMLCD

Я убрал "лишние детали” и получил вот что:

char lcd_buffer[33]; //создается буфер для символов, выводимых на дисплей
char sign; //объявляются переменные
int temp;
temp=245; /* зададим значение переменной, в проекте имеется ввиду что в этой переменной будет храниться значение температуры датчика, в данном случае будет отображаться температура 24,5 градуса
В переменной sign хранится знак + или – */
sprintf(lcd_buffer,"t=%c%i.%u xdfC",sign,temp/10,temp%10);

Как работает данная функция:

надпись lcd_buffer указывает куда будет помещаться результат обработки переменных.
t= так и отобразится на дисплее
%c указывает компилятору что будет выводится один символ, из переменной sign
%i указывает на то, что будет выведено целое десятичное число – результат операции temp/10 (равно просто 24)
Далее следующая точка так и будет выведена на дисплей 
%u -выводит целое десятичное число без знака, это результат операции
temp%10 (равно 5).
xdfC - выводит на дисплей значок цельсия и символ С, если заглянуть в таблицу символов знакогенератора, то значок цельсия имеет код xdf
Затем функция просто вывела символ С.


Надеюсь что этот скромный труд поможет кому-нибудь в освоении LCD.

sprintf(lcd_buffer,"PWM %3u%c%c%u",pwm,'%',y,slag); если первым идет y то slag появляеться только после изменения y(char) с 0(0- это не char) на + или -
sprintf(lcd_buffer,"PWM %u%c%u%c",pwm,'%',slag,y); так slag будет видно сразу на lcd

Code
/*****************************************************
Project : приемы работы с популярными LCD на контролере HD44780. автор : Freerider 
Date : 24.01.2012
Company : c2.at.ua 
Chip type : ATmega8
Program type : Application
Clock frequency : 2,000000 MHz
*****************************************************/
#include <mega8.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x12 ;PORTD
#endasm
#include <lcd.h>
#include <stdio.h>
#include <delay.h>
int x; // 
long int i; 
float b;
int znak[10];
char lcd_buffer[33];
flash char text_mass[] = "Privet";
char text_mass1[] ="Zdarova";
void main(void)
{
PORTB=0x00;
DDRB=0x00;
PORTC=0x00;
DDRC=0x00;
PORTD=0x00;
DDRD=0x00;
ACSR=0x80;
SFIOR=0x00;
lcd_init(16); // LCD module initialization
while(1) // Бесконечный цикл 
{
   while(x<16) // Цикл для растановки символов на LCD в зав-сти от x
 {
lcd_gotoxy(x,0); // Функция позиция дисплея х-столбец 0-ряд
lcd_putchar('$'); // Функция отображения символа (в данном $, можно любой)
lcd_gotoxy(0,1); // Позиция 0-столбец 1 ряд
sprintf(lcd_buffer,"x=%2u",x); //Функция обеспечивает форматированный вывод в строку 
//lcd_buffer указывет куда будет помещен результат после обработки
//При x=%2u на экран вывед.x= . %-начало преобразования 2-ширина поля u-целое десят.число без знака(точность)
lcd_puts(lcd_buffer); //Выводим на экран массив lcd_buffer
delay_ms(100); // Задержка 100 мс
x++;
lcd_clear(); // Функция очистки экрана
}; 

lcd_gotoxy(0,0);
lcd_putsf("Hello"); //Функция отображение строки расположенной во FLASH (памяти программ)
delay_ms(1000);
lcd_clear(); 
lcd_putsf(text_mass); // Тоже самое только массив задан в начале flash char text_mass[] = "Privet";
delay_ms(1000);
lcd_clear(); 

lcd_putsf(" x52 x31"); // Для вывода символа из таблицы знакогенератора (в данном случае вывед.R1)
delay_ms(1000);
lcd_clear(); 
lcd_puts(text_mass1); // Ф-я для вывода массива который вписан в опер.память char text_mass1[] ="Zdarova" 
delay_ms(1000);
lcd_clear(); 

sprintf(znak,"QWERTY"); // Преобразуем QWERTY с записью в массив znak
lcd_gotoxy(0,0);
sprintf(lcd_buffer,"%s",znak); //Выводим %s-текстовую строку массива znak
lcd_puts(lcd_buffer);//
delay_ms(1000);
lcd_clear();


i=' x40'; // Можно любой символ (в данном случае x40 это @ смотри таблицу знакогенератора hd44780)
lcd_gotoxy(0,0);
sprintf(lcd_buffer,"%c",i); //Выводим %c-один символ i если i='QW' то вывод. только W
lcd_puts(lcd_buffer);//
delay_ms(1000);
lcd_clear();

b=0.2; 
lcd_gotoxy(0,0);
sprintf(lcd_buffer,"%f",b); //Выводим %f-число с плавающей точкой в десятичной записи (вывед.0.200000)
lcd_puts(lcd_buffer);//
delay_ms(1000);
lcd_clear(); 

lcd_gotoxy(0,0);
sprintf(lcd_buffer,"%.1f",b); //Выводим %f-число с плавающей точкой в десятичной записи (вывед.0.2) 
//.1 кол-во цифр выводимых справа от десят.точки в значениях типа float(можно поставить и больше) 
lcd_puts(lcd_buffer);//
delay_ms(1000);
lcd_clear(); 

i=130;
lcd_gotoxy(0,0);
sprintf(lcd_buffer,"%x",i); //Выводим %x-целое шестнадцатиричное число без знака (в данном случае вывед.82)
lcd_puts(lcd_buffer);//
delay_ms(1000); 

i=1521; 
lcd_gotoxy(0,0);
sprintf(lcd_buffer," tComp n%d n",i); // t-делаем горизонт.табуляцию выводим слово Comp после перемещаем на начало след.строки( n)
// выводим число i %d и в конце в начало новой строки ( n)
lcd_puts(lcd_buffer);//
delay_ms(1000);
lcd_clear(); 

for(i=0;i<256;i++)

lcd_gotoxy(0,0);
lcd_putchar(i); //Функция отображает символ в текущей позиции (i) знакогенератора 
lcd_gotoxy(0,1);
sprintf(lcd_buffer,"%u",i); //
lcd_puts(lcd_buffer);
delay_ms(100); 
lcd_clear();
}; 

lcd_write_byte(0b01000000,0b11111); //Запись в HD44780 символа рюмка
lcd_write_byte(0b01000001,0b10001);
lcd_write_byte(0b01000010,0b10001);
lcd_write_byte(0b01000011,0b01010);
lcd_write_byte(0b01000100,0b00100);
lcd_write_byte(0b01000101,0b00100);
lcd_write_byte(0b01000110,0b11111);
lcd_write_byte(0b01000111,0b00000); 

lcd_write_byte(0b01001000,0b11111); // запись перевернутая рюмка
lcd_write_byte(0b01001001,0b00100);
lcd_write_byte(0b01001010,0b00100);
lcd_write_byte(0b01001011,0b01010);
lcd_write_byte(0b01001100,0b10001);
lcd_write_byte(0b01001101,0b10001);
lcd_write_byte(0b01001110,0b11111);
lcd_write_byte(0b01001111,0b00000); 

lcd_gotoxy(0,0);
lcd_putchar(0); 
lcd_gotoxy(1,0);
lcd_putchar(1); 
delay_ms(1000);
};
}

Скачать проект и  proteus.

Еще пример, как вывести  на экран ЖКИ,   бегущую текстовую строку состоящей в данном случае из 500 символов . За воплощение этого примера в жизнь, большое спасибо пользователю sonata.


Исходный код.

Code
/*****************************************************
This program was produced by the
CodeWizardAVR V1.25.9 Professional
Automatic Program Generator
© Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.
.hpinfotech.
Author : test 
Company : test 
Chip type : ATmega8
Clock frequency : 4,000000 MHz
External SRAM size : 0
Data Stack size : 256
*****************************************************/
#include <mega8.h>
// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x12 ;PORTD
#endasm
#include  
#include  
unsigned char i; 
int n_sim=1,m_end=500; //m_end - общее количество символов в исходной строке;
char ish_str[] = " аіё¶yжaЗcЗ їeєcїoіaЗ cїpoєa. B гaЅЅoј ѕpёјepe ІeґyжaЗ cїpoєa іГіoгёїДcЗ іo 2-№ cїpoєe ЈKҐ, Еїoї 'єycoє' єoгa ѕo·іo»Зeї іГіoгёїД ІeґyжyЖ cїpoєy (cѕpaіa-Ѕa»eіo), і »ЖІoј јecїe ё c ёcѕo»Д·oіaЅёeј »ЖІoґo єo»ёАecїіa ·Ѕaєoјecї, і ЈKҐ ёЅгёєaїopax c єoЅїpo»»epoј HD44780 ё»ё aЅa»oґёАЅoј. HaАa»o Еїo№ ѕpoґpaјјГ, ЅaxoгёїcЗ ·гecД www.stas633.narod.ru г»ёЅЅa Еїoґo cooІжeЅёЗ 500 cёјіo»oі!!!!!! ec»ё cїpoєa cocїoёї ё· 500 cёјіo»oі, і MK гoѕo»Ѕёїe»ДЅo ·aЅёјaeї 1,4 єё»oІa№ї д»eБa. " ;
//Движущаяся текстовая строка. В данном примере бегущая строка выводиться во 2-й строке ЖКИ. Этот 'кусок' кода позволяет выводить бегущую строку (справа-налево), в любом месте и с использованием любого количества знакомест, в ЖКИ индикаторах с контроллером HD44780 или аналогичном. Начало этой программы, находится здесь www.stas633.narod.ru длинна этого сообщения 500 символов!!!!!! если строка состоит из 500 символов, в МК дополнительно занимает 1,4 килобайт флеша. 
void beg_str(void)
{
for(i=0;i<15;i++)lcd_write_byte(0xC0+i,lcd_read_byte(0xC1+i));
lcd_gotoxy(15,1); // указали место курсору во второй строке
lcd_putchar(ish_str[n_sim]);
if(++n_sim>m_end)
{n_sim=1;};
delay_ms(100);

}
void main(void)
{

PORTB=0x04;
DDRB=0x00;

PORTC=0x00;
DDRC=0x00;

PORTD=0x00;
DDRD=0x00;


ACSR=0x80;
SFIOR=0x00;

// LCD module initialization
lcd_init(16);

while (1)
{
beg_str();
 lcd_gotoxy(0,0); 
lcd_putsf("Tekstova stroka"); 

// Place your code here
};

}

Проект с исходником и  proteus, + вариант №2

Если при симуляции проекта в proteus'е некорректно отображаются символы кириллицы на ЖКИ, то для правильного отображения кириллицы на ЖК индикаторе распаковать библиотеку LCDrus.zip (приложена в архиве проекта) в папку models proteus'а.


Вольтметр-амперметр до 30 вольт и 10А

Code
/*****************************************************
Version : АЦП
Company : c2.at.ua 
Chip type : ATmega8
Clock frequency : 4,000000 MHz
*****************************************************/
#include <mega8.h>
#asm
.equ __lcd_port=0x12 ;PORTD
#endasm
#define BYTE unsigned char
#define WORD unsigned short int
#define CARDINAL unsigned long int
#include <lcd.h>
char byDisplay[6]; // áóôåð äàííûõ, äëÿ âûâîäà íà ýêðàí 
char Counter;
char Count = 5;
CARDINAL U;
CARDINAL I_izm;
void PrepareData(CARDINAL Data)
{
BYTE i;
for(i=0; i<6; i++)
{
byDisplay[5-i] = Data % 10 + 48;
Data /= 10;
}

void PrintBuf(void)
{
int i;
for(i=0; i<6; i++)
{
lcd_putchar(byDisplay[i]);
}
}
#define ADC_VREF_TYPE 0xC0
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0x7f);
ADCSRA |=0x40; // Start the AD conversion
while ((ADCSRA & 0x10)==0);
ADCSRA |=0x10; // Wait for the AD conversion to complete
return ADCW;

interrupt [TIM1_OVF] void timer1_ovf_isr(void)

WORD tmp;
TCNT1H=0xFF; // Reinitialize Timer 1 value
TCNT1L=0x3C;
if (Counter++ >= Count)

Counter = 0;
lcd_gotoxy(2,0); //íàïðÿæåíèå

PrepareData(U / Count); // read_adc(1)/10.24*256 
byDisplay[0] = byDisplay[2];
byDisplay[1] = byDisplay[3];
byDisplay[2] = '.';
byDisplay[3] = byDisplay[4];
byDisplay[4] = byDisplay[5]; 
byDisplay[5] = 'V';
PrintBuf(); 

lcd_gotoxy(2,1); //òîê èçìåðåííûé
PrepareData(I_izm / Count) ; // read_adc(0)/10.24*256 
byDisplay[0] = byDisplay[2];
byDisplay[1] = byDisplay[3];
byDisplay[2] = '.';
byDisplay[3] = byDisplay[4];
byDisplay[4] = byDisplay[5]; 
byDisplay[5] = 'A';
PrintBuf(); 

U = 0;
I_izm = 0;
}
else
{
U += read_adc(1) * 3;
I_izm += read_adc(0);
}; 
}

void main(void)
{
PORTB=0x00;
DDRB=0x00;

PORTC=0x00;
DDRC=0x00;

PORTD=0x00;
DDRD=0x00;

TCCR1A=0x00;
TCCR1B=0x05;
TCNT1H=0xFA;
TCNT1L=0xE9;
TIMSK=0x04;
ACSR=0x80;
SFIOR=0x00;
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x82;
lcd_init(16);
#asm("sei") 
while (1)
{
// Place your code here
};
}

Скачать архив проекта; исходный код, прошивка,  proteus.

Пользователь siamds написал код для двух каналов ADC для ATMega8.( Источник информации  РадиоКот )Программа создана при помощи генератора кодов CV_AVR, промоделирована в Proteus’e, снабжена подробными комментариями.

Файлы программы и рисунки генератора кодов во вложении.

   

Code
/*****************************************************
This program was produced by the
CodeWizardAVR V1.25.9 Professional
Automatic Program Generator
© Copyright 1998-2008 Pavel Haiduc, HP InfoTech s.r.l.
.hpinfotech.

Project : 
Version : 
Date : 30.07.2012
Author : Siamds 
Company : Home 
Comments: 

Chip type : ATmega8
Program type : Application
Clock frequency : 1,000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 256
*****************************************************/

#include <mega8.h>
#include  
#include  

// Alphanumeric LCD Module functions
#asm
.equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>

//******* Глобальные переменные ******* 
char lcd_buffer[33]; //Буфер обмена LCD
int ch_1; //Переменная хранения данных ADC0
int ch_2; //Переменная хранения данных ADC1

//********* Переменные ADC *********** 
#define FIRST_ADC_INPUT 0 //Первый кнал ADC ADC0
#define LAST_ADC_INPUT 1 //Следующийй канал ADC ADC1
#define ADC_VREF_TYPE 0x00
unsigned int adc_data[LAST_ADC_INPUT-FIRST_ADC_INPUT+1]; //Переменная хранения ADC данных


//*** Обслуживания прерывания для автоматического сканирования каналов ***
interrupt [ADC_INT] void adc_isr(void) 
{
register static unsigned char input_index=0;
adc_data[input_index]=ADCW; //Чтение результата АЦП преобразования
if (++input_index > (LAST_ADC_INPUT-FIRST_ADC_INPUT)) //Селективный выбор 
input_index=0; //следующего входа АЦП
ADMUX=(FIRST_ADC_INPUT | (ADC_VREF_TYPE & 0xff))+input_index;
delay_us(10); //Выдержка времени для стабилизации входного напряжения
ADCSRA |=0x40; //Старт АЦП преобразования
}

//******* Чтение результатов ADC преобразования *******
void adc_convers(void)
{
ch_1= adc_data[0]; //Запись в переменную ch_1 результата ADC 1-го канала
ch_2= adc_data[1]; //Запись в переменную ch_2 результата ADC 2-го канала

lcd_gotoxy(0,0);
sprintf(lcd_buffer,"ADC0 : %4d", ch_1);
lcd_puts(lcd_buffer);

lcd_gotoxy(0,1); 
sprintf(lcd_buffer,"ADC1 : %4d", ch_2); 
lcd_puts(lcd_buffer); 
}

void main(void)
{
// Port B initialization
PORTB=0x00;
DDRB=0x00;

// Port C initialization
PORTC=0x00;
DDRC=0x00;

// Port D initialization
PORTD=0x00;
DDRD=0x00;

// ADC initialization
// ADC Clock frequency: 125,000 kHz
// ADC Voltage Reference: AREF pin
ADMUX=FIRST_ADC_INPUT | (ADC_VREF_TYPE & 0xff);
ADCSRA=0xCB;

// LCD module initialization
lcd_init(16);

// Global enable interrupts
#asm("sei")

while (1)
{
adc_convers(); //Чтение результатов ADC преобразования

};
}

Скачать архив проекта; исходный код, прошивка,  proteus.


Интересный пример в интернете, представлен корейским радиолюбителем.   

При переводе страницы на русский язык использовался машинный перевод, оригинал страницы здесь


http://blog.naver.com/PostList.nhn?from=postList&blogId=wontae12&categoryNo=8&currentPage=36

Исследование робот codevision ATmega8535 (LCD)  

В экспериментах проводиш весь день ... времени на все в обрез и ...  ничего, что особенного ...

Чтобы открыть  книги,  изучать их так трудно .....А исследование это уже весело....... По этим и другим причинам, экспереметировать интересней ...

Как я изучаю codevision "Робот Исследование ATmega8535" ЖК-часть, здесь примеры чтобы учиться.
 


void main(void)
{
// ЖК-модуль инициализации 
lcd_init (16);


lcd_putchar('A');
lcd_putchar('B');
lcd_putchar('C');
} //main


void main(void)
{
// ЖК-модуль инициализации 
lcd_init (16);
// 0 Переход к строке колонки 5
lcd_gotoxy(5,0);
lcd_putchar('A');
  // вывести 1 строке 6 место 
lcd_gotoxy(6,1);
lcd_putchar('B');
}
 


// Объявления переменных
char disp_1[] = "HELLO !";

char disp_2[] = "Student";

// ЖК-модуль инициализации 

lcd_init (16);
 // Переход к началу строки на 0 
lcd_gotoxy (0,0);
 // для   HELLO! вывод 

  lcd_puts(disp_1);  

// Переход к началу строки 1  

 lcd_gotoxy(0,1);  

// Строка1 Студент 
вывод 
в

 lcd_puts(disp_2);

 


// ЖК-модуль инициализации

lcd_init (16);

// Переход к началу строки

lcd_gotoxy (0,0);  

// вывод в Line0

 lcd_putsf("16*2 LCD TEST");

// Переход к началу Строка1

lcd_gotoxy(0,1); 

// Строка1 вывод

 lcd_putsf("robotstudy.com");


char disp_1[] = "16*2 LCD TEST";

char disp_2[] = "HELLO !";
char disp_3[] = "Student";
char disp_4[] = "robotstudy.com";

char disp_5[] = "Lee Jaechang";

// объявление переменной, 

unsigned char key_val;

// PORTD нижнего 4 бита на входе, выходе, установить верхние 4 бита  

// PORTD как нижние 4 бита начальной тянуть, верхние 4 бита установлены в 0
DDRD=0xF0;

PORTD = 0x0F;

// ЖК-модуль инициализации 

lcd_init (16);
  // очистка экрана 
lcd_clear();
lcd_gotoxy(0,0);
lcd_puts(disp_1);

while(1)
{
/ / извлечение значения ниже 4 бита PORTA

 key_val = PIND & 0x0F;

// Х0 включается, если

if ( key_val == 0x0E ){
lcd_clear();
lcd_gotoxy(0,0);
lcd_puts(disp_2);
}

// X1 во включенном положении, иначе если

else if (key_val == 0x0D ){
lcd_clear();
lcd_gotoxy(0,1);
lcd_puts(disp_3);
}

// X2 переключатель ON, остальное, если

else if (key_val == 0x0B ){
lcd_clear();
lcd_gotoxy(0,0);
lcd_puts(disp_4);
lcd_gotoxy(0,1);
lcd_puts(disp_5);
}

// X3 переключатель ON, остальное,

else if (key_val == 0x07 ){  
lcd_clear();
}
};//while



while(1)

{

// ЖК-модуль инициализации 

lcd_init (16);
// HELLO!

lcd_putchar('H');
lcd_putchar('E');
lcd_putchar('L');
lcd_putchar('L');
lcd_putchar('0');
lcd_putchar('!');

/ / Курсор появляется на IR = 0x0E
/ / Раздел 2.1.2 Справочник по командам
_lcd_ready();
_lcd_write_data(0x0E);

delay_ms(1000);

// Курсор появляется и мигает ИК = 0x0F 

_lcd_ready ();
_lcd_write_data (0x0F);
delay_ms (1000);
  // Нет Курсор мигает IR = 0x0D 
_lcd_ready();
_lcd_write_data(0x0D);

delay_ms(1000);

// Не моргнул без курсора IR = 0x0C 

_lcd_ready();
_lcd_write_data(0x0C);
delay_ms(1000);

//Disply OFF IR = 0x0A, 0x09, 0x08
_lcd_ready();
_lcd_write_data(0x09);
delay_ms(1000);
}; //while


 

unsigned char i;

// инициализируем ЖК-модуля 

   lcd_init(16);
  // Выходной сигнал к ЖКИ 
lcd_putsf("16*2 LCD TEST");
lcd_gotoxy(0,1);
lcd_putsf("HELLO !");

while(1)

{

// Право 5 квадратов двигаться 

for( i=0; i<5; i++)
{
_lcd_ready();
_lcd_write_data(0x1C);
delay_ms(500);
 } 
// влево 5 квадратов двигаться
for( i=0; i<5; i++)
{
_lcd_ready();
_lcd_write_data(0x18);
delay_ms(500);
}

}; //while


ex221-8 CG RAM ЖК-продукции.



EX232-01 ЖК-вывода числовой переменной.

// Объявление переменной,
unsigned char c_val = 0xA1;

int int_val = 12345;

// 16 * 2 LCD выхода на объявление символьной переменной 

char lcd_text[16];

// ЖК-модуль инициализации 

lcd_init (16);
// Изменить шестнадцатеричный символ переменной вывод на ЖК-
sprintf(lcd_text, "Char val = 0x%X",c_val);
lcd_gotoxy(0,0);

lcd_puts(lcd_text);

// Десятичное изменения в символьной переменной вывод на ЖК- 

sprintf(lcd_text, "int val = %i",int_val);
lcd_gotoxy(0,1);
lcd_puts(lcd_text); 

 Вот такой молодец, этот парень.

Сам иследовал и другим показал.

Как это делается.......


 

Выводим информацию на ЖКИ в виде счетчика нажатий кнопки.
Вывод на экран  функцией putchar .
Code
/*****************************************************
Project : Ver. 1.0.0
Version : счетчик 0000
Date : 24.10.2011 
Company : c2.at.ua 
Chip type : ATmega8
Program type : Application
Clock frequency : 4,000000 MHz
*****************************************************/ 
#include                          // библиотека ввода вывода микроконтроллера
#asm
 .equ __lcd_port=0x12 ;PORTD           // сообщаем куда подключен экран
#endasm
#include                               // библиотека для LCD
#include                           // библиотека задержки
int cnt=0;
void main(void) 

PORTB=0xFF; 
DDRB=0x00; 
PORTC=0x01; 
DDRC=0x00; 
PORTD=0x00; 
DDRD=0x00; 
ACSR=0x80; 
lcd_init(16); 
while (1) 

 lcd_gotoxy(0,0); 
lcd_putsf("Cnt="); 
lcd_putchar((cnt/1000)%10+0x30); 
lcd_putchar((cnt/100)%10+0x30); 
lcd_putchar((cnt/10)%10+0x30); 
lcd_putchar(cnt%10+0x30); 
if(PINB.2==0) { 
while(PINB.2==0); 
cnt=cnt+1; 

}

Теперь тоже самое, но вывод на экран  функцией  sprintf.
Code
/*****************************************************
Project : Ver. 1.0.0
Version : счетчик 0000
Date : 24.10.2011 
Company : c2.at.ua 
Chip type : ATmega8
Program type : Application
Clock frequency : 4,000000 MHz
*****************************************************/ 
 #include                          // библиотека ввода вывода микроконтроллера
#asm
 .equ __lcd_port=0x12 ;PORTD            // сообщаем куда подключен экран
#endasm
 #include                              // библиотека для LCD
 #include                          // библиотека задержки                    
 #include                           // стандартная библиотека вывода символов на экран 
unsigned char lcd_buffer[16]; 
int cnt=0;
void main(void) 

PORTB=0xFF; 
DDRB=0x00; 
PORTC=0x01; 
DDRC=0x00; 
PORTD=0x00; 
DDRD=0x00; 
ACSR=0x80; 
lcd_init(16); 
while (1) 

 sprintf(lcd_buffer,"Cnt=%i",cnt);    // записуем в масив показания на экран 
 lcd_clear();                                  // чистим дисплей перед выводом
 lcd_puts(lcd_buffer);                    // выводим масив на LCD
delay_ms(50); 
 if(PINB.2==0) {                           //
while(PINB.2==0); 
cnt=cnt+1; 

}

Функция  itoa.
Code
/*****************************************************
Project : Ver. 1.0.0
Version : счетчик 0000
Date : 24.10.2011 
Company : c2.at.ua 
Chip type : ATmega8
Program type : Application
Clock frequency : 4,000000 MHz
*****************************************************/ 
#include <mega8.h> // библиотека ввода вывода микроконтроллера
#asm
.equ __lcd_port=0x12 ;PORTD // сообщаем куда подключен экран
#endasm
#include <lcd.h> // библиотека для LCD
#include // библиотека задержки 
#include // стандартная библиотека вывода символов на экран 
char str_LCD [4]; //зарезервируерм 4 байта для строковой переменной
int cnt=0;
void main(void) 

PORTB=0xFF; 
DDRB=0x00; 
PORTC=0x02; 
DDRC=0x00; 
PORTD=0x00; 
DDRD=0x00; 
ACSR=0x80; 
lcd_init(16); 
while (1) 

lcd_gotoxy(0,0); //Куда выводить: позиция, строка 
lcd_clear(); // чистим дисплей перед выводом 
lcd_putsf("Cnt=");
itoa(cnt, str_LCD); //перевод числа в строку 

lcd_puts(str_LCD); //Вывод на ЖКИ 
delay_ms(50); 
if(PINB.2==0) { //
while(PINB.2==0); 
cnt=cnt+1; 

if(PINB.3==0) { //
while(PINB.3==0); 
cnt=cnt-1; 

}
}

Итог практически одинаков, но размеры скомплимированых хеков различаются значительно.
Скачать  proteus.
 

 Делаем плавную цифровую регулировку . Для плавной регулировки используем ШИМ.
Широтно-импульсная модуляция (Pulse-width modulation (PWM)).
В CodeVisionAVR, выберем следующие установки:
 
Для реализации ШИМа используем Timer 2.Код:
Code
/*****************************************************
This program was produced by the
CodeWizardAVR V2.04.4a Advanced
Automatic Program Generator
© Copyright 1998-2009 Pavel Haiduc, HP InfoTech s.r.l.
.hpinfotech.

Project : Fast PWM
Date : 21.02.2012
Company : c2.at.ua 
Chip type : ATmega8
Program type : Application
Clock frequency : 4,000000 MHz
*****************************************************/
#include <mega8.h>
#asm
.equ __lcd_port=0x12 ;PORTD
#endasm
#include <lcd.h>
#include <delay.h>
#include  
unsigned char lcd_buffer[16];
unsigned int tmp=128;
void main(void)
{
PORTB=0b00110000;
DDRB=0b00001000; 

PORTC=0x00;
DDRC=0x00;

PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x00;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Timer/Counter 2 initialization
// Clock source: System Clock //тактируется внутренним генеретором
// Clock value: 500,000 kHz //частота счета
// Mode: Fast PWM top=FFh //переведен в режим ШИМ
// OC2 output: Non-Inverted PWM //выход не инвертирован
ASSR=0x00;
TCCR2=0x6A; //выбор режима и частоты счетчика
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
lcd_init(16); // LCD module initialization
while (1)
{
if((PINB.4==0)&&(tmp !=0xff))
tmp+=1;
delay_ms(10); // задержка 10 мс. 

if((PINB.5==0)&&(tmp !=0x00))
tmp-=1;
delay_ms(10); // задержка 10 мс. 

OCR2 = tmp; // заполнение ШИМ от 0 до 255 

sprintf(lcd_buffer," PWM = %i%%",((tmp*100)/255)); // записуем в масив показания на экран 
lcd_clear(); // чистим дисплей перед выводом
lcd_puts(lcd_buffer); // выводим масив на LCD
delay_ms(50);

};
}

 
 
Скачать архив проекта исходник, proteus.
 

Простой пример реализации частотомера....
Используем 1й счетчик тактируемый от внешнего генератора, пин T1.
    
 
 
Code
/*****************************************************
CodeWizardAVR V2.04.4a Advanced
Automatic Program Generator
© Copyright 1998-2009 Pavel Haiduc, HP InfoTech s.r.l.

Date : 12.03.2012
Author : c2.at.ua

Chip type : ATmega8
AVR Core Clock frequency: 4,000000 MHz

*****************************************************/

#include <mega8.h>
#include <delay.h>
#asm
.equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>
#include  

unsigned long int frequency;

unsigned char lcd_buffer[17]; //Буфер LCD

void main(void)
{

PORTB=0x00;
DDRB=0x00;
PORTC=0x00;
DDRC=0x00;
PORTD=0x00;
DDRD=0x00;

TCCR0=0x00;
TCNT0=0x00;
TCCR1A=0x00;
TCCR1B=0x07;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
MCUCR=0x00;
TIMSK=0x01;
ACSR=0x80;
SFIOR=0x00;
lcd_init(16);
#asm("sei")

while (1)
{

TCNT1=0; //Обнуляем
 // воспользуемся delay_xx надо выдержать секунду
 //на практике для этого лучше использовать второй счетчик
delay_ms(998);
delay_us(500);
//Подсчитываем сколько насчитал счетчик , пин T1
frequency =TCNT1; 

sprintf(lcd_buffer," %i Hz ",frequency); // 
lcd_gotoxy(2,0); //указали место на дисплее
lcd_puts(lcd_buffer); 

};
}

 
 
 
 

Этот проект дает Вам приятный и простой калькулятор с использованием AVR микроконтроллера. Он имеет 2 клавиатуры, как показано на схеме, а результаты отображаются на ЖК-дисплей 16x2. Вы можете сделать SIN, COS, загар функций с помощью этого проекта.
Код написан на языке C (Codevision AVR) . Вы можете скачать файл codevision проекта, а также файл Proteus моделирования.
 
 

Code

#include <mega16.h>
#include <delay.h>
#include <lcd.h>
#include <stdlib.h>
#include <math.h>

#asm
.equ __lcd_port=0x18
#endasm
//#############################################
int key(void);
float _Main(void);
void Mohandes(void);
void Mohasebe(void);
void Alamat(int,int);
float Emoji(int);
//#############################################
float a = 0 , b = 0 , c = 0 , q , t;
int i ;
char y=0 , lcd[25] , z ;
//#############################################
void main(void){

DDRB=0x0F;
DDRC=0x07;
DDRD=0x0F;

lcd_init(16);
while (1){
_Main();
}
}
//#############################################################
float _Main(void){
int Loop = 1 ;
y = key();
if( y == 15 ){a = 0 ;b = 0 ;c = 0 ;lcd_clear();return 0 ;}
if( y < 10 ){
a = (a*10)+y ;
itoa(y , lcd);
lcd_puts(lcd);
delay_ms(50);
}

if( y > 9 && y < 16 ){
if( y == 15 ){a = 0 ;b = 0 ;c = 0 ;lcd_clear();return 0 ;}
z = y ;
Alamat(y,1);
while(Loop){
y = key();
if( y == 15 ){a = 0 ;b = 0 ;c = 0 ;lcd_clear();return 0 ;}
if( y < 10 ){
b = (b*10)+y ;
itoa(y , lcd);
lcd_puts(lcd);
delay_ms(50); 
}else if(y == 14){
lcd_putchar('=');
Mohasebe();
y = 0 ;
Loop = 0 ;
}
}

if( y > 15 ){
lcd_clear();
a= 0 ; b = 0 ; c = 0;
Alamat(y , 2);
z = y ;
Loop = 1 ;
while(Loop){
y = key();
if( y == 15 ){a = 0 ;b = 0 ;c = 0 ;lcd_clear();return 0 ;}
if(y < 10){
a = (a*10) + y ;
itoa(y , lcd);
lcd_puts(lcd);
delay_ms(50);
}else if ( y == 14){
lcd_putchar('=');
Mohandes();
}
Loop = 1 ;
}
}
return 0;
}
//##########################################################
void Mohasebe(void){ 
if(z == 10)c = a / b ;
if(z == 11)c = a * b ;
if(z == 12)c = a - b ;
if(z == 13)c = a + b ;
ftoa(c , 3 , lcd); 
lcd_puts(lcd);
delay_ms(100);
}
//#########################################################
float Emoji(int rr){
q=1;
for(i=0;i<rr;i++)q = q * 2.71728 ;
return q; 
}
//######################################################### 
void Mohandes(void){
t = (3.1415926535897932384626433832795/180)*a ;
if(z == 16)c = sin(t) ;
if(z == 17)c = cos(t) ;
if(z == 18)c = tan(t) ;
if(z == 19)c = 1/tan(t) ;
if(z == 20)c = asin(t) ;
if(z == 21)c = acos(t) ;
if(z == 22)c = log(a) ;
if(z == 23)c = sqrt(a) ;
if(z == 24)c = Emoji(a) ;
ftoa(c , 3 , lcd); 
lcd_puts(lcd);
delay_ms(100);
}
//#########################################################
void Alamat(int Moji,int Halat){
if(Halat == 1){
if(Moji == 10)lcd_putchar('/') ;
if(Moji == 11)lcd_putchar('*') ;
if(Moji == 12)lcd_putchar('-') ;
if(Moji == 13)lcd_putchar('+') ; 
delay_ms(100); 
}
if(Halat == 2){
if(Moji == 16)lcd_putsf("Sin ") ;
if(Moji == 17)lcd_putsf("Cos ") ;
if(Moji == 18)lcd_putsf("Tan ") ;
if(Moji == 19)lcd_putsf("Cot ") ; 
if(Moji == 20)lcd_putsf("aSin") ;
if(Moji == 21)lcd_putsf("aCos") ;
if(Moji == 22)lcd_putsf("Log ") ;
if(Moji == 23)lcd_putsf("Sqrt ") ; 
if(Moji == 24)lcd_putsf("exp ") ;
delay_ms(100);

}
}
//#########################################################
int key(void){
char KEY = 1 ;
while(KEY){

PORTD.0 = 1 ;
PORTD.1 = 0 ;
PORTD.2 = 0 ;
PORTD.3 = 0 ;
if(PIND.4 == 1){return 7 ; KEY = 0;delay_ms(50);} 
if(PIND.5 == 1){return 8 ; KEY = 0;delay_ms(50);} 
if(PIND.6 == 1){return 9 ; KEY = 0;delay_ms(50);} 
if(PIND.7 == 1){return 10; KEY = 0;delay_ms(50);} 
//==========================================
PORTD.0 = 0 ;
PORTD.1 = 1 ;
PORTD.2 = 0 ;
PORTD.3 = 0 ;
if(PIND.4 == 1){return 4 ; KEY = 0;} 
if(PIND.5 == 1){return 5 ; KEY = 0;} 
if(PIND.6 == 1){return 6 ; KEY = 0;}
if(PIND.7 == 1){return 11; KEY = 0;} 
//==========================================
PORTD.0 = 0 ;
PORTD.1 = 0 ;
PORTD.2 = 1 ;
PORTD.3 = 0 ;
if(PIND.4 == 1){return 1 ; KEY = 0;} 
if(PIND.5 == 1){return 2 ; KEY = 0;} 
if(PIND.6 == 1){return 3 ; KEY = 0;} 
if(PIND.7 == 1){return 12; KEY = 0;} 
//==========================================
PORTD.0 = 0 ;
PORTD.1 = 0 ;
PORTD.2 = 0 ;
PORTD.3 = 1 ;
if(PIND.4 == 1){return 15; KEY = 0;} 
if(PIND.5 == 1){return 0 ; KEY = 0;} 
if(PIND.6 == 1){return 14; KEY = 0;} 
if(PIND.7 == 1){return 13; KEY = 0;}

//==================================================
PORTC.0 = 1 ;
PORTC.1 = 0 ;
PORTC.2 = 0 ;
if(PINC.5 == 1){return 16 ; KEY=0;}
if(PINC.6 == 1){return 17; KEY=0;}
if(PINC.7 == 1){return 18 ; KEY=0;}
//===================================================== 
PORTC.0 = 0 ;
PORTC.1 = 1 ;
PORTC.2 = 0 ;
if(PINC.5 == 1){return 19 ; KEY=0;} 
if(PINC.6 == 1){return 20 ; KEY=0;}
if(PINC.7 == 1){return 21 ; KEY=0;}
//=====================================================
PORTC.0 = 0 ;
PORTC.1 = 0 ;
PORTC.2 = 1 ;
if(PINC.5 == 1){return 22 ; KEY=0;} 
if(PINC.6 == 1){return 23 ; KEY=0;}
if(PINC.7 == 1){return 24 ; KEY=0;}

KEY = 1 ; 
}
}
//############################################################

   
 
 
Скачать файлы проекта.Источник: www.elec4u.ir (перевод текста, машинный)))))))) 
 

 
Генератор  источник импульсов.Выходная частота, снимаемая с выхода ШИМ (вывод 15 МК), задается энкодером с кнопкой и показывается на экране ЖКИ
Тактовая частота МК стабилизируется кварцем 8МГц
При нажатии и удержании кнопки энкодера 0.5с меняется возможность установки частоты при подаче питания генератор выключен, импульсы на выходе появляются при повороте ручки энкодера, частоту можно менять на 1Гц; после первого нажатия кнопки энкодера частоту можно задавать десятками герц, после второго - сотнями и после третьего нажатия кнопки,
 
частота меняется тысячами герц (до 30кГц); затем все повторяется.
 
О точности.
Значения выходной частоты проверялись осциллографом. На малых частотах, примерно до 200Гц, значения совпадают с измеренными на осциллографе, затем чем больше частота, тем больше погрешность (это получается из-за нецелых чисел, записываемых в регистр сравнения). Точность можно повысить, если в регистр сравнения заносить константы из массива (мне высокие частоты не нужны были, да и просто лень считать и заносить числа в массив))), На высоких частотах, чтобы повысить точность, нужно брать другую частоту таймера.
Разъем J1 для внутрисхемного программирования МК.
Code
/*****************************************************
Project : Pulse Generator
Version : 1.0
Date : 19.09.2010
Author : Serega (Deneb-80)
Comments: Модернизация c2.at.ua.

Chip type : ATmega8
Program type : Application
Clock frequency : 8,000000 MHz
Memory model : Small
External SRAM size : 0
Data Stack size : 256
*****************************************************/
#include <mega8.h>
#include <delay.h>
#asm
.equ __lcd_port=0x12 ;PORTD
#endasm
#include <lcd.h>
#include <stdio.h>
unsigned char lcd_buffer[33]; // массив с данными для экрана
unsigned char ENC_COUNT=0; // счетчик для кнопки энкодера
unsigned int EncData=0; // 0...65535
unsigned int F0=0;
float temp;
float div1;

#define Fclk 8000000.000

#define div 64.000 // предделитель таймера T1. Если предделитель равен 64,
#define MIN_VALUE 0 // то максимальная частота будет 30кГц, т.к. после будут
#define MAX_VALUE 30000 // уже отрицательные значения в регистре OCR1A


void Encquest(void)
{

switch (ENC_COUNT)
{
case 0:{if ((PINC.4==0)&(PINC.5==1)&(EncData<MAX_VALUE))
{
delay_ms(250);
EncData += 1;
};
if ((PINC.4==1)&(PINC.5==0)&(EncData>MIN_VALUE))
{
delay_ms(250);
EncData -= 1;
};
break;
}
case 1:{
if ((PINC.4==0)&(PINC.5==1)&(EncData<=(MAX_VALUE-10)))
{
delay_ms(250);
EncData += 10;
};
if ((PINC.4==1)&(PINC.5==0)&(EncData>=(MIN_VALUE+10)))
{
delay_ms(250);
EncData -= 10;
};
break;
}
case 2:{
if ((PINC.4==0)&(PINC.5==1)&(EncData<=(MAX_VALUE-100)))
{
delay_ms(250);
EncData += 100;
};
if ((PINC.4==1)&(PINC.5==0)&(EncData>=(MIN_VALUE+100)))
{
delay_ms(250);
EncData -= 100;
};
break;
}
case 3:{
if ((PINC.4==0)&(PINC.5==1)&(EncData<=(MAX_VALUE-1000)))
{
delay_ms(250);
EncData += 1000;
};
if ((PINC.4==1)&(PINC.5==0)&(EncData>=(MIN_VALUE+1000)))
{
delay_ms(250);
EncData -= 1000;
};
break;
}

} // switch

} // подпрограмма опроса


// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Place your code here
Encquest();

}

void main(void)
{
// Declare your local variables here
PORTB=0b00000000;
DDRB=0b00000000;
PORTC=0b10111000; // «WzAVR «Port C initialization
DDRC=0b00000000;
PORTD=0b00000000; // «WzAVR «Port D initialization
DDRD=0b00000000;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
TCCR0=0x03;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 125,000 kHz
// Mode: CTC top=OCR1A
// OC1A output: Toggle
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x40;
TCCR1B=0x0B;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer 2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

/******************* Инициализация ЖКИ ***********************/
lcd_init(16);
#asm("sei")
lcd_clear(); // чистим дисплей перед выводом
lcd_putsf("Generator vkl."); // записываем в массив для экрана
lcd_puts(lcd_buffer); // выводим массив на LCD
lcd_gotoxy(0,1); // переходим на вторую строку
lcd_putsf("ShIM + chastota ");
delay_ms(2000);
lcd_clear();

while (1)
{
if (PINC.3==0 ) { //вход в меню настроек
while(PINC.3==0); //
lcd_clear();
ENC_COUNT++; //Установка шага частоты
delay_ms(15);
};
if (ENC_COUNT>3) ENC_COUNT = 0;


if (EncData>0)
{
DDRB=0x02; // делаем PB1 выходом
F0 = EncData;
div1 = (float)(2*div*F0);
temp = (float)((Fclk/div1)-1); // деление на 2 - это сдвиг вправо на одно значение
OCR1A = temp;
}
if (F0!=EncData)
{
F0 = EncData;
}

if (F0==0)
{
DDRB=0x00; //отключаем частотный выход
lcd_gotoxy(0,0);
sprintf(lcd_buffer, "freq.= 0Hz ");
lcd_puts(lcd_buffer); // частота 0.0Hz
}


if ((F0>0)&(F0<1000))
{
lcd_gotoxy(0,0);
sprintf(lcd_buffer, "freq.= %uHz ", F0);
lcd_puts(lcd_buffer); // выводим массив на LCD

}
else
{

if ((F0>0)&(F0%1000)<10)
{
lcd_gotoxy(0,0);
sprintf(lcd_buffer,"freq.=%u.00%ukHz ", F0/1000, F0%1000);
lcd_puts(lcd_buffer);
}

if ((F0>0)&((F0%1000)>=10)&((F0%1000)<100))
{
lcd_gotoxy(0,0);
sprintf(lcd_buffer,"freq.=%u.0%ukHz ", F0/1000, F0%1000);
lcd_puts(lcd_buffer);
}

if ((F0>0)&(F0%1000)>=100)
{
lcd_gotoxy(0,0);
sprintf(lcd_buffer,"freq.=%u.%ukHz ", F0/1000, F0%1000);
lcd_puts(lcd_buffer);
}

};


switch (ENC_COUNT)
{
case 0:{
lcd_gotoxy(0,1);
sprintf(lcd_buffer, "step set.*1Hz ");
lcd_puts(lcd_buffer);

break;
}
case 1:{
lcd_gotoxy(0,1);
sprintf(lcd_buffer, "step set.*10Hz ");
lcd_puts(lcd_buffer);
break;
}
case 2:{
lcd_gotoxy(0,1);
sprintf(lcd_buffer, "step set.*100Hz ");
lcd_puts(lcd_buffer);
break;
}
case 3:{
lcd_gotoxy(0,1);
sprintf(lcd_buffer, "step set.*1000Hz");
lcd_puts(lcd_buffer);
break;
}

} // switch

};
}

Скачать исходный проект с proteus. 
 
 
  
 
Пример использования Watchdog Timer  (программно, fuse не запрограммирован) .

Код программы.
Code
/*****************************************************
CodeWizardAVR V2.04.4a 
Chip type : ATmega8
AVR Core Clock frequency: 4,000000 MHz
*****************************************************/
#include <mega8.h>
#asm
.equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>
#include // библиотека задержки 
#include // стандартная библиотека вывода символов на экран 
unsigned char lcd_buffer[16];
unsigned int pokazometr=0; 
unsigned char iii=0; 
eeprom unsigned int kol_VKL=0; 
void main(void)
{
PORTB=0b00000000; //подтяжка
DDRB=0b00000000; //выход
PORTC=0b00000011; 
DDRC=0b00000000;
PORTD=0b00000000; 
DDRD=0b00000000; 
ACSR=0x80;
SFIOR=0x00;
lcd_init(16);
kol_VKL++;
lcd_gotoxy(0,0); 
lcd_putsf("c2.at.ua");
lcd_gotoxy(0,1);
lcd_putsf("START MK.");
while (iii<200) {iii+=1;
delay_ms(8);}; //задержка надписи 
lcd_clear(); 
// Watchdog Timer initialization
// Watchdog Timer Prescaler: OSC/2048k
#pragma optsize-
WDTCR=0x1F;
WDTCR=0x0F;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

while (1)

#asm("wdr"); //Сбрасываем счетчик WDT 
pokazometr++;//Счетчик работы МК, - показометр

sprintf(lcd_buffer,"pokazometr=%i",pokazometr); // записуем в масив показания на экран 
lcd_gotoxy(0,0); // указали место на дисплее
lcd_puts(lcd_buffer); // выводим масив на LCD

sprintf(lcd_buffer,"kol_VKL.=%i",kol_VKL); // записуем в масив показания на экран 
lcd_gotoxy(0,1);
lcd_puts(lcd_buffer); // выводим масив на LCD
// delay_ms(30); 
if(PINC.0==0) while (1) {} //имитируем зависание 

if(PINC.1==0) { // 
pokazometr=0;
kol_VKL=0; //обнуляем счетчик включений
lcd_clear(); 
}
};
}

Проект ; исходник, протеус.  
 

 
Пример работы аналогового компаратора, МК ATmega8.
Активируем функцию в генераторе кода..
.  
 
Схема в протеусе
Code
/***************************************************** 
CodeWizardAVR V2.04.4a Advanced 
Date : 07.09.2012 
Author : C@at 
Company : c2.at.ua 
Comments: Analog Comparator 
Chip type : ATmega8 
AVR Core Clock frequency: 8,000000 MHz 
*****************************************************/ 

#include  
#asm 
  .equ __lcd_port=0x18 ;PORTB 
#endasm 
#include  
void main(void) 

PORTB=0x00; 
DDRB=0x00; 
PORTC=0x00; 
DDRC=0x00; 
PORTD=0x00; 
DDRD=0x08; 

// Analog Comparator initialization 
// Analog Comparator: On 
// Analog Comparator Input Capture by Timer/Counter 1: Off 
ACSR=0x00; 
SFIOR=0x00; 
//SFIOR=0x08;//негатив 
lcd_init(20); 
while (1) 
  { 
  PORTD.3=ACSR>>5;  
  if (PORTD.3==1 ) {  
  lcd_putsf("log.1 na PORTD.3 ");  
  }else {  
  lcd_putsf("log.0 na PORTD.3"); }; 
  lcd_gotoxy(0,0);  
  }; 
}

Архив; протеус, прошивка, код. 
 

 
Связь двух МК Atmega8  по USART.На передающей стороне кнопочки на на принимающей светодиоды. 
 
 

Программа от пользователя sanypes.
 

 
Сигнал состоит из серии длинной и короткой сирены, в конце кря-кря.
 

 
 
В настоящее время появилось много интересных и не сложных в изготовлении любительских устройств на микроконтроллерах ATtiny и ATmega , но перед большинством сразу возникает вопрос - как и чем тогда их запрограммировать?
На самом деле все очень просто, ниже приведен пример как это можно сделать с помощью PonyProg для "прошивки" ATtiny2313.
В компьютере для подключения программатора должно быть наличие LPT или СОМ порта, т.к. на работу с USB PonyProg изначально не был рассчитан. 
Скачать саму программу можно на сайте ее автора - Сlaudio Lanconelli , в разделе Download, последняя версия сейчас - v2.07, на сайте там так же есть схемы подключения для разных контроллеров и микросхем памяти.
Программатор или адаптер безопасней подключать к выключенному компьютеру, "горячее подключение" устройств не рекомендуется и грозит выходом из строя оборудования! После скачивания программы и установки на компьютере запускаем ее, в двух появляющихся окнах соглашаемся - жмем на ОК рис.1.Запускаем PonyProg 
 
1. Запускаем PonyProg
При первом запуске нужно будет сделать калибровку - нажимаем Setup > выбираем Calibration> нажимаем Yes > OK. рис.2.Делаем калибровку PonyProg
 2. Делаем калибровку PonyProgВсе - калибровка выполнена и при следующих запусках программы ее уже проводить больше не нужно.
Дальше нам нужно зайти в меню Setup > выбрать Interface Setup... (или кнопка на панели "гаечный ключ")
 
рис.3.Настройка Interface Setup... 
3. Настройка Interface Setup... в PonyProgтам проверяем установки для подключаемого нами программатора.
 рис.4.Выбор порта в PonyProg 
4. Выбор порта в PonyProg Для LPT-программатора выбрать Parallel или Serial - для программатора подключаемого к СОМ, после выбора нужного порта нажимаем для проверки определения подключенного устройства - Probe и должно появиться сообщение - Test OK!Пони Прог определяет наличие подключенного устройства только по соответствующим перемычкам на разъеме и на самом деле этот тест не говорит об исправности самого программатора - только о его наличии.

В случае появления сообщения Test Failed - может означать, что возможно не правильно выбран в списке тип программатора и нужно попробовать другие варианты в настройках I/O port setup или возможно придется проверить еще настройки самой ОС, настройки в BIOS - LPT порт должен иметь адрес 378h, включен в режиме работы ECP, EPP или ECP+EPP, режим работы SPP-Normal нам не подойдет, к тому же порт к которому подключен программатор не должен быть "занят" другими устройствами, такими как например принтер, модем или другим оборудованием.Выбираем из списка тип микросхемы, которую нужно запрограммировать, на скриншотах далее показан пример для ATtiny2313рис.5.Выбор типа микросхемы в PonyProg 
5. Выбор типа микросхемы в PonyProgС начала рекомендуется перед записью прочитать контроллер, это позволит лишний раз убедиться в том, что он определяется, что программа правильно настроена и все остальное работает как нужно.
Сообщение об ошибке Device missing or unknown device (-24) (Устройство неизвестно или повреждено) - говорит о том что Понипрог не может прочитать микросхему и нужно еще раз проверить правильность подключения, подается ли питание на программируемый контроллер и настройки самой программы
рис.6. Сообщение об ошибке Device missing or unknown device (-24) 
6. Сообщение об ошибке Device missing or unknown device (-24) в PonyProg

Если все нормально читается, то открываем файл прошивки, выбрав Open Device File... ( или иконка - "желтая папка")
 рис.7.Открытие файла прошивки в PonyProg
 7. Открытие файла прошивки в PonyProgстандартная процедура - в открывшемся окне выбираем папку где находиться нужный файл > кликаем мышкой на самом файле и потом нажимаем "Открыть". Если не нужно записывать всю микросхему, а только область FLASH или EEPROM, то выбираем соответствующее - Open Program File (FLASH) или Open Data File (EEPROM).
Программируем нажав на иконку Write Device All (запись) или иное, если нужно записать только FLASH или EEPROM, при этом появиться шкала отображающая процесс записи. по окончании записи должно появиться - Programming successful (программирование завершено). 
Все микроконтроллер записан.Если нужно изменить установку FUSE, то открываем - Security and Configuration Bits... (или кнопка "замок")рис.8.Открытие окна установки FUSE-бит в PonyProg 
8. Открытие окна установки FUSE-бит в PonyProg
В этом окне можно изменить (при необходимости) установку FUSE-бит , снимая или отмечая галочками на нужных нам. 
Здесь ВАЖНО помнить, что после некоторых изменениях Фьюзов, будет НЕ ВОЗМОЖНО повторное программирование этого микроконтроллера с PonyProg до тех пор, пока в (лучшем случае) не будут поданы внешние тактирующие импульсы на вывод XTAL или FUSE не будут сброшены в первоначальные установки с помощью более сложного параллельного программатора, поэтому прежде чем нажать на Write - проверяйте все внимательно!
рис.9.Окно установки FUSE-бит в PonyProg
9. Окно установки FUSE-бит в PonyProgОсновные кнопки здесь - Write (запись) и Read (чтение). Установленная галочка соответствует - будет записан 0. 
В PonyProg, как и в большинстве других подобных программ, галочка обозначает что будет записан 0, а не единица, как многие ошибочно думают. Так как вся память (микроконтроллеров, ПЗУ и просто микросхем памяти) не записанная (чистая) содержит во всех ячейках единицы - FF, то можно при программировании в них записать только ноль (запрограммировать) или оставить как F (=1) -не программировать ячейку.Основные используемые кнопки (иконки) панели в PonyProg
 10. Обозначение кнопок в PonyProgКнопки верхнего ряда:
1. New Window - открыть новое окно2. Open Device File... - открыть файл прошивки
3. Open Program Memory (FLASH) File - открыть файл прошивки FLASH
4. Open Data Memory (EEPROM) File - открыть файл прошивки EEPROM5. Save Device File – сохранить файл
6. Save Program Memory (FLASH) File - сохранить файл прошивки FLASH
7. Save Data Memory (EEPROM) File - сохранить файл прошивки EEPROMКнопки нижнего ряда: 
8. Read Device - прочитать все микросхему
9. Read Program Memory (FLASH) - прочитать FLASH
10. Read Data Memory (EEPROM) - прочитать EEPROM11. Write Device - записать все микросхему
12. Write Program Memory (FLASH) - записать FLASH
13. Write Data Memory (EEPROM) - записать EEPROM14. Erase all the Device to FF - стереть микросхему 
15. Security and Configuration Bits... - вызов меню FUSE и биты конфигурации Источник статьи 
 

 
Как реанимировать Atmega8 (Atmega168).Множество раз приходится при прошивке МК выставлять определенные Fuse Bits.Порой, кажется, что знаешь наизусть нужную комбинацию бит.Так нет, все равно бывает, наступаешь на эти грабли снова и снова.Последний мой случай, насколько помню, выставил все точно, прошил, а контроллер программатор больше не видит :(( ….
Допустил Ашипку и сам не заметил какую.
В таких случаях уже нужен  параллельный программатор. Но Atmeg’у можно починить и без него. Для этого понадобиться второй такой же микроконтроллер.Или если по неосторожности или по не знанию запрограммировать микроконтроллеру Atmega8 во фьюзах бит RSTDISBL, то последовательным программатором его уже не прошить.
Это решение я нашел в интернете давно, где точно уже не помню, пользуюсь уже не впервый раз, и как не странно такой простой способ помогает.
 Принцип действия прост: «неисправную» Atmeg’у накладывается сверху на «лечащую» со специальной прошивкой.
Лечащая (ATmega8 прошитая спец. программой из архива) должна тактироваться от внутреннего RC генератора 1 MHz, или можно взять новую, с фьюзами по умолчанию.
На вывод Reset «неисправной» Atmeg’и подается 12 Вольт.Питания +5 (VCC) и +12 (RESET) подаются  одновременно. Через секунду все готово.
Я  делаю это все, прямо на своей отладочной плате. 
Вот есть такой рисуночек в интернете, он еще наглядней отображает этот принцип «лечения».
 
В данном случае Atmega с прошивкой из приложенного архива выполняет функцию программатора. Функция у него только одна – сброс фьюзов к заводским настройкам.
Все фьюзы будут сброшены к заводским настройкам и Atmega снова можно прошить, последовательным программатором.Аналогичная ситуация может возникнуть с Atmega168.
Для этого потребуется другая прошивка (приложена в архиве.)
 
 

В обычных схемах на МК, варианты выставленых Fuse Bits не отличаются большим разнообразием, вот самые распространенные варианты для ATmega8 и ATtiny2313для PonyProg и CodeVisionAVR
 
 
 
 
 
 
 
 
 
Калькулятор фьюз,  может работать на компьютере автономно. 
 
 
програматор

 

                             Электронные компоненты на http://aliexpress.com
Digital LCD Power Timer  Д/У три канала. Часы + будильник. DC 100V 10A V / A
AC-Digital-V.A.-LED
Digital LCD Power Timer.
20-555 20-555 20-555 20-555  
           
 ATMEGA8A  TQFP-32 PT2262 coding decoder   ATMEGA128A   ATMEGA328P-DIP Микросхема AD9850   
 ATMEGA8A  TQFP-32 10pcs/lot PT2262 DIP-18 Encoding decoder  10pcs Titanium Step Drill Bits 3-20mm  20-555  20-555   
           
LCD 20X4 5V Blue nokia 5110 lcd ST7920  Сдвиговый регистр 74HC595D  1602 ЖК (синий экран)   
  LCD 20X4 5V Blue nokia 5110 lcd модуль (2) Titanium Step Drill Bits 3-20mm  20-555   
           
RELAY-12V-DC 8-channel  relay 5V SLA-12VDC Relay 30A T90  SRA-12VDC-CL 20A  5V  Relay Module 
   8-channel  relay 5V SLA-12VDC-SL-C   Relay 30A T90    5V trigger Channel Relay Module   
           
Плата AD9850 Transmitter-Receive DSO138 2.4  SIM800L GPRS GSM   Генератор до 10МГц
20-555 433Mhz RF transmitter receiver link kit for Arduino DSO138 2.4 SIM800L GPRS GSM Module MicroSIM -TTL Serial Port 20-555   
           
Клемник 2Pin 5.0 мм  Plastic  Box Red Light 250V 40 Pin Single 40Pin 2.54 Single   
20-555 Plastic Electronic Project Box Red Light 250V AC 15 AMP 125/20A Duplex Switch 40 Pin Single Row Straight Female 2.54mm 10Pcs/Lot 40Pin 2.54 Single Row Pin Male  
           
BTA41-600V L7805-TO220 AMS1117 3.3V 1A    Ams1117-5.0 SOT-223  78L05  SOT-89 5V   
20-555 L7805-TO220-L7805-TO-220 AMS1117 3.3V 1A SOT-223     78L05 SOT89 SOT-89 5V 50PCS    
           
Titanium Bits 3-20mm Multi-function electric PCB mini drill Bit carbide  99pcs-Titanium-Steel-Drill.   BTS443P  TO252  
Titanium Step Drill Bits 3-20mm Multi-function electric machine soldering 10pcs 0.3mm to 1.2mm PCB mini drill Bit tungsten steel carbide   20-555   10pcs/lot BTS443P  TO252  
           
PCB  thermal  paper PCB DIY  TQFP - DIP Adapter PCB   8 pin DIP Round IC socket   6-28-pins-DIP-IC   
PCB  thermal  paper Ccl-PCB-DIY  TQFP - DIP Adapter PCB  8 pin DIP Round IC socket  20-555   
           
LM2596s DC-DC 5A DC-DC Step Up MT3608 2A  mini DC-DC 3A    Rotary Encoder  RM-065 5kOm  
20-555 DC-DC Step Up Power MT3608 2A Max    Rotary Encoder  Переменный резистор RM-065 502    
           
12V 5A 60W 110V-220V  12V 5A 60W LNK305PN DIP-7   Драйвер светодиодов рег. напр. DC-DC LCD    
12V 5A 60W 110V-220V Lighting Transformer High quality LED driver 12V 5A 60W LED Driver  20-555  20-555  20-555   
           
RTCpro DS3231    А3144  

RTC DS1307

 
quartz resonator     DS1302  
фото  фото  фото     фото  
           
Transistor Tester ESR  Quadcopter Drone  Probe Oscilloscope X1 X10  RS232 to TTL Parking Camera 170" 
Transistor Tester LCR - ESR meter - Frequency Signal Generator Quadcopter Drone Probe Oscilloscope X1 X10  CH340G RS232 to TTL module 20-555   
           
MQ-135 Air Sensor   GL5528

Microphone Sensor

Photosensitive Sensor 

IR Sensor

 
MQ-135 Air Quality Sensor  
           
ОУ  SOT23-5

BC847 NPN SOT-23 

SS8050+SS8550

BSS138 SOT-23 MOSFET Gerkon  
45 BSS138LT1G SOT-23 MOSFET Gerkon   
           
LED  220V  LED DC 12 В  100PCS-5mm-LED  LED-Display 4*4 Matrix Array    
LED лампы 220V дневные ходовые огни DC 12 В 100PCS-5mm-LED-Green-Blue-White-Yellow-Red 20-555 4*4 Matrix Array/Matrix Keyboard 16 Key   
Toroid Ferrite 10 x 6 x 5mm   BNC Connector  Video Balun BNC  DC Power Male- female   BNC Female Connectors  
фото  фото  фото  фото  фото   
           
           
Metal Film Resistor  high frequency - capacitor Metal-Resistor-Kit 1206-SMD-Resistors-2000pcs-Kit

0.6mm Tin Lead Solder  

 
 
1220pcs 0.33R~4.7M 1% Metal Film Resistor Assorted Kit 220uF 50V 8*16 high frequency - capacitor 50pcs/lot 20-555 20-555 20-555   
           
Sensor Module ZMCT103C HC-SR501  PIR Датч.уличный USB  Tester volt-ammeter Soldering-Kits-T12   
Transformer Sensor Module ZMCT103C 5A/5mA FZ0809 HC-SR501  PIR module  Sensor 20-555 Digital USB  Tester  charger doctor voltmeter ammeter 20-555   
           
DS18B20 TO-92 DHT22 digital 

Crystal Oscillator49S 

Датчик РТ100     
DS18B20 TO-92 - Temperature Sensor 10pcs/lot DHT22 digital temperature and humidity sensor   20-555     
           
Transmitter-Receiver  TF card U disk MP3 Player WIFI модель ESP-12E (Esp8266) Д/У для ворот      
2CH-RF-Remote-Control-Switch-Transmitter-Receiver 20-555 20-555 20-555