[an error occurred while processing this directive]
Ответ:
(«Телесистемы»: Конференция «Микроконтроллеры и их применение»)

миниатюрный аудио-видеорекордер mAVR

Отправлено ubobrov 02 августа 2006 г. 15:55
В ответ на: помогите please с процедурой 1-wire на C для PIC отправлено Роман_В 02 августа 2006 г. 14:41

/*

16F628 Pin Assignments:

A0 Unused
A1 Unused
A2 Unused
A3 Unused
A4 Unused
A5 Unused
B0 LCD RS
B1 LCD RW
B2 LCD ENABLE
B3 DS18S20 DQ
B4 LCD DATA 4
B5 LCD DATA 5
B6 LCD DATA 6
B7 LCD DATA 7

Internal ~4MHz RC oscillator is used, timing is not critical.
WDT timeout is set to max, which will give around 6.5 - 7
seconds between temperature updates. This greatly prolongs
battery life, since most of the time is spent in sleep mode!

*/
#include <16F628.h>
#device *=16
#use delay(clock=4000000,RESTART_WDT)
#fuses INTRC,WDT,PUT,NOBROWNOUT,NOLVP,NOMCLR
#use RS232(baud=9600, xmit=PIN_A5)
#define use_portb_lcd
#define ONEWIRE_PIN PIN_B3

#define SearchROM 0xF0
#define ReadROM 0x33
#define MatchROM 0x55
#define SkipROM 0xCC
#define AlarmSearch 0xEC
#define ConvertT 0x44
#define WriteScratchpad 0x4E
#define ReadScratchpad 0xBE
#define CopyScatchpad 0x48
#define RecallE2 0xB8
#define ReadPowerSupply 0xB4

//
// Here are the DS1820 driver functions, adapted from the Dallas
// app notes
//


//-----------------------------------------------------------------------------
// Generate a 1-Wire reset, return 1 if no presence detect was found,
// return 0 otherwise.
// (NOTE: Does not handle alarm presence from DS2404/DS1994)
//
int OWTouchReset(void)
{
int result;
output_low(ONEWIRE_PIN); // Drives DQ low
delay_us(480);
output_float(ONEWIRE_PIN); // Releases the bus
delay_us(70);
result = input(ONEWIRE_PIN); // Sample for presence pulse from slave
delay_us(410); // Complete the reset sequence recovery
return result; // Return sample presence pulse result
}

//-----------------------------------------------------------------------------
// Send a 1-Wire write bit. Provide 10us recovery time.
//
void OWWriteBit(int bit)
{
if (bit)
{
// Write ‘1’ bit
output_low(ONEWIRE_PIN); // Drives DQ low
delay_us(6);
output_float(ONEWIRE_PIN); // Releases the bus
delay_us(64); // Complete the time slot and 10us recovery
}
else
{
// Write ‘0’ bit
output_low(ONEWIRE_PIN); // Drives DQ low
delay_us(60);
output_float(ONEWIRE_PIN); // Releases the bus
delay_us(10);
}
}

//-----------------------------------------------------------------------------
// Read a bit from the 1-Wire bus and return it. Provide 10us recovery time.
//
int OWReadBit(void)
{
int result;
output_low(ONEWIRE_PIN); // Drives DQ low
delay_us(6);
output_float(ONEWIRE_PIN); // Releases the bus
delay_us(9);
result = input(ONEWIRE_PIN); // Sample the bit value from the slave
delay_us(55); // Complete the time slot and 10us recovery
return result;
}

//-----------------------------------------------------------------------------
// Write 1-Wire data byte
//
void OWWriteByte(int data)
{
int loop;
// Loop to write each bit in the byte, LS-bit first
for (loop = 0; loop < 8; loop++)
{
OWWriteBit(data & 0x01);
// shift the data byte for the next bit
data >>= 1;
}
}

//-----------------------------------------------------------------------------
// Read 1-Wire data byte and return it
//
int OWReadByte(void)
{
int loop, result=0;
for (loop = 0; loop < 8; loop++)
{
// shift the result to get it ready for the next bit
result >>= 1;
// if result is one, then set MS bit
if (OWReadBit())
result |= 0x80;
}
return result;
}

//-----------------------------------------------------------------------------
// Write a 1-Wire data byte and return the sampled result.
//
int OWTouchByte(int data)
{
int loop, result=0;
for (loop = 0; loop < 8; loop++)
{
// shift the result to get it ready for the next bit
result >>= 1;
// If sending a ‘1’ then read a bit else write a ‘0’
if (data & 0x01)
{
if (OWReadBit())
result |= 0x80;
}
else
OWWriteBit(0);
// shift the data byte for the next bit
data >>= 1;
}
return result;
}

//-----------------------------------------------------------------------------
// Write a block 1-Wire data bytes and return the sampled result in the same
// buffer.
//
void OWBlock(unsigned char *data, int data_len)
{
int loop;
for (loop = 0; loop < data_len; loop++)
{
data[loop] = OWTouchByte(data[loop]);
}
}

//
// Following are the LCD driver functions, with a few minot tweaks.
//

