Портал для радиолюбителей и разработчиков электроники · с 2003 годаРеклама на сайте
Найти компонент, схему или даташит

Даташиты, справочник отечественных приборов, схемы с разбором и живой форум

Микроконтроллеры, АЦП, память и т.д Темы касающиеся микроконтроллеров разных производителей, памяти, АЦП/ЦАП, периферийных модулей...

 
Опции темы

asm программирование МК PIC16F630

Непрочитано 11.12.2007, 11:51  
SVDimon
Прохожий
 
Регистрация: 04.10.2007
Сообщений: 6
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
SVDimon на пути к лучшему
По умолчанию asm программирование МК PIC16F630

Уважаемые читатели подскажите.
Как мне правильно опрашивать входные порты МК PIC16F630? Т.Е. когда я ожидаю реакцию программы от ожидаемой 1-ци на его входе он толи сразу выдает её, хоть физически я её не подавал толи вообще ничего не выдает.

Код:
list      P=PIC16F630, f=inhx8m   	; list directive to define processor
#include ‹p16f630.inc›       			; processor specific variable definitions

;*************************************************  *********************
__CONFIG b'00111110010100'  

									;13,12-BG1,BG0-биты калибровки сброса по снижению питания =00-нижн предел
									;11,10,9- не использ (=111)
									;8-CPD1-защита пам EEPROM включена=0, выключена =1 
									;7-CP1-защита пам ПРГР вкл=0, выкл=1
									;6-BODEN разрешен=1, запрещен=0
									;5-MCLR работает=1, вывод цифр работает=0
									;4-PWRT включен=0, выключен=1
									;3-WDT разрешен=1,запрещен=0
									;2,1,0=100=внутр такт RC-генератор, выв OSC работают как порты
;=================================================  ================	

CBLOCK 20H		; этой сторокой указывается, что дальше резервируется память блока 0 от адресса 20h для общего пользования. 
    temp		; Например для размещения там переменных.
    temp1		; Тут я прописываю переменные которые будут располагатся в памяти по порядку 
ENDC
;*************************************************  ***********************************************
;								Инициализация М.К.
;*************************************************  ***********************************************
;---------------------- Инициализация А портов --------------------------------------------------
BCF STATUS,RP0				; сдесь я устанавливаю данк памяти Bank 0.
	CLRF PORTA				; эта команда нужна для того, что бы "проинициализировать все выводы порта А"
	
	BSF STATUS,RP0			; это нужно для смены текущего банка памяти, т.к. команда TRISA находится в Bank 1.
	CLRF WPUA				; 
	CLRF IOCA				; 
	;CLRF ANSEL				; 
	MOVLW 0xC8				;	
	MOVWF TRISA				; УСТАНОВКА назначения портов вход или выход.
	nop
	nop
BCF STATUS,RP0				; смена банка памяти снова на 0.

;---------------------- Инициализация С портов -------------------------------------------------
	CLRF PORTC				; эта команда нужна для того, что бы "проинициализировать все выводы порта С"
	
	BSF STATUS,RP0			; это нужно для смены текущего банка памяти, т.к. команда TRISA находится в Bank 1.
	;CLRF ANSEL				; этим я устанавливаю все порты как двунаправленные цифровые порты.
	MOVLW 0xFE				; 	
	MOVWF TRISC				; УСТАНОВКА назначения портов вход или выход.
	nop
	nop
BCF STATUS,RP0				; смена банка памяти снова на 0.

;=================================================  ==============================================
; вызывая этот макрос внутри программы предварительно следуе установить значение переменной temp, которая как раз и отвечает за 
; время задержки. Устанавливаемоя задержка от этого таймера может ззменятся на любое значение кратное 65 [мили сек].
; Пример вызова этого макроса с предустановкой значения переменной:
; MOVLW 0xCF			; занесение константы в регистер аккумулятор W. (Тут заносимое число представляется в 16-ричним виде)
; MOVWF temp			; запись значения с W на переменную temp.		(это число равно CF=207 в десятиричном).
; TMR_0					; вызов макросса TMR_0.
; !( Метки в теле макроса, обязательно, надо определять, как локальные. Иначе, если макрос будет вызываться 
; больше одного раза в программе, то получиться наложение глобальных меток и компилятор выдаст ошибку! 
; Тело макроса описывается с использованием директив ассемблера: macro – начало макроса, endm – окончание макроса. 
; Для объявления локальных меток используется директива local. )!
;====================== Инициализация таймера ==================================================
TMR_0 macro				; Это заголовок макроса.

