Jump to content
vovancheg86

Как На 16F676 Сохранять И Извлекать Word Переменную С Ацп В Eeprom

Recommended Posts

Неужели в хелпе на компилятор нет подобных примеров ?

PS: Если дальше будете продолжать бездумно постить одно и тоже во всех темах подряд, или создавать кучу тем по одним и тем же вопросам - не обижайтесь, получите бан.

Share this post


Link to post
Share on other sites

Литиевые батарейки Fanso для систем телеметрии и дистанционного контроля

Системы телеметрии находят все более широкое применение во многих отраслях на промышленных и коммунальных объектах. Требования, предъявляемые к условиям эксплуатации приборов телеметрии и, как следствие, источников питания для них, могут быть довольно жесткими. Fanso предоставляет широкую линейку продукции, рассчитанной на различные условия эксплуатации, что позволяет подобрать батарейку для каждого конкретного применения, в том числе и для устройств телеметрии.

Подробнее

XD действительно))

Но вот еще вопрос (раз уж тема уже создана не баньте пожалуйста :crazy: ),

V:=adc_read(1);
V:=V shr 2;
EEPROM_Write(calibrN,VLo);

Как я слышал, АЦП 16F676 имеет чувствительность 1024 растянутые на 5 Вольт, а это 10 бит, Память EEPROM как я понял 8 битовая, Переменная V word формата - 16бит, как я нашел в справке, команда shr - сдвиг вправо, как я догадался shr 2 значит два раза вправо, т.е. автор кода получается это сделал чтобы просто запихать 10 битовое значение в 8 битную ячейку памяти...

А по началу думал какого ху..дожника у меня микросхема не реагирует на обещанные 5мВольт... Как сохранить этот массив в память eeprom полноценным? а потом загрузить его обратно тоже полноценным?

Share this post


Link to post
Share on other sites

Загрузить в память сначала старший, а потом младший байт

сейчас у вас записывается только младший....

Share this post


Link to post
Share on other sites
                     

Приглашаем на вебинар Решения для построения ультразвуковых счетчиков жидкостей и газов на базе MSP430

Компэл совместно с Texas Instruments 23 октября 2019 приглашают на вебинар, посвященный системам-на-кристалле для построения ультразвуковых расходомеров жидкостей и газов на базе ядра MSP430. Вебинар проводит Йоханн Ципперер – эксперт по ультразвуковым технологиям, непосредственно участвовавший в создании данного решения. На вебинаре компания Texas Instruments представит однокристальное решение, позволяющее создавать точные недорогие счетчики жидкостей и газов.

Подробнее...

Вы не программируете на mikropascal?

Если да то не могли бы пример привести? А то естественным языком то просто звучит... Синтаксис я не знаю, первый раз вот программирую на mikropascal, да и вообще я не программист, так... увлекался маленько...

Share this post


Link to post
Share on other sites

Нет не пишу, как по мне это извращение

V:=adc_read(1);

EEPROM_Write(calibrN,VHo);
EEPROM_Write(calibrN+1,VLo);

Share this post


Link to post
Share on other sites

А не

EEPROM_Write(calibrN,VHi);
случаем ? :unknw:

Странный какой то синтаксис. Добавил 2 символа и получил разделение по байтам. А если такие переменные будут существовать :vava:

Share this post


Link to post
Share on other sites

Таки да...

так у товарища все три переменные по абсолютному адресу обявлены...

V накладывается на VHi и VLo ....

интересно будет когда и компилятор по этим адресам свои добавит

а выяснять знает ли поскакаль о структурах, обединениях и указателях лично у меня желания нет

Share this post


Link to post
Share on other sites

Вообще на 8 битовом процесоре обработка 16 битовых чисел это проблема. Это от компилятора зависит как они обрабатываются.

Share this post


Link to post
Share on other sites

окей, попробую так, а как обратно, из еепром склепать переменную word из двух однобайтовых ячеек?

Share this post


Link to post
Share on other sites

Когда то у меня тоже такая проблема была и я придумал такое решение. Так можно два байта в один записать хотя точность немножко уменьшается но если большая точность не нужна то пойдет.

