
Правильный
 
Профиль
Группа: Комодератор
Сообщений: 825
Регистрация: 3.4.2003
Репутация: 9 Всего: 21
|
Пример на каком языке? На С или Ассемблере? файл 1.с Код | /***************************************************** This program was produced by the CodeWizardAVR V1.25.8 Professional Automatic Program Generator c Copyright 1998-2007 Pavel Haiduc, HP InfoTech s.r.l. http://www.hpinfotech.com
Project : Version : Date : 03.01.2008 Author : CronOS Company : Comments: Пример показывающий работу LCD и датчика температуры DS18B20. Это пример неплох как демонстрация, неболее, вы все поймете увидев размер скомпилированной прошивки =)). К примеру прилагатеся готовый проект в симуляторе ISIS (использовалась версия 7.1 SP2), специально для него параметр (s)printf Features расположенный в Project->Configure->C Compilier был установлен в положение "long,width".
Chip type : ATmega8 Program type : Application Clock frequency : 4,000000 MHz Memory model : Small External SRAM size : 0 Data Stack size : 256 *****************************************************/
#include <mega8.h> #include <delay.h>
#define LCD_PORT PORTB #define LCD_DDR DDRB #include <My_LCD.h>
#asm .equ __w1_port=0x12 ;PORTD .equ __w1_bit=0 #endasm #include <1wire.h>
#define ONE_WIRE_PIN 0 #define ONE_WIRE_PORTIN PIND #define ONE_WIRE_PORT PORTD #define ONE_WIRE_DDR DDRD
#define MAX_DEVICES 4
#include "My_DS18B20.h"
char Rom_Code[MAX_DEVICES][9];
void main(void) { char nDevice; char i = 0; // Input/Output Ports initialization // 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=0xFF;
// Port C initialization // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // 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 TCCR0=0x00; TCNT0=0x00;
// Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer 1 Stopped // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 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: Timer 2 Stopped // Mode: Normal top=FFh // OC2 output: Disconnected ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00;
// External Interrupt(s) initialization // INT0: Off // INT1: Off MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x00;
// Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; SFIOR=0x00;
LCD_Init();
/* do { temp = OneWire_SearchRom(ROM[nDevice], temp); nDevice++; } while(temp != 0);
Это пример использования команды SearchRom из моего My_OneWire.h, не знаю как в реальной схеме, но в симуляторе ISIS этот код ведет себя не всегда правильно, поэтому вместо него, ради эксперимента была взята соответствующая функция w1_search из стандартной библиотеки CVAVR. */ nDevice = w1_search(0xF0, Rom_Code); while(1) { switch(i) { case 0: LCD_CursorPos(1,1); break; case 1: LCD_CursorPos(2,1); break; case 2: LCD_CursorPos(1,9); break; case 3: LCD_CursorPos(2,9); break; } //------------------------------------------------ // Способ первый - сначала команда к измерению, потом чтение. // Преимущество в том, что вместо задержки (750мс в данном случае) // можно выполнять какую-либо полезную работу и только через // определенное время возвращаясь в цикл для чтения уже готовой // температуры. //------------------------------------------------ DS18B20_StartConvTemp(Rom_Code[i]); delay_ms(750); DS18B20_GetTemp(Rom_Code[i]); LCD_SendStr_S(DS18B20_GetCurrentTempStr()); //------------------------------------------------ // Способ второй. Вызываем только одну функцию, которая // и даст команду, подождет, считает и вернет тем-ру в // виде готовой строки символов. //------------------------------------------------ //LCD_SendStr_S(DS18B20_ReadTemp(Rom_Code[i])); //------------------------------------------------ i++; if(i > nDevice) i = 0; } }
|
файл my_ds18b20.h Код | #ifndef MY_DS18B20_H #define MY_DS18B20_H
#include <My_OneWire.h> #include <stdio.h>
/* Программа-драйвер для работы цифрового термометра DS18B20 фирмы DALLAS (MAXIM) использующего интерфейс 1-Wire. */
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //Прежде чем включать этот файл в ваш проект, не забудьте перед ним обьявить !! //адресс порта к которому подключенно ваше устройство. !! //Пример для PORTD.0: !! // !! // #define ONE_WIRE_PIN 0 !! // #define ONE_WIRE_PORTIN PIND !! // #define ONE_WIRE_PORT PORTD !! // #define ONE_WIRE_DDR DDRD !! // !! //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
/* Внимание! В каждой из функций ...ReadTemp... с помощью предопределения DS18B20_CONV_PAUSE установлены задержки между операциями посылки комманды измерения тем-ры и ее чтения. Значение в 750(мс) является максимальным и определяет время нужное датчику для конвертации тем-ры в 12-битном разрешении, для других разрешений этот промежуток составляет: 11-бит: 375 10-бит: 188 9-бит: 94 Так как конфигурационный регистр отражающий настройки этого разрешения является энергозависимым, при включении DS18B20 разрешением по-умолчанию является всегда 12-бит. Если во время работы датчика вам необходимо его изменять, не забудьте определить соответствующие значение задержки в нижеследующем опредлении: */ #define DS18B20_CONV_PAUSE 750 //-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-; //-------------------------- // ВСЕ ПЗУ КОМАНДЫ DS18B20 | //--------------------------
#define CONVERT_TEMP 0x44 //Команда к началу измерения температуры. #define WRITE_SCRATCHPAD 0x4E //Записать пользовательские данные в регистры TEMP_TL, TEMP_TH и находящиеся в ПЗУ. #define READ_SCRATCHPAD 0xBE //Прочесть содержимое ОЗУ (9 байт). #define COPY_SCRATCHPAD 0x48 //Сохранение текущих значений регистров TEMP_TL\TH в ПЗУ. #define RECALL_E2 0xB8 //Команда действует обратным образом предыдущей. #define READ_POWER_SUPPLY 0xB4 //Проверка используемого режима питания (обычное \ паразитное питание).
//-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;-;
unsigned char tempBuffer[30];
typedef struct //Структура хранения считываемых данных из ОЗУ DS18S20. { unsigned char tempLsb; unsigned char tempMsb; unsigned char tempTH; unsigned char tempTL; unsigned char ConfReg; unsigned char Reserved_0; unsigned char Reserved_1; unsigned char Reserved_2; unsigned char crc; }DS18B20_ScratchPad;
DS18B20_ScratchPad ds18b20;
//---------------------------------------------------------------------------------------------------------------------- /////////////////////////////////////////////////////ФУНКЦИИ.///////////////////////////////////////////////////////////| //----------------------------------------------------------------------------------------------------------------------
unsigned char* DS18B20_GetCurrentTempStr(void); unsigned char* ConvTempToStr(void); unsigned char* DS18B20_ReadTemp_ALL(void); unsigned char* DS18B20_ReadTemp(unsigned char *id); void DS18B20_StartConvTemp_ALL(void); void DS18B20_StartConvTemp(unsigned char *id); unsigned char DS18B20_GetTemp_ALL(void); unsigned char DS18B20_GetTemp(unsigned char *id); void DS18B20_WriteScratchPad(unsigned char *three_bytes); unsigned char DS18B20_ReadScratchPad(void); //--------------------------------------------------------------------------------------------------------------------- ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////| //---------------------------------------------------------------------------------------------------------------------
/***************************************************************************** * * Имя функции : DS18B20_GetCurrentTempStr * * Возвращаемые значения : Строка символов отражающих измеренную тем-ру. * * Параметры : Нет. * * Задача : Функция возвращает строку символов, содержащуюся в буфере * tempBuffer (объявлен глобально в этом файле), эта строка отражает * последнюю измеренную тем-ру с помощью функций DS18B20_ReadTemp / * ..._ALL. Но в тоже самое время эти функции возвращают такую строку * сами, поэтому интерес в использовании именно этой функции - в * поочередном вызове сначала DS18B20_StartConvTemp / ..._ALL, потом * DS18B20_GetTemp / ..._ALL, а уже после выводить тем-ру на ЖКИ при * помощи DS18B20_GetCurrentTempStr - это позволяет избавиться от * обязательного ожидания 750мс в функциях ...ReadTemp...(время нужное * датчику для конв. тем-ры в 12-битном режиме) и делать в это время * какие-то полезные действия (между вызовом StartConvTemp и GetTemp). * Полученная строка может быть выведена на ЖКИ например с помощью * стандартной библиотеки LCD.h в CVAVR: * lcd_puts(DS18B20_GetCurrentTempStr()); * * *****************************************************************************/
unsigned char* DS18B20_GetCurrentTempStr(void) { return ConvTempToStr(); }
/***************************************************************************** * * Имя функции : DS18B20_ReadTemp_ALL * * Возвращаемые значения : Строка символов полученной тем-ры. * * Параметры : Нет. * * Задача : Функция чтения тем-ры у единственного DS18B20 на шине. * * *****************************************************************************/
unsigned char* DS18B20_ReadTemp_ALL(void) { DS18B20_StartConvTemp_ALL(); //Вызываем команду для начала измерения тем-ры. delay_ms(DS18B20_CONV_PAUSE); //Ждем паузу за которую DS18B20 будет производить свои измерения.
if(DS18B20_GetTemp_ALL() == 0) //Читаем тем-ру и заодно проверяем ее правильность. { sprintf(tempBuffer, "CRC_ERROR"); //Если пришедшая тем-ра не прошла проверку - return tempBuffer; //возврщаем сигнал об ошибке. } return ConvTempToStr(); //Возвращаем тем-ру в символьной строке. }
/***************************************************************************** * * Имя функции : DS18B20_SrartConvTemp * * Возвращаемые значения : Нет. * * Параметры : id - указатель на массив хранящий идентификационный код * выбранного DS18B20. * * Задача : Функция чтения тем-ры выбранного DS18B20. * * *****************************************************************************/
unsigned char* DS18B20_ReadTemp(unsigned char *id) { DS18B20_StartConvTemp(id); delay_ms(DS18B20_CONV_PAUSE); if(DS18B20_GetTemp(id) == 0) { sprintf(tempBuffer, "CRC_ERROR"); return tempBuffer; } return ConvTempToStr(); }
/***************************************************************************** * * Имя функции : ConvTempToStr * * Возвращаемые значения : Строка символов преобразованной тем-ры. * * Параметры : Нет. * * Задача : Функция преобразует текущее содержание структуры ds18b20 в * тем-ру, а потом и в символьную строку (для вывода на ЖКИ). * Используется функциями ...ReadTemp... и DS18B20_GetCurrentTempStr * (см. описание последней для подробностей). * * *****************************************************************************/
unsigned char* ConvTempToStr(void) { unsigned int celsius; //Переменная будет содержать целы части тем-ры. unsigned int dicelsius; //Переменная будет содержать десятые доли тем-ры. unsigned char sign = '+'; //Знак тем-ры. /* Из двух байтов получаем одну 16-битную перменную. */ celsius = (ds18b20.tempLsb) + ((unsigned int)(ds18b20.tempMsb) << 8); if((ds18b20.tempMsb >> 4) != 0) //Если 4 старших бита, старшего байта тем-ры содерж. нули - тем-ра отрицательная. { sign='-'; celsius -= 2; celsius ^= 0xFFFF; //Инвертируем результат для того что бы получить реальную тем-ру. } dicelsius = celsius & 0x0F; //Выделяем 4 младших бита - это будут десятые доли тем-ры. dicelsius = (long)dicelsius * 0.625; //Конвертируем их в гр. цельсия умножением на разреш. способность датчика. celsius >>= 4; //Теперь убираем уже ненужные десятые доли. /* Конвертируем переменные в символы ASCII. "%c", sign - первым идет знак. "%u", celsius - целая часть. "%u", dicelsius - десятые доли. "%cC", 0xDF - сначала символ градуса (кружочек вверху), затем большая С. */ sprintf(tempBuffer, "%c%u.%u%cC", sign, celsius, dicelsius, 0xDF); return tempBuffer; }
/***************************************************************************** * * Имя функции : DS18B20_SrartConvTemp_ALL * * Возвращаемые значения : Нет. * * Параметры : Нет. * * Задача : Функция дает команду на начало преобразования температуры для * единственного DS18B20 на шине. * * *****************************************************************************/
void DS18B20_StartConvTemp_ALL(void) { OneWire_SkipRom(); OneWire_WriteByte(CONVERT_TEMP); }
/***************************************************************************** * * Имя функции : DS18B20_SrartConvTemp * * Возвращаемые значения : Нет. * * Параметры : id - указатель на массив хранящий идентификационный код * выбранного DS18B20. * * Задача : Функция дает команду на начало преобразования температуры для * выбранного DS18B20. * * *****************************************************************************/
void DS18B20_StartConvTemp(unsigned char *id) { OneWire_MatchRom(id); //Вызов функции которая передаст идентиф. номер нужного DS18B20 на шину. //Следующая за ней команда будет выполненна только этим DS18B20. OneWire_WriteByte(CONVERT_TEMP); //Посылка команды для начала конвертирования температуры. }
/***************************************************************************** * * Имя функции : DS18B20_GetTemp_ALL * * Возвращаемые значения : При успешном окончании процесса передачи данных * из ОЗУ DS18B20 в МК, функция возвращает 1, иначе 0. * * Параметры : Нет. * * Задача : После преобразования температуры (DS18B20_ConvTemp) функция читает * содержимое ОЗУ DS18B20 в массив DS18B20_ScratchPad (в том числе * и температуру). * * *****************************************************************************/
unsigned char DS18B20_GetTemp_ALL(void) { OneWire_SkipRom(); if(DS18B20_ReadScratchPad() == 1) return 1; else return 0; }
/***************************************************************************** * * Имя функции : DS18B20_GetTemp * * Возвращаемые значения : При успешном окончании процесса передачи данных из * ОЗУ DS18B20 в МК, функция возвращает 1, иначе 0. * * Параметры : id - указатель на массив хранящий идентификационный кода * выбранного DS18B20. * * Задача : После преобразования температуры (DS18B20_ConvTemp) функция читает * содержимое ОЗУ DS18B20 в массив DS18B20_ScratchPad (в том числе * и температуру). * * *****************************************************************************/
unsigned char DS18B20_GetTemp(unsigned char *id) { OneWire_MatchRom(id); //Вызов функции которая передаст идентиф. номер нужного DS18B20 на шину. //Следующая за ней команда будет выполненна только этим DS18B20. if(DS18B20_ReadScratchPad() == 1) //Проводим чтение всего ОЗУ DS18B20 и заодно проверяем его на честность. return 1; else return 0; }
/***************************************************************************** * * Имя функции : DS18B20_WriteScratchPad * * Возвращаемые значения : Нет. * * Параметры : *three_bytes - указатель на массив их трех байтов: * (необходимо соблюдать порядок) * 1)TEMP_TH - Верхний предел пороговой темп. сработывания сигнализации. * 2)TEMP_TL - Нижний предел пороговой темп. сработывания сигнализации. * 3)CONFIG_R - Байт задания разрешения вых. температуры. * Имеет вид: * (MSB)->0-R1-R0-1-1-1-1-1<-(LSB) * R1 = 0; R0 = 0; Разрешение 9-бит. * R1 = 0; R0 = 1; Разрешение 10-бит. * R1 = 1; R0 = 0; Разрешение 11-бит. * R1 = 1; R0 = 1; Разрешение 12-бит. * * Задача : Функция настройки DS18B20 путем записи пользовательских данных о * разрешении температуры и верхнего, нижнего порогов температуры * вызывающей сигнализацию (опрашивание на предмет сигнализации * происходит с помощью команды ALARM_SEARCH (CONDITIONAL_SEARCH). * * *****************************************************************************/
void DS18B20_WriteScratchPad(unsigned char *three_bytes) { unsigned char i; OneWire_WriteByte(WRITE_SCRATCHPAD); //Команда записи в ПЗУ DS18B20. //После принятия команды, датчик готов принять 3 байта. for(i=0; i<3; i++) //Отправка. { OneWire_WriteByte(*three_bytes); three_bytes++; } }
/***************************************************************************** * * Имя функции : DS18B20_ReadScratchPad * * Возвращаемые значения : 0 - если при чтении содержимого ОЗУ произошли ошибки * (сумма CRC принятая от датчика не совпадает с посчитанной * в МК). 1 - в случае если все благополучно. * * Параметры : Нет. * * Задача : Чтение содержимого ОЗУ DS18B20 в массив DS18B20_ScratchPad. Все 8 * входящих байт проверяются на честность с CRC (9-й принятым байтом). * * *****************************************************************************/
unsigned char DS18B20_ReadScratchPad(void) { unsigned char i; unsigned char *ptr = (char*) &ds18b20; //указатель для доступа к структуре ds18b20. //Глобальная переменная CRC объявлена в My_OneWire.h CRC = 0; //Перед началом очередного считывания ОЗУ датчика, ее следует обнулять. OneWire_WriteByte(READ_SCRATCHPAD); //Команда чтения ОЗУ DS18B20.
for(i=0; i<9; i++) //ОЗУ DS18B20 содержит 9 байт, поэтому у нас 9 циклов. { *(ptr+i) = OneWire_ReadByte(); //Поочередно заполняем структуру DS18B20_ScratchPad содержанием ОЗУ датчика.
if(i < 8) //Первые 8-байт отправляем на алгоритм подсчета контрольной суммы. CRC8(*(ptr+i)); }
if(CRC == ds18b20.crc) //Если посчитанная МК сумма совпадает с той что была переданна 9 байтом - вернем 1. return 1; else //Если нет, возможно при передаче произошла ошибка, следовательно данные неверны, return 0; //возвращаем 0. }
#endif
|
файл 1.inc Код |
_rowAdress: .DB 0x80,0xC0,0x94,0xD4 .DEF _CRC=R5 _CRC_Table: .DB 0x0,0x5E,0xBC,0xE2,0x61,0x3F,0xDD,0x83 .DB 0xC2,0x9C,0x7E,0x20,0xA3,0xFD,0x1F,0x41 .DB 0x9D,0xC3,0x21,0x7F,0xFC,0xA2,0x40,0x1E .DB 0x5F,0x1,0xE3,0xBD,0x3E,0x60,0x82,0xDC .DB 0x23,0x7D,0x9F,0xC1,0x42,0x1C,0xFE,0xA0 .DB 0xE1,0xBF,0x5D,0x3,0x80,0xDE,0x3C,0x62 .DB 0xBE,0xE0,0x2,0x5C,0xDF,0x81,0x63,0x3D .DB 0x7C,0x22,0xC0,0x9E,0x1D,0x43,0xA1,0xFF .DB 0x46,0x18,0xFA,0xA4,0x27,0x79,0x9B,0xC5 .DB 0x84,0xDA,0x38,0x66,0xE5,0xBB,0x59,0x7 .DB 0xDB,0x85,0x67,0x39,0xBA,0xE4,0x6,0x58 .DB 0x19,0x47,0xA5,0xFB,0x78,0x26,0xC4,0x9A .DB 0x65,0x3B,0xD9,0x87,0x4,0x5A,0xB8,0xE6 .DB 0xA7,0xF9,0x1B,0x45,0xC6,0x98,0x7A,0x24 .DB 0xF8,0xA6,0x44,0x1A,0x99,0xC7,0x25,0x7B .DB 0x3A,0x64,0x86,0xD8,0x5B,0x5,0xE7,0xB9 .DB 0x8C,0xD2,0x30,0x6E,0xED,0xB3,0x51,0xF .DB 0x4E,0x10,0xF2,0xAC,0x2F,0x71,0x93,0xCD .DB 0x11,0x4F,0xAD,0xF3,0x70,0x2E,0xCC,0x92 .DB 0xD3,0x8D,0x6F,0x31,0xB2,0xEC,0xE,0x50 .DB 0xAF,0xF1,0x13,0x4D,0xCE,0x90,0x72,0x2C .DB 0x6D,0x33,0xD1,0x8F,0xC,0x52,0xB0,0xEE .DB 0x32,0x6C,0x8E,0xD0,0x53,0xD,0xEF,0xB1 .DB 0xF0,0xAE,0x4C,0x12,0x91,0xCF,0x2D,0x73 .DB 0xCA,0x94,0x76,0x28,0xAB,0xF5,0x17,0x49 .DB 0x8,0x56,0xB4,0xEA,0x69,0x37,0xD5,0x8B .DB 0x57,0x9,0xEB,0xB5,0x36,0x68,0x8A,0xD4 .DB 0x95,0xCB,0x29,0x77,0xF4,0xAA,0x48,0x16 .DB 0xE9,0xB7,0x55,0xB,0x88,0xD6,0x34,0x6A .DB 0x2B,0x75,0x97,0xC9,0x4A,0x14,0xF6,0xA8 .DB 0x74,0x2A,0xC8,0x96,0x15,0x4B,0xA9,0xF7 .DB 0xB6,0xE8,0xA,0x54,0xD7,0x89,0x6B,0x35 _294: .DW 0x00 _0: .DB 0x43,0x52,0x43,0x5F,0x45,0x52,0x52,0x4F .DB 0x52,0x0,0x25,0x63,0x25,0x75,0x2E,0x25 .DB 0x75,0x25,0x63,0x43,0x0
__GLOBAL_INI_TBL: .DW 0x02 .DW _p_S62 .DW _294*2
.DW 0 _0x134:
|
--------------------
Мне нужны помощники.
|