LOCAL START_TIMER0,PRERIV		; Этой строкой я определяю в теле макроса локальные переменные которые должны и будут 
								; использоваться только в теле этого макроса.
START_TIMER0: CLRF TMR0			; Очистка таймера 0, этим я же и активизурую его.
			  CLRF INTCON		; Очистка всех значений регистра отвечающего за разрешение прерываний.
			  BSF STATUS,RP0	; Установка Банка 1, для того что бы потом можно было бы обратится к регистру OPTION_REG.
nop
MOVLW 0xC7				; тут я настроил предделитель TIME0 на 1:256. Бит7 - включение подтягивающих регистолров (тут они 0 - отключены).
MOVWF OPTION_REG		; Бит6 - 1 прерывание по перднему фронту. Бит5 - 0 выбор внешнего тактового сигналла.
						; Бит4 - 0 выбор фронта прерывания от всешнего сигналла (тут этот бит не используется).
						; Бит3 - 0 выбор включения предделителя перед таймером. Бит2-бит0 - значение предделителя.
						
BCF STATUS,RP0			; Переключить на Банк 0.
;BSF INTCON,T0IE			; Разрешить прерывание от TIMER 0. Тут я повыключал прерывание которое вызывается по переполению теймера потому, 
;BSF INTCON,GIE				; Разрешиить внешние прервывания. что это может вызвать прость туму , что программа вернётся в началло СТЕКА сразу по переполнению таймера.
nop						; 
nop						; Эта короткая задержка нужна для того, чтобы таймер успел бы начать работать.
nop						; 
nop						; 
PRERIV: BTFSS INTCON, T0IF	; Проверка флага T0IF - который сам устанавливается при репеполнии таймера TIME0.
GOTO PRERIV					; 
				
DECFSZ temp1,1			; Умен. перем. temp на 1 и сохр. результата в temp. Если резул. ваполнения операции = 0 пропуск следующей команды.
GOTO START_TIMER0		; Этой строкой я указываю, что выход из макросса только тогда когда значение переменной temp будет = 0.

endm					; это конец макроса.
;=================================================  =======================================
CLRW 					; очистка и сброс таймер счетчика W (этот рег. нужен для того что бы передать нужную инфор. на рег. управ. работой МК).
CLRF FSR				; очистка вспомогательного регистра F (этот риг. нужен для времен. хранения данных, для того чтобы передать их на W).
clrf temp				; очистка служебных переменных. 
clrf temp1				; очистка служебных переменных.
;=================================================  =======================================
;*************************************************  ***************************************
; 					ВЫПОЛНЯЕМЫЙ КОД ПРОГРАММЫ
;*************************************************  ***************************************
; Все 3 инфракрастных детектора должны быть настроенны таким образом, что бы при попадании
; луча от излучателя на приёмник бы выдавал 0 на своем выходе. А при обрыве луча приёмник
; выдавал бы 1 на своем выходе.
;----------------------------------------------------------------------------------------
BCF PORTA,0					; 
BCF PORTA,1					; 
BCF PORTA,2					; 
BCF PORTC,0					; 
main:

BSF PORTA,4					; Установка в 1 этого вых. порта мне нужно для того, что бы потом подать эту 1 на входы порта когда это нужно.
	
M:   BTFSC  PORTC,5			; ОПРОС входа на RC5.
GOTO M						; 
M1:  BTFSC  PORTC,4			; ОПРОС входа на RC4.
GOTO M1						; 
M2:  BTFSC  PORTC,3			; ОПРОС входа на RC3.
GOTO M2						; 

;*************************************************  *********************************
; ВИПОЛНЯЕМ ПРОВЕРКУ СРАБОТАЛ ЛЮБОЙ ДАТЧИК (УСТАНОВЛЕНА ЛИ 1 НА ЛЮБОМ ИЗ ПОРТОВ RC5,RC4,RC3).
;*************************************************  *********************************

