1 / 1 / 0
Регистрация: 17.01.2010
Сообщений: 165
1

DS18B20->Atmega8->UART

26.05.2018, 18:51. Показов 1101. Ответов 3
Метки нет (Все метки)

Всем привет!

Я ломаю голову над тем, как передавать температуру по UART, а именно как предоставить измеренное датчиком цифровое значение на передачу в UART. Пришел к такому коду (со всеми инициализациями и т.д.), но генерация сигнала на выходе UARTa по нажатию кнопки все равно не происходит.

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// [url]http://radioparty.ru/prog-avr/program-c/378-lesson2-ds18b20[/url]
 
#define F_CPU 8000000 // Рабочая частота контроллера
#define BAUD 9600L // Скорость обмена данными
#define UBRRL_value (F_CPU/(BAUD*16))-1 //Согластно заданной скорости подсчитываем значение для регистра UBRR
 
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdlib.h>
 
#define NOID 0xCC //Пропустить идентификацию
#define T_CONVERT  0x44 //Код измерения температуры
#define READ_DATA 0xBE //Передача байтов ведущему
 
#define PORTTEMP PORTC
#define DDRTEMP DDRC
#define PINTEMP PINC
#define BITTEMP 0
 
int dt_check(void); //функция преобразования показаний датчика в температуру
char converttemp (unsigned int tt); //преобразование температуры в единицы
 
//функция определения датчика на шине
char dt_testdevice(void) //dt - digital termomether | определим, есть ли устройство на шине
{
    char stektemp=SREG;// сохраним значение стека
    cli(); //запрещаем прерывание
    char dt;
    DDRTEMP |= 1<<BITTEMP; //притягиваем шину
    _delay_us(485); //задержка как минимум на 480 микросекунд
    DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину
    _delay_us(65); //задержка как максимум на 60 микросекунд
    if ((PINTEMP & (1<<BITTEMP))==0)//проверяем, ответит ли устройство
    {
        dt=1;//устройство есть
    }
    else dt=0;//устройства нет
    SREG = stektemp;// вернем значение стека
    _delay_us(420); //задержка как минимум на 480 микросекунд, но хватит и 420, тк это с учетом времени прошедших команд
    return dt; //вернем результат
}
 
//функция записи бита на устройство
void dt_sendbit(char bt)
{
    char stektemp=SREG;// сохраним значение стека
    cli(); //запрещаем прерывание
    DDRTEMP |= 1<<BITTEMP; //притягиваем шину
    _delay_us(2); //задержка как минимум на 2 микросекунды
    if(bt)
    DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину
    _delay_us(65); //задержка как минимум на 60 микросекунд
    DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину
    SREG = stektemp;// вернем значение стека
}
 
//функция записи байта на устройство
void dt_sendbyte(unsigned char bt)
{
    char i;
    for(i=0;i<8;i++)//посылаем отдельно каждый бит на устройство
    {
        if((bt & (1<<i)) == 1<<i)//посылаем 1
        dt_sendbit(1);
        else //посылаем 0
        dt_sendbit(0);
    }
}
 
//функция чтения бита с устройства
char dt_readbit(void)
{
    char stektemp=SREG;// сохраним значение стека
    cli(); //запрещаем прерывание
    char bt; //переменная хранения бита
    DDRTEMP |= 1<<BITTEMP; //притягиваем шину
    _delay_us(2); //задержка как минимум на 2 микросекунды
    DDRTEMP &= ~(1<<BITTEMP); //отпускаем шину
    _delay_us(13);
    bt = (PINTEMP & (1<<BITTEMP))>>BITTEMP; //читаем бит
    _delay_us(45);
    SREG = stektemp;// вернем значение стека
    return bt; //вернем результат
}
 
//функция чтения байта с устройства
unsigned char dt_readbyte(void)
{
    char c=0;
    char i;
    for(i=0;i<8;i++)
    c|=dt_readbit()<<i; //читаем бит
    return c;
}
 
//функция преобразования показаний датчика в температуру
int dt_check(void)
{
    unsigned char bt;//переменная для считывания байта
    unsigned int tt=0;
    if(dt_testdevice()==1) //если устройство нашлось
    {
        dt_sendbyte(NOID); //пропустить идентификацию, тк у нас только одно устройство на шине
        dt_sendbyte(T_CONVERT); //измеряем температуру
        _delay_ms(750); //в 12битном режиме преобразования - 750 милисекунд
        dt_testdevice(); //снова используем  те же манипуляции с шиной что и при проверке ее присутствия
        dt_sendbyte(NOID); //пропустить идентификацию, тк у нас только одно устройство на шине
        dt_sendbyte(READ_DATA); //даем команду на чтение данных с устройства
        bt = dt_readbyte(); //читаем младший бит
        tt = dt_readbyte(); //читаем старший бит MS
        tt = (tt<<8)|bt;//сдвигаем старший влево, младший пишем на его место, тем самым получаем общий результат
    }
    return tt;
}
 
