Свежие обсуждения
Микроконтроллеры

TEX учится

1 7

Начну тему заново.
Предположим, хочу сделать программный SPI. Алгоритм выглядит сильно проще чем I2C, идея его понятна - два замкнутых в кольцо сдвиговых регистра синхронно сдвигаемых по сигналу SCK. В голове укладывается. Но имеется непонятка как это сделать на МК, т.к аккумулятор 8051 имеет только один "вывод" для последовательных данных - бит переноса (С) через который поступают и выводятся данные в/из аккумулятора при выполнении инструкций циклического сдвига через перенос. Как замкнуть в кольцо реальный и программный сдвиговые регистры не очень ясно. Мог бы предположить что единицу из С пропустить через A за 8 машинных циклов, чтоб она опять появилась в С, но на это надо не 8, а 9 операций сдвига, (с учетом бита С, А получается 9-разрядным) от чего вся логика летит к чертям.

Нашел документ (стр 9), но там еще непонятней. Объясните пожалуйста.

 

А что там непонятного ?
Старший разряд символа вдвигается в С перед началом цикла, а потом производится восемь сдвигов.

 

TEX, я делаю так:
1. Проверяю 0й (или 8й - смотря какой сторойной нужно отправлять);
2. Выставляю на ножке Out этот уровень;
3. Даю Clock;
4. Сдвигаю в исходном байте все биты на 1 (в нужную сторону);
5. Перехожу к п.1. И так по кругу 8 раз (можно и 16, если на Си сделать 16-ти битную переменную);

 

Эта схема неправильная, или я еще что-то не узнал об этих МК? У них же нога порта это "открытый коллектор", и применение индикатора с общим катодом невозможно, не так ли? Единица записанная в защелку порта превращает выход во вход.

 

Любая нога порта 1 может выдать только 60 мкА при напряжении более 2.4 В. Как при этом будут светиться сегменты, и будут ли, непонятно, но формально схемотехника правильная.

Порты имеют различную схемотехнику, например порт 0 явно пуш-пул, остальные имеют пулап резисторы, т.е. явно не ОК, детальнее можно посмотреть в документе 4316Е-051-01/07, с. 2-73

 

TEX: Эта схема неправильная, или я еще что-то не узнал об этих МК?

Не скажу по поводу Атмелов и конкретно про указанный МК, но я делал аналогичную схему на PIC16, там выход через полевик подключается либо к земляной шине (0) либо к шине питания (1), допустимый ток на ножку обычно 25 мА (хотя в PIC18 есть отдельные ножки для которых максимальный ток в режиме выхода может быть всего 2 мА!). Есть еще допустимый ток на один порт (опять же у PICов, может быть 200 мА, может 95 мА) и ток шины Vdd и Vss.
В одной схеме я обошелся и без "общих транзисторов", завел общие прямо на ножку МК, но тогда я применял суперяркий индикатор и снизил общий ток (все сегменты включены) ниже 25 мА.

 


Сергей К: TEX, я делаю так:
1. Проверяю 0й (или 8й - смотря какой сторойной нужно отправлять);

Попробовал двигать регистр самого порта, получилось довольно быстро. Всего 57 инструкций на передачу байта по SPI
http://radiohlam.ru/forum/viewtopic.php?f=12&t=3467&sid=2f45195d85d9d8113a489d2f...

 

помогите разобраться.

нужно поморгать светиком по таймеру. регистр порта меняется а светик не моргает.

/*****************************************************
Chip type : ATtiny13
AVR Core Clock frequency: 0,128000 MHz
Memory model : Tiny
External RAM size : 0
Data Stack size : 16
*****************************************************/

#include <tiny13.h>

// Timer 0 output compare A interrupt service routine
interrupt [TIM0_COMPA] void timer0_compa_isr(void)
{
// Place your code here
PINB.0 =~PINB.0;
TCNT0=0x00;
}

// Declare your global variables here

void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif

// Input/Output Ports initialization
// Port B initialization
// Func5=In Func4=In Func3=In Func2=Out Func1=Out Func0=Out
// State5=T State4=T State3=T State2=0 State1=0 State0=0
PORTB=0x00;
DDRB=0x07;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 0,125 kHz
// Mode: Normal top=0xFF
// OC0A output: Clear on compare match
// OC0B output: Disconnected
TCCR0A=0x82;
TCCR0B=0x05; // остановить таймер TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x7D;
OCR0B=0x00;

// External Interrupt(s) initialization
// INT0: Off
// Interrupt on any change on pins PCINT0-5: Off
GIMSK=0x00;
MCUCR=0x00;

// Timer/Counter 0 Interrupt(s) initialization
TIMSK0=0x04;

// Analog Comparator initialization
// Analog Comparator: Off
ACSR=0x80;
ADCSRB=0x00;
DIDR0=0x00;

// ADC initialization
// ADC disabled
ADCSRA=0x00;

// Global enable interrupts
#asm("sei")

while (1)
{
// Place your code here
#asm("nop")
}
}

где ошибка?

 

Hamster: PINB.0 =~PINB.0;

Попробуйте PORTB.0=~PORTB.0;

 

Tadas: Не помогло. все так же

На картинке видно что в порту единица, а светик не горит.