VLo = VLo >> 2;

temp = (VHi << 6) + VLo;

Share this post


Link to post
Share on other sites

это фигня) проблему решил, во-первых объявил массив калибровочных значений word'ом, потом поставил при записи вот так:

V:=ADC_Read(0);
    EEPROM_Write(2*calibrN,VHi);
    EEPROM_Write(2*calibrN+1,VLo);

А потом в процедуре чтения (заполнения массива из eeprom в озу) заставил также попарно считывать

procedure ReadData;
begin
 for i := 0 to (AdrHi) do
 begin
 dat[i]:=EEPROM_Read(2*i);
 dat[i]:=dat[i] shl 8;
 dat[i]:=dat[i]+EEPROM_Read(2*i+1);
 end;
end;

Еще маленькие поправочки и код заработал! Ура :dance2: .

Leon42 спасибо но у меня и так было "Точность немного снижается", как раз это и было основанием создать эту тему...

Конечно не без минусов обошлось - калибровочных точек AdrHi меньше влезло... Зато удобное программирование на языке высокого уровня))) А на ассемблере я бы запарился ее отлаживать))

P.S. IMXO спасибо за помощь, больше всех помог)))

Share this post


Link to post
Share on other sites

и что это???

Это, видимо, изощрённый способ из правого выравнивания, получить выравнивание левое. :)

...У меня работало.

Не проще было написать:

ADFM = 0 ;
...
temp = VHi;

и получить то-же самое, но без бубна и быстрее? :)

Edited by boatcall

Share this post


Link to post
Share on other sites

Вообще то нет, но я уже не помню какое у меня было выравнивание, левое или правое, скорей всего оно было стандартным. Этот код у меня вычислял среднее значение которое в зависимости от напряжения на АЦП было соответствено больше или меньше и потом на основе этого числа на LCD выводился индикатор в виде балки.

Share this post


Link to post
Share on other sites

Вообще то нет...

Результат получается именно такой.

...скорей всего оно было стандартным.

А "стандартное" выравнивание это какое именно?

....Этот код у меня вычислял среднее значение...

Ну раз нужно среднее значение, так и брали-бы все 10 бит с правым выравниванием:

ADFM = 1 ;
... // ADC
unsigned int val = ( unsigned int ) VHi << 8 + VLo ;
... // Усреднение

Другое дело, что младшие биты, как правило, "шумят", поэтому ими часто пренебрегают, я как-то младший бит вообще для генератора случайных чисел поиспользовал :). Для этого и можно применить "левое выравнивание", когда ADFM = 0, а в VHi сразу лежат старших 8-бит результата.

Edited by boatcall

Share this post


Link to post
Share on other sites

Я думаю что "Стандартное" выравнивание" это левое. А это "unsigned int val = ( unsigned int ) VHi << 8 + VLo ; " у меня не возможно было зделать так как я не в С програмировал. Да и к тому же это не всегда работает так как не все компиляторы 16 бит, и мой тоже не поддерживал.

А так как у нас всего 10 битов то мы знаем что в VLo у нас используются 2 бита а в VHi 8.

VLo = VLo >> 2; //VLo = ADRESL

//VHi = ADRESH

temp = (VHi << 6) + VLo;

Share this post


Link to post
Share on other sites

Я думаю что "Стандартное" выравнивание" это левое.

