Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Передача данных в ATtiny13
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Oleg_IT
Программирование в IAR.
Так как в ATtiny13 ни каких аппаратных интерфейсов нет, то приходится делать всё самому. Делаю трех проводную связь (наверное, можно более оптимально сделать, но пока так).
………………………………..
#include <ioavr.h>
#include <inavr.h>

unsigned int Byte = 0;
extern unsigned int ByteEx = 0;
struct {
unsigned Bt1 : 1;
unsigned Bt2 : 1;
unsigned Bt3 : 1;
unsigned Bt4 : 1;
};

void main( void )
{
Bt1 = 1;
Bt2 = 1;
Bt3 = 0;
Bt4 = 1;

DDRB = 0x03; // 00 0011
PORTB = 0x3C; // 11 1100
__enable_interrupt();

while (1)
{
if (PINB_Bit2 == 0)
{
if (Bt4)
{
Byte = 0;
Nbit = 0;
Bt4 = 0;
}
if (PINB_Bit4 == 0 && Nbit < 8)
{
if (Bt2)
{
PORTB_Bit1 = 1;

// if (PINB_Bit3)
Byte = 127;//|= (1 << Nbit);

Nbit++;
}
Bt2 = 0;
}
else
{
PORTB_Bit1 = 0;
Bt2 = 1;
}
if (Nbit == 8)
Bt3 = 1;
}
else
{
if (Bt3)
{
// ByteEx = Byte;
Bt4 = 1;
}
Bt3 = 0;
}
}
}
………………………………..

Пин 2 это Chip Select, пин 4 – Data Clock, пин 3 – данные. Если передаю большие значения, больше 40 – 50 (точно границу не отлавливал), то всё принимается нормально, если меньше, то идут сбои в тактировании битов, периодические объединения битов (виден четкий период). Пин 1 специально ввёл для теста. Также для теста закомментировал проверку бита данных (if (PINB_Bit3)) и установку константы в переменную данных. С константой ситуация не изменилась.
Переменные объявлял и как unsigned int, и как unsigned char.
Два дня бьюсь, не могу понять, в чём дело. Помогите разобраться.
Александр Куличок
Для начала, сделай хотя-бы дефайнами переопределение пинов на
#define CS PINB_Bit2
и дай понятные имена битам состояния Bt1..Bt3 или хотя бы опиши, что они означают.
Тогда Вам может кто и ответ напишет.
И напиши рабочий, а не тестовый вариант, а то не понятно, какие биты у Вас объединяются и где сбои тактирования.
Ну и попрробуй проверить этот часток без __enable_interrupt()
Oleg_IT
Ниже код как рекомендует Александр Куличок.
Без __enable_interrupt(). Работает. Но без него ни как. Это всё делается для внешнего управления таймером. Если включит пару __enable_interrupt(); __disable_interrupt(); то сбои меняют вид, но избавится от них всё равно не удаётся.
В общем я понял свою ошибку, но какая связь с величиной записываемой в ByteOCR0A (закомментированная строка)? Если бы там были только младшие или только старшие биты, тогда было бы понятно.
После некоторых мук решил перейти на ATtiny25/45, с аппаратным USI. Думаю это будет лучше, но дороже.


#include <ioavr.h>
#include <inavr.h>

#define CS PINB_Bit2
#define CLOCK PINB_Bit4
#define DATA PINB_Bit3
#define TEST PINB_Bit1

unsigned int ByteOCR0A = 0,Nbit = 0;
unsigned int CntTim = 0;
unsigned int CntTimConst = 20;
struct {
unsigned SetBit : 1;
unsigned WriteData : 1;
unsigned ResetData : 1;
};

#pragma vector = TIM0_COMPA_vect
__interrupt void Timer0ACompare(void)
{
TCNT0 = 0x00;
CntTim++;
if (CntTim == CntTimConst)
{
PORTB_Bit0 = 1;
__no_operation();
__no_operation();
PORTB_Bit0 = 0;
CntTim = 0;
}
}

