Форум Микро-Чип
Поиск и заказ электронных компонентов
 

Вернуться   Форум Микро-Чип > Вопросы начинающих

Вопросы начинающих Прежде чем задать вопрос, стоит воспользоваться поиском

Ответ
 
Опции темы Опции просмотра
Старый 01.11.2010, 17:26   #1
rezor
Junior Member
 
Регистрация: 01.11.2010
Возраст: 29
Сообщений: 15
Вес репутации: 100/36
rezor will become famous soon enoughrezor will become famous soon enough
По умолчанию АЦП в pic16f877 + LCD

На порт А подается напряжение как его преобразовать через АЦП и вывести на LCD???? Где почитать или пример глянуть???
Пытался написать сам но что-то вывод не коректный.
То что отображается на вольтметре нужно вывести на LCD

Код:
;************************************************************************
;
; Прогр. интерфейс для ЖК-модуля на основе контройллера Hitachi HD77480
; Использующий 4-строчный * 20 символов модуль дисплея.
;
; Эта программа собрана для 8-битного интерфейса данных.
;
;************************************************************************

;************************************************************************
; Fosc		= 4MHz
; Cycle_time	= 1/Fosc / 4
;		= 1/(4*10^6) / 4
;		= 1uSec
;************************************************************************

	LIST P=16F877, F=INHX8M
;	ERRORLEVEL  2
	__CONFIG _CP_OFF & _WDT_OFF & _XT_OSC

	#include <p16f877.inc>

;===============================================================
;               PIC16F877 I/O
;                 +------------   ------------+
;                -|MCLR/Vpp            RB7/PGD|-  
;                -|RA0/AN0             RB6/PGC|-  
;                -|RA1/AN1             RB5    |-  
;                -|RA2/AN2/Vref-       RB4    |-  
;                -|RA3/AN3/Vref+       RB3/PGM|-  
;                -|Ra4/TOCKI           RB2    |-  
;                -|RA5/AN4/SS          RB1    |-  
;                -|RE0/RD/AN5          RB0/INT|-  
;                -|RE1/WR/AN6          Vdd    |-  +5V
;                -|RE2/CS/AN7          Vss    |-  GND
;   +5V          -|Vdd                RD7/PSP7|-  LCD DB7  
;   GND          -|Vss                RD6/PSP6|-  LCD DB6
;   XTAL         -|OSC1/CLKIN         RD5/PSP5|-  LCD DB5
;   XTAL         -|OSC2/CLKOUT        RD4/PSP4|-  LCD DB4
;   LCD R/S	 -|RC0/T1OSO/T1CKI RC7/RX/DT  |-  
;   (LCD R/W)	 -|RC1/T1OSI/CCP2  RC6/TX/CK  |-  
;   LCD E	 -|RC2/CCP1        RC5/SDO    |-  
;                -|RC3/SCK/SCL     RC4/SDI/SDA|-  
;   LCD DB0      -|RD0/PSP0        RD3/PSP3   |-  LCD DB3
;   LCD DB1      -|RD1/PSP1        RD2/PSP2   |-  LCD DB2
;                 +------------   ------------+
;
;===============================================================
		cblock	0x20			;start of general purpose registers
			count
			count1	
			counta	
			countb	
			LoX		
			Bit_Cntr	
			Timer_H		
			Flags		
			Flags2		
			tmp1		
			tmp2		
			tmp3			
			NumL	
			NumH	
			TenK		
			Thou	
			Hund	
			Tens			
			Ones		
			templcd	
			templcd2	
			Acc1L			;16 bit maths register 1
			Acc1H
			Point			;position of decimal point
TenkOUT
DPout
ThouOUT
HundOUT
TensOUT
OnesOUT
		endc
;************************************************************************
; Определение портов и регистров для работы с LCD
;************************************************************************
RESET_V		EQU	0x0000	; Адрес вектора сброса
ISR_V		EQU	0x0004	; Адрес вектора прерывания
;OSC_FREQ	EQU	D'4000000'	; Частота генератора 4 МГц

LCD_DATA	EQU	PORTD	; Линии передачи данных на LCD
LCD_DATA_TRIS	EQU	TRISD
LCD_CTRL	EQU	PORTC	; Линии управления интерфейсом LCD

LCD_LINE0	EQU	0x000	; Адресс начала 1 стоки ЖК-Дисплея
LCD_LINE1	EQU	0x040	; Адресс начала 2 стоки ЖК-Дисплея
LCD_LINE2	EQU	0x014	; Адресс начала 3 стоки ЖК-Дисплея
LCD_LINE3	EQU	0x054	; Адресс начала 4 стоки ЖК-Дисплея

; PORTC bits
LCD_E		EQU	2	; Линия стробирования/синхронизации
LCD_RW		EQU	1	; Линия выбора операции Чтение/Запись
LCD_RS		EQU	0	; Выбор регистра (RS=0 команды; RS=1 данные)

; PORTD bits
DB7		EQU	7	; LCD dataline 7 (Старший бит данных)
DB6		EQU	6	; LCD dataline 6
DB5		EQU	5	; LCD dataline 5
DB4		EQU	4	; LCD dataline 4
DB3		EQU	3	; LCD dataline 3
DB2		EQU	2	; LCD dataline 2
DB1		EQU	1	; LCD dataline 1
DB0		EQU	0	; LCD dataline 0 (Младший бит данных)

; Регистры общего назначения
LCD_TEMP	EQU	0x020	; Регистр обмена данными с LCD

TABLE_INDEX	EQU	0x021	; Индекс к таблице строк
COUNT		EQU	0x022	; Счетчик
DELAY		equ	0x023	; Регистры задержки
X_DELAY		equ	0x024	;


;************************************************************************
; Начало программы
;************************************************************************
	ORG	RESET_V	; Вектор сброса (начальная точка программы)
RESET	
	GOTO	START

;************************************************************************
; Это рутина периферийных прерываний. НЕ должны получиться здесь
;************************************************************************
	ORG	ISR_V	; Точка вектора прерываний
INTERRUPT
	BCF     STATUS, RP0	; Переходим в банк 0
	GOTO    INTERRUPT

