Обсуждаем контроллеры компании Atmel.
Ответить

Проблема с 8-битным АЦП

Вт дек 13, 2022 21:59:38

Контроллер Atmega32.Код вроде верный, но при достижении значения переменной i=170 должно происходить переключение цвета светодиода (индикатор разряда батареи). Это при пересчете примерно 3,3 вольта. Это и работает, но кроме этого значения 3,3 вольта происходит переключение еще при 6 значениях(0.85;1.25;2.15;2.50;3.75;4.7 вольта). Не могу найти и устранить причину. Прошу помочь с этим форумчан. Подобная программа для 10-битного АЦП работает нормально. Но мне нужно 8 бит хочу переслать эту переменную через USART на тачскрин Nextion ля создания прогресс-бара. Но я новичок в программировании МК еще не могу толком использовать USART,тем более для 10 битной переменной. Спасибо.

Добавлено after 1 minute 23 seconds:
Протеус

Добавлено after 2 minutes:
В архиве файл PROTEUS
Вложения
ADC.rar
(16.85 KiB) Скачиваний: 39
main.c
(794 байт) Скачиваний: 49

Re: Проблема с 8-битным АЦП

Вт дек 13, 2022 22:29:05

https://www.radiokot.ru/forum/viewtopic ... 8&t=185219

Код:
////////////////////////////////////////////////////////////////////////////////
#include <mega328p.h> // 8 МГц

unsigned int u;                   // буфер АЦП
////////////////////////////////// АЦП: -0,000.070c
void adc(unsigned char adc_input) 
{
ADMUX = 0b01000000 | adc_input;  // опорное AVCC // канал ADC0...ADC7 
delay_us(10);                     
ADCSRA|=0b01000000;               
while (ADCSRA & 0b01000000);     
}

////////////////////////////////////////////////////////////////////////////////
void main(void)
{

////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////АЦП ATmega328:
//ADMUX
//1... ....  REFS1 - опорное напряжение - 0
//.1.. ....  REFS0 - опорное напряжение - 1 - AVCC
//..1. ....  ADLAR - Выравнивание результата
//...1 ....   - 
//.... 1...   MUX3 - номер канала
//.... .1..   MUX2 - номер канала
//.... ..1.   MUX1 - номер канала
//.... ...1   MUX0 - номер канала - ADC0...ADC7 (0000=ADC0)
//REFS1=0  REFS0=0 - ИОН=AREF
//REFS1=0  REFS0=1 - ИОН=AVCC
//REFS1=1  REFS0=0 - не используется (зарезервировано)
//REFS1=1  REFS0=1 - ИОН=2.56V (встроенный ИОН 2.56V)

//ADLAR=1
// Выравнивание результата в левую сторону < (8-бит):   
// ADCH  // 1111 1111 - читать вторым (или первым, тогда последии 2 бит потеряем)
// ADCL  // 0000 0011 - читать первым
//ADLAR=0
// Выравнивание результата в правую сторону > (10-бит): 
// ADCH  // 0000 0011 - читать вторым
// ADCL  // 1111 1111 - читать первым

// MUX3...MUX0 - номер канала:
// 0000 - ADC0
// 0001 - ADC1
// .................
// 0111 - ADC7
// 1000 temperature sensor 1 mV/°C
// 1110 - ИОН (1,23V) !

//ADCSRA
//1... ....  ADEN - 1- вкл ADC. (0-ADC не потребляет мощности)
//.1.. ....  ADSC - 1- Старт. При завершении преобразования сбрасывается аппаратно.
//..1. ....  ADFR - 1- режим Непрерывного Преобразования.
//...1 ....  ADIF - 1-  флаг завершения преобразования
//                           -сброс программно.
//                            -для прерывания очищается аппаратно.
//.... 1...  ADIE - 1- Разрешение прерывания
//.... .1..  ADPS2 - предделитель 
//.... ..1.  ADPS1 - предделитель 
//.... ...1  ADPS0 - предделитель

//предделитель ADC:
//ADPS2 -ADPS1 -ADPS0
// 000:  1 МГц/2=500.000     Hz   
// 001:  1 МГц/2=500.000     Hz 
// 010:  1 МГц/4=250.000     Hz   
// 011:  1 МГц/8=125.000     Hz 
// 100:  1 МГц/16=62.500     Hz   
// 101:  1 МГц/32=31.250     Hz 
// 110:  1 МГц/64=15.625     Hz   
// 111:  1 МГц/128=7.812,5  Hz 

//int a;             
//int u, ub;       
//ADCSRA=0b10000100; // вкл ADC. 250.000 Hz.
//////////////////////////////////////////// ADC:
//ADMUX=0b01000101;                // канал 5
//delay_us(10);                            // стабилизация входа...
//ADCSRA|=0b01000000;             // Старт преобразования.
//while (ADCSRA & 0b01000000);  // При завершении преобразования этот бит сбрасывается аппаратно.
////////////////////////////////////////////// АЦП:   
//adc(7); a=ADCW/2;   
//if (a>ub+1) {u=a/2; ub=a;};   
//if (a<ub-1) {u=a/2; ub=a;};

ADCSRA=0x85;   // вкл. ADC // 8 МГц/32=250.000 Hz
////////////////////////////////////////////////////////////////////////////////


adc(5); u=ADCW;         // канал ADC 5

}
////////////////////////////////////////////////////////////////////////////////