надо не думать, а читать даташиты, и не изобретать костыли для велосипеда, по дефолту выравнивание левое и определяется регистром ADCON1 бит ADFM и нет такого языка, где бы это нельзя было бы указать, и работает это всегда без разницы какой у вас компилятор....

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Similar Content

    • By Максим123456789
      делаю диплом, в схеме у меня микроконтроллер PIC16F688 и мне нужно его заменить на ATmega. Не могу найти похожий
    • By artos5
      Приветствую всех на этом форуме!
      Есть необходимость измерять сигнал при помощи данного АЦП. С помощью этого АЦП можно измерять 4 аналоговых не дифференциальных сигнала . Схема следующая:
      Schematic_Temp_opto_sens_V2_20190817124112.pdf
      Картинками с более низким разрешением:
      библиотеку за основу взял эту:
      https://github.com/nsaspook/nidaq700/blob/master/supermoon/example/ADS1220.c
      Путем незначительного допиливания, получилась такая библиотека:
       
      Поправил только эти функции:
      void ADS1220SendByte(unsigned char Byte) { unsigned char Result = 0x01, i=0, flg=0; MOSI_LO; Delay_us(1); for(i=0;i<8;i++) { SCK_LO; //ADC_CLK=0 Delay_us(4); if (flg) MOSI_LO; Delay_us(1); SCK_HI; //ADC_CLK=1 Delay_us(1); if (Byte&Result){ MOSI_HI; flg=1; } else MOSI_LO; Delay_us(4); Result<<=1; } SCK_LO; //ADC_CLK=0 } unsigned char ADS1220ReceiveByte(void) { unsigned char Result = 0, i=0; for(i=0;i<8;i++) { Result<<=1; SCK_LO; //ADC_CLK=0 Delay_us(5); //Delay_us(5); SCK_HI; //ADC_CLK=1 Delay_us(3); if (MISO) Result++; Delay_us(2); } SCK_LO; //ADC_CLK=0 return Result; } И добавил эту функцию:
      void ADS1220Config_MUX_GAIN(uint8_t mux, uint8_t gain) { unsigned Temp; ADS1220ReadRegister(ADS1220_0_REGISTER, 0x01, &Temp); // clear prev value; Temp &= 0x0f; Temp |= gain; Temp |= mux; // write the register value containing the new value back to the ADS ADS1220WriteRegister(ADS1220_0_REGISTER, 0x01, &Temp); ADS1220ReadRegister(ADS1220_1_REGISTER, 0x01, &Temp); // clear prev DataRate code; Temp &= 0x1f; Temp |= (ADS1220_DR_600 + ADS1220_CC); // Set default start mode to 600sps and continuous conversions // write the register value containing the new value back to the ADS ADS1220WriteRegister(ADS1220_1_REGISTER, 0x01, &Temp); } ADS1220.h :
      в результате получаю такую осциллограмму :

      То есть , постоянно считывается 0.
      А вот регистры конфигурации:
      Задаю номер входа MUX и усиление :
       

       
      Читаю данные так:
      ADS1220Config_MUX_GAIN(ADS1220_MUX_0_G, ADS1220_GAIN_1); HAL_Delay(10); temp_[0] = ADS1220ReadData(); Это для 0 канала. 
      Пробовал и так:
      ADS1220SetChannel(ADS1220_MUX_0_G); ADS1220SetGain(ADS1220_GAIN_1); temp_[0] = ADS1220ReadData(); Результат аналогичный. Кто что подскажет? Может кто заметит какой косяк в коде? Уже голова дымит ..
    • By pryanic
      Доброго времени суток. Понадобилось разобраться с АЦП.  Основной материал использовал Евстифеева (микроконтроллеры семейства мега) и учебный курс Di-Halt.
      На первый раз задача простая - обработать напряжение с переменного резистора и послать по UART в терминал. С терминалом уже кое-что делал, так что тут вряд ли косяк есть.
      Кратко опишу программу: каждую секунду в обработчике прерывания таймера (не совсем точно, прерывание по переполнению Т0) запускаю преобразование АЦП установкой в 1 бита ADSC. 
      В обработчике прерывания АЦП читаю байт ADCH (выравнивание по левому краю ADLAR=1) и шлю по уарт. Но в терминал приходят одни FF независимо от положения движка потенциометра (подключен к PC1 средним контактом, крайними на землю и AVCC)
       
       
      ADC_test.zip
    • By dav1977
      Кто-нибудь запускал скоростные  АЦП  AD7606(последовательного приближения)
       в последовательном режиме считывания данных ?,
      из 4 шт одна заработала, остальные на выводе последовательного вывода DOUT ничего не выдают постоянно 0.
      пробовал переключаться с внутренним опорным источником(выдает 2.49), и с внешним без разницы.
      Может у них есть какая то очередность включения?
       

    • By Илья Говжеев
      Поделитесь опытом , кто уже пробывал из arduino сделать программатор pic? 

×
×
  • Create New...