;************************************************************************
; Инициализация регистров процессора
;************************************************************************
START				; POWER_ON Reset (начало программы)
	CLRF	STATUS		; Сбрасываем все флаги, установлен банк 0
	CLRF	INTCON		; Запретить все прерывания
	CLRF	PCLATH		; Keep in lower 2KByte

	clrf	PORTA	; Сброс PORTA
	clrf	PORTB	; Сброс PORTB
	clrf	PORTC	; Сброс PORTC
	clrf	PORTD	; Сброс PORTD
	clrf	PORTE	; Сброс PORTE
			BANKSEL ADCON1			;disable A2D
    		movlw   0x06
    		movwf   ADCON1
    		BANKSEL PORTA
	BSF	STATUS, RP0	; Переходим в Банк 1
	clrf	TRISA	; Настройка всех портов на вывод
	clrf	TRISB	; 
	clrf	TRISC	; 
	clrf	TRISD	; 
	clrf	TRISE	; 
	BCF	STATUS, RP0	; Переходим в Банк 0

	CALL	LCDINIT		; Инициализируем LCD дисплей
    call	Init_ADC		;initialise analogue input
call Read_ADC;
call Convert;
	movf	NumH, W
	call	LCD_HEX			;and display in hexadecimal
;***********************************************************************
; Показать несколько строк, здесь
;	----------------------
;	|This is on line :  0|
;	|This is on line :  1|
;	|This is on line :  2|
;	|This is on line :  3|
;	----------------------
;***********************************************************************

	MOVLW	0x030		; ASCII '0'
	MOVWF	COUNT
	MOVLW	LCD_LINE0
	CALL	LCDSDDA		; Позиция курсора слева на первой строке
	CALL	TABLE_MSG	; Показать сообщение
	MOVLW	LCD_LINE0 + 0x010
	CALL	LCDSDDA		; Установить позицию курсора к 16 символу

	MOVF	COUNT, W
	CALL	LCDPUTCHAR	; Отобразить номер строки

	INCF	COUNT, F	; Увеличиваем значение номера строки
	MOVLW	LCD_LINE1
	CALL	LCDSDDA
	CALL	TABLE_MSG
	MOVLW	LCD_LINE1 + 0x010
	CALL	LCDSDDA
	MOVF	COUNT, W
	CALL	LCDPUTCHAR

	INCF	COUNT, F
	MOVLW	LCD_LINE2
	CALL	LCDSDDA
	CALL	TABLE_MSG
	MOVLW	LCD_LINE2 + 0x010
	CALL	LCDSDDA
	MOVF	COUNT, W
	CALL	LCDPUTCHAR

	INCF	COUNT, F
	MOVLW	LCD_LINE3
	CALL	LCDSDDA
	CALL	TABLE_MSG
	MOVLW	LCD_LINE3 + 0x010
	CALL	LCDSDDA
	MOVF	COUNT, W
	CALL	LCDPUTCHAR


;************************************************************************
; Программа заканчивается здесь
;************************************************************************
LOOP
	GOTO	LOOP		; Вечный цикл

Init_ADC
; Set ADCON0
    		movlw   b'10000001'
    		movwf   ADCON0
; Set ADCON1
    		BANKSEL ADCON1
    		movlw   b'10000101'
    		movwf   ADCON1
    		BANKSEL ADCON0
		return

Read_ADC
    		bsf	ADCON0, GO_DONE		;initiate conversion
    		btfsc   ADCON0, GO_DONE
    		goto    $-1			;wait for ADC to finish

    		movf    ADRESH,W
    		andlw   0x03
    		movwf   NumH
    		BANKSEL ADRESL
    		movf    ADRESL,W
    		BANKSEL	ADRESH
		movwf	NumL			;return result in NumL and NumH
		return

;************************************************************************
; Отправить сообщение с помощью таблицы для вывода сообщений
;************************************************************************
TABLE_MSG
	MOVLW	0		; Начальный индекс таблицы сообщений
DISP_MSG
	MOVWF	TABLE_INDEX	; Считать адреса сообщений
	CALL	MSG1
	ANDLW	0x0FF		; Проверка, если в конце сообщения
	BTFSC	STATUS, Z	; (ноль - вернутся в конец)
	GOTO	TABLE_MSG_END             
	CALL	LCDPUTCHAR	; Показать символ
	MOVF	TABLE_INDEX, W	; Переход на следующий символ
	ADDLW	1
	GOTO	DISP_MSG
TABLE_MSG_END
	RETURN

;************************************************************************
; Подпрограммы ЖК-модуля
;************************************************************************
;
;========================================================================
; LCDINIT
; Инициализируем LCD дисплей
; Может быть изменена по вашим требованиям (например, тип дисплея, вкл/выкл курсора и т.д.)
;========================================================================
LCDINIT	; Busy-flag is not yet valid (Флаг занятости еще не действует)
	CLRF	LCD_CTRL	; Очищаем PORTC
; Задержка питания
	MOVLW	.30		; Помещаем в аккумулятор число 30 
	CALL	X_DELAY500	; 30 * 0.5mS = 15mS
; Флаг занятости должен быть здесь уже задействован
	MOVLW	0x038		; 8-bit-interface, 2-lines
	CALL	LCDPUTCMD
	MOVLW	0x000		; disp.off, curs.off, no-blink
	CALL	LCDDMODE
	CALL	LCDCLEAR
	MOVLW	0x004		; disp.on, curs.off
	CALL	LCDDMODE
	MOVLW	0x002		; auto-inc (shift-cursor)
	CALL	LCDEMODE
	RETURN
;========================================================================
; LCD_ENABLE
; Pulses LCD enable pin (Импульсы включения контактов LCD)
;========================================================================
LCD_ENABLE
	BSF	LCD_CTRL, LCD_E	; LCD E-line High
	BCF	LCD_CTRL, LCD_E	; LCD E-line Low
	RETURN