// преобразование температуры в единицы
 char converttemp (unsigned int tt)
 {
    char t = tt>>4;//сдвиг и отсечение части старшего байта
    return t;
 }
 
 
 
/*** Инициализация USORT ***/
void init_USORT() {
    //скорость обмена данными
    UBRRH = 0;  //старший байт
    UBRRL = 51; //младший байт
    //8 бит данных, 1 стоп бит, без контроля четности
    UCSRC = ( 1 << URSEL ) | ( 1 << UCSZ1 ) | ( 1 << UCSZ0 );
    //разрешить прием и передачу данных
    UCSRB = ( 1 << TXEN ) | ( 1 <<RXEN );
}
 
void send_UART(char value) {
    while(!( UCSRA & (1 << UDRE)));   // Ожидаем когда очистится буфер передачи
    UDR = value; // Помещаем данные в буфер, начинаем передачу
}
 
int main(tt)
{
    DDRB = 0b00000001; // кнопка
    PORTB = 0b00000001; // кнопка
    init_USORT();    //инициализация USORT в режиме 9600/8-N-1
    while(1)
    {
        if (PINB==0b00000000)
            {
                send_UART(tt); //посылаем температуру,
            }
    }
 
}
Подскажите, что надо записать в скобках send_UART()???

Добавлено через 17 минут
Точнее по нажатию не передается информация о температуре, а сигнал от самого нажатия передается по UART'y
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.05.2018, 18:51
Ответы с готовыми решениями:

Atmega8 + DS18B20
Доброе время! Собственно что за беда... я в этом электронном деле совсем новенький. Возникла...

ATmega8 + DS18B20. Не работает
Мужики, помогите пожалуйста разобраться с термометром ничего в голову уже не лезет. Буду благодарен...

Односторонний UART DS18b20
Подскажите как правильно реализовать передачу данных на комп непрерывным потоком через UART......

Работа с UART в МК ATMega8
Не хочет работать передача данных. Подключаю к ножкам PD0 и PD1 через USB/UART TTL конвертор...

3
2791 / 1302 / 167
Регистрация: 28.10.2011
Сообщений: 4,827
Записей в блоге: 6
28.05.2018, 10:46 2
В main не измеряется температура. Вместо этого когда на PINB будет 0, отправляется неизвестно что в UART (переменная tt, которая непонятно почему передается через параметр main без объявления типа). Разве вы этого в коде не видите?
0
1 / 1 / 0
Регистрация: 17.01.2010
Сообщений: 165
28.05.2018, 19:56  [ТС] 3
Да, точно. Я добавил в main функцию преобразования показаний датчика в температуру dt_check(), которая возвращает значение tt. И в main'e передаю в UART двумя байтами измеренную температуру.

C
1
2
3
4
5
6
7
8
9
10
11
int main(void)
{
    unsigned tt;
    USORT_ini(103); // BAUD = 9600
    dt_check();
    while (1) 
    {
        USORT_Transmit((unsigned char)tt);
        USORT_Transmit((unsigned char)(tt>>8));
     }
}
Прием данных на втором контроллере происходит в прерывании:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
ISR(USORT_RXC_vect)
{
        static unsigned char fl=0;
        switch(fl)
        {
            case 0:
            tt = (unsigned int) UDR;
            break;
            case 1:
            tt |= ((unsigned int) UDR)<<8;
            break;
        }
}
Переменная tt для второго контроллера объявлена глобальной.
Получив данные, я хочу, например, сравнивать измеренную температуру с какой-либо величиной. Однако, данные, которые получил контроллер по UART, имеют формат int. В какой тип следует преобразовать переменную, чтобы ее можно было сравнивать с числами, например от 0 до 40?
0
2791 / 1302 / 167
Регистрация: 28.10.2011
Сообщений: 4,827
Записей в блоге: 6
01.06.2018, 15:27 4
Цитата Сообщение от манускрипт Посмотреть сообщение
Я добавил в main функцию преобразования показаний датчика в температуру dt_check(), которая возвращает значение tt.
Где происходит присвоение переменной tt в main?

Цитата Сообщение от манускрипт Посмотреть сообщение
Прием данных на втором контроллере происходит в прерывании
В fl будет всегда 0 и этот код выполнятся не будет.
C
1
2
3
            case 1:
            tt |= ((unsigned int) UDR)<<8;
            break;
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
01.06.2018, 15:27

Работа с UART ATMega8
к примеру надо отправить число 21367 в ком порт с атмеги8 чтобы потом на компе программой считать....

Передача по UART (ATMega8)
Доброго времени суток! Есть необходимость обработать передачу данных с помощью USORT через COM...

UART Atmega8 Terminal
Всем доброго времени суток! У меня есть код : #define F_CPU 8000000UL #include &lt;avr/io.h&gt;...

Приём данных по UART Atmega8
Доброго времени суток! Продолжаю постигать азы микроконтроллеров. В прошлой теме задавал, как уже...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.