void main( void )
{
CLKPR = (1 << CLKPCE);
CLKPR = (1 << CLKPS2);

SetBit = 1;
WriteData = 0;
ResetData = 1;

TCCR0A = 0x00;
TCCR0B = (1 << CS00);
TCNT0 = 0x00;
OCR0A = 1;
OCR0B = 0x00;
TIMSK0 = (1 << OCIE0A);

DDRB = 0x03;
PORTB = 0x3C;
__enable_interrupt();

while (1)
{
if (CS == 0)
{
if (ResetData)
{
ByteOCR0A = 0;
Nbit = 0;
ResetData = 0;
__enable_interrupt();
}
if (CLOCK == 0 && Nbit < 8)
{
if (SetBit)
{
TEST = 1;

if (DATA)
ByteOCR0A |= (1 << Nbit);
// ByteOCR0A = 127;
Nbit++;
}
SetBit = 0;
}
else
{
TEST = 0;
SetBit = 1;
}
if (Nbit == 8)
WriteData = 1;
}
else
{
if (WriteData)
{
OCR0A = ByteOCR0A;
ResetData = 1;
__disable_interrupt();
}
WriteData = 0;
}
}
}
KRS
А вы родные APP Notes http://www.atmel.com/dyn/products/app_note...p?family_id=607
смотрели там например есть

AVR274: Single-wire Software UART (14 pages, revision A, updated 03/07)
This application note describes a software implementation of a single wire UART. The protocol supports half duplex communication between two devices. The only requirement is an I/O port supporting external interrupt and a timer compare interrupt.

AVR305: Half Duplex Compact Software UART (9 pages, revision C, updated 09/05)
This Application Note describes how to implement a polled software UART capable of handling speeds up to 614,400 bps on an AT90S1200.

AVR320: Software SPI Master

и т.д.
GDI
Человеку надо принимать данные, т.е. нужен слейв, а слейвы программно труднее делать чем мастеры.

2Oleg_IT у вас тут не 3х проводной интерфейс, а 2х проводной Chip select не в счет. Я делал программный 3х проводной интерфейс, аналог 3-wire применяемый в еепром AT93C56, там сигналы clk, data_in, data_out делал и мастер и слейв, на слейве заводил сигнал clk на внешнее прерывание и по прерыванию считывал данные с data_in и передавал на data_out. скорость правда не большая у меня, примерно 7кбит/сек, но у меня применено 5-кратное считывание данных, для защиты от помех, если этого не делать то можно скорость увеличить.
Oleg_IT
Цитата(GDI @ May 16 2007, 16:34) *
Человеку надо принимать данные, т.е. нужен слейв, а слейвы программно труднее делать чем мастеры.

2Oleg_IT у вас тут не 3х проводной интерфейс, а 2х проводной Chip select не в счет. Я делал программный 3х проводной интерфейс, аналог 3-wire применяемый в еепром AT93C56, там сигналы clk, data_in, data_out делал и мастер и слейв, на слейве заводил сигнал clk на внешнее прерывание и по прерыванию считывал данные с data_in и передавал на data_out. скорость правда не большая у меня, примерно 7кбит/сек, но у меня применено 5-кратное считывание данных, для защиты от помех, если этого не делать то можно скорость увеличить.


Спасибо за подсказку. Общий смысл понятен. Неясность по поводу помех. У вас длинная линия? Откуда помехи? У меня всё на одной плате, расстояние между МК не более 3 см., думаю помех не будет.
GDI
Линия до 50см, межплатный интерфейс, там наводки просто от слейвов. Кстати в одном проекте у нас делали на тини12 интерфейс I2C, там SCL тоже на вход внешнего прерывания подается INT0, а он имеет наибольший приоритет, расстояние 3см, тини12 работает от внутреннего RC генератора, программа на ассемблере, по поводу скорости передачи я не в курсе.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.