;========================================================================
; LCDBUSY
; Returns when LCD busy-flag is inactive (Возвращает флаг занятости, когда LCD неактивен)
;========================================================================
LCDBUSY
	BSF	STATUS,RP0	; Переходим в Банк 1
	MOVLW	0x0FF		;(B'11111111') Уст. PORTD для ввода
	MOVWF	LCD_DATA_TRIS
	BCF	STATUS, RP0	; Переходим в Банк 0
	BCF	LCD_CTRL, LCD_RS; Устанавливаем LCD в командный режим
	BSF	LCD_CTRL, LCD_RW; Установка чтения флага занятости
	BSF	LCD_CTRL, LCD_E	; Начать стробирующий импульс
	MOVF	LCD_DATA, W	; Считаем флаг занятости + DDRAM адрес
	BCF	LCD_CTRL, LCD_E	; Закончить стробирующий импульс
	ANDLW	0x80		; Проверяем флаг занятости, High = Занят
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ANDLW - Поразрядное сложения символа (B'10000000') и WREG
; BTFSS - пропустить команду, если Z-бит равен единице
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
	BTFSS	STATUS, Z	
	GOTO	LCDBUSY
LCDNOTBUSY	
	BCF	LCD_CTRL, LCD_RW; RW = 0
	BSF	STATUS, RP0	; Переходим в Банк 1
	CLRF	LCD_DATA_TRIS	; Устанавливаем PORTD для вывода 
	BCF	STATUS, RP0	; Переходим в Банк 0
	RETURN
;========================================================================
; LCDCLEAR
; Очищает экран и возвращает курсор в исходное положение (левый верхний угол).
;========================================================================
LCDCLEAR
	MOVLW	0x001
	CALL	LCDPUTCMD
	RETURN
;========================================================================
; LCDHOME
; Возвращает курсор в исходную позицию.
; Возвращает дисплей в исходное положение (при сдвиге).
;========================================================================
LCDHOME
	MOVLW	0x002
	CALL	LCDPUTCMD
	RETURN
;========================================================================
; LCDEMODE
; Устанавливает режим записи дисплея.
; Требуемый режим записи должен быть установлен в W(аккумулятор)
;  b0 - сдвиг видимого поля на дисплее	: 0 =сдвига нет	1 = сдвиг выполн.
;  b1 - направление смещения курсора	: 0 = влево(--)	1 = вправо(++)
;  b2-7	: не волнуют
; OK
;========================================================================
LCDEMODE
	ANDLW	0x003	; Срезать верхние биты '00000011'
	IORLW	0x004	; Команда IORLW k - логическое ИЛИ константы и W.
			; Содержимое W логически складывается с k
	CALL	LCDPUTCMD	; Посылаем команды на LCD
	RETURN
;========================================================================
; LCDDMODE
; Устанавливает управления дисплеем.
; Требуемый режим отображения должен быть установлен в W(аккумулятор)
;  b0 - мерцание курсора	: 0 = мерцание выкл	1 = мерцание вкл
;  b1 - наличие курсора		: 0 = курсор выкл	1 = курсор вкл
;  b2 - вкл/выкл вывода из DDRAM: 0 = вывода выкл	1 = вывода вкл
;  b3-7	: не волнуют
;========================================================================
LCDDMODE
	ANDLW	0x007	; Срезать верхние биты '00000111'
	IORLW	0x008	; Команда IORLW k - логическое ИЛИ константы и W.
			; Содержимое W логически складывается с k
	CALL	LCDPUTCMD	; Посылаем команды на LCD
	RETURN
;========================================================================
; LCDSCGA - НЕИСПОЛЬЗУЕТСЯ В ЭТОЙ ПРОГЕ!!
; Устанавливаем адрес Генератора символов RAM. CGRAM для чтения/записи после этого параметра.
; Нужный адрес CGRAM должен быть установлен в W
;  b0-5	: требуемый CGRAM адрес
;  b6-7	: не волнуют
;========================================================================
LCDSCGA
	ANDLW	0x03F	; Срезать верхние биты '00111111'
	IORLW	0x040	; Команда IORLW k - логическое ИЛИ константы и W.
			; Содержимое W логически складывается с k
	CALL	LCDPUTCMD	; Посылаем команды на LCD
	RETURN
;========================================================================
; LCDSDDA
; Устанавливаем адрес Отображение Данных ОЗУ. DDRAM данные чтения/записи после этого параметра.
; Нужный адрес DDRAM должен быть установлен в W
;  b0-6	: требуемый DDRAM адрес
;  b7	: не волнуют
;========================================================================
LCDSDDA
	IORLW	0x080	; Команда IORLW k - логическое ИЛИ константы и W.
			; Содержимое W логически складывается с k
	CALL	LCDPUTCMD	; Посылаем команды на LCD
	RETURN
;========================================================================
; LCDGADDR
; Возвращает адрес содержимый в счетчике, используется как для DDRAM и CGRAM.
; RAM адрес возвращается в W
;========================================================================
LCDGADDR
	BSF	STATUS,RP0	; Переходим в банк регистров 1
	MOVLW	0x0FF		; Устанавливаем PORTD для ввода (B'11111111')
	MOVWF	LCD_DATA_TRIS
	BCF	STATUS, RP0	; Переходим в банк регистров 0
	BCF	LCD_CTRL, LCD_RS; Устанавливаем LCD в командный режим
	BSF	LCD_CTRL, LCD_RW; Установка чтения флага занятости
	BSF	LCD_CTRL, LCD_E	; LCD E-line High (Включаем режим записи сигналов в LCD)
	MOVF	LCD_DATA, W	; Read busy flag + RAM address (Читаем флаг занятости + DDRAM адрес)
	BCF	LCD_CTRL, LCD_E	; LCD E-line Low (Включаем режим чтения сигналов в LCD)
	ANDLW	0x07F		; Strip upper bit (Срезать верхний бит)
				; ANDLW - Логическая операция "И" поразрядного сложения с символом (B'01111111') и WREG

	BCF	LCD_CTRL, LCD_RW
	BSF	STATUS, RP0	; Переходим в банк регистров 1
	MOVLW	0x000
	MOVWF	LCD_DATA_TRIS	; Устанавливаем PORTD для вывода (B'00000000')
	BCF	STATUS, RP0	; Переходим в банк регистров 0
	RETURN
;========================================================================
; LCDPUTCHAR
; Передает символ на LCD
; Обязательный символ должен быть в W
;========================================================================
LCDPUTCHAR
	MOVWF	LCD_TEMP	; Символ, который был направлен в W
	CALL	LCDBUSY		; Ожидание готовности LCD
	BCF	LCD_CTRL, LCD_RW; Установить LCD в режиме чтения
	BSF	LCD_CTRL, LCD_RS; Установить LCD в режиме передачи данных
	BSF	LCD_CTRL, LCD_E	; Начать стробирующий импульс
	MOVF	LCD_TEMP, W
	MOVWF	LCD_DATA	; Передача данных на LCD
	BCF	LCD_CTRL, LCD_E	; Закончить стробирующий импульс
	RETURN