M4: MOVLW 0x02				; Этот цикл работает очень просто. Сначала в переменную temp записываю
MOVWF temp					; константу 2 потом инкрементирую переменную на 1. Далее, что бы цикл работал циклически 
M3: INCF temp,1				; конечно же проверяю эту переменную на переполнение (до 8=100h) вернее сверяю 
BTFSC temp,3				; 3-й бит этого регистра как только он равен 1 записываю в переменную 2.
GOTO M4						; Если переменная не переполнена выполняю проверку порта RC, номер проверяемого 
BTFSc PORTC,temp			; порта равен числу в переменной. Если какой нибудь из проверяемых портов равен 1 
GOTO M3						; цикл заканчивается.

;*************************************************  *********************************
; включение выхода (послание 1 на вход системы SOS) длительно стью 131 [мс]. После чего
; этот выход сбрасывается в 0 и программа начинает работать заново.
;*************************************************  *********************************
BSF PORTA,0					; 
BSF PORTA,1					; 
BSF PORTA,2					; 
BSF PORTC,0					; 

NOP							; 
NOP							; 
NOP							; 
NOP							; 
MOVLW 0x0a					; Это 16-ричное число = 10. Или эквивалентно задержке в 655 мили сек.
MOVWF temp1					; 
TMR_0						; 

;---------------------------------------------------------------------------------
;				ВЫКЛЮЧИТЬ ВЫХОДНОЙ ПОРТ
;---------------------------------------------------------------------------------
BCF PORTA,0					; 
BCF PORTA,1					; 
BCF PORTA,2					; 
BCF PORTC,0					; 

NOP							; 
NOP							; 
NOP							; 
NOP							; 
;---------------------------------------------------------------------------------

goto main
END
Реклама:
SVDimon вне форума  
Непрочитано 11.12.2007, 13:21  
user_ushastyj
Временная регистрация
 
Регистрация: 06.12.2007
Сообщений: 91
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
user_ushastyj на пути к лучшему
По умолчанию

Во-первых, используйте тег [_code_].
Во- вторых, мне из текста абсолютно неясно, что происходит с переменной при срабатывании - и зачем циклить при опросе ????
Я немного исправил, что понял.

Прикрепленный файл: 4469108.rar
__________________
разум когда-нибудь победит... (с)
user_ushastyj вне форума  
Непрочитано 11.12.2007, 16:08  
SVDimon
Прохожий
 
Регистрация: 04.10.2007
Сообщений: 6
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
SVDimon на пути к лучшему
По умолчанию

А что такое [_code_].

А прога предельно проста. Она постоянно должна опрашивать входы и как только на любом из них =1 должна установится 1 на его выходе на определлённое время. После этого все заново.
Вот только даже теперь прога физически работает не корректно, всегда 1 на его входе.
Код:
;list P=PIC16F630, f=inhx8m ; list directive to define processor
#include ‹p16f630.inc› ; processor specific variable definitions

;*************************************************  *********************
;__CONFIG b'00111110010100'

__CONFIG _INTRC_OSC_NOCLKOUT  & _CP_OFF  & _BODEN  & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF

#define dat_1 5
#define dat_2 4

CBLOCK 20H ; этой сторокой указывается, что дальше резервируется память блока 0 от адресса 20h для общего пользования.
temp ; Например для размещения там переменных.
temp1 ; Тут я прописываю переменные которые будут располагатся в памяти по порядку
port_c
ENDC
       ORG 0

;*************************************************  ***********************************************
; Инициализация М.К.
;*************************************************  ***********************************************
;---------------------- Инициализация А портов --------------------------------------------------
BSF STATUS,RP0
CALL 0x3FF
MOVWF OSCCAL
MOVLW 0xC8 ;
MOVWF TRISA ; УСТАНОВКА назначения портов вход или выход.
MOVLW 0x20 ;
MOVWF TRISC ; УСТАНОВКА назначения портов вход или выход.
BCF STATUS,RP0 ; сдесь я устанавливаю данк памяти Bank 0.
MOVLW 7
MOVWF CMCON
CLRF PORTA ; эта команда нужна для того, что бы "проинициализировать все выводы порта А"
CLRF PORTC ; эта команда нужна для того, что бы "проинициализировать все выводы порта С"



