Страница 1 из 1

АЦП+EEPROM+UART)))

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

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
Навалял я тут :oops:

В общем не очень понимаю я как реализовать вызов кусков кода I2C, чтобы записать полученное от АЦП значение в память (и потом вытащить его в УАРТ, но об этом позже).

Не бейте больно, пожалуйста,Э я только учусь :o И подскажите, где у меня ошибки...

Re: АЦП+EEPROM+UART)))

Добавлено: Вт мар 23, 2010 12:46:45
GP1
:shock: и что работает? :shock:

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

Код: Выделить всё

         sbr       flags, 1<<adc_rd
ну вот так например
adc_rd - флаг готовности данных от АЦП