struct lcd_pin_map { // This structure is overlayed
boolean rs; // on to an I/O port to gain
boolean rw; // access to the LCD pins.
boolean enable; // The bits are allocated from
boolean unused; // low order up. ENABLE will
int data : 4; // be pin B0.
} lcd;
#define num_msgs 5
#byte lcd = 6 // PORTB address for LCD
#define set_tris_lcd(x) set_tris_b(x)
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the second line
byte CONST LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
// These bytes need to be sent to the LCD
// to start it up.


// The following are used for setting
// the I/O port direction register.
STRUCT lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
STRUCT lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in


byte lcd_read_byte() {
byte low,high;
set_tris_lcd(LCD_READ);
lcd.rw = 1;
delay_cycles(1);
lcd.enable = 1;
delay_cycles(1);
high = lcd.data;
lcd.enable = 0;
delay_cycles(1);
lcd.enable = 1;
delay_us(1);
low = lcd.data;
lcd.enable = 0;
set_tris_lcd(LCD_WRITE);
return( (high<<4) | low);
}

void lcd_send_nibble( byte n ) {
lcd.data = (n);
delay_cycles(1);
lcd.enable = 1;
delay_us(2);
lcd.enable = 0;
}

void lcd_send_byte( byte address, byte n ) {

lcd.rs = 0;
while ( bit_test(lcd_read_byte(),7) ) ;
lcd.rs = address;
delay_cycles(1);
lcd.rw = 0;
delay_cycles(1);
lcd.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}

void lcd_init() {
byte i;
set_tris_lcd(LCD_WRITE);
lcd.rs = 0;
lcd.rw = 0;
lcd.enable = 0;
delay_ms(50);
for(i=1;i<=3;++i) {
lcd_send_nibble(3);
delay_ms(15);
}
lcd_send_nibble(2);
for(i=0;i<=3;++i)
lcd_send_byte(0,LCD_INIT_STRING[i]);
}

void lcd_gotoxy( byte x, byte y) {
byte address;

if(y!=1)
address=lcd_line_two;
else
address=0;
address+=x-1;
lcd_send_byte(0,0x80|address);
}

void lcd_putc( char c) {
switch (c) {
case '\f' : lcd_send_byte(0,1);
delay_ms(2);
break;
case '\n' : lcd_gotoxy(1,2); break;
case '\b' : lcd_send_byte(0,0x10); break;
default : lcd_send_byte(1,c); break;
}
}

//
// The rest of this is all original code, something I can actually
// take credit (or blame) for...
//

const char msgs[5][17] = {" Current Temp: ",
"AAAAAAAAAAAAAAAA",
"BBBBBBBBBBBBBBBB",
"CCCCCCCCCCCCCCCC",
"DDDDDDDDDDDDDDDD"};

long get_temperature() {
int x, data, scratch = 0;
long raw_temp;

if (owTouchReset()) // Reset the 1-Wire bus
return 0; // Return if no devices found

OWWriteByte(SkipROM); // Tell DS18S20 to skip ROM select
OWWriteByte(ConvertT); // Start temperature conversion
delay_ms(100);
if (owTouchReset()) // Reset the 1-Wire bus
return 0; // Return if no devices found
OWWriteByte(SkipROM); // Tell DS18S20 to skip ROM select
OWWriteByte(ReadScratchPad); // Send read scratchpad comand to DS18S20
data = OWReadByte(); // Get the first byte
raw_temp = data; // Store as high byte of raw temp data
data = OWReadByte(); // Get second byte
raw_temp |= (data * 256); // Store as low byte of raw temp data
return raw_temp;
}

void main() {
char count, message, n = 0;
char buffer[17];
long x;
long temp_c, temp_f;
char d_c, d_f;

port_b_pullups(TRUE);
setup_counters(RTCC_INTERNAL,WDT_2304MS);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_vref(FALSE);
setup_comparator(FALSE);
lcd_init();
lcd_putc('\f');
while(1) {
x = get_temperature();
// temp_c = (float)(x/2);
// temp_f = ((temp_c * 1.8) + 32);
temp_c = x;
//d_c = (temp_c % 2) * 5;
temp_c /= 2;
temp_f = (x * 9) + 320;
//d_f = (temp_f % 10);
temp_f /= 10;

switch(count++) {
case 0:
lcd_gotoxy(1,1);
for(n=0;n<16;n++) {
lcd_putc(msgs[0][n]);
}
break;
case 5:
count = 0;
if(++message >= num_msgs) message = 1;
lcd_gotoxy(1,1);
for(n=0;n<16;n++) {
lcd_putc(msgs[message][n]);
}
}
lcd_gotoxy(1,2);
printf(lcd_putc," ");
lcd_gotoxy(1,2);
printf(lcd_putc," %3ldF / %3ldC",temp_f, temp_c);
output_a(0xFF);
output_b(0);
sleep();
sleep();
sleep();
}
}


Составить ответ  |||  Конференция  |||  Архив

Ответы


Отправка ответа

Имя (обязательно): 
Пароль: 
E-mail: 

Тема (обязательно):
Сообщение:

Ссылка на URL: 
Название ссылки: 

URL изображения: 


Rambler's Top100 Рейтинг@Mail.ru
Перейти к списку ответов  |||  Конференция  |||  Архив  |||  Главная страница  |||  Содержание