;========================================================================
; LCDPUTCMD
; Посылает команды на LCD
; Требуемые команды должны быть в W(Аккумуляторе)
;========================================================================
LCDPUTCMD
	MOVWF	LCD_TEMP	; Команда, которая была отправлена в W
	CALL	LCDBUSY		; Ждем готовности LCD
	BCF	LCD_CTRL, LCD_RW; Устанавливаем LCD в режиме чтения
	BCF	LCD_CTRL, LCD_RS; Устанавливаем LCD в командный режим
	BSF	LCD_CTRL, LCD_E	; Начать стробирующий импульс
	MOVF	LCD_TEMP, W
	MOVWF	LCD_DATA	; Передача данных на LCD
	BCF	LCD_CTRL, LCD_E	; Закончить стробирующий импульс
	RETURN

;*****************************************************************************
; Delay_time	= ((DELAY_value * 3) + 4) * Cycle_time
; DELAY_value	= (Delay_time - (4 * Cycle_time)) / (3 * Cycle_time)
;
; Например (@ 4MHz crystal)
; Примем тактовую частоту - Fтакт. = 4,096 МГц (стандартный кварц). 
; Тогда время цикла составит tc = 1/Fтакт. * 4 = 0,97656 мкс (1uSec)
;
; Delay_time	= ((32 * 3) + 4) * 1uSec
;		= 100uSec
; DELAY_value	= (500uSec - 4) / 3
;		= 165.33
;		= 165
;*****************************************************************************
DELAY500
	MOVLW	D'165'		; +1		1 cycle
	MOVWF	DELAY		; +2		1 cycle
DELAY500_LOOP	
	DECFSZ	DELAY, F	; step 1	1 cycle
	GOTO	DELAY500_LOOP	; step 2	2 cycles
	RETURN			; +3		2 cycles
;
X_DELAY500	
	MOVWF	X_DELAY		; +1		1 cycle
X_DELAY500_LOOP	
	CALL	DELAY500	; step1		wait 500uSec
	DECFSZ	X_DELAY, F	; step2		1 cycle
	GOTO	X_DELAY500_LOOP	; step3		2 cycles
	RETURN			; +2		2 cycles


;========================================================================
; Таблица сообщения для отображения
;========================================================================
HEX_Table  	addwf   PCL       , f
            	retlw   0x30
            	retlw   0x31
            	retlw   0x32
            	retlw   0x33
            	retlw   0x34
            	retlw   0x35
            	retlw   0x36
            	retlw   0x37
            	retlw   0x38
            	retlw   0x39
            	retlw   0x41
            	retlw   0x42
            	retlw   0x43
            	retlw   0x44
            	retlw   0x45
            	retlw   0x46
return
;==============================================
LCD_HEX		movwf	tmp1
		swapf	tmp1,	w
		andlw	0x0f
		call	HEX_Table
		CALL	LCDPUTCHAR	; Показать символ
		movf	tmp1, w
		andlw	0x0f
		call	HEX_Table
		addlw	0x30
		retlw	0x00
;==================================================
MSG1
	addwf	PCL ,F	; Сложение F с PCL и пересылка резульата в PCL

	retlw	TenkOUT	;
	retlw	DPout	;
retlw	ThouOUT	;
retlw	HundOUT	;
retlw	TensOUT;
retlw	OnesOUT;
	
MSG1_END
	RETURN
;
;This routine downloaded from http://www.piclist.com
Convert:                        ; Takes number in NumH:NumL
                                ; Returns decimal in
                                ; TenK:Thou:Hund:Tens:Ones
        swapf   NumH, w
	iorlw	B'11110000'
        movwf   Thou
        addwf   Thou,f
        addlw   0XE2
        movwf   Hund
        addlw   0X32
        movwf   Ones

        movf    NumH,w
        andlw   0X0F
        addwf   Hund,f
        addwf   Hund,f
        addwf   Ones,f
        addlw   0XE9
        movwf   Tens
        addwf   Tens,f
        addwf   Tens,f

        swapf   NumL,w
        andlw   0X0F
        addwf   Tens,f
        addwf   Ones,f

        rlf     Tens,f
        rlf     Ones,f
        comf    Ones,f
        rlf     Ones,f

        movf    NumL,w
        andlw   0X0F
        addwf   Ones,f
        rlf     Thou,f

        movlw   0X07
        movwf   TenK

                    ; At this point, the original number is
                    ; equal to
                    ; TenK*10000+Thou*1000+Hund*100+Tens*10+Ones
                    ; if those entities are regarded as two's
                    ; complement binary.  To be precise, all of
                    ; them are negative except TenK.  Now the number
                    ; needs to be normalized, but this can all be
                    ; done with simple byte arithmetic.

        movlw   0X0A                             ; Ten
Lb1:
        addwf   Ones,f
        decf    Tens,f
        btfss   3,0
        goto   Lb1
Lb2:
        addwf   Tens,f
        decf    Hund,f
        btfss   3,0
        goto   Lb2
Lb3:
        addwf   Hund,f
        decf    Thou,f
        btfss   3,0
        goto   Lb3
Lb4:
        addwf   Thou,f
        decf    TenK,f
        btfss   3,0
        goto   Lb4
LCD_Decimal
		
		btfsc   Flags, 0x00 
		goto    LCD_TENK
		movf    TenK, w
		btfss   STATUS, Z
		goto    LCD_TENK
		movf    Thou, w
		btfss   STATUS, Z
		goto    LCD_THOU
		movf    Hund, w
		btfss   STATUS, Z
		goto    LCD_HUND
		movf    Tens, w
		btfss   STATUS, Z
		goto    LCD_TENS
		goto    LCD_ONES
LCD_TENK
		movlw	0x05			;test if decimal point 5
		subwf   Point, w
		btfss   STATUS    , Z
		goto	NO_DP5
		movlw	'.'
		movwf TenkOUT
