ring_buffer
This commit is contained in:
parent
7819975461
commit
aa0d7df6fc
25
README.md
25
README.md
@ -1,25 +0,0 @@
|
||||
# Modbus устройство на AVR
|
||||
# Задание
|
||||
Устройство поключено к питанию всегда. Взаимодействие по интерфейсу UART (RS-485) и протоколу Modbus.
|
||||
- Discrete Inputs - 4 штуки
|
||||
- Coils - 4 штуки
|
||||
- Input registers - 2 канала АЦП
|
||||
- Holding Registers - 1 штука: адрес на шине Modbus.
|
||||
Адрес по умолчанию 0х32. Адрес хранить в ПЗУ чипа.
|
||||
Адреса данных определить самостоятельно.
|
||||
# Участники
|
||||
Южакова Лада
|
||||
Салангина Анастасия
|
||||
Макуц Ольга
|
||||
# Составляющие задачи
|
||||
- Изучить Modbus (Салангина Анастасия)
|
||||
- Изучить UART (Макуц Ольга)
|
||||
- Определить, как происходит передача по протоколу (Салангина Анастасия)
|
||||
- Разобрать назначение и способы использования регистров и вхоов-выходов (Макуц Ольга)
|
||||
- Изучить, как переопределять адрес по умолчанию в ПЗУ (Южакова Лада)
|
||||
- Изучить, как определять адреса данных в ПЗУ (Южакова Лада)
|
||||
- Изучить, как использовать RX/TX (Макуц Ольга)
|
||||
- Изучить, что такое верхняя архитектура (все)
|
||||
- Изучить ПЗУ (Южакова Лада)
|
||||
- Изучить кольцевой буфер (Южакова Лада)
|
||||
- Понять, в какой полседовательности будет работать программа (все)
|
56
device_adc.c
56
device_adc.c
@ -1,56 +0,0 @@
|
||||
#define REFS1_BIT (7)
|
||||
#define REFS1_MASK (1<<REFS1_BIT)
|
||||
#define REFS0_BIT (6)
|
||||
#define REFS0_MASK (1<<REFS0_BIT)
|
||||
#define ADLAR_BIT (5)
|
||||
#define ADLAR_MASK (1<<ADLAR_BIT)
|
||||
#define MUX3_BIT (3)
|
||||
#define MUX3_MASK (1<<MUX3_BIT)
|
||||
#define MUX2_BIT (2)
|
||||
#define MUX2_MASK (1<<MUX2_BIT)
|
||||
#define MUX1_BIT (1)
|
||||
#define MUX1_MASK (1<<MUX1_BIT)
|
||||
#define MUX0_BIT (0)
|
||||
#define MUX0_MASK (1<<MUX0_BIT)
|
||||
#define ADEN_BIT (7)
|
||||
#define ADEN_MASK (1<<ADEN_BIT)
|
||||
#define ADPS2_BIT (2)
|
||||
#define ADPS2_MASK (1<<ADPS2_BIT)
|
||||
#define ADPS1_BIT (1)
|
||||
#define ADPS1_MASK (1<<ADPS1_BIT)
|
||||
#define ADPS0_BIT (0)
|
||||
#define ADPS0_MASK (1<<ADPS0_BIT)
|
||||
#define ADSC_BIT (6)
|
||||
#define ADSC_MASK (1<<ADSC_BIT)
|
||||
#define ADIF_BIT (4)
|
||||
#define ADIF_MASK (1<<ADIF_BIT)
|
||||
|
||||
uint16_t value = 0;
|
||||
|
||||
void adc_init(void)
|
||||
{
|
||||
// Источник опорного напряжения (внутренний источник 1.1В)
|
||||
ADMUX |= REFS1_MASK | REFS0_MASK;
|
||||
// Выравнивание результата вправо
|
||||
ADMUX &= ~ADLAR_MASK;
|
||||
// Коммутация выбранного входа с АЦП (ADC0)
|
||||
ADMUX &= ~(MUX3_MASK | MUX2_MASK | MUX1_MASK | MUX0_MASK);
|
||||
// Разерешение работы АЦП
|
||||
ADCSRA |= ADEN_MASK;
|
||||
// Предделитель частоты (128)
|
||||
ADCSRA |= ADPS2_MASK | ADPS1_MASK | ADPS0_MASK;
|
||||
}
|
||||
|
||||
ISR(ADC_vect)
|
||||
{
|
||||
// Запуск работы АЦП
|
||||
ADCSRA |= ADSC_MASK;
|
||||
// Ожидание окончания преобразования
|
||||
while ((ADCSRA & ADIF_MASK) == 0);
|
||||
value = (ADCH << 8) | ADCL;
|
||||
}
|
||||
|
||||
uint16_t get_adc_value(void)
|
||||
{
|
||||
return value;
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
#ifndef DEVICE_ADC_H
|
||||
#define DEVICE_ADC_H
|
||||
|
||||
void adc_init(void);
|
||||
uint16_t get_adc_value(void);
|
||||
|
||||
#endif /*DEVICE_C_H*/
|
@ -1,41 +0,0 @@
|
||||
#include "device_address.h"
|
||||
|
||||
#define DEFAULT_MODBUS_ADDRESS (32)
|
||||
|
||||
uint8_t EEPROM_ReadByte(uint8_t __eeprom*adr)
|
||||
{
|
||||
while (EECR & (1<<EEWE));
|
||||
EEAR = (uint16_t)adr;
|
||||
EECR |= (1<<EERE);
|
||||
return EEDR;
|
||||
}
|
||||
|
||||
void EEPROM_WriteByte(uint8_t __eeprom*adr, uint8_t value)
|
||||
{
|
||||
while (EECR & (1<<EEWE));
|
||||
EEAR = (uint16_t)adr;
|
||||
EEDR = value;
|
||||
EECR |= (1<<EEMWE);
|
||||
EECR |= (1<<EEWE);
|
||||
}
|
||||
|
||||
uint8_t get_device_address(void)
|
||||
{
|
||||
return EEPROM_ReadByte(0);
|
||||
}
|
||||
|
||||
void write_device_address(uint8_t address)
|
||||
{
|
||||
EEPROM_WriteByte(0, address);
|
||||
EEPROM_WriteByte(1, ~address);
|
||||
}
|
||||
|
||||
uint8_t get_default_address(void)
|
||||
{
|
||||
return DEFAULT_MODBUS_ADDRESS;
|
||||
}
|
||||
|
||||
int is_valid_device_address(void)
|
||||
{
|
||||
return (EEPROM_ReadByte(0) ^ EEPROM_ReadByte(1) == 0xFF);
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
#ifndef DEVICE_ADDRESS_H
|
||||
#define DEVICE_ADDRESS_H
|
||||
|
||||
uint8_t get_device_address(void);
|
||||
void write_device_address(uint8_t address);
|
||||
uint8_t get_default_address(void);
|
||||
int is_valid_device_address(void);
|
||||
|
||||
#endif /*DEVICE_ADDRESS_H*/
|
46
device_ring_buffer.c
Normal file
46
device_ring_buffer.c
Normal file
@ -0,0 +1,46 @@
|
||||
#include <stdio.h>
|
||||
|
||||
struct rb {
|
||||
char buf[8];
|
||||
char head;
|
||||
char tail;
|
||||
};
|
||||
|
||||
static void rb_initialize(struct rb* _rb)
|
||||
{
|
||||
memset(_rb, 0, sizeof(_rb));
|
||||
}
|
||||
|
||||
int rb_put(struct rb* _rb, char element)
|
||||
{
|
||||
if (_rb->tail != _rb->head) {
|
||||
_rb->buf[_rb->tail] = element;
|
||||
_rb->tail++;
|
||||
if (_rb->tail == sizeof(_rb->buf))
|
||||
{
|
||||
_rb->tail = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int rb_get(struct rb* _rb, char *element)
|
||||
{
|
||||
if (_rb->tail != _rb->head) {
|
||||
*element = _rb->buf[_rb->head];
|
||||
_rb->head++;
|
||||
if (_rb->head == sizeof(_rb->buf))
|
||||
{
|
||||
_rb->head = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
8
device_ring_buffer.h
Normal file
8
device_ring_buffer.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef DEVICE_RING_BUFFER_H
|
||||
#define DEVICE_RING_BUFFER_H
|
||||
|
||||
static void rb_initialize(struct rb* _rb);
|
||||
int rb_put(struct rb* _rb, char element);
|
||||
int rb_get(struct rb* _rb, char *element);
|
||||
|
||||
#endif /*DEVICE_RING_BUFFER_H*/
|
Loading…
Reference in New Issue
Block a user