Показать сообщение отдельно
Старый 28.01.2011, 03:36   #1
EviL_LaugH
Senior Member
 
Регистрация: 14.12.2010
Возраст: 30
Сообщений: 194
Вес репутации: 141/37
EviL_LaugH will become famous soon enoughEviL_LaugH will become famous soon enough
По умолчанию MAX232 и USART, отсутствует сигнал на выходе.

Приветствую всех в столь поздний час.

Люди, помогите разобраться. Сил моих больше нету.

Решил попробовать написать что-нибудь для связи с компьютером, чтобы железяка что-нибудь ему передавала и что-нибудь же и принимала.

Какой у нас самый ходовой интерфейс для связи с ПК (ну, помимо USB)?. Правильно, RS-232. Его и выбрал. В качестве передаваемых данных выбрал значение АЦП, в качестве принимаемых данных - любой байт. Для согласования уровней используется микросхема MAX232N из старых домашних запасов. Микроконтроллер - PIC16F876A.

Блок-схема работы программы такова: контроллер оцифровывает напряжение на входе АЦП и отправляет байтик компьютеру. Приём данных заведен на прерывание, соотв-но когда данные принимаются - можно сразу их и обработать. Как только байтик обработан - выходим из прерывания и передаём данные АЦП дальше. Обработка принятого байта заключается в выводе его прямиком на целый порт, на котором висят 8 светодиодиков. Соответственно, можно сразу проконтролировать, что приняли и правильно ли. При приёме определённой команды контроллер уходит в спящий режим.

В качестве приёмника/передатчика на стороне компьютера пока выступает обычная терминальная программа, коих множество.

Есть проблема, точнее, несколько.

Первая. В окне принятых данных, куда, по идее, должно было бы выводиться значение АЦП, нет ничего. Пусто. Ничего не принимается.

Вторая. При отправке данных в контроллер он высвечивает на диодах совсем не те данные, что я передаю. Но так бывает не всегда. К примеру, передаю я 0,1,2,3 - всё нормально, горят так, как надо. Передаю "4" (по идее должно загореться 00000100) - все светодиоды гаснут. Передаю FF - горят все диоды, как и надо. Передаю команду "уйти в спящий режим" - уходит. То есть не всё принимается неверно, но большая часть. Скорость обмена выбрана 9600 бод, микроконтроллер засчёт использования не-USARTовского кварца (10 МГц) выдаёт 9615 бод, что, как я понимаю, никак не может привести к такому количеству ошибок.

Ладно, стал разбираться. Для начала решил понять, почему же, собственно, ПК не принимает никаких данных. Проверил сигнал на выходе МК - он есть, имеет примерно такой вид.



То есть МК успешно передаёт байтики АЦП, как ему и положено. USART работает.

Проверяю сигнал на выходе MAX232. Его попросту нет. Ноль. А точнее, -9 В, что, как я понимаю из логики работы интерфейса, есть "простой" линии. Idle state.

Теперь понятно, почему ПК не принимает сигналы. Там попросту нечего принимать!

Десять раз проверил схему подключения MAX232. Всё полностью правильно. Разводка совпадает с даташитом. Полярность подключения конденсаторов верная.
Десять раз проверил схему и разводку COM порта. Всё полностью правильно.
Десять раз проверил программу МК, дабы понять, почему же он высвечивает на диодах не то, что было ему передано.

Вот мой код.

Код:
;Программа передаёт данные по протоколу USART в компьютер.
;Скорость кварца 10 МГц, скорость обмена 9600 Бод   


list        p=16f876a   ; list directive to define processor
    #include    <p16f876a.inc>  ; processor specific variable definitions
    		;  32109876543210	
    __CONFIG b'11111101110010'


	org		0x00

	goto	start

	org		0x04	
	goto	interrupt



start

	bsf		STATUS,RP0		;Банк 1
	bcf		STATUS,RP1

;//////////////////////////////////////////////////////////////////////////////////////////////////////////
;										G P I O  P O R T S
;//////////////////////////////////////////////////////////////////////////////////////////////////////////


	clrf	TRISB			;порт B - на выход
	movlw	b'11000000'		;порт C - в соответствии с конфигурацией USART
	movwf	TRISC
	movlw	b'00000001'		;порт A - канал АЦП RA0 - вход, остальные выходы
	movwf	TRISA

	bcf		STATUS,RP0

	clrf	PORTB
	clrf	PORTC
	clrf	PORTA

;//////////////////////////////////////////////////////////////////////////////////////////////////////////
;								A N A L O G U E  T O  D I G I T A L  C O N V E R T E R
;//////////////////////////////////////////////////////////////////////////////////////////////////////////



;	Частота кварца 10 МГц
;	ждём 16 Tosc, ADCS2:ADCS1:ADCS0 = 101

	movlw	b'10000001'		;АЦП включен, 16Tosc, считываем с AN0
	movwf	ADCON0

	bsf		STATUS,RP0		;банк1
	
	movlw	b'01001110'		;16Tosc, левое выравнивание, AN0 - аналоговый вход
	movwf	ADCON1