NO_DP5		movf    TenK, w
		addlw	0x30
		movlw	0x04			;test if decimal point 4
		subwf   Point, w
		btfss   STATUS    , Z
		goto	LCD_THOU
		movlw	'.'
		movwf	DPout		;display decimal point
LCD_THOU
		movf    Thou, w
		addlw	0x30
		movlw	0x03			;test if decimal point 3
		subwf   Point, w
		btfss   STATUS    , Z
		goto	LCD_HUND
		movlw	'.'
	    movwf ThouOUT
LCD_HUND
		movf    Hund, w
		addlw	0x30
		movlw	0x02			;test if decimal point 2
		subwf   Point, w
		btfss   STATUS    , Z
		goto	LCD_TENS
		movlw	'.'
		movwf HundOUT
LCD_TENS
		movf    Tens, w
		addlw	0x30
		movlw	0x01			;test if decimal point 1
		subwf   Point, w
		btfss   STATUS    , Z
		goto	LCD_ONES
		movlw	'.'
		movwf TensOUT
LCD_ONES
		movf     Ones, w
		movwf OnesOUT
 
       retlw	0x00

	END		; Конец программы.
rezor вне форума   Ответить с цитированием
Старый 01.11.2010, 17:39   #2
karapet
Junior Member
 
Регистрация: 22.09.2010
Сообщений: 28
Вес репутации: 100/36
karapet will become famous soon enoughkarapet will become famous soon enough
По умолчанию Re: АЦП в pic16f877 + LCD

Пиши на С. намного быстрее и проще.

Вот так можно сделать то о чем попросил ты на С:

Код:
set_adc_channel(0);
value = read_adc();
result=(value*5)/1023;
printf(LCD_PUTC, "U=%2.3f V",result);

Последний раз редактировалось karapet; 01.11.2010 в 17:52.
karapet вне форума   Ответить с цитированием
Старый 01.11.2010, 17:58   #3
rezor
Junior Member
 
Регистрация: 01.11.2010
Возраст: 29
Сообщений: 15
Вес репутации: 100/36
rezor will become famous soon enoughrezor will become famous soon enough
По умолчанию Re: АЦП в pic16f877 + LCD

Это курсач на С нельзя.
rezor вне форума   Ответить с цитированием
Старый 01.11.2010, 23:50   #4
karapet
Junior Member
 
Регистрация: 22.09.2010
Сообщений: 28
Вес репутации: 100/36
karapet will become famous soon enoughkarapet will become famous soon enough
По умолчанию Re: АЦП в pic16f877 + LCD

Посмотри по этой ссылке (ЖК-модуль 16x2):
http://icmicro.narod.ru/source/index.htm

И на сколько я рассмотрел в скриншете у тебя ЖК 2-х строчный и 16 символов в каждой. А ты помоему используешь драйвер для 4-строчный * 20 символов модуля.
karapet вне форума   Ответить с цитированием
Старый 02.11.2010, 07:59   #5
rezor
Junior Member
 
Регистрация: 01.11.2010
Возраст: 29
Сообщений: 15
Вес репутации: 100/36
rezor will become famous soon enoughrezor will become famous soon enough
По умолчанию Re: АЦП в pic16f877 + LCD

ЖК я настроил и ацп инициализировал не пойму как преобразовать результат для вывода на жк.
rezor вне форума   Ответить с цитированием
Старый 02.11.2010, 11:50   #6
karapet
Junior Member
 
Регистрация: 22.09.2010
Сообщений: 28
Вес репутации: 100/36
karapet will become famous soon enoughkarapet will become famous soon enough
По умолчанию Re: АЦП в pic16f877 + LCD

Тебе нужно преобразовать двоичное число в двоично-десятичное.
Я гогда-то делал с помощью этой подпрограмки.

Код:
Для вывода цифр на индикатор (в примере на 4-разрядный) необходимо 
преобразовать 2-байтное двоичное число в двоично-десятичное (3-бфйтное). Вот подпрограмма, которая может это сделать.

Название: bin2bcd
Входные данные: двоичное число в регистрах bin1, bin2. При этом bin1 - старший байт. 
(Данные с АЦП загружаешь в эти регистры - ADRESH в bin1, ADRESL в bin2)
Выходные: единицы будут в младшей тетраде регистра bcd3, десятки в 
старшей регистра bcd3, сотни в младшей тетраде регистра bcd2, тысячи 
в старшей bcd2, десятки тысяч будут находиться в младшей тетраде 
регистра bcd1 - эти преобразованные числа выводишь уже на ЖК.

ну только естественно переводиш их в ASCII, т.е. 1 - это 0x31, 2 - 0x32, 3 - 0x33 и т.д




Используемые регистры: bin1, bin2, bcd1, bcd2, bcd3, ctr.

bin2bcd         movlw .16 
                movwf ctr 
                clrf bcd1 
                clrf bcd2 
                clrf bcd3 
                goto start 

adjdec          movlw 0x33 
                addwf bcd1,f 
                addwf bcd2,f 
                addwf bcd3,f 

                movlw 0x03 
                btfss bcd1,3 
                subwf bcd1,f 
                btfss bcd2,3 
                subwf bcd2,f 
                btfss bcd3,3 
                subwf bcd3,f 

                movlw 0x30 
                btfss bcd1,7 
                subwf bcd1,f 
                btfss bcd2,7 
                subwf bcd2,f 
                btfss bcd3,7 
                subwf bcd3,f 

start           rlf bin2,f 
                rlf bin1,f 
                rlf bcd3,f 
                rlf bcd2,f 
                rlf bcd1,f 
                decfsz ctr,f 
                goto adjdec 
                return

Последний раз редактировалось karapet; 02.11.2010 в 12:08.
karapet вне форума   Ответить с цитированием
Старый 02.11.2010, 17:58   #7
rezor
Junior Member
 
Регистрация: 01.11.2010
Возраст: 29
Сообщений: 15
Вес репутации: 100/36
rezor will become famous soon enoughrezor will become famous soon enough
По умолчанию Re: АЦП в pic16f877 + LCD

Ок спасибо буду пробовать преаброзовать!!!
rezor вне форума   Ответить с цитированием
Старый 05.11.2010, 16:50   #8
rezor
Junior Member
 
