Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
demiurg301
Опытный кот
Сообщения: 812 Зарегистрирован: Ср мар 18, 2009 21:14:33
Сообщение
demiurg301 » Вс фев 12, 2012 16:03:04
НЕ могу забрать данные с AD7715. Кода то всего ничего... Упорно возвращает ноль...
Схема типовая для Pt100 как в DataSheet.
reset - >+5
CS - > GND
Вот код :
Код: Выделить всё
/*****************************************************
Chip type : ATmega16
Program type : Application
AVR Core Clock frequency: 8,000000 MHz
Memory model : Small
External RAM size : 0
Data Stack size : 256
*****************************************************/
#include <mega16.h>
#include <delay.h>
#include <stdlib.h>
#include <string.h>
// Standard Input/Output functions
#include <stdio.h>
#define SetBit(reg, b) reg |= (1<<b)
#define ClearBit(reg, b) reg &= (~(1<<b))
#define InvBit(reg, b) reg ^= (1<<b)
#define BitIsSet(reg, b) ((reg & (1<<b)) != 0)
#define BitIsClear(reg, b) ((reg & (1<<b)) == 0)
#define DATA_PORT PORTB
#define SCK 7
#define MOSI 5
#define MISO 6
#define DRDY ((PIND & (1<<2)) != 0)
void Writetoreg (unsigned char byteword)
{
unsigned char i;
for (i=0;i<8;i++)
{
ClearBit(PORTB, MOSI); // DIN=0
ClearBit(PORTB,SCK); // Подаем синхроимпульс: SCLK=0
if (byteword & 0x80) SetBit(PORTB, MOSI);// Если выделенный бит =1, то DIN=1
byteword=byteword<<1; // Сдвигаем byteword на один разряд влево для выделения следующего бита
SetBit(PORTB,SCK); // SCLK=1
#asm("NOP");
};
};
unsigned int Read (void)
{
unsigned int tmp=0;
unsigned char i;
delay_ms(1);
for (i=0;i<16;i++)
{
ClearBit(PORTB,SCK); // SCLK=0 Подаем синхроимпульс
#asm("NOP");
#asm("NOP");
SetBit(PORTB,SCK); // SCLK=1
tmp=tmp<<1; // Если DOUT=0, тогда просто сдвигаем tmp влево
if BitIsSet(PORTB, MISO) tmp=tmp+1; // Если DOUT=1 - тогда прибавляем еще единицу
};
return tmp; // Возвращаем 16-и разрядное слово
};
void INIT_ADC(void)
{
delay_ms(100);
Writetoreg (0b00010011);
delay_ms(100);
Writetoreg (0b01000110);
};
unsigned int ADC(void)
{
unsigned int V;
while DRDY;
Writetoreg(0b00111011);
V=Read();
return V;
};
// Declare your global variables here
void main(void)
{
// Declare your local variables here
unsigned char str[10];
unsigned int I;
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;
// Port B initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0x00;
// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// 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: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: Off
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0x08;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// ADC initialization
// ADC disabled
ADCSRA=0x00;
// SPI initialization
// SPI disabled
SPCR=0x00;
// TWI initialization
// TWI disabled
TWCR=0x00;
DDRB|=(1<<7)|(1<<5);
PORTB|=(1<<7);
INIT_ADC();
while (1)
{
// Place your code here
I=ADC();
UDR=I>>8;
delay_ms(10);
UDR=I;
delay_ms(1000);
}
}
DRDY дёргается, на Dout тоже вроде есть сигнал...
Но...
demiurg301
Опытный кот
Сообщения: 812 Зарегистрирован: Ср мар 18, 2009 21:14:33
Сообщение
demiurg301 » Вс фев 12, 2012 20:12:38
Народ чо никто с этим зверем не сталкивался? Мож у кого либа готовая есть?
IfoR
Поставщик валерьянки для Кота
Сообщения: 2029 Зарегистрирован: Сб ноя 15, 2008 10:09:56
Откуда: г. Тула
Контактная информация:
Сообщение
IfoR » Вс фев 12, 2012 20:53:14
У меня смутные сомнения... Попробуйте функцию ADC() переименовать по другому, например adc(). А то вроде как литерал ADC продефайнен как порт, собственно, ADC микроконтроллера.
/dev/urandom - гигабайты информации.
OS: openSUSE 13.2 (x86_64)
demiurg301
Опытный кот
Сообщения: 812 Зарегистрирован: Ср мар 18, 2009 21:14:33
Сообщение
demiurg301 » Вс фев 12, 2012 22:04:16
Посмотрел дефайны - вроде нету... Сейчас не у железа, но проверю...
Раньше осцилом глядел - "пички" видно, но почему то "не ловятся". Т.е. отрабатывает вроде как синхроимпульсы.
Engineer_Keen
Друг Кота
Сообщения: 3872 Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва
Сообщение
Engineer_Keen » Пн фев 13, 2012 10:54:52
Во-первых, в чем великая надобность использовать программный SPI, при существующем железном, да еще и практически на тех же ногах?
Во-вторых, советую хотя бы на время отладки все-таки управлять линией CS.
Так в чем проблема? МК не ловит сигнал по DRDY или ловит, но читает не то, что надо?
demiurg301
Опытный кот
Сообщения: 812 Зарегистрирован: Ср мар 18, 2009 21:14:33
Сообщение
demiurg301 » Пн фев 13, 2012 11:09:31
Железный вообще не пошёл... Даже инициализацию не прошёл - просто висяк в ожидании сигнала DRDY.
CS прикрутил - "0 на массу". Опускаю при вычитывании - подымаю после.
А самое интересное - этот код на другой плате работал ( плату я правда немного того...выбросил короче). Потом версию компилятора поменял... Так что где собака порылась непонятно...
Engineer_Keen
Друг Кота
Сообщения: 3872 Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва
Сообщение
Engineer_Keen » Пн фев 13, 2012 11:28:20
demiurg301 писал(а): Железный вообще не пошёл... Даже инициализацию не прошёл - просто висяк в ожидании сигнала DRDY.
Странно, никогда не было проблем с железным SPI в AVR...
demiurg301 писал(а):
CS прикрутил - "0 на массу". Опускаю при вычитывании - подымаю после.
Че-то не совсем понял как это?
demiurg301 писал(а):
А самое интересное - этот код на другой плате работал ( плату я правда немного того...выбросил короче). Потом версию компилятора поменял... Так что где собака порылась непонятно...
Чем старая плата отличалась кроме кода, сгенерированного другой версией компилятора? И куда делся от нее HEX?
demiurg301
Опытный кот
Сообщения: 812 Зарегистрирован: Ср мар 18, 2009 21:14:33
Сообщение
demiurg301 » Пн фев 13, 2012 11:46:50
Engineer_Keen писал(а):
Странно, никогда не было проблем с железным SPI в AVR...
Нуууу, возможно это у меня руки кривые, попробую сейчас опять железный... Результаты сюды выкину...
Че-то не совсем понял как это?
НУ при считывании и записи на CS выставляю "0".
Чем старая плата отличалась кроме кода, сгенерированного другой версией компилятора? И куда делся от нее HEX?
Разводкой (не по "ногам", а вообще, там лутом делал 0 дороги по 0.8 , тут фоторезистом - 0.35 , может изза толщины дорог? ).
HEX вливал - аналогично.
Engineer_Keen
Друг Кота
Сообщения: 3872 Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва
Сообщение
Engineer_Keen » Пн фев 13, 2012 11:55:12
demiurg301 писал(а): может изза толщины дорог?
Это вряд ли, если конечно нет обрывов и КЗ...
demiurg301
Опытный кот
Сообщения: 812 Зарегистрирован: Ср мар 18, 2009 21:14:33
Сообщение
demiurg301 » Пн фев 13, 2012 12:53:58
Вот переделал на железо (правда не уверен что правильно.).... Сыпет мусор...Но DRDY дёргается - проинициализировался.
Код: Выделить всё
#include <mega16.h>
#include <delay.h>
#define SetBit(reg, b) reg |= (1<<b)
#define ClearBit(reg, b) reg &= (~(1<<b))
#define InvBit(reg, b) reg ^= (1<<b)
#define BitIsSet(reg, b) ((reg & (1<<b)) != 0)
#define BitIsClear(reg, b) ((reg & (1<<b)) == 0)
#define CS 1
#define RESET 2
#define DRDY ((PIND & (1<<2)) != 0)
void Writetoreg(char data)
{
ClearBit(PORTB, CS);
SPDR=data;
delay_ms(10);
SetBit(PORTB, CS);
};
unsigned char ReadReg(void)
{
unsigned char data;
ClearBit(PORTB, CS);
data=SPDR;
delay_ms(10);
SetBit(PORTB, CS);
return data;
};
void INIT_ADC(void)
{
ClearBit(PORTB, RESET);
delay_ms(1000);
SetBit(PORTB, RESET);
delay_ms(100);
Writetoreg(0b00010011);
Writetoreg(0b01000110);
};
unsigned int ADC_VALUE(void)
{
unsigned int V;
while DRDY;
Writetoreg(0b00111011);
V=ReadReg();
V<<=8;
V|=ReadReg();
return V;
};
// Declare your global variables here
void main(void)
{
// Declare your local variables here
unsigned int I;
// Input/Output Ports initialization
// Port A initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTA=0x00;
DDRA=0x00;
// Port B initialization
// Func7=Out Func6=In Func5=Out Func4=Out Func3=In Func2=In Func1=In Func0=In
// State7=0 State6=T State5=0 State4=0 State3=T State2=T State1=T State0=T
PORTB=0x00;
DDRB=0xB6;
// Port C initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTC=0x00;
DDRC=0x00;
// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T
PORTD=0x00;
DDRD=0x00;
// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer1 Stopped
// Mode: Normal top=0xFFFF
// 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: Timer2 Stopped
// Mode: Normal top=0xFF
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// INT2: Off
MCUCR=0x00;
MCUCSR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x00;
// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: Off
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=0x00;
UCSRB=0x08;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// ADC initialization
// ADC disabled
ADCSRA=0x00;
// SPI initialization
// SPI Type: Master
// SPI Clock Rate: 62,500 kHz
// SPI Clock Phase: Cycle Half
// SPI Clock Polarity: High
// SPI Data Order: MSB First
SPCR=0x5F;
SPSR=0x00;
// TWI initialization
// TWI disabled
TWCR=0x00;
INIT_ADC();
delay_ms(100);
while (1)
{
// Place your code here
I=ADC_VALUE();
UDR=I>>8;
delay_ms(10);
UDR=I;
delay_ms(100);
}
}
Вот такая должная быть осцилограмма
СЫпет вот такую вот хрень...
00 00
3F 3F
FF FF
00 00
64 64
00 00
00 00
AC AC
19 19
01 01
9F 9F
FF FF
01 01
1E 1E
7F 7F
00 00
B4 B4
19 19
00 00
0D 0D
FF FF
00 00
F4 F4
19 19
00 00
00 00
00 00
01 01
A7 A7
FF FF
00 00
Engineer_Keen
Друг Кота
Сообщения: 3872 Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва
Сообщение
Engineer_Keen » Пн фев 13, 2012 13:27:28
Зачем после SPDR=data; везде стоит delay_ms(10)? Это чтобы МК успел передать данные по SPI? Так не делают, есть специальный бит в регистре статуса. Даже в даташите пример есть
А то, что по 2 одинаковых числа передается говорит о том, что второго чтения просто не происходит. Видимо считываться должно последовательно 16 бит, а CS дергается после первых 8-и. Нужно дерганье CS из ReadReg перенести в ADC_VALUE.
demiurg301
Опытный кот
Сообщения: 812 Зарегистрирован: Ср мар 18, 2009 21:14:33
Сообщение
demiurg301 » Пн фев 13, 2012 14:18:20
Вот так
Зависает
****************
Дык, правильно, SPIF то вроде как выставляется если прерывание разрешено...
void Writetoreg(char data)
{
SPDR=data;
while(!(SPSR&(1<<SPIF)));
};
unsigned char ReadReg(void)
{
while(!(SPSR&(1<<SPIF)));
return SPDR;
};
Engineer_Keen
Друг Кота
Сообщения: 3872 Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва
Сообщение
Engineer_Keen » Пн фев 13, 2012 15:14:06
demiurg301 писал(а): Дык, правильно, SPIF то вроде как выставляется если прерывание разрешено...
Не верно. SPIF выставляется всегда после окончания передачи. Это прерывание вызывается если SPIF=SPIE=1.
А зависает вот тут:
Код: Выделить всё
unsigned char ReadReg(void)
{
unsigned char data;
ClearBit(PORTB, CS); //CS в ноль, ОК
data=SPDR; //читаем регистр данных SPI, но откуда там данные, мы же еще не сделали 8 тактов CLK
while(!(SPSR&(1<<SPIF))); //вот и ждем когда флаг выставится, а этого никогда не случится...
SetBit(PORTB, CS); //дальше код естественно не будет выполняться...
return data;
};
А всего-то нужно лишний раз вывести любой байт в регистр данных:
Код: Выделить всё
//ClearBit(PORTB, CS); //- перенесли отсюда...
SPDR=0; //выводим 0 в SPI, при этом SPI сам сделает 8 тактов и выставит флаг в конце
while(!(SPSR&(1<<SPIF)));//который тут и ждем
//SetBit(PORTB, CS); // и это перенесли отсюда...
data=SPDR; //теперь читаем что пришло
return data;
demiurg301
Опытный кот
Сообщения: 812 Зарегистрирован: Ср мар 18, 2009 21:14:33
Сообщение
demiurg301 » Пн фев 13, 2012 16:32:36
Engineer_Keen Вроде заработало - буду теперь экранировать - прыгает по 6-7 бит ...
demiurg301
Опытный кот
Сообщения: 812 Зарегистрирован: Ср мар 18, 2009 21:14:33
Сообщение
demiurg301 » Вт фев 14, 2012 11:52:35
Странная вещь.
После каждого reset-а АЦП по разному показывает...
Прыгает по 50-100 Единиц. Хотя вместо термопары - эталонный магазин сопротивлений. Все земли выходят на отдельный слой полигона.
Вот такая схема..
Как будто калибруется по разному... Никто не сталкивался?
************************
Нашёл. Ref192, в режиме источника тока, вместо постоянки генерит синусоиду с очень стабильной амплитудой в 1.5 В
7-8 разрядов прыгают.
Опорник ёпти
Вроде не импульсный.
Вложения
RTD.JPG
(26.49 КБ) 404 скачивания
Последний раз редактировалось
demiurg301 Вт фев 14, 2012 12:39:12, всего редактировалось 1 раз.
Engineer_Keen
Друг Кота
Сообщения: 3872 Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва
Сообщение
Engineer_Keen » Вт фев 14, 2012 12:38:39
В процедуре инициализации стоит 2 подряд вызова записи в SPI. По задумке, первая из них пишет в Comm регистр (0х13), вторая в Setup регистр (0х46). Если дерганья ногой CS не вынесены из процедуры записи в SPI в, то получается что
оба эти вызова пишут в Comm регистр, следовательно в Setup остается по-умолчанию 0x28, и калибровки не происходит. Если дело в этом, нужно сначала CS->0, потом запись Comm, потом Setup, а потом CS->1.
demiurg301 писал(а):
Нашёл. Ref192, в режиме источника тока, вместо постоянки генерит синусоиду с очень стабильной амплитудой в 1.5 В
7-8 разрядов прыгают.
Опорник ёпти
Вроде не импульсный.
фигасе...
demiurg301
Опытный кот
Сообщения: 812 Зарегистрирован: Ср мар 18, 2009 21:14:33
Сообщение
demiurg301 » Вт фев 14, 2012 12:49:44
СТоял на выходе 1 мкФ - была частота - 2КГц. Убрал - частота стала 20КГц- прыгает 10-11 разрядов
Феррит чтоли поставить...
****************
Поставил тантал lowesr на 470. Выдаёт меандр с частотой 20Гц, 2.5В
Ерунда какая-то...