Re: Проблема с 8-битным АЦП

Вт дек 13, 2022 22:31:29

включите 8-битный АЦП и взять только старшую часть: ADCH

Код:
 i = (ADCL | ADCH << 8); // Считываем ADC

на
Код:
  ADMUX |= (1 << ADLAR);
  i = ADCH; // Считываем ADC, 8 старших бит
Вложения
main_cor.c
(893 байт) Скачиваний: 44

Re: Проблема с 8-битным АЦП

Вт дек 13, 2022 22:52:30

еще не могу толком использовать USART,тем более для 10 битной переменной.

1. включаем АЦП с 10-битный режим.

2. или передаём по USART младшие 8-бит АЦП
UDR=u;

3. или передаём по USART старшие 8-бит АЦП
UDR=(u>>2);

4. или передаём по USART все 10-бит АЦП
UDR=(u>>2);
UDR=u;

5. или сначала фильтруем... убираем шум квантования АЦП (чтоб показания не прыгали)...
a=ADCW/2;
if (a>ub+1) {u=a/2; ub=a;};
if (a<ub-1) {u=a/2; ub=a;};
а потом передаём по USART младшие 8-бит АЦП
UDR=u;

и т.д.
можно в любой комбинации))
:tea:

Re: Проблема с 8-битным АЦП

Вт дек 13, 2022 23:00:12

Спасибо за помощь, с АЦП разобрался.
С USART еще поэкспериментирую - спасибо за поддержку roman.com

Re: Проблема с 8-битным АЦП

Вт дек 13, 2022 23:11:42

catrock писал(а):С USART еще поэкспериментирую

а зачем нам USART...
сразу передаём на телефон или ПК по Интернету))


и т.д.
можно в любой комбинации))
:tea:

Re: Проблема с 8-битным АЦП

Вт дек 13, 2022 23:36:51

Спасибо, roman.com Я изучаю Nextion и ,кроме других функций, на его экране хочу сделать индикатор разряда батареи. Там в устройстве которое я хочу сделать питание от "кроны" , нет ни телефона ни компьютера. Надеюсь в дальнейшем научиться пользоваться USART, в Nextion все идет через него. Правда есть в некоторых моделях I/O. Но через них не подключишь всего(я думаю).

Re: Проблема с 8-битным АЦП

Ср дек 14, 2022 00:18:53

catrock писал(а):Я изучаю Nextion

никада не работал с Nextion...

https://www.youtube.com/watch?v=Z_XUt5--UaI

всё ясно))

неее... писать свои приложения на телефоне и компьютере... интересней ))
:tea:

Добавлено after 4 minutes 37 seconds:
4. или передаём по USART все 10-бит АЦП
UDR=(u>>2);
UDR=u;

это работает только для своих приложений... на телефоне и компьютере...))

для Nextion надо писать так:

4. или передаём по USART все 10-бит АЦП
UDR=(u>>8); // передаём в Nextion по USART старшие 8-бит АЦП
UDR=u; // передаём в Nextion по USART младшие 8-бит АЦП

:tea:

Re: Проблема с 8-битным АЦП

Вт дек 27, 2022 13:22:20

С передачей 10 бит тоже разобрался, ну а если нужно передать ,например,8 бит переменной "a"и 8 бит переменной "b". Т. е. два байта для разных переменных. Как поступать в таких случаях?
Спасибо.

Re: Проблема с 8-битным АЦП

Вт дек 27, 2022 14:56:14

UDR=a; // передаём в Nextion по USART 8 бит переменной "a".
UDR=b; // передаём в Nextion по USART 8 бит переменной "b".

Re: Проблема с 8-битным АЦП

Вт дек 27, 2022 15:18:33

не получается, в аргументе функции void out_uart() только одна переменная "а". Я не знаю можно ли добавить еще переменную, Studio пишет ошибку.

ОТПРАВКА ДАННЫХ ЧЕРЕЗ UART
*****************************************************/
void out_uart(uint8_t а)
{ // Передача байта через UART
while ( !( UCSR0A & (1<<UDRE0)) ); // Ожидание готовности UART к передаче
UDR0 = а;// Запись в регистр UDR байта данных начинает процесс передачи
}

Re: Проблема с 8-битным АЦП

Вт дек 27, 2022 15:32:47