;=================================================  ==============================================
; вызывая этот макрос внутри программы предварительно следуе установить значение переменной temp, которая как раз и отвечает за
; время задержки. Устанавливаемоя задержка от этого таймера может ззменятся на любое значение кратное 65 [мили сек].
; Пример вызова этого макроса с предустановкой значения переменной:
; MOVLW 0xCF ; занесение константы в регистер аккумулятор W. (Тут заносимое число представляется в 16-ричним виде)
; MOVWF temp ; запись значения с W на переменную temp. (это число равно CF=207 в десятиричном).
; TMR_0 ; вызов макросса TMR_0.
; !( Метки в теле макроса, обязательно, надо определять, как локальные. Иначе, если макрос будет вызываться
; больше одного раза в программе, то получиться наложение глобальных меток и компилятор выдаст ошибку!
; Тело макроса описывается с использованием директив ассемблера: macro – начало макроса, endm – окончание макроса.
; Для объявления локальных меток используется директива local. )!
;====================== Инициализация таймера ==================================================
TMR_0 macro ; Это заголовок макроса.
LOCAL START_TIMER0,PRERIV ; Этой строкой я определяю в теле макроса локальные переменные которые должны и будут
; использоваться только в теле этого макроса.
START_TIMER0: CLRF TMR0 ; Очистка таймера 0, этим я же и активизурую его.
CLRF INTCON ; Очистка всех значений регистра отвечающего за разрешение прерываний.
BSF STATUS,RP0 ; Установка Банка 1, для того что бы потом можно было бы обратится к регистру OPTION_REG.
nop
MOVLW 0xC7 ; тут я настроил предделитель TIME0 на 1:256. Бит7 - включение подтягивающих регистолров (тут они 0 - отключены).
MOVWF OPTION_REG ; Бит6 - 1 прерывание по перднему фронту. Бит5 - 0 выбор внешнего тактового сигналла.
; Бит4 - 0 выбор фронта прерывания от всешнего сигналла (тут этот бит не используется).
; Бит3 - 0 выбор включения предделителя перед таймером. Бит2-бит0 - значение предделителя.

BCF STATUS,RP0 ; Переключить на Банк 0.
;BSF INTCON,T0IE ; Разрешить прерывание от TIMER 0. Тут я повыключал прерывание которое вызывается по переполению теймера потому,
;BSF INTCON,GIE ; Разрешиить внешние прервывания. что это может вызвать прость туму , что программа вернётся в началло СТЕКА сразу по переполнению таймера.
nop ;
nop ; Эта короткая задержка нужна для того, чтобы таймер успел бы начать работать.
nop ;
nop ;
PRERIV: BTFSS INTCON, T0IF ; Проверка флага T0IF - который сам устанавливается при репеполнии таймера TIME0.
GOTO PRERIV ;
DECFSZ temp1,1 ; Умен. перем. temp на 1 и сохр. результата в temp. Если резул. ваполнения операции = 0 пропуск следующей команды.
GOTO START_TIMER0 ; Этой строкой я указываю, что выход из макросса только тогда когда значение переменной temp будет = 0.
endm ; это конец макроса.
;=================================================  =======================================
CLRW ; очистка и сброс таймер счетчика W (этот рег. нужен для того что бы передать нужную инфор. на рег. управ. работой МК).
CLRF FSR ; очистка вспомогательного регистра F (этот риг. нужен для времен. хранения данных, для того чтобы передать их на W).
clrf temp ; очистка служебных переменных.
clrf temp1 ; очистка служебных переменных.
clrf port_c
;=================================================  =======================================
;*************************************************  ***************************************
; ВЫПОЛНЯЕМЫЙ КОД ПРОГРАММЫ
;*************************************************  ***************************************
; Все 3 инфракрастных детектора должны быть настроенны таким образом, что бы при попадании
; луча от излучателя на приёмник бы выдавал 0 на своем выходе. А при обрыве луча приёмник
; выдавал бы 1 на своем выходе.
;----------------------------------------------------------------------------------------
;BCF PORTA,0 ;
;BCF PORTA,1 ;
;BCF PORTA,2 ;
BCF PORTC,5 ;
BCF PORTC,4 ;
main:

