Страница 1 из 1
АЦП+EEPROM+UART)))
Добавлено: Пн мар 22, 2010 18:01:02
UG_n
Всем доброго дня)))....вопрос такой...Реализую программно шину I2C на Atmega8 на асме(так надо)! для связи с памятью EEPROM....(знаю что идиот,но такое уж учебное задание))))....,короче надо чтобы биты из регистров АЦП сначала писались в память а потом в регистры UARTа....с ацп разобрался,с уартом тоже,а программно шину не получается нормально реализовать.....Подскажите ....заранее спасибо....

Re: АЦП+EEPROM+UART)))
Добавлено: Вт мар 23, 2010 03:50:19
Liv
Когда-то давным-давно писал на ассемблере:
Код: Выделить всё
.equ I2CDelHp = 40 ;I2C half period delay 5 uS, D=(8+3*N)*Tclk
.equ I2CDelQp = 20 ;I2C quarter period delay 2.5 uS, D=(8+3*N)*Tclk
;I2C bus 1 support:
;Start I2C-1 communications:
;Input: temp - device address
I2C1_Start:
Port_SDA1_0 ;force SDA low
rcall I2C_qp_delay ;quarter period delay
;Write data byte via I2C-1:
;Input: temp - data byte
;Out: C = ASK
I2C1_Wr:
sec ;set carry flag
rol temp ;shift in carry and out bit one
rjmp i2c1_wr_first
i2c1_wr_bit:
lsl temp ;if transmit register empty
i2c1_wr_first:
breq i2c1_get_ack ; goto get acknowledge
Port_SCL1_0 ;force SCL low
brcc i2c1_wr_low ;if bit high
nop ; (equalize number of cycles)
Port_SDA1_Z ; release SDA
rjmp i2c1_wr_high
i2c1_wr_low: ; else
Port_SDA1_0 ; force SDA low
rjmp i2c1_wr_high ; (equalize number of cycles)
i2c1_wr_high:
rcall I2C_hp_delay ;half period delay
Port_SCL1_Z ;release SCL
rcall I2C_hp_delay ;half period delay
rjmp i2c1_wr_bit
i2c1_get_ack:
Port_SCL1_0 ;force SCL low
nop
nop
Port_SDA1_Z ;release SDA
rcall I2C_hp_delay ;half period delay
Port_SCL1_Z ;release SCL
rcall I2C_hp_delay ;half period delay
clc ;clear carry flag
Skip_if_Port_SDA1_0 ;if SDA is high
sec ; set carry flag
rcall I2C_hp_delay ;half period delay
ret
;Read data byte via I2C-1:
;Out: temp - data byte
I2C1_Rd:
ldi temp,0x01 ;data = 0x01
i2c1_rd_bit: ;do
Port_SCL1_0 ; force SCL low
rcall I2C_hp_delay ; half period delay
Port_SCL1_Z ; release SCL
rcall I2C_hp_delay ; half period delay
clc ; clear carry flag
Skip_if_Port_SDA1_0 ; if SDA is high
sec ; set carry flag
rol temp ; store data bit
brcc i2c1_rd_bit ;while receive register not full
Port_SCL1_0 ;force SCL low
nop
nop
Port_SDA1_0 ;force SDA low (ASK=0)
rcall I2C_qp_delay ;quarter period delay
Port_SCL1_Z ;release SCL
rcall I2C_hp_delay ;half period delay
ret
;Stop I2C-1 communications:
I2C1_Stop:
Port_SCL1_0 ;force SCL low
nop
nop
Port_SDA1_0 ;force SDA low
rcall I2C_hp_delay ;half period delay
Port_SCL1_Z ;release SCL
rcall I2C_qp_delay ;quarter period delay
Port_SDA1_Z ;release SDA
rcall I2C_hp_delay ;half period delay
ret
;I2C half clock period delay:
;(normal: 5.0us / fast: 1.3us)
I2C_hp_delay:
ldi Cnt,I2CDelHp
i2c_hp_delay_loop:
dec Cnt
brne i2c_hp_delay_loop
ret
;I2C quarter clock period delay:
;(normal: 2.5us / fast: 0.6us)
I2C_qp_delay:
ldi Cnt,I2CDelQp
i2c_qp_delay_loop:
dec Cnt
brne i2c_qp_delay_loop
ret
Re: АЦП+EEPROM+UART)))
Добавлено: Вт мар 23, 2010 09:10:59
UG_n
Спасибо)))...начинаю понимать)))....ещё вопрос....а как грамотно задавать адрес слейва....у моей памяти он не выставляется((
и ещё...а что за конструкция Port_SCL1_Z и подобные?????где они задаются????....компилятор ругается(((
Re: АЦП+EEPROM+UART)))
Добавлено: Вт мар 23, 2010 10:48:28
MisterDi
Перед вызовом процедуры чтения или записи в ячейку temp нужно записать соответствующее значение.
обэтом говорит комментарий:
Код: Выделить всё
;Start I2C-1 communications:
;Input: temp - device address
Re: АЦП+EEPROM+UART)))
Добавлено: Вт мар 23, 2010 10:52:17
UG_n
Спасибо. Перерыл датащит, нельзя изменять адрес у моей памяти, у нее просто нет этих ножек...
Вопрос с необъвленными процедурами в примере программы остается открытым... Помогите, товарищи коты

