роботы
робототехника
микроконтроллеры
Главная
Как сделать робота
Новости
Спорт
Статьи
Wiki
Форум
Downloads
Ссылки
Контакты  


 Страниц (1): [1]   

> Без описания
ShimkoMax
Отправлено: 27 Июня, 2018 - 19:08:32
Post Id


Рядовой


Сообщений всего: 3
Дата рег-ции: Июнь 2018  





Здравствуйте. Требуется вывести данные температуры и влажности на экран. С LCD дисплеем разобрался, осталось разобраться с SHT21. Постоянно выводит 0 на дисплей:

Main.c:
CODE:

#define F_CPU 8000000UL
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <stdio.h>
#include <stdlib.h>

#include "globals.h"
#include "LCD_lib.h"
#include "twi.h" // I2C
#include "sht21.h"

int main(void)
{
I2C_Init();
_delay_ms(100);
LCD_init();

char buffer[20];

roomAdrInit();

SHT21_reset();

while(1)
{
SHT21_reset();
LCD_sendString(itoa((int)get_temperature(), buffer, 10), 4, 0, 0);
_delay_ms(1000);
}
}


twi.c:
CODE:


#include#inclu <avr/io.h>
#include "twi.h"

void I2C_Init(void)
{
TWSR = 0;
TWBR = 0x20;
TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
}

void I2C_StartCondition(void)
{
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while(!(TWCR & (1<<TWINT)));
}

void I2C_StopCondition(void)
{
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
}

void I2C_SendByte(uint8_t data)
{
TWDR = data;
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT)));
}

unsigned char I2C_ReadByteAck(void)
{
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWEA);
while(!(TWCR & (1<<TWINT)));

return TWDR;
}

unsigned char I2C_ReadByteNak(void)
{
TWCR = (1<<TWINT) | (1<<TWEN);
while(!(TWCR & (1<<TWINT)));

return TWDR;
}


sht21.c:
CODE:

#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <stdlib.h>
#include <stdio.h>
#include "twi.h"
#include "sht21.h"

void SHT21_reset()
{
unsigned char reg[1];
reg[0]=SHT21_reset_cmd;
I2C_StartCondition();
I2C_SendByte(SHT21_i2c_write);
I2C_SendByte(*reg);
I2C_StopCondition();
_delay_ms(100);
}

uint16_t checksum(unsigned char data[],uint8_t byte, uint8_t check)
{
uint8_t crc=0;
uint8_t bytectr,bit;
for (bytectr=0; bytectr<byte;bytectr++)
{
crc^=(data[bytectr]);
for (bit=8;bit>0;bit--)
{
if(crc&0x80)
{
crc=(crc<<1)^polynomial;
}
else
{
crc=crc<<1;
}
}
}
if (crc!=check)
{
return 0;
}
else
{
return data;
}
}

void write_user_register()
{
unsigned char reg[3];
reg[0]=user_register_write;
reg[1]=0x44;

I2C_StartCondition();
I2C_SendByte(SHT21_i2c_write);
I2C_SendByte(*reg);
I2C_StopCondition();
}

uint16_t read_value(uint8_t reg)
{
char data[4],crc;
uint16_t result;
data[0]=reg;

I2C_StartCondition();
I2C_SendByte(SHT21_i2c_write);
I2C_SendByte(reg);

I2C_StartCondition();
I2C_SendByte(SHT21_i2c_read);
data[1] = I2C_ReadByteAck();
data[2] = I2C_ReadByteAck();
crc=I2C_ReadByteNak();
I2C_StopCondition();

result=(data[1]<<8) | data[2];
checksum(result,4,crc);
result &= 0xFFFC;
return result;
}

float get_humidity()
{
//char buffer2[4];
uint16_t hum_value = read_value(humidity_hold_mode);
return -6 + 125.0 / 65536.0 * hum_value;
//dtostrf(rh,5,2,buffer2);
_delay_ms(100);
}

float get_temperature()
{
//char buffer1[4];
uint16_t temp_value = read_value(temperature_hold_mode);
return -46.85 + 175.72 / 65536.0 * temp_value;
//dtostrf(tc,5,2,buffer1);
_delay_ms(100);
}

(Отредактировано автором: 27 Июня, 2018 - 19:09:15)

 
 Top
Predator Супермодератор
Отправлено: 27 Июня, 2018 - 20:24:39
Post Id


Супермодератор


Сообщений всего: 1149
Дата рег-ции: Июль 2012  





в первом приближении всё должно работать.
попробуйте для начала вывести прочитанное значение (до пересчета в градусы и проценты), для продолжения прочитать User Register.
ну и схему включения в студию (на случай если косяк на физическом уровне).
 
 Top
ShimkoMax
Отправлено: 27 Июня, 2018 - 20:42:32
Post Id


Рядовой


Сообщений всего: 3
Дата рег-ции: Июнь 2018  





Вместо return -46.85 + 175.72 / 65536.0 * temp_value;
Написал return (float)temp_value;
Скрин схемы: (на мультиплексор не смотрите)
http://prntscr.com/k01wrv
Немного приврал. 0 вывело уже после того как я убрал вычисления. Если считать по формуле выводит -46.

(Отредактировано автором: 27 Июня, 2018 - 20:43:59)

 
 Top
Predator Супермодератор
Отправлено: 27 Июня, 2018 - 22:50:25
Post Id


Супермодератор


Сообщений всего: 1149
Дата рег-ции: Июль 2012  





я так понимаю - пока на виртуальном уровне, и в протеусе?
так осциллограф туда и смотреть... шлёт-ли контроллер запрос, шлёт-ли градусник данные (может он и шлёт 0-ли), выставляют-ли ACK....
 
 Top
ShimkoMax
Отправлено: 27 Июня, 2018 - 22:52:48
Post Id


Рядовой


Сообщений всего: 3
Дата рег-ции: Июнь 2018  





Predator пишет:
я так понимаю - пока на виртуальном уровне, и в протеусе?
так осциллограф туда и смотреть... шлёт-ли контроллер запрос, шлёт-ли градусник данные (может он и шлёт 0-ли), выставляют-ли ACK....

Да, нужно в протеусе. На осциллографе какая-то билеберда по-моему, но я пришел из высокоуровневого программирования, ничего не понимаю. Какие данные нужно скинуть?
 
 Top
Predator Супермодератор
Отправлено: 28 Июня, 2018 - 12:34:49
Post Id


Супермодератор


Сообщений всего: 1149
Дата рег-ции: Июль 2012  





собственно не скинуть, а перепроверить. Сравнить то, что на линиях с тем, что на 8 странице сего
http://www.farnell.com/datasheets/1780639.pdf
датащита.
ну и страница 280 сего
https://eu.mouser.com/ds/2/36/At...sheet-464632.pdf
датащита пояснит, как должны выглядеть старт, стоп ACK, NACK и прочее...
 
 Top
Страниц (1): [1]
« Программирование микроконтроллеров »


Все гости форума могут просматривать этот раздел.
Только зарегистрированные пользователи могут создавать новые темы в этом разделе.
Только зарегистрированные пользователи могут отвечать на сообщения в этом разделе.
 





Powered by Exclusive Bulletin Board
ExBB FM 1.0 RC1 Smiles by Fool from Foolstown