Примеры CodeVisionAVR - АЦП & ЖКИ

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

Зміст статті

Вольтметр-амперметр до 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.