реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> прог. реализ. AVR+adc124s101 подкл. через SPI, терморегулятор на 0.1
Чип-Хрум
сообщение Apr 1 2007, 15:31
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 33
Регистрация: 1-04-07
Пользователь №: 26 675



Нужна программная реализация получения 12 бит от ADC124s101 на Atmega32 .
Пробывал опрашивать как на прямую так и с помощью прерывания ,по моим подсчетам
эта микросхема должна выдавать все 12 бит через каждый мегахерц.
А на самом деле получается около раза в секунду.
Выводится все на жки в таком порядке:
на одной знакопозиции
0909
4b4b
0909
4a4a
0909
4949
0909
4949
Короче сейчас дело не в точности показаний а в том чтобы вывести 0949 за место 09094949.
Может я че в програмке напутал Кто силен подскажите!
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdlib.h>
#include <util/delay.h>
#include <stdio.h>
#include <avr/eeprom.h>

#define bitset(var,bitno) ((var) |= 1 << (bitno))
#define bitclr(var,bitno) ((var) &= ~(1 << (bitno)))

char dat0=0,dat1=0; //переменные, 8бит для dat0 и 4бита для dat1
char revers=0;

ISR(SPI_STC_vect) // вектор прерывания для окончания посылки байта
{

while(revers==0) // что-то типа реверса за одно прохождение
{ // опрашавается одна часть 12 бит
dat0 = SPDR; //
revers=1; //
} //
//
while(revers==1) //
{ //
dat1 = SPDR;
revers=0;
}

bitset(SREG,7);
SPDR = 0x00;
}

int main(void)
{

DDRB=0xb0; // настройка порта b
SPCR=0xd3; // настройка spi

SPDR = 0x00;
bitset(SREG,7); // включаем прерывание

while(1) // вечный цикл

return (0);

}
Go to the top of the page
 
+Quote Post
defunct
сообщение Apr 2 2007, 02:11
Сообщение #2


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



А если в лоб, без аппаратного SPI?

Код
#define set_cs()    (PORTB |= (1 << CS))
#define clr_cs()    (PORTB &= ~(1 << CS))
#define set_scl()   (PORTB |= (1 << SCL))
#define clr_scl()   (PORTB &= ~(1 << SCL))
#define get_miso()  ((PINB & (1 << MISO)) ? 1 : 0)

short Read12Bits(void)
{
    int i;
    short result = 0;

    clr_cs();
    for( i = 0; i < 12; i++)
    {
         clr_scl();
         result <<= 1;
         set_scl();
         result |= get_miso();
    }
    set_cs();
    return result;
}
Go to the top of the page
 
+Quote Post
Чип-Хрум
сообщение Apr 2 2007, 10:57
Сообщение #3


Участник
*

Группа: Новичок
Сообщений: 33
Регистрация: 1-04-07
Пользователь №: 26 675



smile.gif Надо заметить идея заслуживающая уважения a14.gif !
Но дело в том что перед тем как получить 12 бит из ADC, нужно 8бит отправить.
Я в си новечек раньше только на ассемблере писал програмки.
Короче теперь нужен цикл отправки переменной char по тому же SPI.
И подскажите где правильно научиться битами управлять в переменных,
а то пролистал всю мукулатуру а дельного ничего нет.
Go to the top of the page
 
+Quote Post
Kolia
сообщение Apr 2 2007, 13:56
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 188
Регистрация: 28-09-06
Из: Minsk
Пользователь №: 20 762



Цитата
ISR(SPI_STC_vect) // вектор прерывания для окончания посылки байта
{

while(revers==0) // что-то типа реверса за одно прохождение
{ // опрашавается одна часть 12 бит
dat0 = SPDR; //
revers=1; //
} //
//
while(revers==1) //
{ //
dat1 = SPDR;
revers=0;
}

bitset(SREG,7);
SPDR = 0x00;
}


Не правильно описано работа с прерыванием. Код dat0 = SPDR; и dat1 = SPDR; выполняются за каждый проход (т.е dat0==dat1). Соответственно появляются ошибки при отображении данных.
Должно быть что-то вроде этого.

Код
ISR(SPI_STC_vect) // вектор прерывания для окончания посылки байта
{

bitclr(SPCR,7);

if(SPSR & 0x80){//SPIF
bitclr(SPSR ,7);

if(revers==0) // что-то типа реверса за одно прохождение
{ // опрашавается одна часть 12 бит
dat0 = SPDR; //
revers=1; //
}
else
{ //
dat1 = SPDR;
revers=0;
}
}
else{
bitclr(SPSR ,6);//WCOL=0;
}


SPDR = 0x00;
bitset(SPCR,7);
}