BSF PORTA,4 ; Установка в 1 этого вых. порта мне нужно для того,
; что бы потом подать эту 1 на входы порта когда это нужно.

;---------------------------------
MOVF PORTC,0
MOVWF port_c
;---------------------------------
;M: BTFSC PORTC,5 ; ОПРОС входа на RC5.
;GOTO M ;
;M1: BTFSC PORTC,4 ; ОПРОС входа на RC4.
;GOTO M1 ;
;M2: BTFSC PORTC,3 ; ОПРОС входа на RC3.
;GOTO M2 ;

;*************************************************  *********************************
; ВИПОЛНЯЕМ ПРОВЕРКУ СРАБОТАЛ ЛЮБОЙ ДАТЧИК (УСТАНОВЛЕНА ЛИ 1 НА ЛЮБОМ ИЗ ПОРТОВ RC5,RC4,RC3).
;*************************************************  *********************************

;M4: MOVLW 0x02 ; Этот цикл работает очень просто. Сначала в переменную temp записываю
;MOVWF temp ; константу 2 потом инкрементирую переменную на 1. Далее, что бы цикл работал циклически
;M3: INCF temp,1 ; конечно же проверяю эту переменную на переполнение (до 8=100h) вернее сверяю
;BTFSC temp,3 ; 3-й бит этого регистра как только он равен 1 записываю в переменную 2.
;GOTO M4 ; Если переменная не переполнена выполняю проверку порта RC, номер проверяемого
;BTFSc PORTC,temp ; порта равен числу в переменной. Если какой нибудь из проверяемых портов равен 1
;GOTO M3 ; цикл заканчивается.

 BTFSC port_c,dat_1		; ВСЁ РАВНО ПОЧЕМУ ТО ПОРТ RС5 ВСЕГДА =1 КАК ТОЛЬКО Я ПОДАЮ ПИТАНИЕ НА МК ?
 GOTO er_1
 ;BTFSC port_c,dat_2
 ;GOTO er_2
 ;BTFSC port_c,dat_3
 ;GOTO er_3
 GOTO main
 ;-----------------------
 er_1:
 ;er_2:
 ;er_3:
;*************************************************  *********************************
; включение выхода (послание 1 на вход системы SOS) длительно стью 131 [мс]. После чего
; этот выход сбрасывается в 0 и программа начинает работать заново.
;*************************************************  *********************************
BSF PORTC,4 ;
;BSF PORTA,1 ;
;BSF PORTA,2 ;
;BSF PORTC,0 ;

NOP ;
NOP ;
NOP ;
NOP ;
MOVLW 0x0a ; Это 16-ричное число = 10. Или эквивалентно задержке в 655 мили сек.
MOVWF temp1 ;
TMR_0 ;

;---------------------------------------------------------------------------------
; ВЫКЛЮЧИТЬ ВЫХОДНОЙ ПОРТ
;---------------------------------------------------------------------------------
BCF PORTA,0 ;
BCF PORTA,1 ;
BCF PORTA,2 ;
BCF PORTC,0 ;

NOP ;
NOP ;
NOP ;
NOP ;
;---------------------------------------------------------------------------------

goto main
END
Прикрепленный файл: 4469108.rar
SVDimon вне форума  
Непрочитано 11.12.2007, 17:00  
urry
Почётный гражданин KAZUS.RUN
 
Аватар для urry
 
Регистрация: 06.02.2007
Сообщений: 1,340
Сказал спасибо: 3
Сказали Спасибо 107 раз(а) в 66 сообщении(ях)
urry на пути к лучшему
По умолчанию

Когда ножка настроена на вход, она практически в 3 состоянии, за исключением случаев, когда включены внутренние подтягивающие резисторы. Включены или нет - проверьте сами.Схему я не видел, так что-то сказать определенное не могу, но не вредно поставить килоом 5 -10 на землю от каждой ножки.
urry вне форума  
Непрочитано 11.12.2007, 17:22  
SVDimon
Прохожий
 