Re: АЦП+EEPROM+UART)))
Добавлено: Вт мар 23, 2010 11:00:14
MisterDi
Это процедуры или макросы настройки выводов соответствующего порта. Например процедура Port_SCL1_Z должна переводить вывод МK, к которому подключен сигнал SCL1 в Z-состояние.
Re: АЦП+EEPROM+UART)))
Добавлено: Вт мар 23, 2010 12:41:40
UG_n
Нава
лял я тут
В общем не очень понимаю я как реализовать вызов кусков кода I2C, чтобы записать полученное от АЦП значение в память (и потом вытащить его в УАРТ, но об этом позже).
Не бейте больно, пожалуйста,Э я только учусь

И подскажите, где у меня ошибки...
Re: АЦП+EEPROM+UART)))
Добавлено: Вт мар 23, 2010 12:46:45
GP1

и что работает?

Re: АЦП+EEPROM+UART)))
Добавлено: Вт мар 23, 2010 12:53:13
UG_n
нееееет(((((......поможыте разобратся......AVRstudio ошибок не выдаёт(((((((((.....
Re: АЦП+EEPROM+UART)))
Добавлено: Вт мар 23, 2010 13:04:20
GP1
Пожалуй начнем во с этого:
Код: Выделить всё
;================
ADC_OK: IN R16,ADCH
RJMP SoftI2CStart
RJMP SoftI2CTransmit
RETi
при первом же проходе программа зависнет.
я мог бы еще понять, если бы вместо
rjmp было написано
rcall, но такой подход к использованию прерываний я не использую и не одобряю ИМХО, и пусть товарищ
IM1 со мной не согласен, прерывание должно быть как можно короче.
Re: АЦП+EEPROM+UART)))
Добавлено: Вт мар 23, 2010 16:12:31
Liv
У I2C EEPROM часть адреса фиксирована, а часть задается ножками A0..A2. Иногда ножки не используются, тогда весь адрес фиксированный: 0xA0 для нулевой страницы и т.д.
А макросы вот:
Код: Выделить всё
.equ SCL1 = PA4 ;I2C port 1 SCL
.equ SDA1 = PA5 ;I2C port 1 SDA
.macro Port_SCL1_0 ;SCL1 = 0
sbi DDRA,SCL1
.endm
.macro Port_SCL1_Z ;SCL1 = Z
cbi DDRA,SCL1
.endm
.macro Port_SDA1_0 ;SDA1 = 0
sbi DDRA,SDA1
.endm
.macro Port_SDA1_Z ;SDA1 = Z
cbi DDRA,SDA1
.endm
Re: АЦП+EEPROM+UART)))
Добавлено: Ср мар 24, 2010 09:10:48
UG_n
Всем спасибо за советы))))очень помогли.....а можно ли к подпрограммам старт,стоп и др. прерывания как-то приделать...например прерывание от АЦП?...это в векторах надо выставлять,правильно???
Re: АЦП+EEPROM+UART)))
Добавлено: Ср мар 24, 2010 09:24:13
GP1
ИМХО запускать из прерываний процедуры старт стоп и т.п. не совсем правильный подход.
Лучше сохранить значение АЦП где-нибудь в памяти, а уже в основном теле все это обрабатывать.
Re: АЦП+EEPROM+UART)))
Добавлено: Ср мар 24, 2010 10:28:21
UG_n
да))0согласен....щаас токой глюк был с прерыванием...уххх...."прерывания должны быть короткими"-ИСТИНА ёпт))))
Re: АЦП+EEPROM+UART)))
Добавлено: Ср мар 24, 2010 10:44:29
GP1
Если интересно, я обычно делаю так:
в прерывании получаю данные, с минимум обработки, сохраняю в память, где удобней/есть место, и выставляю признак в регистре, обозванном flags, какой-нибудь бит, а в теле основной программы по мере необходимости анализирую этот бит, и при наступлении события "данные готовы" выполняю требуемые действия.
Re: АЦП+EEPROM+UART)))
Добавлено: Ср мар 24, 2010 11:48:49
UG_n
Выставляю признак в регистре????...эт как???
Re: АЦП+EEPROM+UART)))
Добавлено: Ср мар 24, 2010 12:02:28
GP1
ну вот так например
adc_rd - флаг готовности данных от АЦП