Регистрация: 01.11.2010
Возраст: 29
Сообщений: 15
Вес репутации: 100/36
rezor will become famous soon enoughrezor will become famous soon enough
По умолчанию Re: АЦП в pic16f877 + LCD

По моему за вывод я рано взялся, у меня инициализация АЦП не коректная.
rezor вне форума   Ответить с цитированием
Старый 05.11.2010, 17:16   #9
karapet
Junior Member
 
Регистрация: 22.09.2010
Сообщений: 28
Вес репутации: 100/36
karapet will become famous soon enoughkarapet will become famous soon enough
По умолчанию Re: АЦП в pic16f877 + LCD

Если ты загжужаешь в ADCON1 это значение
Код:
    		movlw   b'10000101'
    		movwf   ADCON1
значит нада к ноге RA3 подключить подтягивающее напряжение относительно которого он будит оцифровывать. Но тебе насколько я понял нада, чтоб он оцифровывал относительно напряжению питания ПИКа, попробуй поменяй вышеуказанные 2 строчки кода на следующие:

Код:
MOVLW B'10001110'
MOVWF ADCON1
karapet вне форума   Ответить с цитированием
Старый 05.11.2010, 17:35   #10
rezor
Junior Member
 
Регистрация: 01.11.2010
Возраст: 29
Сообщений: 15
Вес репутации: 100/36
rezor will become famous soon enoughrezor will become famous soon enough
По умолчанию Re: АЦП в pic16f877 + LCD

Сделал вот так и на схеме показано что напряжение пошло на порт

Код:
Init_ADC
 ; Инициализация порта А. PORTA0 - вход АЦП
        clrf PORTA ; Очищаем опрт А
        bsf STATUS,RP0 ; Банк 1
        movlw b'11111111' ; Все ножки порта на вход
        movwf TRISA
        bcf STATUS,RP0 ; Банк 0
        movlw b'11000001' ; 
        movwf ADCON0 ; Адресс 1Fh (банк 0)
        bsf STATUS,RP0 ; Банк 1
        movlw b'00000000' ; Сдвиг-влево; Опорное напряжение: питание и земля
        movwf ADCON1 ; Адресс 9Fh (банк 1)
        bcf STATUS,RP0 ; Банк 0
		return
Хотя при старой и при нынешней иницеализации значения выводятся одинаковые.Ваши изменения роли не сыграли.

Последний раз редактировалось rezor; 05.11.2010 в 17:41.
rezor вне форума   Ответить с цитированием
Старый 06.11.2010, 17:21   #11
rezor
Junior Member
 
Регистрация: 01.11.2010
Возраст: 29
Сообщений: 15
Вес репутации: 100/36
rezor will become famous soon enoughrezor will become famous soon enough
По умолчанию Re: АЦП в pic16f877 + LCD

Как в протеусе глянуть что я получил в порте А и в регистрах NumH и NumL после работы АЦП???
rezor вне форума   Ответить с цитированием
Старый 10.11.2010, 20:47   #12
HOT
Member
 
Аватар для HOT
 
Регистрация: 19.07.2008
Возраст: 33
Сообщений: 46
Вес репутации: 135/44
HOT will become famous soon enoughHOT will become famous soon enough
По умолчанию Re: АЦП в pic16f877 + LCD

Вот когда-то пользовался, модули на асм для pic16:
BINARY to DECIMAL CONVERSION for LCD-Display for PIC 16XXX V1.02
Wait Routine for PIC 16XXX V1.02
LCD INTERFACE V2.06 for PIC 16XXX
оригиналы тут
Вложения
Тип файла: rar lcd.rar (8.6 Кб, 33 просмотров)
HOT вне форума   Ответить с цитированием
Старый 15.11.2010, 19:08   #13
rezor
Junior Member
 
Регистрация: 01.11.2010
Возраст: 29
Сообщений: 15
Вес репутации: 100/36
rezor will become famous soon enoughrezor will become famous soon enough
По умолчанию Re: АЦП в pic16f877 + LCD

спасибо за примеры преобразования у меня все же проблема в инициализации ацп
rezor вне форума   Ответить с цитированием
Старый 15.11.2010, 20:40   #14
Mikhail
Senior Member
 
Регистрация: 03.03.2007
Сообщений: 109
Вес репутации: 207/51
Mikhail has a spectacular aura aboutMikhail has a spectacular aura aboutMikhail has a spectacular aura about
По умолчанию Re: АЦП в pic16f877 + LCD

Цитата:
Сообщение от rezor Посмотреть сообщение
спасибо за примеры преобразования у меня все же проблема в инициализации ацп
Рекомендованная последовательность действий для работы с АЦП:
1. Настроить модуль АЦП:
- Настроить выводы как аналоговые входы, входы VREF или цифровые каналы
ввода/вывода (ADCON1);
- Выбрать входной канал АЦП (ADCON0);
- Выбрать источник тактовых импульсов для АЦП (ADCON0);
- Включить модуль АЦП (ADCON0).
2. Настроить прерывание от модуля АЦП (если необходимо):
- Сбросить бит ADIF в '0';
- Установить бит ADIE в '1';
- Установить бит PEIE в '1';
- Установить бит GIE в '1'.
3. Выдержать паузу, необходимую для зарядки конденсатора CHOLD.
4. Начать аналого-цифровое преобразование:
- Установить бит GO/-DONE в '1' (ADCON0).
5. Ожидать окончания преобразования:
- Ожидать пока бит GO/-DONE не будет сброшен в '0'; ИЛИ
- Ожидать прерывание по окончанию преобразования.
6. Считать результат преобразования из регистров ADRESH:ADRESL, сбросить бит ADIF в '0',
если это необходимо.
7. Для следующего преобразования необходимо выполнить шаги начиная с пункта 1 или 2.
Время преобразования одного бита определяется как время TAD.
Минимальное время ожидания перед следующим
преобразованием должно составлять не менее 2TAD.

Последний раз редактировалось Mikhail; 15.11.2010 в 20:52.
Mikhail вне форума   Ответить с цитированием
Старый 22.11.2010, 14:19   #15
rezor
Junior Member
 
Регистрация: 01.11.2010
Возраст: 29
Сообщений: 15
Вес репутации: 100/36
rezor will become famous soon enoughrezor will become famous soon enough
По умолчанию Re: АЦП в pic16f877 + LCD