Регистрация: 04.10.2007
Сообщений: 6
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
SVDimon на пути к лучшему
По умолчанию

Похоже там просто их нет или я не знаю как их настраивать на порте RC.
SVDimon вне форума  
Непрочитано 11.12.2007, 17:38  
tempora
Почётный гражданин KAZUS.RUN
 
Регистрация: 10.01.2007
Сообщений: 3,411
Сказал спасибо: 65
Сказали Спасибо 664 раз(а) в 443 сообщении(ях)
tempora на пути к лучшему
По умолчанию

Сообщение от urry
... не вредно поставить килоом 5-10 на землю от каждой ножки.
Если говорить о входах, то уж лучше на питание - при включении внутренних пуллапов не будет утечек (по 0.5-1mA на каждый вход, однако).
tempora вне форума  
Непрочитано 11.12.2007, 22:20  
urry1
Временная регистрация
 
Регистрация: 11.12.2007
Сообщений: 79
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
urry1 на пути к лучшему
По умолчанию

Человек "0" увидеть не может - пусть посадит резисторы со входов на землю и кнопками на + покоротит - опять же через резисторы желательно.
urry1 вне форума  
Непрочитано 11.12.2007, 22:38  
tempora
Почётный гражданин KAZUS.RUN
 
Регистрация: 10.01.2007
Сообщений: 3,411
Сказал спасибо: 65
Сказали Спасибо 664 раз(а) в 443 сообщении(ях)
tempora на пути к лучшему
По умолчанию

Сообщение от urry
Человек "0" увидеть не может...
Ну-да, пожалуй, о микроамперах заботиться рановато... Хотя, с другой стороны - в схемотехнике, как и в любой другой, достаточно сложной, технике, человек запоминает однажды сработавшие решения и пользуется ими потом всю жизнь, не проверяя, чтобы сэкономить время на построение более сложных решений. Как грится - как вы лодку назовёте, так она и поплывёт... Я больше люблю кнопки на землю сажать (через резики, разумеется, если есть риск перепрограммировать ногу на выход с полновесной единицей), а не на питалово... Может, это на меня так дурно атмелы повлияли? И потом, есть ещё нормально замкнутые кнопки. Я слышал...
tempora вне форума  
Непрочитано 12.12.2007, 11:20  
SVDimon
Прохожий
 
Регистрация: 04.10.2007
Сообщений: 6
Сказал спасибо: 0
Сказали Спасибо 0 раз(а) в 0 сообщении(ях)
SVDimon на пути к лучшему
По умолчанию

Люди зазве есть возможность включить подтягивающие резисторы к RC входам ? Если да то как ?
SVDimon вне форума  
Непрочитано 12.12.2007, 11:37  
urry1
Временная регистрация
 
Регистрация: 11.12.2007
Сообщений: 79
Сказал спасибо: 0
Сказали Спасибо 1 раз в 1 сообщении
urry1 на пути к лучшему
По умолчанию

Нет, подтягивающие - только на порта, индивидуально.
Регистр WPUA
Кстати, сразу скорректируйте прогу -
Код:
movlw 5
movwf cmcon
bcf status,rp0
clrf ansel
7 - для 628 пика.
urry1 вне форума  
 
Опции темы

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

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

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

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
PIC16F630 Lex_DJ Микроконтроллеры, АЦП, память и т.д 39 06.11.2010 22:22
Проблема с 24C16->I2C->PIC16F630 need help! tolyanv8 Микроконтроллеры, АЦП, память и т.д 25 08.05.2009 20:49
WinAVR и asm Dungeon Микроконтроллеры, АЦП, память и т.д 0 12.06.2007 10:55
программирование PIC16F630 Lex_DJ Микроконтроллеры, АЦП, память и т.д 0 25.05.2007 10:39
ASM (PIC) 4elowek Микроконтроллеры, АЦП, память и т.д 1 18.10.2005 02:38


Часовой пояс GMT +4, время: 04:45.


Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.