Модератор: boogyman
StyleWarrior
Новичок
Сообщения: 5 Зарегистрирован: 23 янв 2012, 09:46
#1
Сообщение
StyleWarrior » 23 янв 2012, 09:56
Сделал 8 разрядный все прекрасно работает, захотелось 10 разрядный, подключил еще 2 светодиода к порту С на РС7 и РС6 мк atmega64 резистор на PF0 остальные светодиоды на PA0-PA7
При прокрутки резистора и при достижении порта РС7 светодиод загорается но при уменьшении он не гаснет в чем может быть проблема?
код программы:
Код: Выделить всё
/***Использование АЦП. Светодиодная шкала***/
#define F_CPU 8000000UL // 8 MHz
#include <avr/io.h>
#include <avr/delay.h>
/***Главная функция***/
int main (void)
{
DDRA = 0xFF;
PORTA = 0x00;
DDRC = 0xFF;
PORTC = 0x00;
/***Настройка АЦП***/
ADCSRA |= (1 << ADEN) //Включение АЦП
|(1 << ADPS1)|(1 << ADPS0); // предделитель преобразователя на 8
ADMUX |= (0 << REFS1)|(0 << REFS0) // внешний ИОН
|(0 << MUX0)|(0 << MUX1)|(0 << MUX2)|(0 << MUX3); // вход PF0
while(1)
{
unsigned int u;
ADCSRA |= (1 << ADSC); //Начинаем преобразование
while ((ADCSRA&(1 << ADIF))== 0); //Ждем флага окончания преобразования
u = (ADCL|ADCH << 8); // Считываем ADC
if (u > 102) //0.5V
{PORTA = (1 << PA0);}
else {PORTA &= ~(1 << PA0);}
if (u > 204) //1.0V
PORTA = (1 << PA0)|(1 << PA1);
if (u > 306) //1.5V
PORTA = (1 << PA0)|(1 << PA1)
|(1 << PA2);
if (u > 408) //2V
PORTA = (1 << PA0)|(1 << PA1)
|(1 << PA2)|(1 << PA3);
if (u > 510) //2.5V
PORTA = (1 << PA0)|(1 << PA1)
|(1 << PA2)|(1 << PA3)
|(1 << PA4);
if (u > 612) //3V
PORTA = (1 << PA0)|(1 << PA1)
|(1 << PA2)|(1 << PA3)
|(1 << PA4)|(1 << PA5);
if (u > 714) //3.5V
PORTA = (1 << PA0)|(1 << PA1)
|(1 << PA2)|(1 << PA3)
|(1 << PA4)|(1 << PA5)
|(1 << PA6);
if (u > 816) //4V
PORTA = (1 << PA0)|(1 << PA1)
|(1 << PA2)|(1 << PA3)
|(1 << PA4)|(1 << PA5)
|(1 << PA6)|(1 << PA7);
if (u > 918) { //4.5V
PORTA = (1 << PA0)|(1 << PA1)
|(1 << PA2)|(1 << PA3)
|(1 << PA4)|(1 << PA5)
|(1 << PA6)|(1 << PA7);
PORTC = (1 << PC7);
}
if (u > 1020) { //5V
PORTA = (1 << PA0)|(1 << PA1)
|(1 << PA2)|(1 << PA3)
|(1 << PA4)|(1 << PA5)
|(1 << PA6)|(1 << PA7);
PORTC = (1 << PC7)|(1 << PC6);
}
_delay_ms(30);
}
}
boogyman
Модератор
Сообщения: 183 Зарегистрирован: 25 дек 2011, 22:48
Откуда: Москва
#2
Сообщение
boogyman » 23 янв 2012, 21:38
Проверял в Proteuse или собирал на макетке? Я просимулировал в Proteuse, тоже самое показывает.
boogyman
Модератор
Сообщения: 183 Зарегистрирован: 25 дек 2011, 22:48
Откуда: Москва
#3
Сообщение
boogyman » 23 янв 2012, 22:54
Для полного выключения порта С добавить else, также как для порта А
StyleWarrior
Новичок
Сообщения: 5 Зарегистрирован: 23 янв 2012, 09:46
#4
Сообщение
StyleWarrior » 24 янв 2012, 18:33
на макетке собрал.
Да уже сам разобрался...
надо было погасить сигмент последний в 28 стоке else {PORTD &= ~(1 << PD0);} это и делается только для другова порта, я пошел немного другим путем:
Код: Выделить всё
/***Использование АЦП. Светодиодная шкала***/
#define F_CPU 8000000UL // 8 MHz
#include <avr/io.h>
#include <avr/delay.h>
/***Главная функция***/
int main (void)
{
DDRA = 0xFF;
PORTA = 0x00;
DDRC = 0xFF;
PORTC = 0x00;
DDRD = 0xFF;
PORTD = 0x00;
/***Настройка АЦП***/
ADCSRA |= (1 << ADEN)|(1 << ADPS1)|(1 << ADPS0); // предделитель преобразователя на 8 //Включение АЦП
ADMUX |= (0 << REFS1)|(0 << REFS0)|(0 << MUX0)|(0 << MUX1)|(0 << MUX2)|(0 << MUX3); // вход PF0 // Частота АЦП = такту микроконтроллера / 64
while(1)
{
unsigned int u;
ADCSRA |= (1 << ADSC); //Начинаем преобразование
while ((ADCSRA&(1 << ADIF))== 0); //Ждем флага окончания преобразования
u = (ADCL|ADCH << 8); // Считываем ADC
if (u > 102) //0.5V
{PORTA = 0x01;}
else {PORTA &= ~(1 << PA0);}
if (u > 204) { //1.0V
PORTA = 0x03;
PORTC = 0x00;
PORTD = 0x00;
}
if (u > 306) { //1.5V
PORTA = 0x07;
PORTC = 0x00;
PORTD = 0x00;
}
if (u > 408) { //2V
PORTA = 0x0F;
PORTC = 0x00;
PORTD = 0x00;
}
if (u > 510) { //2.5V
PORTA = 0x1F;
PORTC = 0x00;
PORTD = 0x00;
}
if (u > 612) { //3V
PORTA = 0x3F;
PORTC = 0x00;
PORTD = 0x00;
}
if (u > 714) { //3.5V
PORTA = 0x7F;
PORTC = 0x00;
PORTD = 0x00;
}
if (u > 816) { //4V
PORTA = 0xFF;
PORTC = 0x00;
PORTD = 0x01;
}
if (u > 918) { //4.5V
PORTA = 0xFF;
PORTC = 0x80;
PORTD = 0x01;
}
if (u > 1020) { //5V
PORTA = 0xFF;
PORTC = 0xC0;
PORTD = 0x01;
}
_delay_ms(1);
}
}
гасил сегменты в других условиях.
StyleWarrior
Новичок
Сообщения: 5 Зарегистрирован: 23 янв 2012, 09:46
#5
Сообщение
StyleWarrior » 24 янв 2012, 18:48
В продолжение к теме Занятие №2. Переключение светодиода
Она не рабочая, почему не знаю...
На ноге где светодиод почему то постоянно присутствует +2,5 вольта, соответственно он светится в пол накала, а при нажатии на кнопку, он иногда включается на полную (повторяюсь иногда раза с 3-4)
я предполагаю это из за входа AREF он посажен на +5, хотя врятле скорее всего из за резюка на кнопке...
притом +2.5 вольт появятся только после прошивки контроллера.
Еще встал вопрос о многозадачности контроллеров, как ее реализовать ведь, если в предыдущий вариант скрестить с переключением светодиода ничего не получится так как в обоех случаях используется бесконечный цыкл соответственно как реализовать например вольтметр и амперметр или все в один цикл записать
еще вопрос про мигание светодиодов ведь если делать delay то цикл останавливается и соответственно все измерения тоже.
boogyman
Модератор
Сообщения: 183 Зарегистрирован: 25 дек 2011, 22:48
Откуда: Москва
#7
Сообщение
boogyman » 26 янв 2012, 18:35
StyleWarrior писал(а): Да уж форум гиблый нечего тут оставаться...
Форуму 2 месяца, а ты что хотел?
uuu000
Любитель
Сообщения: 17 Зарегистрирован: 08 апр 2019, 00:15
#8
Сообщение
uuu000 » 12 фев 2020, 14:31
Схема radioparty.ru/programming/avr/c/285-lesson-adc-avr работает прекрасно,собрал на ее основе индикатор разряда аккумулятора.
Но возникла необходимость в замене Atmega 8 на Attiny44 , вроде все делал согласно datasheet -но отказывается работать.
Пробовал выход на порт А(кроме ножки РА0-вход АЦП) или на три ноги порта В.Фьюзы ваставлены по умолчанию из datasheet.
К сожалению слишком малый опыт в программировании не позволил самостоятельно найти проблему.
Прошу помощи.
Спасибо.
КОД:
Код: Выделить всё
#include <avr/io.h>
#define F_CPU 8000000UL
#include <util/delay.h>
int main (void)
{
DDRA|=(1<<PA1)|(1<<PA2)|(1<<PA3)|(1<<PA4)|(1<<PA5)|(1<<PA6)|(1<<PA7);
PORTA&=~((1<<PA1)|(1<<PA2)|(1<<PA3)|(1<<PA4)|(1<<PA5)|(1<<PA6)|(1<<PA7));
//DDRB|=(1<<PB0)|(1<<PB1)|(1<<PB2);
//PORTB&=~((1<<PB0)|(1<<PB1)|(1<<PB2));
/*** Настройка АЦП ***/
ADCSRA |= (1 << ADEN) // Включение АЦП
|(1 << ADPS1)|(1 << ADPS0); // предделитель преобразователя на 8
ADMUX |= (0 << REFS1)|(0 << REFS0) // внешний ИОН
|(0 << MUX0)|(0 << MUX1)|(0 << MUX2)|(0 << MUX3)|(0 << MUX4)|(0 << MUX5); // вход PA0
ADCSRB|=(1<<ADLAR);
while(1)
{
unsigned int u;
ADCSRA |= (1 << ADSC)
|(1<<ADIE)
|(1 << ADATE); // Начинаем преобразование
while ((ADCSRA&(1 << ADIF))== 0); // Ждем флага окончания преобразования
u = (ADCL|ADCH << 8); // Считываем ADC
if (u > 128) // 0.625V
//PORTB |= (1<<PB0);
//else
//PORTA &= ~((1<<PB0));
//if (u > 256) // 1.25V
//PORTB |=(1<<PB0)| (1<<PB1);
//if (u > 384) // 1.875V
//PORTB |= (1<<PB0)|(1<<PB1)|(1<<PB2);
PORTA |= (1<<PA1);
else
PORTA &= ~((1<<PA1)|(1<<PA2)|(1<<PA3)|(1<<PA4)|(1<<PA5)|(1<<PA6)|(1<<PA7));
if (u > 256) // 1.25V
PORTA |=(1<<PA1)| (1<<PA2);
if (u > 384) // 1.875V
PORTA |= (1<<PA1)|(1<<PA2)|(1<<PA3);
if (u > 512) // 2.5V
PORTA |= (1<<PA1)|(1<<PA2)|(1<<PA3)|(1<<PA4);
if (u > 640) // 3.125V
PORTA |=(1<<PA1)|(1<<PA2)|(1<<PA3)|(1<<PA4)|(1<<PA5);
if (u > 768) // 3.75V
PORTA |=(1<<PA1)|(1<<PA2)|(1<<PA3)|(1<<PA4)|(1<<PA5)|(1<<PA6);
if (u > 896) // 4.375V
PORTA |=(1<<PA1)|(1<<PA2)|(1<<PA3)|(1<<PA4)|(1<<PA5)|(1<<PA6)|(1<<PA7);
_delay_ms(30);
}
}
microsystems
Любитель
Сообщения: 12 Зарегистрирован: 11 дек 2019, 19:40
#9
Сообщение
microsystems » 14 фев 2020, 16:29
Не надо было делать левое выравнивание результата АЦП: ADCSRB|=(1<<ADLAR);
Код: Выделить всё
#include <avr/io.h>
#define F_CPU 8000000UL
#include <util/delay.h>
int main (void)
{
DDRA|=(1<<PA1)|(1<<PA2)|(1<<PA3)|(1<<PA4)|(1<<PA5)|(1<<PA6)|(1<<PA7);
PORTA&=~((1<<PA1)|(1<<PA2)|(1<<PA3)|(1<<PA4)|(1<<PA5)|(1<<PA6)|(1<<PA7));
//DDRB|=(1<<PB0)|(1<<PB1)|(1<<PB2);
//PORTB&=~((1<<PB0)|(1<<PB1)|(1<<PB2));
/*** Настройка АЦП ***/
ADCSRA |= (1 << ADEN) // Включение АЦП
|(1 << ADPS1)|(1 << ADPS0); // предделитель преобразователя на 8
ADMUX |= (0 << REFS1)|(0 << REFS0) // внешний ИОН
|(0 << MUX0)|(0 << MUX1)|(0 << MUX2)|(0 << MUX3)|(0 << MUX4)|(0 << MUX5); // вход PA0
//ADCSRB|=(1<<ADLAR);
while(1)
{
unsigned int u;
ADCSRA |= (1 << ADSC); // Начинаем преобразование
while ((ADCSRA&(1 << ADIF))== 0); // Ждем флага окончания преобразования
u = (ADCL|ADCH << 8); // Считываем ADC
if (u > 128){ // 0.625V
PORTA |= (1<<PA1);
if (u > 256){ // 1.25V
PORTA |=(1<<PA2);
if (u > 384){ // 1.875V
PORTA |= (1<<PA3);
if (u > 512){ // 2.5V
PORTA |= (1<<PA4);
if (u > 640){ // 3.125V
PORTA |=(1<<PA5);
if (u > 768){ // 3.75V
PORTA |=(1<<PA6);
if (u > 896){ // 4.375V
PORTA |=(1<<PA7);
}
else PORTA &= ~(1<<PA7);
}
else PORTA &= ~((1<<PA6)|(1<<PA7));
}
else PORTA &= ~((1<<PA5)|(1<<PA6)|(1<<PA7));
}
else PORTA &= ~((1<<PA4)|(1<<PA5)|(1<<PA6)|(1<<PA7));
}
else PORTA &= ~((1<<PA3)|(1<<PA4)|(1<<PA5)|(1<<PA6)|(1<<PA7));
}
else PORTA &= ~((1<<PA2)|(1<<PA3)|(1<<PA4)|(1<<PA5)|(1<<PA6)|(1<<PA7));
}
else PORTA &= ~((1<<PA1)|(1<<PA2)|(1<<PA3)|(1<<PA4)|(1<<PA5)|(1<<PA6)|(1<<PA7));
_delay_ms(30);
}
}