Сообщение отредактировал Kolia - Apr 2 2007, 13:58
Go to the top of the page
 
+Quote Post
Чип-Хрум
сообщение Apr 2 2007, 18:42
Сообщение #5


Участник
*

Группа: Новичок
Сообщений: 33
Регистрация: 1-04-07
Пользователь №: 26 675



Ошибка и в правду была моя , спасибо за подсказку но всетаки дело не в этом
а втом что этот adc имеет 4 входа на каждый я должен сделать по два запроса ,
в сумме получается что за восемь прохождений я получу четыре байта.
Многова-то получается да и с данными не все так просто по моему аппаратная
реализация не надежна (я оговариваюсь в данном случае ) нужна
программная, постараюсь обьяснить почему .
В datasheet описывается что за один запрос я должен получить 12 бит
заметьте не 16.
Т.Е. я посылаю к примеру 00 а он мнен отвечает fff. И ничего лишнего.
Вопрос не снят с повестки дня помогите кто чем может.
Нужен цикл отправки переменной char по тому же SPI в программной реализации ,а не в аппоратной!!!
И подскажите где правильно научиться битами управлять в переменных,
а то пролистал всю мукулатуру а дельного ничего нет.

Сообщение отредактировал Чип-Хрум - Apr 2 2007, 18:44
Go to the top of the page
 
+Quote Post
WHALE
сообщение Apr 2 2007, 19:27
Сообщение #6


Знающий
****

Группа: Свой
Сообщений: 902
Регистрация: 2-01-06
Из: Краснодар
Пользователь №: 12 768



char a;
a|=0x80; //установить старший бит
a&=0x7F //сбросить старший бит


--------------------
"Hello, word!" - 17 errors 56 warnings
Go to the top of the page
 
+Quote Post
Kolia
сообщение Apr 3 2007, 11:13
Сообщение #7


Частый гость
**

Группа: Свой
Сообщений: 188
Регистрация: 28-09-06
Из: Minsk
Пользователь №: 20 762



Цитата(Чип-Хрум @ Apr 2 2007, 19:42) *
Нужен цикл отправки переменной char по тому же SPI в программной реализации ,а не в аппоратной!!!


Для вашей задачи нет различия между программным и аппаратным SPI. Просто аппаратный намного проше, быстрее и занимеет меньше памяти.
Микросхема ADC124s101 работает с пакетами данных длиной 16 бит.
Временную диаграмму можно посмотреть в Datasheete. Вначале отправляется упрявляющий байт, а затем нулевой байт. И соответственно в этой посылке принимаются 16 бит данных (по 2 байта), 12 бит которых являются информативными.
Что-бы микросхема выдала напряжение какого-либо канала неабходимо закинуть ей в первом пакете 2 байта с номером канала (например 0x08 0x00 - ADD0), затем ждем преобразования ADC124s101 (примерно 50 мкс), и читаем полученный результат следующей посылкой (0x08, 0x00 - здесь можно указать следующий канал ADC - в данном случае это ADD0), затем ждем преобразования ... и т.д.

Вот примерный код

Код
int ReadFromAdc(unsigned char Chanel){
int OUT;
if(Chanel>2) return -1;

CS=0; //чип селект на микросхеме
SPDR =( (0x01<<3)<<Chanel);
while ((SPSR & 0x80) == 0); // wait SPIF
SPSR&=~0x80;
OUT=SPDR;
OUT=OUT<<8;

SPDR = 0x00;
while ((SPSR & 0x80) == 0); // wait SPIF
SPSR&=~0x80;
OUT |=SPDR;

CS=1; //чип селект на микросхеме

return OUT;
}

main(void)
int ADC1;
......//настройка

bitclr(SREG,7); //не включаем прерывание


ReadFromAdc(1); // настройка на канал 1
delay_mks(50);
while(1) // вечный цикл
{

ADC1=ReadFromAdc(1);  
delay_mks(50);
}

Если вас все же интересует программная реализация, то могу выложить.

Сообщение отредактировал Kolia - Apr 3 2007, 11:17
Go to the top of the page
 
+Quote Post
Чип-Хрум
сообщение Apr 9 2007, 14:35
Сообщение #8


Участник
*

Группа: Новичок
Сообщений: 33
Регистрация: 1-04-07
Пользователь №: 26 675



Теперь проблемма в другой части , нашел термодатчик lm335 он вроде-бы
подходит для этой цели(подключение к ацп) в даташит описан способ
подключения 3 последовательно +сопротивление .
Вопрос : каким образом этот набор полупроводников отколибровать ,
без загрубления градации характеристик на ноль.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 17:59
Рейтинг@Mail.ru


Страница сгенерированна за 0.01417 секунд с 7
ELECTRONIX ©2004-2016