Получил данные от работы АЦП в порты С и В подскажите насколько они корректны.

Код:
list p=16f877				;тип процессора
 	include "p16f877.inc"		;подключение файла
cblock	0x20			;start of general purpose registers
tempHIGH
tempLOW
PauseBuffer
DIGIT1
DIGIT2
DIGIT3
DIGIT4
HILO
TEMPTEN
endc
	org 0x00				;переход к вектору начала программы
 	nop					;для отладчика

Start
BCF     STATUS, RP0	; Переходим в банк 0
    CLRF	STATUS		; Сбрасываем все флаги, установлен банк 0
	CLRF	INTCON		; Запретить все прерывания
	

	clrf	PORTA	; Сброс PORTA
	clrf	PORTB	; Сброс PORTB
	clrf	PORTC	; Сброс PORTC
	clrf	PORTD	; Сброс PORTD
	clrf	PORTE	; Сброс PORTE
	BSF	STATUS, RP0	; Переходим в Банк 1
	clrf	TRISA	; Настройка всех портов на вывод
	clrf	TRISB	; 
	clrf	TRISC	; 
	clrf	TRISD	; 
	clrf	TRISE	; 
    movlw b'11111111' ; Все ножки порта на вход
 	
 	movwf TRISA


bcf STATUS,RP0 ; Банк 0
        ; Установка прерывания по завершению преобразования АЦП
        bcf PIR1,ADIF ; Сбразываем флаг прерывания (банк 0)      
        bsf PIE1,ADIE ; Включаем прерывание от АЦП (банк 1)
        bsf INTCON,PEIE ; Включение прерывания от переферии (банк -)

bcf STATUS,RP0 ; Банк 0
banksel ADCON0
movlw 0xC1
movwf ADCON0

movlw 0x80
banksel ADCON1
movwf ADCON1

call getADC
LOOP
	GOTO	LOOP		; Вечный цикл
;============GetADC============
getADC call PauseForADC
      banksel ADCON0
      bsf ADCON0,GO
ADCloop btfsc ADCON0,GO
goto ADCloop
bcf PIR1,ADIF

movf ADRESH,w

movwf PORTC
movf ADRESL,w
movwf PORTB
return
;============PauseADC=======
 PauseForADC
        movlw 0xFF
        movwf PauseBuffer
        decfsz PauseBuffer
        goto $-1
        return

 end
rezor вне форума   Ответить с цитированием
Старый 22.11.2010, 20:26   #16
Mikhail
Senior Member
 
Регистрация: 03.03.2007
Сообщений: 109
Вес репутации: 207/51
Mikhail has a spectacular aura aboutMikhail has a spectacular aura aboutMikhail has a spectacular aura about
По умолчанию Re: АЦП в pic16f877 + LCD

Если посмотреть карту памяти ОЗУ то ADRESL следует читать из банка 1, а не из нулевого.
Mikhail вне форума   Ответить с цитированием
Старый 22.11.2010, 20:45   #17
AlexPv
Senior Member
 
Регистрация: 02.03.2009
Адрес: Russia
Сообщений: 1,800
Вес репутации: 565/64
AlexPv is a name known to allAlexPv is a name known to allAlexPv is a name known to allAlexPv is a name known to allAlexPv is a name known to allAlexPv is a name known to all
По умолчанию Re: АЦП в pic16f877 + LCD

Цитата:
Сообщение от rezor Посмотреть сообщение
Получил данные от работы АЦП в порты С и В подскажите насколько они корректны.
Так Вы и сами можете определить: N=Ux/(Uref/1024)=Uref/(Ux*1024),
Ux - измеряемое напряжение [В], Uref - опорное напряжение [В], 1024 - для 10-ти разрядного АЦП, N - значение АЦП в дес. формате.

А зачем в программе разрешено прерывание от АЦП?
AlexPv вне форума   Ответить с цитированием
Старый 23.11.2010, 17:54   #18
rezor
Junior Member
 
Регистрация: 01.11.2010
Возраст: 29
Сообщений: 15
Вес репутации: 100/36
rezor will become famous soon enoughrezor will become famous soon enough
По умолчанию Re: АЦП в pic16f877 + LCD

А как прочитать ADRESL из банка 1??
если перейти педед чтением в банк
Код:
movf ADRESH,w
movwf PORTC
BSF	STATUS, RP0	; Переходим в Банк 1
movf ADRESL,w
movwf PORTB
return
в порт вообще ни чего не попадает
Прерывание от АЦП я просто разрешил так в примере было показано.Опорное напряжение мне не нужно!!!
Еще у меня ADCON1 инициализировался в нулевом банке, но это я поправил.
Подскажите как настроить ADCON1 биты настройки каналов PCFG3: PCFG0
если напряжение подается на A0 и нет опорного напряжения, а то по таблице я не особо разобрался у меня получилось значение 0x0E при нем в порте получаю 153 при напряжении в 3V и 255 при напряжении 4,99V.

Код:
list p=16f877				;тип процессора
 	include "p16f877.inc"		;подключение файла
cblock	0x20			;start of general purpose registers
tempHIGH
tempLOW
PauseBuffer
DIGIT1
DIGIT2
DIGIT3
DIGIT4
HILO
TEMPTEN
endc
	org 0x00				;переход к вектору начала программы
 	nop					;для отладчика

Start
BCF     STATUS, RP0	; Переходим в банк 0
    CLRF	STATUS		; Сбрасываем все флаги, установлен банк 0
	CLRF	INTCON		; Запретить все прерывания
	

	clrf	PORTA	; Сброс PORTA
	clrf	PORTB	; Сброс PORTB
	clrf	PORTC	; Сброс PORTC
	clrf	PORTD	; Сброс PORTD
	clrf	PORTE	; Сброс PORTE
	BSF	STATUS, RP0	; Переходим в Банк 1
	clrf	TRISA	; Настройка всех портов на вывод
	clrf	TRISB	; 
	clrf	TRISC	; 
	clrf	TRISD	; 
	clrf	TRISE	; 
    movlw b'11111111' ; Все ножки порта на вход 	
 	movwf TRISA
    movlw 0x0E 
    movwf ADCON1
    bsf PIE1,ADIE ; Включаем прерывание от АЦП (банк 1)
