|
USI типа I2C на Tiny45, просто не работает |
|
|
|
Feb 28 2010, 10:00
|
Местный
  
Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017

|
Цитата А вообще, логично было бы назвать вывод MISO - DI , MOSI - DO у Тини. Чем руководствовались Атмел, не понятно... Возможно, Вы будете удивлены, но они почти так у Атмела и названы (с точностью до наоборот). У тини названия выводов MISO и MOSI никак не связаны с USI. Эти названия касаются только назначения ног в режиме программирования.
|
|
|
|
|
Mar 1 2010, 06:34
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
С USI(SPI) работает, но нужно организовывать протокол передачи байт, либо синхронизировать начало передачи выводом SS. А у Тини у меня уже нет лишних выводов. Вернулся я все-таки к интерфейсу USI->TWI(Slave). Обнаружил у себя одну ошибку настройки портов. Но все-равно драйвер USI->TWI(Slave) avr312 не работает, а вот этот исходник - работает.
|
|
|
|
|
Mar 2 2010, 09:23
|
Знающий
   
Группа: Свой
Сообщений: 589
Регистрация: 24-04-05
Пользователь №: 4 447

|
Чтобы отправить от Slave(Tiny45) длинный байт Код for(;;) { if(usiTwiSlave.available()) { //usiTwiSlave.receive();
usiTwiSlave.write((unsigned char)(Value >> 24)); usiTwiSlave.write((unsigned char)(Value >> 16)); usiTwiSlave.write((unsigned char)(Value >> 8)); usiTwiSlave.write((unsigned char)(Value >> 0)); } } в Master(Мега) нужно добавить задержки Код void ReadSensor() { I2c_StartWait(SENSOR_ADDR | W); // slave address, write to capsensor SENSOR_ADDR I2c_Write(TWI_CMD_MASTER_READ); I2c_RepStart(SENSOR_ADDR | R); // slave address + read bit, read capsensor SENSOR_ADDR ValueOfCharge = (unsigned long)I2c_Read(I2C_ACK) << 24; delay_ms(100); ValueOfCharge |= (unsigned long)I2c_Read(I2C_ACK) << 16; delay_ms(100); ValueOfCharge |= (unsigned long)I2c_Read(I2C_ACK) << 8; delay_ms(100); ValueOfCharge |= (unsigned long)I2c_Read(I2C_NACK) << 0; I2c_Stop(); } Тини работает от 8МГц, Мега - на 20 МГц. При меньших задержках - не работает.
|
|
|
|
|
Apr 1 2010, 11:15
|

Участник

Группа: Участник
Сообщений: 23
Регистрация: 1-07-09
Пользователь №: 50 799

|
код для принимающего утройтва принимает 6 байт ну еще широковещательный пакет обрабатываеться рабоатет по прерываниям CODE .include "tn45def.inc"
.def temp =r16 .def USIcnt =r19 .def USIstate =r20
.org 0 RJMP reset;RESET External Pin, Power-on Reset, Brown-out RJMP reset;INT0 External Interrupt Request 0 RJMP reset;PCINT0 External Interrupt Request 1 RJMP reset;TIMER1 COMPA Timer/Counter1 Compare Match A RJMP reset;TIMER1 OVF Timer/Counter1 Overflow RJMP reset;TIMER0 OVF Timer/Counter0 Overflow RJMP reset;EE_RDY EEPROM Ready RJMP reset;ANA_COMP Analog Comparator RJMP reset;ADC ADC Conversion Complete RJMP reset;TIMER1 COMPB Timer/Counter1 Compare Match B RJMP reset;TIMER0 COMPA Timer/Counter0 Compare Match A RJMP reset;TIMER0 COMPB Timer/Counter0 Compare Match B RJMP reset;WDT RJMP USIstart;USI - start RJMP USIofl;USI - Overflow ;----------------------- USIstart: push temp
ldi temp,1 mov USIstate,temp
in temp,USICR;(Enable USI Counter overflow interrupt) sbr temp,0b01000000 out USICR,temp rcall ClearACK pop temp reti
USIofl: push temp
mov temp,USIstate cpi temp,1 breq I2Cadr cpi temp,2 breq I2Cack cpi temp,3 breq I2Cbyte
rjmp USIend
I2Cadr: in temp,USIDR cpi temp,0b11111110 breq I2Calladr cpi temp,0b00000100 brne I2Cbadadr
; cbi portb,1
ldi xl,low(0x80);Set pointer on the first received byte ldi xh,high(0x80);адрес буфера дл япримеа
rcall SetACK
ldi temp,2 mov USIstate,temp clr USIcnt rjmp USIend
I2Cack: rcall ClearACK
inc USIcnt mov temp,USIcnt cpi temp,6; сколько приянть байтов breq I2Call
ldi temp,3 mov USIstate,temp rjmp USIend
I2Cbyte:
in temp,USIDR st X+,temp; прияняли очередной байт rcall SetACK
ldi temp,2 mov USIstate,temp rjmp USIend
I2Calladr: ; пришел шыроковещательный пакет
rjmp I2Cbadadr I2Call: ; sbi portb,1 ; прияны все данные!
I2Cbadadr: rcall StopDetected
USIend: pop temp reti ;-------- SetACK: sbi DDRB,0 sbi PortB,2 sbi DDRB,2
in temp,USISR cbr temp,0b00000001;(Set counter to 0xE) sbr temp,0b11101110;(Enable new interrupts. Releasing SCL) out USISR,temp ret
StopDetected:
in temp,USICR;(Disable USI Counter overflow interrupt) cbr temp,0b01000000 out USICR,temp
ClearACK:
cbi DDRB,0 cbi PortB,2 cbi DDRB,2
in temp,USISR cbr temp,0b00001111;(Clear counter) sbr temp,0b11100000;(Enable new interrupts. Releasing SCL) out USISR,temp ret ;------------------ reset:
ldi temp,high(RAMEND);High byte only required if out SPH,temp ;RAM is bigger than 256 Bytes ldi temp,low(RAMEND) out SPL,temp
ldi temp,0b00000010 out PORTB,temp ldi temp,0b00000010 out DDRB,temp
ldi temp,(1<<USISIE)+(1<<USIWM1)+(1<<USIWM0)+(1<<USICS1) out USICR,temp ldi temp,0xf0 out USISR,temp
ldi Zh,HIGH(reset) ldi Zl,LOW(reset)
ldi temp, 0b00100000 out MCUCR,temp
sei
clr USIstate
loop: sleep rjmp loop
Сообщение отредактировал IgorKossak - Apr 1 2010, 16:38
Причина редактирования: Неправильное оформление длинного текста
--------------------
|
|
|
|
|
Jan 24 2013, 11:31
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 21-09-11
Пользователь №: 67 320

|
Скажите, а примера реализации похожей задачи на ассемблере кто-нибудь видел? Цитата(Nuts_ @ Apr 1 2010, 15:15)  код для принимающего утройтва А кода для передающего устройства, того же Atiny45 ни у кого нету?
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|