void out_uart(uint8_t а) // функция ОТПРАВКА ДАННЫХ ЧЕРЕЗ UART
{ // Передача байта через UART
while ( !( UCSR0A & (1<<UDRE0)) ); // Ожидание готовности UART к передаче
UDR0 = а;// Запись в регистр UDR байта данных начинает процесс передачи
}


void main(void) // главная функция
{

out_uart(а); // вызываем функцию void out_uart() и передаём в функцию void out_uart() 8 бит переменной "a".
out_uart(b); // вызываем функцию void out_uart() и передаём в функцию void out_uart() 8 бит переменной "b".

} // END

Re: Проблема с 8-битным АЦП

Вт дек 27, 2022 16:01:54

/* ОСНОВНАЯ ПРОГРАММА */
int main(void)
{ adc_ini ();
USART_Init(MYUBRR); // Инициализация uart (скорость 9600)
_delay_ms(1000);

void out_uart(a);
void out_uart(b);

while (1)
{
adc ();
outNumber("n1.val", a); // Отображение числа в числовом компоненте n1
outNumber("n0.val", b); // Отображение числа в числовом компоненте n0
//outNumber("j0.val",a); // Отображение числа в компоненте progress bar j0
//outNumber("z0.val",a); // Отображение числа в компоненте progress bar j0
//
_delay_ms(300); // задержка 100 мс в цикле
}
}



Error conflicting types for 'out_uart'

Re: Проблема с 8-битным АЦП

Вт дек 27, 2022 16:35:36

Код:
unsigned char a;          // переменная "a".
unsigned char b;          // переменная "b".

void out_uart(uint8_t а) // функция ОТПРАВКА ДАННЫХ ЧЕРЕЗ UART
{ // Передача байта через UART
while ( !( UCSR0A & (1<<UDRE0)) ); // Ожидание готовности UART к передаче
UDR0 = а;// Запись в регистр UDR байта данных начинает процесс передачи
}


/* ОСНОВНАЯ ПРОГРАММА */
int main(void)
{
adc_ini ();
USART_Init(MYUBRR); // Инициализация uart (скорость 9600)
_delay_ms(1000);


while (1)
{
//adc (); // ???
outNumber("n1.val", a); // Отображение числа в числовом компоненте n1
outNumber("n0.val", b); // Отображение числа в числовом компоненте n0

// вызываем функцию out_uart() в цикле и передаём в функцию out_uart() 8 бит переменной "а".
out_uart(а);
// вызываем функцию out_uart() в цикле и передаём в функцию out_uart() 8 бит переменной "b".
out_uart(b);

//outNumber("j0.val",a); // Отображение числа в компоненте progress bar j0
//outNumber("z0.val",a); // Отображение числа в компоненте progress bar j0
//
_delay_ms(300); // задержка 100 мс в цикле
}
}

:dont_know:

Re: Проблема с 8-битным АЦП

Вт дек 27, 2022 17:24:56

studio пропустила, но перестал работать UART, пока не могу разобраться в чем дело.

Re: Проблема с 8-битным АЦП

Вт дек 27, 2022 17:57:40

а может просто надо подождать... пока закончится передача... ?

хотя за это должна отвечать функция ОТПРАВКА ДАННЫХ ЧЕРЕЗ UART ))

Код:
unsigned char a;          // переменная "a".
unsigned char b;          // переменная "b".

void out_uart(uint8_t а) // функция ОТПРАВКА ДАННЫХ ЧЕРЕЗ UART
{ // Передача байта через UART
while ( !( UCSR0A & (1<<UDRE0)) ); // Ожидание готовности UART к передаче
UDR0 = а;// Запись в регистр UDR байта данных начинает процесс передачи
}


/* ОСНОВНАЯ ПРОГРАММА */
int main(void)
{
adc_ini ();
USART_Init(MYUBRR); // Инициализация uart (скорость 9600)
_delay_ms(1000);


while (1)
{
//adc (); // ???
outNumber("n1.val", a); // Отображение числа в числовом компоненте n1
outNumber("n0.val", b); // Отображение числа в числовом компоненте n0

// вызываем функцию out_uart() в цикле и передаём в функцию out_uart() 8 бит переменной "а".
out_uart(а);

_delay_ms(300); // задержка 100 мс в цикле //ждём... пока закончится передача...

// вызываем функцию out_uart() в цикле и передаём в функцию out_uart() 8 бит переменной "b".
out_uart(b);

_delay_ms(300); // задержка 100 мс в цикле //ждём... пока закончится передача...

//outNumber("j0.val",a); // Отображение числа в компоненте progress bar j0
//outNumber("z0.val",a); // Отображение числа в компоненте progress bar j0
//
_delay_ms(300); // задержка 100 мс в цикле
}
}

Re: Проблема с 8-битным АЦП

Вт дек 27, 2022 18:26:30

работает только unsigned char b
Ответить