;//////////////////////////////////////////////////////////////////////////////////////////////////////////
;											I N T E R R U P T S
;//////////////////////////////////////////////////////////////////////////////////////////////////////////


	bcf		STATUS,RP0

	movlw	b'11000000'			;включены глобальные прерывания
	movwf	INTCON

	bsf		STATUS,RP0

	movlw	b'00100000'			;Включено прерывание от приёма USART
	movwf	PIE1


;//////////////////////////////////////////////////////////////////////////////////////////////////////////
;											U S A R T
;//////////////////////////////////////////////////////////////////////////////////////////////////////////

;	Асинхронный режим.	Частота обмена 9600 Бод

	

	movlw	b'00100110'		;Передача включена, High baud-rate speed
	movwf	TXSTA

	bcf		STATUS,RP0		;банк0

	movlw	b'10010000'		;Последовательный порт включен, приём включен
	movwf	RCSTA	

	bsf		STATUS,RP0		;банк1

	movlw	d'64'
	movwf	SPBRG			;9600 Бод!

	bcf		STATUS,RP0		;банк0



;//////////////////////////////////////////////////////////////////////////////////////////////////////////


;начинаем конвертацию

	movlw	d'255'
	movwf	PORTB


adc_convert_start

	bsf		ADCON0,2

adc_convert

	btfsc	ADCON0,2		;конвертирование завершено?
		goto	adc_convert		;Нет
	
	movf	ADRESH,0			;Считываем сконвертированные данные
	call	transmit			;Передаём их в компьютер

	goto	adc_convert_start

	




transmit

	movwf	TXREG		;передаём данные
	


check	

	bsf		STATUS,RP0

	btfss	TXSTA,1		;данные переданы? 
		goto	check

	bcf		STATUS,RP0



	return
		
	

interrupt		

;	Прерывание может быть только в одном случае: если принят байт данных.

	btfss	PIR1,5		;приняли данные?
		retfie			;нет - ошибочно попали в прерывание

	nop
	nop
	nop


	movf	RCREG,0		;Считываем данные
	movwf	0x40		;в регистр 40

	sublw	0x4F	;Принята такая команда?
	btfsc	STATUS,Z
		sleep			;Засыпаем
	movf	0x40,0
	movwf	PORTB		;Данные на светодиоды.
	
	bsf		STATUS,RP0

	movlw	b'00100000'			;Включено прерывание от приёма USART
	movwf	PIE1

	bcf		STATUS,RP0
	bcf		PIR1,5		;Данные приняты.

	retfie				;Возврат

	end
Отладка программы производилась в Proteus с "виртуальным терминалом", без max232. С него прекрасно принимаются и отправляются данные, светодиоды высвечивают то, что нужно. Прилагаю файл Протеуса. Только я обратил внимание, что когда возникает прерывание (там, где принятый байт считывается в порт), СПЕРВА из регистра приёма RCREG считывается предыдущее принятое значение, потом регистр приёма принимает нынешнее принятое значение, МК выходит из прерывания... и тут же в него попадает опять (по флагу, который почему-то не сбросился), уже считывая в порт правильное значение. Я не могу понять, почему так.

Вот моя печатная плата. Прилагается также в формате *.lay. Для тех, у кого нет Sprint Layout-a, прилагаю скриншот.

http://s45.radikal.ru/i109/1101/e7/32221f2a0237.png

Схема подключения COM порта взята из Интернета.



Вот схема подключения MAX232 из даташита и её распиновка. Проверьте правильность подключения, пожалуйста. Глаз мог запросто замылиться. Это как я сегодня же полчаса искал лежавший передо мной на столе огромный моток припоя :)



Собственно, у меня два вопроса: почему ничего нет на выходе MAX232 (хотя на входе всё присутствует в лучшем виде!) и почему так принимаются данные в МК, хотя в Proteus всё отлично работает? Микросхему менял, безрезультатно. У меня такое ощущение, что эти две ошибки как-то связаны. Не может же быть, чтобы на компьютере всё великолепно отлаживалось, а в реальности были такие ошибки. Это же интерфейс, там всё стандартизовано и унифицировано - скорости обмена, логические уровни...

У меня есть единственное подозрение. Я поставил конденсаторы на 1 мкФ 50 В. Может, в этом дело? Большой вольтаж и малая ёмкость? В готовой схеме программатора моего контроллера, паяной мной, эти конденсаторы имеют номинал 10 мкФ, 16 В. Но как же тогда схема из даташита?

Помогите, пожалуйста. Принимаются любые мысли. Всем заранее спасибо.

P.S. Если кто увидит эту тему на некоторых других форумах своего и моего обитания - не удивляйтесь и не сердитесь, ведь десять голов хорошо, а двадцать лучше :) может, и кому-то из народа инфа полезной окажется, когда найдётся решение.
Вложения
Тип файла: rar Archive.rar (39.6 Кб, 3 просмотров)
EviL_LaugH вне форума   Ответить с цитированием