bcf STATUS,RP0 ; Банк 0
       
movlw 0xC1
movwf ADCON0
 ; Установка прерывания по завершению преобразования АЦП           
        
		bcf PIR1,ADIF ; Сбразываем флаг прерывания (банк 0)
        bsf INTCON,PEIE ; Включение прерывания от переферии (банк -)
call getADC
LOOP
	GOTO	LOOP		; Вечный цикл
;============GetADC============
getADC call PauseForADC
      banksel ADCON0
      bsf ADCON0,GO
ADCloop btfsc ADCON0,GO
goto ADCloop
bcf PIR1,ADIF

movf ADRESH,w

movwf PORTC
movf ADRESL,w
movwf PORTB
return
;============PauseADC=======
 PauseForADC
        movlw 0xFF
        movwf PauseBuffer
        decfsz PauseBuffer
        goto $-1
        return

 end

Последний раз редактировалось rezor; 23.11.2010 в 18:05.
rezor вне форума   Ответить с цитированием
Старый 23.11.2010, 19:42   #19
Mikhail
Senior Member
 
Регистрация: 03.03.2007
Сообщений: 109
Вес репутации: 207/51
Mikhail has a spectacular aura aboutMikhail has a spectacular aura aboutMikhail has a spectacular aura about
По умолчанию Re: АЦП в pic16f877 + LCD

Перед записью в PORTB вставить строку
Цитата:
BCF STATUS, RP0 ; Переходим в Банк 0
По регистру ADCON1, у Вас, установлено сейчас Vопорное = Vdd
Mikhail вне форума   Ответить с цитированием
Старый 23.11.2010, 19:53   #20
Mikhail
Senior Member
 
Регистрация: 03.03.2007
Сообщений: 109
Вес репутации: 207/51
Mikhail has a spectacular aura aboutMikhail has a spectacular aura aboutMikhail has a spectacular aura about
По умолчанию Re: АЦП в pic16f877 + LCD

Про микроконтроллеры на русском языке смотрите
http://www.microchip.ru/lit/?mid=1x0
Mikhail вне форума   Ответить с цитированием
Старый 23.11.2010, 21:11   #21
rezor
Junior Member
 
Регистрация: 01.11.2010
Возраст: 29
Сообщений: 15
Вес репутации: 100/36
rezor will become famous soon enoughrezor will become famous soon enough
По умолчанию Re: АЦП в pic16f877 + LCD

Спасибо прочитать значение удалось!!Vdd это ведь , как я понял, опорное напряжение от питание контролера!!!

Последний раз редактировалось rezor; 23.11.2010 в 21:31.
rezor вне форума   Ответить с цитированием
Старый 23.11.2010, 21:42   #22
rezor
Junior Member
 
Регистрация: 01.11.2010
Возраст: 29
Сообщений: 15
Вес репутации: 100/36
rezor will become famous soon enoughrezor will become famous soon enough
По умолчанию Re: АЦП в pic16f877 + LCD

А если считать по приведеной формуле N=Ux/(Uref/1024)=Uref/(Ux*1024)
чему будет равно мое опорное напряжение Vdd если измеряемое напряжение на порту А0 +5V ???
rezor вне форума   Ответить с цитированием
Старый 24.11.2010, 19:52   #23
AlexPv
Senior Member
 
Регистрация: 02.03.2009
Адрес: Russia
Сообщений: 1,800
Вес репутации: 565/64
AlexPv is a name known to allAlexPv is a name known to allAlexPv is a name known to allAlexPv is a name known to allAlexPv is a name known to allAlexPv is a name known to all
По умолчанию Re: АЦП в pic16f877 + LCD

Что будет использоваться в качестве опоры АЦП зависит от битов PCFG3:PCFG0 регистра ADCON1. В даташите на это есть подробнейшая табличка.
Если использовать внешнюю опору, следует иметь ввиду, что:
(VREF+ - VREF-) должно лежать в интервале от 2,0 до Vdd
VREF+ от AVDD-2.5V до AVDD+0.3V
VREF- от AVSS-0.3V до VREF+ - 2.0V
(короче, см. даташит)

Опору ниже 2,5В лучше не делать.
AlexPv вне форума   Ответить с цитированием
Старый 24.11.2010, 19:54   #24
AlexPv
Senior Member
 
Регистрация: 02.03.2009
Адрес: Russia
Сообщений: 1,800
Вес репутации: 565/64
AlexPv is a name known to allAlexPv is a name known to allAlexPv is a name known to allAlexPv is a name known to allAlexPv is a name known to allAlexPv is a name known to all
По умолчанию Re: АЦП в pic16f877 + LCD

Цитата:
Сообщение от rezor Посмотреть сообщение
чему будет равно мое опорное напряжение Vdd если измеряемое напряжение на порту А0 +5V ???
Измерение происходит относительно опорного напряжения!
AlexPv вне форума   Ответить с цитированием
Старый 24.11.2010, 19:56   #25
rezor
Junior Member
 
Регистрация: 01.11.2010
Возраст: 29
Сообщений: 15
Вес репутации: 100/36
rezor will become famous soon enoughrezor will become famous soon enough
По умолчанию Re: АЦП в pic16f877 + LCD

Я понимаю что преобразования идут относительно опорного напряжения, поэтому и уточняю как выставить именно внутренее.Внешнюю опору я использовать не хочу , мне наоборот нужно только внутренее.Я вроде получил уже результат преобразования АЦП. Теперь пытаюсь его преобразовать из двоичного в двоично-десятичный, но выводит совершенно бредовые значения!
rezor вне форума   Ответить с цитированием
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы
Опции просмотра

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Инициализация HD44780. Ittoo Вопросы начинающих 207 15.05.2011 15:27
PIC16F877 + АЦП + ASM Harikolo Продукция MICROCHIP 18 19.05.2010 22:59
PIC16F877 и LCD svg67 Продукция MICROCHIP 7 15.09.2009 10:58
LCD + PIC zaman Продукция MICROCHIP 7 05.09.2009 23:52
АЦП, PIC16F877 ГЫнок Продукция MICROCHIP 6 02.03.2008 01:03


Часовой пояс GMT +3, время: 12:54.


Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd. Перевод: zCarot