Администрация форума не несёт ответственности за достоверность информации и оставляет за собой право редактировать или в особых случаях даже удалять посты без предупреждения. Спасибо за понимание.

Программирование ATMEL в BASCOM.

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » Программирование ATMEL в BASCOM. » Примеры применения в среде Баском » Исследование расширителей портов контроллера


Исследование расширителей портов контроллера

Сообщений 1 страница 16 из 16

1

Исследование расширителей портов по шине i2c:

PCF8574

PCF8575

MCP23008

MCP23016

MCP23017

Исследование расширителей портов по шине SPI:

MCP23S08

MCP23S16

MCP23S17

'
'
'                                                                             !!! В Н И М А Н И Е !!!

Во избежание проблем, при работе в железе, ОБЯЗАТЕЛЬНО ПОДТЯГИВАЙТЕ вывод "Reset" MCP23008 к "+" через резистор 5к-10к!

'                                                                            !!! В Н И М А Н И Е !!!
'
'
'
'
'
'

Отредактировано Mrshilov (2013-10-10 20:11:25)

+1

2

Mrshilov написал(а):

Мой экземпляр при Config I2cdelay = 1 глючит. Написано Philips.

Отредактировано Mrshilov (Сегодня 19:11:25)

У меня работает. Проверил еще раз.

Апаратный I2c быстрее чем программный.

'  Аппаратный I2c

  $regfile = "m328pdef.dat"
  $crystal = 8000000
  $hwstack = 40
  $swstack = 16
  $framesize = 32

  $lib"i2c_twi.lbx"

  Config Scl = Portc.5
  Config Sda = Portc.4
  Config Twi = 400000
  I2cinit

  I2cstart       ' 8.1250 мкс
  I2cwbyte &H70       ' 48 мкс
  I2cwbyte &B00000000       ' 48.250 мкс
  I2cstop ' 1.8750 мкс

*********************************************

'  Программный I2c

  $regfile = "m328pdef.dat"
  $crystal = 8000000
  $hwstack = 40
  $swstack = 16
  $framesize = 32

  Config Scl = Portc.5
  Config Sda = Portc.4
  Config I2cdelay = 1
  I2cinit

  I2cstart       ' 7.1250 мкс
  I2cwbyte &H70       ' 54.750 мкс
  I2cwbyte &B00000000       ' 54.750 мкс
  I2cstop ' 7.6250 мкс

Отредактировано sasha_1973 (2013-10-10 20:45:58)

+2

3

'
'
'                                !!! В Н И М А Н И Е !!!

Во избежание проблем, при работе в железе, ОБЯЗАТЕЛЬНО ПОДТЯГИВАЙТЕ вывод "Reset" MCP23008 к "+" через резистор 5к-10к!

'                                !!! В Н И М А Н И Е !!!

Протеус 7.10; 8.1 + исходники Bascom 2.0.7.1 (разбиты на отдельные подключаемые файлы с использованием процедур)  --  скачать

+1

4

Коммутация входов на выходы + бегущий огонёк (всё в качестве примера использования)

Atmega8 + 2 x MCP23016

Симуляция Протеус 7.10 + исходники Bascom 2.0.7.1  -  скачать

http://sc.uploads.ru/t/OoKbV.jpg

+1

5

Как оказалось, очень удобная микросхема. Всего 2 ножки контроллера + 1 на прерывание (если надо), и практически не ограниченные возможности коммутации и вывода

PCF8574 - 8-ми канальный, дунаправленный расширитель порта

Будьте внимательны, от буквы в конце названия PCF8574x, зависит адресация микросхемы !!!

Адресация микросхем PCF8574x, PCF8575x

'------------------------------------------------------------------
'|             |  PCF8574,PCF8574N, PCF8575 |  PCF8574A, PCF8574AP |
'|-------------|----------------------------|----------------------|
'|  A0  A1  A2 |     Чтение  |   Запись     |   Чтение  |  Запись  |
'|-------------|-------------|--------------|-----------|----------|
'|  0   0   0  |      &H40   |     &H41     |    &H70   |   &H71   |
'|  1   0   0  |      &H42   |     &H43     |    &H72   |   &H73   |
'|  0   1   0  |      &H44   |     &H45     |    &H74   |   &H75   |
'|  1   1   0  |      &H46   |     &H47     |    &H76   |   &H77   |
'|  0   0   1  |      &H48   |     &H49     |    &H78   |   &H79   |
'|  1   0   1  |      &H4A   |     &H4B     |    &H7A   |   &H7B   |
'|  0   1   1  |      &H4C   |     &H4D     |    &H7C   |   &H7D   |
'|  1   1   1  |      &H4E   |     &H4F     |    &H7E   |   &H7F   |
'------------------------------------------------------------------

Версия с независимой фиксацией

'*******************************************************************************
' * * * * * * *  Atmega32 + расширитель портов I2c PCF8574   * * * * * * * * * *
'*******************************************************************************
$regfile = "m32def.dat"
$crystal = 8000000
$framesize = 80
$hwstack = 80
$swstack = 80
'*******************************************************************************
'-------------------------------------------------------------------------------
' $sim
'-------------------------------------------------------------------------------
'*******************************************************************************
'* * * * * * * * * * * * *  Переменные   * * * * * * * * * * * * * * * * * * * *
'*******************************************************************************
Dim Knopka As Byte , Adres_key As Byte , Adres_out_port As Byte
Dim Chtenie_out_port As Byte , Port_out As Byte , N_key As Byte
Dim Pcf8574port_key As Byte , Pcf8574port_out As Byte , A As Byte
Dim Flag_key_port As Bit
'-------------------------------------------------------------------------------
Dim Key_p0 As Byte , Key_p1 As Byte
Dim Key_p2 As Byte , Key_p3 As Byte , Key_p4 As Byte
Dim Key_p5 As Byte , Key_p6 As Byte , Key_p7 As Byte
Dim Out1 As Byte , Out_p0 As Bit , Out_p1 As Bit
Dim Out_p2 As Bit , Out_p3 As Bit , Out_p4 As Bit
Dim Out_p5 As Bit , Out_p6 As Bit , Out_p7 As Bit
'-------------------------------------------------------------------------------
Norma Alias Portd.0       '> Моргающий светодиод, показывает, что МК не завис
Speaker Alias Pinc.7       '> Озвучивание
'-------------------------------------------------------------------------------
Config Pind.0 = Output
'-------------------------------------------------------------------------------
Config Lcdpin = Pin , Rs = Portb.0 , E = Portb.1 , Db4 = Portb.4 , Db5 = Portb.5 , Db6 = Portb.6 , Db7 = Portb.7
Config Lcd = 20 * 4
Initlcd
Cursor Off
Cls
'*******************************************************************************
'* * * * * * * * * * * * *  Конфигурация PCF8574  * * * * * * * * * * * * * * *
'*******************************************************************************
'-------------------------------------------------------------------------------
Const Pcf8574read_out = &H41       '> Адресация чтения PCF8574
Const Pcf8574write_out = &H40       '> Адресация записи PCF8574
'-------------------------------------------------------------------------------
Const Pcf8574read_key = &H4F       '> Адресация чтения PCF8574
Const Pcf8574write_key = &H4E       '> Адресация записи PCF8574
'-------------------------------------------------------------------------------
Config Scl = Portc.0       '> Конфигурация порта
Config Sda = Portc.1       '> Конфигурация порта
Config I2cdelay = 1       '> Задержки i2c "10 - 100кГц, 5 - 200кГц, 2 - 500кГц, 1 - 1Мгц" - для стабильной работы чем длиннее провода тем меньше частота
I2cinit  '> Инициализация i2c
'-------------------------------------------------------------------------------
I2creceive Pcf8574read_key , Pcf8574port_key       '> Чтение состояния PCF8574port_key
I2creceive Pcf8574read_out , Chtenie_out_port       '> Чтение состояния PCF8574port_Out
'*******************************************************************************
'* * * * * * * * Настройка прерывания клавиатуры на PCF8574  * * * * * * * * * *
'*******************************************************************************
Config Pind.2 = Input
Config Int0 = Falling
Enable Int0
On Int0 Pcf8574_key_int
'-------------------------------------------------------------------------------
'*******************************************************************************
'* * * * * * * * * * * *  Конфигурация подпрограмм  * * * * * * * * * * * * * *
'*******************************************************************************
Declare Sub Lcd_display
'*******************************************************************************
'* * * * * * * * * * * *  Конфигурация функций  * * * * * * * * * * * * * * * *
'*******************************************************************************
Declare Sub Goend
Declare Sub Sub_exit
'-------------------------------------------------------------------------------
Declare Sub Bip_bip
Declare Sub Key_adress
Declare Sub Pcf8574_key_int
Declare Sub Chtenie_port_out
Declare Sub Chtenie_port_key
'*******************************************************************************
'* * * * * * * * * * * * * *  Основной цикл  * * * * * * * * * * * * * * * * * *
'*******************************************************************************
' For A = 1 To 3                                            'To 5
'    I2csend Pcf8574write_out , &B01010101                   '> Запись 00000000 в PCF8574port_out
'      Waitms 200                                            '>  Пауза 300мс
'    I2csend Pcf8574write_out , &B10101010                   '> Запись 00000000 в PCF8574port_out
'      Waitms 200                                            '>  Пауза 300мс
'    I2csend Pcf8574write_out , &B11110000                   '> Запись 00000000 в PCF8574port_out
'      Waitms 200                                            '>  Пауза 300мс
'    I2csend Pcf8574write_out , &B11110000                   '> Запись 00000000 в PCF8574port_out
'      Waitms 200                                            '>  Пауза 300мс
'  Next A
'*******************************************************************************
'* * * * * * * * * * * * * *  Основной цикл  * * * * * * * * * * * * * * * * * *
'*******************************************************************************
Sound Speaker , 65 , 1274
Waitms 125
Sound Speaker , 87 , 954
Waitms 125
Sound Speaker , 98 , 850
Waitms 125
Sound Speaker , 87 , 954
Sound Speaker , 117 , 715
Waitms 125
Sound Speaker , 110 , 758
Waitms 125
Sound Speaker , 98 , 850
Waitms 125
Sound Speaker , 110 , 758
Sound Speaker , 87 , 954
Waitms 125
Wait 1
'-------------------------------------------------------------------------------
'I2csend Pcf8574write_out , &B11111111
Enable Interrupts       '>  Включаем прерывание INT0
'-------------------------------------------------------------------------------
'*******************************************************************************
  Do

    Toggle Norma
      Waitms 50
    Call Key_adress:

    Call Lcd_display:

  Loop
'*******************************************************************************
'====================== Подпрограмма индикации LCD =============================
  Sub Lcd_display:

    Call Chtenie_port_key
    Call Chtenie_port_out
      Adres_key = Pcf8574port_key
      Adres_out_port = Chtenie_out_port

    Locate 1 , 1
     Lcd "Adres Key: " ; Bin(adres_key)

    Locate 2 , 1
     Lcd "Adres Out: " ; Bin(adres_out_port)

    'Waitms 100
  End Sub
'==================== Подпрограмма расчета кнопки ==============================
  Sub Key_adress:

   If Flag_key_port = 1 Then Call Chtenie_port_key

   Call Chtenie_port_out
    Out1 = Chtenie_out_port
     N_key = Pcf8574port_key
      Select Case N_key
       Case Is = 0 : Goto Key_adress_out
       Case Is = 255 : Goto Key_adress_out
       Case Is = 254 :
         Out_p0 = Out1.0
           Call Bip_bip
             Toggle Out_p0
           Out1.0 = Out_p0
         I2csend Pcf8574write_out , Out1

       Case Is = 253 :
         Out_p1 = Out1.1
           Call Bip_bip
             Toggle Out_p1
           Out1.1 = Out_p1
         I2csend Pcf8574write_out , Out1
       Case Is = 251 :
         Out_p2 = Out1.2
           Call Bip_bip
             Toggle Out_p2
           Out1.2 = Out_p2
         I2csend Pcf8574write_out , Out1
       Case Is = 247 :
         Out_p3 = Out1.3
           Call Bip_bip
             Toggle Out_p3
           Out1.3 = Out_p3
         I2csend Pcf8574write_out , Out1
       Case Is = 239 :
         Out_p4 = Out1.4
           Call Bip_bip
             Toggle Out_p4
           Out1.4 = Out_p4
         I2csend Pcf8574write_out , Out1
       Case Is = 223 :
         Out_p5 = Out1.5
           Call Bip_bip
             Toggle Out_p5
           Out1.5 = Out_p5
         I2csend Pcf8574write_out , Out1
       Case Is = 191 :
         Out_p6 = Out1.6
           Call Bip_bip
             Toggle Out_p6
           Out1.6 = Out_p6
         I2csend Pcf8574write_out , Out1
       Case Is = 127 :
         Out_p7 = Out1.7
           Call Bip_bip
             Toggle Out_p7
           Out1.7 = Out_p7
         I2csend Pcf8574write_out , Out1
       End Select
     Reset Flag_key_port
    Key_adress_out:
  End Sub
'===============================================================================
'================ Подпрограмма прерывания клавиатуры ===========================
  Pcf8574_key_int:
   Set Flag_key_port
    Gifr = 64
      'If Flag_key_port = 1 Then Call Key_adress
  Return
'===============================================================================
'================ Подпрограмма чтения порта PCF8574 Key ========================
  Chtenie_port_key:
   I2creceive Pcf8574read_key , Pcf8574port_key       'Короткий вариант чтения данных с pcf8574 key              Out_p = Out_p + Out_p0
  Return
'===============================================================================
'================ Подпрограмма чтения порта PCF8574 Out ========================
  Chtenie_port_out:
   I2creceive Pcf8574read_out , Chtenie_out_port       'Короткий вариант чтение данных с pcf8574 Out
  Return
'===============================================================================
'================ Подпрограмма озвучивания нажатия кнопок ======================
  Bip_bip:
   Sound Portc.7 , 100 , 500       'BEEP
   'Sound Portc.7 , 400 , 450                                'BEEP
  Return
'===============================================================================
'*******************************************************************************
  Goend:
End

'End Program
'*******************************************************************************
'*******************************************************************************
'***************************   ПРИМЕРЫ   ***************************************
'*******************************************************************************
'*******************************************************************************
   ' Sound Speaker , 65 , 1274
' Waitms 125
' Sound Speaker , 87 , 954
' Waitms 125
' Sound Speaker , 98 , 850
' Waitms 125
' Sound Speaker , 87 , 954
' Sound Speaker , 117 , 715
' Waitms 125
' Sound Speaker , 110 , 758
' Waitms 125
' Sound Speaker , 98 , 850
' Waitms 125
' Sound Speaker , 110 , 758
' Sound Speaker , 87 , 954
' Waitms 125
' Wait 2
'-------------------------------------------------------------------------------
'Sound Portc.7 , 400 , 450                                   'BEEP
'Sound Portc.7 , 400 , 250                                   'BEEP
'Sound Portc.7 , 400 , 450                                   'BEEP
'*******************************************************************************

http://s4.uploads.ru/t/hElkf.jpg

Архив со всем необходимым скачать:   http://www.fayloobmennik.net/2978780

Версия с зависимой фиксацией

'*******************************************************************************
'*******************************************************************************
$regfile = "m32def.dat"
$crystal = 8000000
$hwstack = 80
$swstack = 80
$framesize = 80
'-------------------------------------------------------------------------------
'$sim
'-------------------------------------------------------------------------------
Config Pind.0 = Output
Config Pind.1 = Output
'*******************************************************************************
'****************** Конфигурация PCF8574 ***************************************
'*******************************************************************************
'Const Pcf8574 = &H40          '
'Const Pcf8574 = &H42          '
'Const Pcf8574 = &H44          '
'Const Pcf8574 = &H46          '
'Const Pcf8574 = &H48          '
'Const Pcf8574 = &H4A          '
'Const Pcf8574 = &H4C          '
'Const Pcf8574 = &H4E          '

'Const Pcf8574 = &H41
'Const Pcf8574 = &H43
'Const Pcf8574 = &H45
'Const Pcf8574 = &H47
'Const Pcf8574 = &H49
'Const Pcf8574 = &H4B
'Const Pcf8574 = &H4D
'Const Pcf8574 = &H4F
'-------------------------------------------------------------------------------
Const Pcf8574write_out = &B1000000       '&H40
Const Pcf8574read_out = &B1000001       '&H41

Const Pcf8574write_key = &B1001110       '&H4E
Const Pcf8574read_key = &B1001111       '&H4F
'-------------------------------------------------------------------------------
Config Scl = Portc.0
Config Sda = Portc.1
Config I2cdelay = 5

'-------------------------------------------------------------------------------
'---------------- Настройка прерывания клавиатуры на PCF8574 -------------------
'-------------------------------------------------------------------------------
Config Pind.2 = Input
Config Int0 = Falling

Enable Int0
On Int0 Pcfint
'-------------------------------------------------------------------------------
Dim Pcf8574port_key As Byte
'-------------------------------------------------------------------------------
Dim Pcf8574_out0 As Byte
Dim Pcf8574_out1 As Byte
Dim Pcf8574_out2 As Byte
Dim Pcf8574_out3 As Byte
Dim Pcf8574_out4 As Byte
Dim Pcf8574_out5 As Byte
Dim Pcf8574_out6 As Byte
Dim Pcf8574_out7 As Byte
'-------------------------------------------------------------------------------
Dim Flag_pcf8574_out0 As Byte : Flag_pcf8574_out0 = 0
Dim Flag_pcf8574_out1 As Byte : Flag_pcf8574_out1 = 0
Dim Flag_pcf8574_out2 As Byte : Flag_pcf8574_out2 = 0
Dim Flag_pcf8574_out3 As Byte : Flag_pcf8574_out3 = 0
Dim Flag_pcf8574_out4 As Byte : Flag_pcf8574_out4 = 0
Dim Flag_pcf8574_out5 As Byte : Flag_pcf8574_out5 = 0
Dim Flag_pcf8574_out6 As Byte : Flag_pcf8574_out6 = 0
Dim Flag_pcf8574_out7 As Byte : Flag_pcf8574_out7 = 0
'-------------------------------------------------------------------------------
Dim Reset_8574_out As Byte : Reset_8574_out = &B00000000
I2cstart
I2cwbyte Pcf8574write_out
I2cwbyte Reset_8574_out
I2cstop
'-------------------------------------------------------------------------------
Declare Sub Out1()
Declare Sub Pcfint_out

Declare Sub Pcf8574_0
Declare Sub Pcf8574_1
Declare Sub Pcf8574_2
Declare Sub Pcf8574_3
Declare Sub Pcf8574_4
Declare Sub Pcf8574_5
Declare Sub Pcf8574_6
Declare Sub Pcf8574_7

'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'*******************************************************************************
'*******************************************************************************
'-------------------------------------------------------------------------------
   Enable Interrupts

'-------------------------------------------------------------------------------
   Do

     Call Out1

    'Call Out2

   Loop
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'*******************************************************************************
  Sub Out1()
'-------------------------------------------------------------------------------
      Toggle Portd.0

    Waitms 100

  End Sub
'-------------------------------------------------------------------------------
'*******************************************************************************
  Pcfint:
'-------------------------------------------------------------------------------

   Waitms 10
        I2cinit
        I2cstart
        I2cwbyte Pcf8574read_key
        I2crbyte Pcf8574port_key , Nack
        I2cstop

        If Pcf8574port_key = 254 Then Toggle Portd.1

        If Pcf8574port_key = 254 Then Toggle Flag_pcf8574_out0
        If Pcf8574port_key = 254 Then Call Pcf8574_0

        If Pcf8574port_key = 253 Then Toggle Flag_pcf8574_out1
        If Pcf8574port_key = 253 Then Call Pcf8574_1

        If Pcf8574port_key = 251 Then Toggle Flag_pcf8574_out2
        If Pcf8574port_key = 251 Then Call Pcf8574_2

        If Pcf8574port_key = 247 Then Toggle Flag_pcf8574_out3
        If Pcf8574port_key = 247 Then Call Pcf8574_3

        If Pcf8574port_key = 239 Then Toggle Flag_pcf8574_out4
        If Pcf8574port_key = 239 Then Call Pcf8574_4

        If Pcf8574port_key = 223 Then Toggle Flag_pcf8574_out5
        If Pcf8574port_key = 223 Then Call Pcf8574_5

        If Pcf8574port_key = 191 Then Toggle Flag_pcf8574_out6
        If Pcf8574port_key = 191 Then Call Pcf8574_6

        If Pcf8574port_key = 127 Then Toggle Flag_pcf8574_out7
        If Pcf8574port_key = 127 Then Call Pcf8574_7

   'Pcfint_out:

      Gifr = 64

    Return

  End
'-------------------------------------------------------------------------------
'*******************************************************************************
'*******************************************************************************
'-------------------------------------------------------------------------------
Pcf8574_0:
   If Flag_pcf8574_out0 = 255 Then Pcf8574_out0 = 1       'Else Pcf8574_out0 = &B00000000 End If
       I2cstart
       I2cwbyte Pcf8574write_out
       I2cwbyte Pcf8574_out0
      ' I2cwbyte Pcf8574_out0
       I2cstop
     Return
'*******************************************************************************
'-------------------------------------------------------------------------------
Pcf8574_1:
   If Flag_pcf8574_out1 = 255 Then Pcf8574_out1 = 2       'Else Pcf8574_out1 = &B00000000 End If
       I2cstart
       I2cwbyte Pcf8574write_out
       I2cwbyte Pcf8574_out1
       I2cwbyte Pcf8574_out1
       I2cstop
     Return
'*******************************************************************************
'-------------------------------------------------------------------------------
Pcf8574_2:
   If Flag_pcf8574_out2 = 255 Then Pcf8574_out2 = 4       'Else Pcf8574_out2 = &B00000000 End If
       I2cstart
       I2cwbyte Pcf8574write_out
       I2cwbyte Pcf8574_out2
       I2cstop
     Return
'*******************************************************************************
'-------------------------------------------------------------------------------
Pcf8574_3:
   If Flag_pcf8574_out3 = 255 Then Pcf8574_out3 = 8       'Else Pcf8574_out3 = &B00000000 End If
       I2cstart
       I2cwbyte Pcf8574write_out
       I2cwbyte Pcf8574_out3
       I2cstop
     Return
'*******************************************************************************
'-------------------------------------------------------------------------------
Pcf8574_4:
   If Flag_pcf8574_out4 = 255 Then Pcf8574_out4 = 16       'Else Pcf8574_out4 = &B00000000 End If
       I2cstart
       I2cwbyte Pcf8574write_out
       I2cwbyte Pcf8574_out4
       I2cstop
     Return
'*******************************************************************************
'-------------------------------------------------------------------------------
Pcf8574_5:
   If Flag_pcf8574_out5 = 255 Then Pcf8574_out5 = 32       'Else Pcf8574_out5 = &B00000000 End If
       I2cstart
       I2cwbyte Pcf8574write_out
       I2cwbyte Pcf8574_out5
       I2cstop
     Return
'*******************************************************************************
'-------------------------------------------------------------------------------
Pcf8574_6:
   If Flag_pcf8574_out6 = 255 Then Pcf8574_out6 = 64       'Else Pcf8574_out6 = &B00000000 End If
       I2cstart
       I2cwbyte Pcf8574write_out
       I2cwbyte Pcf8574_out6
       I2cstop
     Return
'*******************************************************************************
'-------------------------------------------------------------------------------
Pcf8574_7:
   If Flag_pcf8574_out7 = 255 Then Pcf8574_out7 = 128       'Else Pcf8574_out7 = &B00000000 End If
       I2cstart
       I2cwbyte Pcf8574write_out
       I2cwbyte Pcf8574_out7
       I2cstop
     Return
     'Goto Pcfint_out:
   'End Sub
'*******************************************************************************
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'*******************************************************************************

End

'*******************************************************************************
'*******************************************************************************
'***************-----------*****************************************************
'***************| Pcf8574 |*****************************************************
'***************-----------*****************************************************
'**********| A0 | A1 | A2 | code |**********************************************
'**********| 0  | 0  | 0  | &H40 |**********************************************
'**********| 1  | 0  | 0  | &H42 |**********************************************
'**********| 0  | 1  | 0  | &H44 |**********************************************
'**********| 1  | 1  | 0  | &H46 |**********************************************
'**********| 0  | 0  | 1  | &H48 |**********************************************
'**********| 1  | 0  | 1  | &H4A |**********************************************
'**********| 0  | 1  | 1  | &H4C |**********************************************
'**********| 1  | 1  | 1  | &H4E |**********************************************
'*******************************************************************************
'*******************************************************************************
'*********** Const Pcf8574 = &H40 **********************************************
'*********** Const Pcf8574 = &H42 **********************************************
'*********** Const Pcf8574 = &H44 **********************************************
'*********** Const Pcf8574 = &H46 **********************************************
'*********** Const Pcf8574 = &H48 **********************************************
'*********** Const Pcf8574 = &H4A **********************************************
'*********** Const Pcf8574 = &H4C **********************************************
'*********** Const Pcf8574 = &H4E **********************************************
'*******************************************************************************
'*******************************************************************************
'*********** Const Pcf8574 = &H41 **********************************************
'*********** Const Pcf8574 = &H43 **********************************************
'*********** Const Pcf8574 = &H45 **********************************************
'*********** Const Pcf8574 = &H47 **********************************************
'*********** Const Pcf8574 = &H49 **********************************************
'*********** Const Pcf8574 = &H4B **********************************************
'*********** Const Pcf8574 = &H4D **********************************************
'*********** Const Pcf8574 = &H4F **********************************************
'*******************************************************************************
'*******************************************************************************

http://s4.uploads.ru/t/37fxR.jpg

Архив со всем необходимым, скачать:   http://www.fayloobmennik.net/2978794

+1

6

Atmega8A + матричная клавиатура 4х4 + 8 внешних входов + 8 внешних выходов

'
'
'                                !!! В Н И М А Н И Е !!!

Во избежание проблем, при работе в железе, ОБЯЗАТЕЛЬНО ПОДТЯГИВАЙТЕ вывод "Reset" MCP23008 к "+" через резистор 5к-10к!

'                                !!! В Н И М А Н И Е !!!

Симуляция Протеус 7.10; 8.1 + исходники Bascom 2.0.7.1  -  скачать

http://sa.uploads.ru/t/wLOVQ.jpg

0

7

Исследование расширителей портов по шине i2c:

PCF8574

PCF8575

MCP23008

MCP23016

MCP23017

Исследование расширителей портов по шине SPI:

MCP23S08

MCP23S16

MCP23S17

0

8

Будьте внимательны, от буквы в конце названия PCF8574x, зависит адресация микросхемы !!!

Адресация PCF8574, PCF8574N, PCF8574A, PCF8575

'------------------------------------------------------------------
'|             |  PCF8574,PCF8574N, PCF8575 |  PCF8574A, PCF8574AP |
'|-------------|----------------------------|----------------------|
'|  A0  A1  A2 |     Чтение  |   Запись     |   Чтение  |  Запись  |
'|-------------|-------------|--------------|-----------|----------|
'|  0   0   0  |      &H40   |     &H41     |    &H70   |   &H71   |
'|  1   0   0  |      &H42   |     &H43     |    &H72   |   &H73   |
'|  0   1   0  |      &H44   |     &H45     |    &H74   |   &H75   |
'|  1   1   0  |      &H46   |     &H47     |    &H76   |   &H77   |
'|  0   0   1  |      &H48   |     &H49     |    &H78   |   &H79   |
'|  1   0   1  |      &H4A   |     &H4B     |    &H7A   |   &H7B   |
'|  0   1   1  |      &H4C   |     &H4D     |    &H7C   |   &H7D   |
'|  1   1   1  |      &H4E   |     &H4F     |    &H7E   |   &H7F   |
'------------------------------------------------------------------

Пример использования микросхем PCF8574x

'*******************************************************************************
' $regfile = "m32def.dat" : $crystal = 8000000 : $hwstack = 80 : $swstack = 80 : $framesize = 80
'-------------------------------------------------------------------------------
  $regfile = "m8def.dat" : $crystal = 1000000 : $framesize = 32 : $hwstack = 40 : $swstack = 40 : $baud = 4800       '1200     '2400     '4800     '9600     '19200     '38400     '57600     '115000
'*******************************************************************************
'-------------------------------------------------------------------------------
  Config Lcdpin = Pin , Rs = Portb.0 , E = Portb.1 , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5
  Config Lcd = 20 * 4       ' Используемый LCD
  Initlcd           ' Инициализируем LCD
  Waitms 50         ' Ждем пока все запустится
  Cursor Off Noblink       ' Выключаем неморгающий курсор
'  Cursor On Noblink         ' Включаем неморгающий курсор
'  Cursor On Blink           ' Включаем моргающий курсор
  Cls               ' Чистим экран, на всякий случай

  Dim Буфер_lcd_string As String * 20
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'*****************                                       ***********************
'*****************         Конфигурация шины I2c         ***********************
'*****************        микросхема часов DS1307        ***********************
'*****************                                       ***********************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Config Sda = Portc.4       ' Конфигурация порта
  Config Scl = Portc.5       ' Конфигурация порта
  Config I2cdelay = 5       ' Задержки i2c "10 - 100кГц, 5 - 200кГц, 2 - 500кГц, 1 - 1Мгц" - для стабильной работы чем длиннее провода тем меньше частота
  I2cinit           ' Инициализация i2c
  Dim Инициализация_i2c As Byte
'-------------------------------------------------------------------------------
'------------------------------------------------------------------
'|             |  PCF8574,PCF8574N, PCF8575 |  PCF8574A, PCF8574AP |
'|-------------|----------------------------|----------------------|
'|  A0  A1  A2 |     Чтение  |   Запись     |   Чтение  |  Запись  |
'|-------------|-------------|--------------|-----------|----------|
'|  0   0   0  |      &H40   |     &H41     |    &H70   |   &H71   |
'|  1   0   0  |      &H42   |     &H43     |    &H72   |   &H73   |
'|  0   1   0  |      &H44   |     &H45     |    &H74   |   &H75   |
'|  1   1   0  |      &H46   |     &H47     |    &H76   |   &H77   |
'|  0   0   1  |      &H48   |     &H49     |    &H78   |   &H79   |
'|  1   0   1  |      &H4A   |     &H4B     |    &H7A   |   &H7B   |
'|  0   1   1  |      &H4C   |     &H4D     |    &H7C   |   &H7D   |
'|  1   1   1  |      &H4E   |     &H4F     |    &H7E   |   &H7F   |
'------------------------------------------------------------------
'-------------------------------------------------------------------------------

  Const Чтение_клавиатуры_pcf8574 = &H40
  Const Запись_клавиатуры_pcf8574 = &H41

  Const Чтение_клавиатуры_pcf8574a = &H70
  Const Запись_клавиатуры_pcf8574a = &H71

  Const Чтение_бегущий_огонь_pcf8574a = &H72
  Const Запись_бегущий_огонь_pcf8574a = &H73

'  Const Чтение_клавиатуры_pcf8575 = &H40
'  Const Запись_клавиатуры_pcf8575 = &H41

  Const Чтение_выхода_pcf8574 = &H42
  Const Запись_выхода_pcf8574 = &H43

'  Const Чтение_выхода_pcf8575 = &H42
'  Const Запись_выхода_pcf8575 = &H43

'-------------------------------------------------------------------------------
'-------------------------   Сброс выхода на PCF8574   -------------------------
'-------------------------------------------------------------------------------
  Const Сброс = &B00000000
  I2csend Запись_выхода_pcf8574 , Сброс
'-------------------------------------------------------------------------------
'--------------   Настройка прерывания клавиатуры на PCF8574   -----------------
'-------------------------------------------------------------------------------
  Config Pind.3 = Input       ' Настраиваем вывод на вход
  Set Portd.3
  Config Int1 = Falling       ' Прерывание срабатывает по спаду уровня   Rising ; Falling ; Low Level
  On Int1 Прерывание_клавиатуры       'Nosave       '> После прерывания идем в подпрограмму обработки прерывания с Ds1307
  Const Антидребезг = 0       ' Значение антидребезга (используется в подпрограмме "Клавиатура"
'-------------------------------------------------------------------------------
'------------------   Конфигурация выхода для светодиодика   -------------------
'-------------------------------------------------------------------------------
  Config Portc.0 = Output       ' Натраиваем порт на выход
  Светодиод Alias Portc.0       ' Присваиваем собственное имя ножке порта контроллера
'-------------------------------------------------------------------------------
'--------------------   Конфигурация выхода для пищалки   ----------------------
'-------------------------------------------------------------------------------
  Config Portb.7 = Output       ' Натраиваем порт на выход
  Пищалка Alias Portb.7       ' Присваиваем собственное имя ножке порта контроллера
  Dim Задержка_пищалки As Byte
  Задержка_пищалки = 30
'-------------------------------------------------------------------------------
'------------------------   Конфигурация переменных   --------------------------
'-------------------------------------------------------------------------------

  Defbit Вывод_выхода As Bit       ' Множественная переменная для хранения значений коммутированого выхода
  Dim Коммутация_выхода As Byte       ' Переменная для хранения значений коммутации выхода
  Dim Код_нажатой_кнопки As Byte       ' Переменная для хранения значений кода нажатой кнопки
  Dim Флаг_нажатия_кнопки As Byte       ' Переменная для хранения информации о том, что была нажата одна из кнопок клавиатуры
  Dim Счетчик_кнопка_нажата As Byte       ' Переменная для хранения информации о продолжительности нажатия кнопки
  Dim Флаг_есть_новые_данные As Byte       ' Флаг сигнализирующий о необходимости обновления LCD
  Dim Флаг_прочитать_клавиатуру As Byte       ' Флаг сигнализирующий о произошедшем нажатии кнопки клавиатуры, и появившейся возможности считать код нажатой кнопки

'-------------------------------------------------------------------------------
  Dim Бегущий_огонь_byte As Byte

  Бегущий_огонь_byte = &B00000001
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
  Enable Int1

  Enable Interrupts ' Разрешаем работу прерываний
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
  Do : Nop
'-------------------------------------------------------------------------------
  Главный_цикл:
'-------------------------------------------------------------------------------

    If Флаг_прочитать_клавиатуру = 1 Then Rcall Обработка_клавиатуры

    If Флаг_есть_новые_данные = 1 Then Rcall Вывод_на_lcd

    rcall Бегущий_огонь

Waitms 100
'-------------------------------------------------------------------------------
'-----------------   Засыпаем, ждем, когда что нибудь нажмется   ---------------
'-------------------------------------------------------------------------------
'  Idle
'-------------------------------------------------------------------------------
'--------------------------   Переходим на метку   -----------------------------
'-------------------------------------------------------------------------------
  Goto Главный_цикл
'-------------------------------------------------------------------------------
  Loop : End
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'*************   Подпрограмма чтения кода нажатой кнопки PCF8574   *************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Чтение_кода_нажатой_кнопки:
'-------------------------------------------------------------------------------
    I2creceive Чтение_клавиатуры_pcf8574 , Код_нажатой_кнопки       'Короткий вариант чтения данных с PCF8574A key

    If Код_нажатой_кнопки > 0 And Код_нажатой_кнопки < 255 Then Флаг_нажатия_кнопки = 1
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'***************   Подпрограмма чтения состояния выхода PCF8574   **************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Чтение_коммутации_выхода:
'-------------------------------------------------------------------------------
    I2creceive Чтение_выхода_pcf8574 , Коммутация_выхода       ' Короткий вариант чтения данных с PCF8574 Выход
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'**************   Подпрограмма записи состояния выхода PCF8574   ***************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Запись_коммутации_выхода:
'-------------------------------------------------------------------------------
    I2csend Запись_выхода_pcf8574 , Коммутация_выхода       ' Короткий вариант записи данных в PCF8574 Выход
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
  Обработка_клавиатуры:
'-------------------------------------------------------------------------------
   If Флаг_нажатия_кнопки = 1 Then

       Waitms Антидребезг

       rCall Чтение_кода_нажатой_кнопки

       Incr Счетчик_кнопка_нажата

       If Счетчик_кнопка_нажата > 2 And Код_нажатой_кнопки = 255 Then Флаг_нажатия_кнопки = 0

     Else

       Счетчик_кнопка_нажата = 0

      Goto Выход_обработка_клавиатуры

   End If
'------------------------------------------------
   rCall Чтение_коммутации_выхода
'------------------------------------------------
      Select Case Код_нажатой_кнопки
     '------------------------------------------------
       Case Is = 0 : Goto Выход_обработка_клавиатуры
     '------------------------------------------------
       Case Is = 255 : Goto Выход_обработка_клавиатуры
     '------------------------------------------------
       Case Is = 254 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_0 = Коммутация_выхода.0
                           Toggle Вывод_выхода_0
                           Коммутация_выхода.0 = Вывод_выхода_0

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 253 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_1 = Коммутация_выхода.1
                           Toggle Вывод_выхода_1
                           Коммутация_выхода.1 = Вывод_выхода_1

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 251 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_2 = Коммутация_выхода.2
                           Toggle Вывод_выхода_2
                           Коммутация_выхода.2 = Вывод_выхода_2

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 247 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_3 = Коммутация_выхода.3
                           Toggle Вывод_выхода_3
                           Коммутация_выхода.3 = Вывод_выхода_3

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 239 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_4 = Коммутация_выхода.4
                           Toggle Вывод_выхода_4
                           Коммутация_выхода.4 = Вывод_выхода_4

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 223 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_5 = Коммутация_выхода.5
                           Toggle Вывод_выхода_5
                           Коммутация_выхода.5 = Вывод_выхода_5

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 191 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_6 = Коммутация_выхода.6
                           Toggle Вывод_выхода_6
                           Коммутация_выхода.6 = Вывод_выхода_6

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 127 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_7 = Коммутация_выхода.7
                           Toggle Вывод_выхода_7
                           Коммутация_выхода.7 = Вывод_выхода_7

                           rCall Bip_bip
                         Else
                       End If
'------------------------------------------------
       End Select

       rcall Запись_коммутации_выхода

       Флаг_прочитать_клавиатуру = 0
'------------------------------------------------
     Выход_обработка_клавиатуры:
       Флаг_есть_новые_данные = 1
'------------------------------------------------
    Gifr = 64
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
  Bip_bip:
'-------------------------------------------------------------------------------
    Set Пищалка

    Waitms Задержка_пищалки

    Reset Пищалка
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'******************   Подпрограмма прерывания клавиатуры   *********************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Прерывание_клавиатуры:
'-------------------------------------------------------------------------------
    Флаг_нажатия_кнопки = 1

    Флаг_прочитать_клавиатуру = 1

'    Gifr = 64
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'***********************  Подпрограмма вывода на LCD  **************************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Вывод_на_lcd:
'-------------------------------------------------------------------------------
    Буфер_lcd_string = Str(код_нажатой_кнопки)

    Буфер_lcd_string = Format(буфер_lcd_string , "  0")

    Locate 1 , 1
    Lcd Буфер_lcd_string

    Флаг_есть_новые_данные = 0
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'**********************   Подпрограмма бегущий огонь   *************************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Бегущий_огонь:
'-------------------------------------------------------------------------------

    Rotate Бегущий_огонь_byte , Left

    I2csend Запись_бегущий_огонь_pcf8574a , Бегущий_огонь_byte

'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------

http://s4.uploads.ru/t/gRSy9.jpg

http://s5.uploads.ru/t/e76EO.jpg http://s5.uploads.ru/t/U84Ke.jpg

Видео, выложено на файлообменник (~16 Mb) в формате МР4, поэтому кто с мобильных устройств, сделайте выводы  -  скачать

Исходник, эмуляция  -  скачать

+1

9

PCF8575 - 16-ти канальный, дунаправленный расширитель порта

Будьте внимательны, от буквы в конце названия PCF8574x, зависит адресация микросхемы !!!

Адресация PCF8574, PCF8574N, PCF8574A, PCF8575

'------------------------------------------------------------------
'|             |  PCF8574,PCF8574N, PCF8575 |  PCF8574A, PCF8574AP |
'|-------------|----------------------------|----------------------|
'|  A0  A1  A2 |     Чтение  |   Запись     |   Чтение  |  Запись  |
'|-------------|-------------|--------------|-----------|----------|
'|  0   0   0  |      &H40   |     &H41     |    &H70   |   &H71   |
'|  1   0   0  |      &H42   |     &H43     |    &H72   |   &H73   |
'|  0   1   0  |      &H44   |     &H45     |    &H74   |   &H75   |
'|  1   1   0  |      &H46   |     &H47     |    &H76   |   &H77   |
'|  0   0   1  |      &H48   |     &H49     |    &H78   |   &H79   |
'|  1   0   1  |      &H4A   |     &H4B     |    &H7A   |   &H7B   |
'|  0   1   1  |      &H4C   |     &H4D     |    &H7C   |   &H7D   |
'|  1   1   1  |      &H4E   |     &H4F     |    &H7E   |   &H7F   |
'------------------------------------------------------------------

Пример использования микросхем PCF8575x

'*******************************************************************************
' $regfile = "m32def.dat" : $crystal = 8000000 : $hwstack = 80 : $swstack = 80 : $framesize = 80
'-------------------------------------------------------------------------------
  $regfile = "m8def.dat" : $crystal = 1000000 : $framesize = 32 : $hwstack = 40 : $swstack = 40 : $baud = 4800       '1200     '2400     '4800     '9600     '19200     '38400     '57600     '115000
'*******************************************************************************
'-------------------------------------------------------------------------------
  Config Lcdpin = Pin , Rs = Portb.0 , E = Portb.1 , Db4 = Portb.2 , Db5 = Portb.3 , Db6 = Portb.4 , Db7 = Portb.5
  Config Lcd = 20 * 4       ' Используемый LCD
  Initlcd           ' Инициализируем LCD
  Waitms 50         ' Ждем пока все запустится
  Cursor Off Noblink       ' Выключаем неморгающий курсор
'  Cursor On Noblink         ' Включаем неморгающий курсор
'  Cursor On Blink           ' Включаем моргающий курсор
  Cls               ' Чистим экран, на всякий случай

  Dim Буфер_lcd_string As String * 20
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'*****************                                       ***********************
'*****************         Конфигурация шины I2c         ***********************
'*****************        микросхема часов DS1307        ***********************
'*****************                                       ***********************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Config Sda = Portc.4       ' Конфигурация порта
  Config Scl = Portc.5       ' Конфигурация порта
  Config I2cdelay = 5       ' Задержки i2c "10 - 100кГц, 5 - 200кГц, 2 - 500кГц, 1 - 1Мгц" - для стабильной работы чем длиннее провода тем меньше частота
  I2cinit           ' Инициализация i2c
  Dim Инициализация_i2c As Byte
'-------------------------------------------------------------------------------
'------------------------------------------------------------------
'|             |  PCF8574,PCF8574N, PCF8575 |  PCF8574A, PCF8574AP |
'|-------------|----------------------------|----------------------|
'|  A0  A1  A2 |     Чтение  |   Запись     |   Чтение  |  Запись  |
'|-------------|-------------|--------------|-----------|----------|
'|  0   0   0  |      &H40   |     &H41     |    &H70   |   &H71   |
'|  1   0   0  |      &H42   |     &H43     |    &H72   |   &H73   |
'|  0   1   0  |      &H44   |     &H45     |    &H74   |   &H75   |
'|  1   1   0  |      &H46   |     &H47     |    &H76   |   &H77   |
'|  0   0   1  |      &H48   |     &H49     |    &H78   |   &H79   |
'|  1   0   1  |      &H4A   |     &H4B     |    &H7A   |   &H7B   |
'|  0   1   1  |      &H4C   |     &H4D     |    &H7C   |   &H7D   |
'|  1   1   1  |      &H4E   |     &H4F     |    &H7E   |   &H7F   |
'------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------------------------   Адресация для выхода   ----------------------------
'-------------------------------------------------------------------------------
  Const Чтение_выхода_pcf8575 = &H42
  Const Запись_выхода_pcf8575 = &H43
'-------------------------------------------------------------------------------
'-----------------------   Адресация для клавиатуры   --------------------------
'-------------------------------------------------------------------------------
  Const Чтение_клавиатуры_pcf8575 = &H40
  Const Запись_клавиатуры_pcf8575 = &H41
'-------------------------------------------------------------------------------
'-----------------------   Адресация для бегущего огня   -----------------------
'-------------------------------------------------------------------------------
  Const Чтение_бегущий_огонь_pcf8575 = &H4E
  Const Запись_бегущий_огонь_pcf8575 = &H4F
'-------------------------------------------------------------------------------
'-------------------------   Сброс выхода на PCF8574   -------------------------
'-------------------------------------------------------------------------------
  Dim Коммутация_выхода As Word       ' Переменная для хранения значений коммутации выхода
  Коммутация_выхода = 0
'-------------------------------------------------------------------------------
'!!! Пишем в PCF8575 значение переменной за 2 прохода, почему-то заработал только этот вариант!
'-------------------------------------------------------------------------------
  I2csend Запись_выхода_pcf8575 , Коммутация_выхода , 2       ' Пишем в PCF8575 значение переменной за 2 прохода, почему-то заработал только этот вариант!
'-------------------------------------------------------------------------------
'--------------   Настройка прерывания клавиатуры на PCF8575   -----------------
'-------------------------------------------------------------------------------
  Config Pind.3 = Input       ' Настраиваем вывод на вход
  Set Portd.3
  Config Int1 = Falling       ' Прерывание срабатывает по спаду уровня   Rising ; Falling ; Low Level
  On Int1 Прерывание_клавиатуры       'Nosave       '> После прерывания идем в подпрограмму обработки прерывания с клавиатуры на PCF8575
  Const Антидребезг = 0       ' Значение антидребезга (используется в подпрограмме "Клавиатура"
'-------------------------------------------------------------------------------
'------------------   Конфигурация выхода для светодиодика   -------------------
'-------------------------------------------------------------------------------
  Config Portc.0 = Output       ' Натраиваем порт на выход
  Светодиод Alias Portc.0       ' Присваиваем собственное имя ножке порта контроллера
'-------------------------------------------------------------------------------
'--------------------   Конфигурация выхода для пищалки   ----------------------
'-------------------------------------------------------------------------------
  Config Portb.7 = Output       ' Натраиваем порт на выход
  Пищалка Alias Portb.7       ' Присваиваем собственное имя ножке порта контроллера
  Dim Задержка_пищалки As Byte
  Задержка_пищалки = 30
'-------------------------------------------------------------------------------
'------------------------   Конфигурация переменных   --------------------------
'-------------------------------------------------------------------------------

  Defbit Вывод_выхода As Bit       ' Множественная переменная для хранения значений коммутированого выхода
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  Dim Код_нажатой_кнопки As Word       ' Переменная для хранения значений кода нажатой кнопки
'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  Dim Флаг_нажатия_кнопки As Byte       ' Переменная для хранения информации о том, что была нажата одна из кнопок клавиатуры
  Dim Счетчик_кнопка_нажата As Byte       ' Переменная для хранения информации о продолжительности нажатия кнопки
  Dim Флаг_есть_новые_данные As Byte       ' Флаг сигнализирующий о необходимости обновления LCD
  Dim Флаг_прочитать_клавиатуру As Byte       ' Флаг сигнализирующий о произошедшем нажатии кнопки клавиатуры, и появившейся возможности считать код нажатой кнопки

'-------------------------------------------------------------------------------
  Dim Бегущий_огонь_word As Word

  Бегущий_огонь_word = 1
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
  Enable Int1

  Enable Interrupts ' Разрешаем работу прерываний
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
  Do : Nop
'-------------------------------------------------------------------------------
  Главный_цикл:
'-------------------------------------------------------------------------------

    If Флаг_прочитать_клавиатуру = 1 Then Rcall Обработка_клавиатуры

    If Флаг_есть_новые_данные = 1 Then Rcall Вывод_на_lcd

    rcall Бегущий_огонь

Waitms 100
'-------------------------------------------------------------------------------
'-----------------   Засыпаем, ждем, когда что нибудь нажмется   ---------------
'-------------------------------------------------------------------------------
'  Idle
'-------------------------------------------------------------------------------
'--------------------------   Переходим на метку   -----------------------------
'-------------------------------------------------------------------------------
  Goto Главный_цикл
'-------------------------------------------------------------------------------
  Loop : End
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'*************   Подпрограмма чтения кода нажатой кнопки PCF8575   *************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Чтение_кода_нажатой_кнопки:
'-------------------------------------------------------------------------------
    I2creceive Чтение_клавиатуры_pcf8575 , Код_нажатой_кнопки , 0 , 2       'Короткий вариант чтения данных с PCF8575 key

    If Код_нажатой_кнопки > 0 And Код_нажатой_кнопки < 65535 Then Флаг_нажатия_кнопки = 1
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'***************   Подпрограмма чтения состояния выхода PCF8575   **************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Чтение_коммутации_выхода:
'-------------------------------------------------------------------------------
    I2creceive Чтение_выхода_pcf8575 , Коммутация_выхода , 0 , 2       ' Короткий вариант чтения данных с PCF8575 Выход
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'**************   Подпрограмма записи состояния выхода PCF8575   ***************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Запись_коммутации_выхода:
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'!!! Пишем в PCF8574 значение переменной за 2 прохода, почему-то заработал только этот вариант!
'-------------------------------------------------------------------------------
    I2csend Запись_выхода_pcf8575 , Коммутация_выхода , 2       ' Пишем в PCF8574 значение переменной за 2 прохода, почему-то заработал только этот вариант!
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'**************   Подпрограмма обработки клавиатуры на PCF8575   ***************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Обработка_клавиатуры:
'-------------------------------------------------------------------------------
   If Флаг_нажатия_кнопки = 1 Then

       Waitms Антидребезг

       rCall Чтение_кода_нажатой_кнопки

       Incr Счетчик_кнопка_нажата

       If Счетчик_кнопка_нажата > 2 And Код_нажатой_кнопки = 65535 Then Флаг_нажатия_кнопки = 0

     Else

       Счетчик_кнопка_нажата = 0

      Goto Выход_обработка_клавиатуры

   End If
'------------------------------------------------
   rCall Чтение_коммутации_выхода
'------------------------------------------------
      Select Case Код_нажатой_кнопки
     '------------------------------------------------
       Case Is = 0 : Goto Выход_обработка_клавиатуры
     '------------------------------------------------
       Case Is = 65535 : Goto Выход_обработка_клавиатуры
     '------------------------------------------------
       Case Is = 65534 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_0 = Коммутация_выхода.0       ' Вытаскиваем нужный бит
                           Toggle Вывод_выхода_0       ' инвертируем, то, что вытащили
                           Коммутация_выхода.0 = Вывод_выхода_0       ' закидываем, то, что инвертировали, назад в переменную

                           rCall Bip_bip       ' пищим
                         Else
                       End If
     '------------------------------------------------
       Case Is = 65533 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_1 = Коммутация_выхода.1
                           Toggle Вывод_выхода_1
                           Коммутация_выхода.1 = Вывод_выхода_1

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 65531 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_2 = Коммутация_выхода.2
                           Toggle Вывод_выхода_2
                           Коммутация_выхода.2 = Вывод_выхода_2

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 65527 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_3 = Коммутация_выхода.3
                           Toggle Вывод_выхода_3
                           Коммутация_выхода.3 = Вывод_выхода_3

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 65519 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_4 = Коммутация_выхода.4
                           Toggle Вывод_выхода_4
                           Коммутация_выхода.4 = Вывод_выхода_4

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 65503 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_5 = Коммутация_выхода.5
                           Toggle Вывод_выхода_5
                           Коммутация_выхода.5 = Вывод_выхода_5

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 65471 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_6 = Коммутация_выхода.6
                           Toggle Вывод_выхода_6
                           Коммутация_выхода.6 = Вывод_выхода_6

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 65407 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_7 = Коммутация_выхода.7
                           Toggle Вывод_выхода_7
                           Коммутация_выхода.7 = Вывод_выхода_7

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 65279 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_8 = Коммутация_выхода.8
                           Toggle Вывод_выхода_8
                           Коммутация_выхода.8 = Вывод_выхода_8

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 65023 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_9 = Коммутация_выхода.9
                           Toggle Вывод_выхода_9
                           Коммутация_выхода.9 = Вывод_выхода_9

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 64511 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_10 = Коммутация_выхода.10
                           Toggle Вывод_выхода_10
                           Коммутация_выхода.10 = Вывод_выхода_10

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 63487 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_11 = Коммутация_выхода.11
                           Toggle Вывод_выхода_11
                           Коммутация_выхода.11 = Вывод_выхода_11

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 61439 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_12 = Коммутация_выхода.12
                           Toggle Вывод_выхода_12
                           Коммутация_выхода.12 = Вывод_выхода_12

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 57343 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_13 = Коммутация_выхода.13
                           Toggle Вывод_выхода_13
                           Коммутация_выхода.13 = Вывод_выхода_13

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 49151 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_14 = Коммутация_выхода.14
                           Toggle Вывод_выхода_14
                           Коммутация_выхода.14 = Вывод_выхода_14

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 32767 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_15 = Коммутация_выхода.15
                           Toggle Вывод_выхода_15
                           Коммутация_выхода.15 = Вывод_выхода_15

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       End Select
     '------------------------------------------------

       rcall Запись_коммутации_выхода

       Флаг_прочитать_клавиатуру = 0
'------------------------------------------------
     Выход_обработка_клавиатуры:
       Флаг_есть_новые_данные = 1
'------------------------------------------------
    Gifr = 64
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
  Bip_bip:
'-------------------------------------------------------------------------------
    Set Пищалка

    Waitms Задержка_пищалки

    Reset Пищалка
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'******************   Подпрограмма прерывания клавиатуры   *********************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Прерывание_клавиатуры:
'-------------------------------------------------------------------------------
    Флаг_нажатия_кнопки = 1

    Флаг_прочитать_клавиатуру = 1

'    Gifr = 64
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'***********************  Подпрограмма вывода на LCD  **************************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Вывод_на_lcd:
'-------------------------------------------------------------------------------
    Буфер_lcd_string = Str(код_нажатой_кнопки)

    Буфер_lcd_string = Format(буфер_lcd_string , "  0")

    Locate 1 , 1
    Lcd Буфер_lcd_string

    Флаг_есть_новые_данные = 0
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'**********************   Подпрограмма бегущий огонь   *************************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Бегущий_огонь:
'-------------------------------------------------------------------------------

    Rotate Бегущий_огонь_word , Left       ' Сдвигаем бит в переменной

    I2csend Запись_бегущий_огонь_pcf8575 , Бегущий_огонь_word , 2       ' Пишем в PCF8575

'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------

http://s5.uploads.ru/t/ietHl.jpg

Исходник, эмуляция в "Протеус" - скачать

Документация на PCF8575 - скачать

К сожалению видео работы в железе не будет (нет в наличии микросхем).

+1

10

Будьте внимательны, от буквы в конце названия PCF8574x, зависит адресация микросхемы !!!

Ещё одно извращение, хотя, как знать, может кому и пригодится.

8-ми разрядная 7-seg LED индикация по шине I2c, через 2хPCF8574.

Адресация PCF8574, PCF8574N, PCF8574A, PCF8575

'------------------------------------------------------------------
'|             |  PCF8574,PCF8574N, PCF8575 |  PCF8574A, PCF8574AP |
'|-------------|----------------------------|----------------------|
'|  A0  A1  A2 |     Чтение  |   Запись     |   Чтение  |  Запись  |
'|-------------|-------------|--------------|-----------|----------|
'|  0   0   0  |      &H40   |     &H41     |    &H70   |   &H71   |
'|  1   0   0  |      &H42   |     &H43     |    &H72   |   &H73   |
'|  0   1   0  |      &H44   |     &H45     |    &H74   |   &H75   |
'|  1   1   0  |      &H46   |     &H47     |    &H76   |   &H77   |
'|  0   0   1  |      &H48   |     &H49     |    &H78   |   &H79   |
'|  1   0   1  |      &H4A   |     &H4B     |    &H7A   |   &H7B   |
'|  0   1   1  |      &H4C   |     &H4D     |    &H7C   |   &H7D   |
'|  1   1   1  |      &H4E   |     &H4F     |    &H7E   |   &H7F   |
'------------------------------------------------------------------

! Обратите ВНИМАНИЕ, ULN2803 управляется лог. "0", а TD62783 лог. "1" !
В исходнике необходимо инвертировать сегменты или разряды, в зависимости от используемых индикаторов (ОА или ОК).

Если большие индикаторы не нужны, можно обойтись без ключей "Дарлингтона" (ULN2803, TD62783).
В этом случае подтяните "+" или "-" резисторами от 100 Ом выходы PCF8574 (разряды), в зависимости от применяемых 7-seg LED индикаторов.

Исходник. Общий, для ОА и ОК

'*******************************************************************************
'******************     Поразрядная 7-seg LED индикация     ********************
'*******************************************************************************

' Контроллер: ATMEGA8A или любой другой "AVR" с небольшими переделками исходника
' Версия компилятора: BASCOM-AVR 2.0.7.1
' Автор: sasha_1973

'*******************************************************************************
'-------------------------------------------------------------------------------
'---------------     Конфигурация используемого контроллера     ----------------
'-------------------------------------------------------------------------------
  $regfile = "m8def.dat" : $crystal = 8000000 : $hwstack = 40 : $swstack = 16 : $framesize = 32
'-------------------------------------------------------------------------------
'*******************************************************************************
'*****************                                       ***********************
'*****************         Конфигурация шины I2c         ***********************
'*****************        микросхема часов DS1307        ***********************
'*****************                                       ***********************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Config Sda = Portc.4       ' Конфигурация порта
  Config Scl = Portc.5       ' Конфигурация порта
  Config I2cdelay = 1       ' Задержки i2c "10 - 100кГц, 5 - 200кГц, 2 - 500кГц, 1 - 1Мгц" - для стабильной работы чем длиннее провода тем меньше частота
  I2cinit           ' Инициализация i2c
  Dim Инициализация_i2c As Byte
'-------------------------------------------------------------------------------
'------------------------------------------------------------------
'|             |  PCF8574,PCF8574N, PCF8575 |  PCF8574A, PCF8574AP |
'|-------------|----------------------------|----------------------|
'|  A0  A1  A2 |     Чтение  |   Запись     |   Чтение  |  Запись  |
'|-------------|-------------|--------------|-----------|----------|
'|  0   0   0  |      &H40   |     &H41     |    &H70   |   &H71   |
'|  1   0   0  |      &H42   |     &H43     |    &H72   |   &H73   |
'|  0   1   0  |      &H44   |     &H45     |    &H74   |   &H75   |
'|  1   1   0  |      &H46   |     &H47     |    &H76   |   &H77   |
'|  0   0   1  |      &H48   |     &H49     |    &H78   |   &H79   |
'|  1   0   1  |      &H4A   |     &H4B     |    &H7A   |   &H7B   |
'|  0   1   1  |      &H4C   |     &H4D     |    &H7C   |   &H7D   |
'|  1   1   1  |      &H4E   |     &H4F     |    &H7E   |   &H7F   |
'------------------------------------------------------------------
'-------------------------------------------------------------------------------

  Const Чтение_сегменты_pcf8574 = &H7E
  Const Запись_сегменты_pcf8574 = &H7F

  Const Чтение_разряды_pcf8574 = &H70
  Const Запись_разряды_pcf8574 = &H71

  Const Разряды_set = &B11111111
  Const Разряды_reset = &B00000000

' ------------------------------------------------------------------------------

'  Немного отвлечемся.
'  Бытует мнение, что компилятор не дружит с кирилицей.
'  Исходя из личного опыта могу сказать, конфликтов не наблюдалось.
'  Единсвенное ограничение - количество символов в именах. Думаю Вам хватит с избытком.

'-------------------------------------------------------------------------------
'-----------------     Определение переменных и констант     -------------------
'-------------------------------------------------------------------------------
Начальные_настройки:       ' Просто метка, для удобства
'-------------------------------------------------------------------------------

  Dim Тип_индикатора_1_канал As Byte       ' Переменная, для хранения значения типа индикатора
  Тип_индикатора_1_канал = 0       ' Если тип_индикатора = 1 , то ОК , если Тип_индикатора = 0 , То ОA

  Dim Тип_индикатора_2_канал As Byte       ' Переменная, для хранения значения типа индикатора
  Тип_индикатора_2_канал = 0       ' Если тип_индикатора = 1 , то ОK , если Тип_индикатора = 0 , То ОA

'-------------------------------------

  Const Общее_количество_разрядов = 8       ' Переменная, для хранения значения общего количества используемых разрядов

  Const Скорость_изменения_переменной = 50       ' Переменная, для хранения значения задержки "Waitms"
  Const Значение_регистра_tcnt0_timer0 = 250       ' Переменная, для хранения значения регистра TCNT0

'-------------------------------------------------------------------------------
  Dim Разряд As Byte

  Dim Цикл_led As Byte       ' Переменная, для хранения количества выводимых разрядов (нужна для разбивки значения на разряды)
  Dim Счетчик_миганий As Word       ' Счетчик для обработки частоты и длительности мигания
  Dim Частота_мигания As Word       ' Переменная, для хранения значения частоты мигания при Флаг_мигание(n) = 1
  Dim Счетчик_разрядов As Byte       ' Счетчик перебора разрядов
  Dim Переменная_word_1 As Word       ' Переменная, которую будем менять
  Dim Переменная_word_2 As Word       ' Переменная, которую будем менять
  Dim Выводимая_цифра_led As Byte       ' Переменная, для загрузки цифр в порт
  Dim Выводимые_данные_led As Word       ' Переменная, для хранения выводимых данных
  Dim Копия_выводимые_данные_led As Word       ' Переменная, для временного хранения выводимых данных (нужна для разбивки значения на разряды)
  Dim 1_канал_выводимые_данные_led As Word       ' Переменная, для хранения выводимых данных
  Dim 2_канал_выводимые_данные_led As Word       ' Переменная, для хранения выводимых данных
  Dim Длительность_горения_при_мигании As Word       ' Переменная, для хранения значения длительности горения знакоместа при "Флаг_мигание(n) = 1"
  Dim Цифра(общее_количество_разрядов) As Byte       ' Значение разряда для 8-ми разрядов
  Dim Флаг_точка(общее_количество_разрядов) As Byte       ' Флаг точки для 8-ми разрядов
  Dim Флаг_гашение(общее_количество_разрядов) As Byte       ' Флаг гашения нужного разряда для 8-ми разрядов
  Dim Флаг_мигание(общее_количество_разрядов) As Byte       ' Флаг мигания нужного разряда для 8-ми разрядов
  Dim Дополнительный_символ(общее_количество_разрядов) As Byte       ' Переменная, для хранения значения дополнительного символа при Флаг_дополнительный_символ(n) = 1
  Dim Флаг_дополнительный_символ(общее_количество_разрядов) As Byte       ' Флаг сигнализирующий о выводе дополнительных символов для 8-ми разрядов

'-------------------------------------------------------------------------------
'----------------------     Определение подпрограмм     ------------------------
'-------------------------------------------------------------------------------

  Declare Sub Гашение_разрядов()
  Declare Sub Индикация_7seg_led()
  Declare Sub Обработка_прерывания_timer0()

'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'------------     Настройка таймера для обновления LED индикации     -----------
'-------------------------------------------------------------------------------

   Config Timer0 = Timer , Prescale = 64 , Clear Timer = 0

'-------------------------------------------------------------------------------

' Даём понять компилятору, что будем использовать таймер в режиме таймера (простите за каламбур),
' с предварительным делителем "PRESCALE = 1024".
' и что же мы имеем: f(тактовая частота - 4МГц) / 1024(настраиваемый делитель таймера
' (возможные варианты - 1 , 8 , 64 , 256 , 1024)) = 3906.25 тактов МК будет проходить,
'пока сработает прерывание от переполнения таймера. так, как перед этим мы проштудировали Datasheet
'и выяснили, что "TIMER0" , считает до 256, то 3 906,25 / 256 ~ 15,26 раз в секунду
'будет обновлятся наша Led индикация (при 8-ми разрядной динамической индикации мы получим ~ 15,26 / 8 = "пшик",
'Это Просто Катастрофа). К нашей великой радости, разработчики "Atmel" продумали этот момент,
'у таймера есть различные регистры, которыми можно манипулировать.
'В данном, конкретном случае, нас интересует регистр "TCNT0". Tcnt0 - 8-ми разрядный(от 0 До 255) регистр таймера - счетчика(TIMER0).
'именно он используетя таймером для счета. Вот его мы, и будем использовать.

'-------------------------------------------------------------------------------
'    Настройка дополнительного делителя таймера для обновления LED индикации
'-------------------------------------------------------------------------------

'  Tcnt0 = Значение_регистра_tcnt0_timer0       ' Настройка дополнительного делителя таймера (значение = 250)

'--------------------------------------------------------------------------------

'И чего мы добились, да просто "TIMER0" будет считать не с "0", а с нашего значения.
'Посчитаем ещё раз: 4000000 / 1024 / (256-(значение Tcnt0)) =  3 906,25 / 6 ~ 651
'прерывание "TIMER0" в секунду, или 1000(ms) /  651 ~ 1,536 ms,
'это и будет частотой обновления нашей  7-seg LED индикации.

'Идем дальше.

'Итак, что мы имеем: порты настроены, периодичность обновления установлена,
'а вот, что будет происходить после прерывания "TIMER0", мы не написали,
'исправляемся.

'Назначим подпрограмму, которая будет выполняться после каждого прерывания таймера.

'-------------------------------------------------------------------------------
'-----------     Подпрограмма выполняемая после прерывания TIMER0     ----------
'-------------------------------------------------------------------------------

   On Timer0 Обработка_прерывания_timer0       ' Переход на подпрограмму после каждого прерывания TIMER0

'-----------------------     Первоначальные установки    -----------------------
'-------------------------------------------------------------------------------

  Переменная_word_1 = 0       ' Значение, которое будем увеличивать
  Переменная_word_2 = 50       ' Значение, которое будем уменьшать

  Частота_мигания = 300       ' Значение частоты мигания знакоместа на LED дисплее при "Флаг_мигание(n) = 1"
  Длительность_горения_при_мигании = Частота_мигания / 2       ' Значение длительности горения знакоместа на LED дисплее при "Флаг_мигание(n) = 1"

'-------------------------------------------------------------------------------
'------------------------     Работа с прерываниями     ------------------------
'-------------------------------------------------------------------------------

    Enable Timer0   ' Разрешаем работу прерывания по ПЕРЕПОЛНЕНИЮ  таймера

    Enable Interrupts       ' Разрешаем работу всех прерываний

'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'--------------------------     Начало программы     ---------------------------
'-------------------------------------------------------------------------------

  Do : Nop          ' Крутимся между Do и Loop, ожидая прерывания TIMER0, для обновления LED индикации

'--------------------------

    Incr Переменная_word_1       ' Считаем, просто для примера
    If Переменная_word_1 > 9999 Then Переменная_word_1 = 0       ' Если досчитали до 9999, сбрасываем счетчик
    1_канал_выводимые_данные_led = Переменная_word_1       ' Будем выводить в 1 канал (первые 4 разряда)

    Decr Переменная_word_2       ' Уменьшаем переменную
    2_канал_выводимые_данные_led = Переменная_word_2       ' Будем выводить в 2 канал (первые 4 разряда)

    If Переменная_word_2 = 0 Then       ' Если досчитали до 0, выводим "stop", и мигаем
        Флаг_дополнительный_символ(5) = 1 : Дополнительный_символ(5) = 5       ' символ "S"
        Флаг_дополнительный_символ(6) = 1 : Дополнительный_символ(6) = 14       ' символ "t"
        Флаг_дополнительный_символ(7) = 1 : Дополнительный_символ(7) = 15       ' символ "o"
        Флаг_дополнительный_символ(8) = 1 : Дополнительный_символ(8) = 28       ' символ "P"

        Флаг_мигание(5) = 1       ' Мигаем 5 разрядом
        Флаг_мигание(6) = 1       ' Мигаем 6 разрядом
        Флаг_мигание(7) = 1       ' Мигаем 7 разрядом
        Флаг_мигание(8) = 1       ' Мигаем 8 разрядом

    End If

    Waitms Скорость_изменения_переменной       ' Задержка, для частоты смены показаний индикаторов

'--------------------------
  Loop
End
'-------------------------------------------------------------------------------
'*******************************************************************************
'*****************   Подпрограмма обработки прерывания TIMER0   ****************
'*****************          происходит каждые 1,536 ms          ****************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Обработка_прерывания_timer0:
'-------------------------------------------------------------------------------
'   Stop Timer0
    Rcall Индикация_7seg_led
'   Start Timer0
'-------------------------------------------------------------------------------
' Делитель TIMER0 = 1000/(4000000/1024/(256-250))=1000/(3 906,25 / 6) = 1,536 ms
'-------------------------------------------------------------------------------

'    Tcnt0 = Значение_регистра_tcnt0_timer0

'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'*****************   Подпрограмма для обработки LED индикации   ****************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Индикация_7seg_led:
'-------------------------------------------------------------------------------
'----------   Смотрим, что будем выводить и делаем копию переменной    ---------
'-------------------------------------------------------------------------------
      Выводимые_данные_led = 1_канал_выводимые_данные_led       '

      Копия_выводимые_данные_led = Выводимые_данные_led
'-------------------------------------------------------------------------------
'------------------   В цикле разбиваем на разряды, с 4 по 1   -----------------
'-------------------------------------------------------------------------------
      For Цикл_led = 4 To 1 Step -1       ' цикл в котором разбивается переменная на 4 числа
          Выводимые_данные_led = Копия_выводимые_данные_led Mod 10
          Цифра(цикл_led) = Выводимые_данные_led       '
          Копия_выводимые_данные_led = Копия_выводимые_данные_led / 10       '
      Next
'-------------------------------------------------------------------------------
'----------   Смотрим, что будем выводить и делаем копию переменной    ---------
'-------------------------------------------------------------------------------
      Выводимые_данные_led = 2_канал_выводимые_данные_led       '

      Копия_выводимые_данные_led = Выводимые_данные_led
'-------------------------------------------------------------------------------
'------------------   В цикле разбиваем на разряды, с 8 по 5   -----------------
'-------------------------------------------------------------------------------
      For Цикл_led = 8 To 5 Step -1       ' цикл в котором разбивается переменная на 4 числа
          Выводимые_данные_led = Копия_выводимые_данные_led Mod 10
          Цифра(цикл_led) = Выводимые_данные_led       '
          Копия_выводимые_данные_led = Копия_выводимые_данные_led / 10       '
      Next
'-------------------------------------------------------------------------------
'----------------------   Гасим все разряды индикатора   -----------------------
'-------------------------------------------------------------------------------
    If Тип_индикатора_1_канал = 1 Then
        I2csend Запись_разряды_pcf8574 , Разряды_set       ' Переход к подпрограмме гашения индикаторов
      Else
        I2csend Запись_разряды_pcf8574 , Разряды_reset       ' Переход к подпрограмме гашения индикаторов
    End If

    If Тип_индикатора_2_канал = 1 Then
        I2csend Запись_разряды_pcf8574 , Разряды_set       ' Переход к подпрограмме гашения индикаторов
      Else
        I2csend Запись_разряды_pcf8574 , Разряды_reset       ' Переход к подпрограмме гашения индикаторов
    End If
'-------------------------------------------------------------------------------
'----   Перебираем разряды, в каждом прерывании выводим следующий разряд   -----
'-------------------------------------------------------------------------------
    Incr Счетчик_разрядов
'-------------------------------------------------------------------------------
'-----   Выбираем разряд для загрузки в обработчик вывода на 7-seg LED    ------
'-------------------------------------------------------------------------------
    If Счетчик_разрядов > Общее_количество_разрядов Then
        Счетчик_разрядов = 1
    End If
'------------------------------------------------------------------------------------
' Участок кода отвечающий за мигание, тушение разрядов и выводит точку в нужном месте
'------------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'----------------------------   Подготовка к миганию  --------------------------
'-------------------------------------------------------------------------------
    Incr Счетчик_миганий

    If Счетчик_миганий > Частота_мигания Then Счетчик_миганий = 1
'-------------------------------------------------------------------------------
'------------------   Если надо, то мигаем в нужных разрядах  ------------------
'-------------------------------------------------------------------------------
    If Флаг_мигание(счетчик_разрядов) = 1 And Счетчик_миганий > Длительность_горения_при_мигании Or Флаг_гашение(счетчик_разрядов) = 1 Then       ' Если флаг мигания этого разряда выставлен и счетчик > 200
        Select Case Счетчик_разрядов
          Case 1 To 4
            If Тип_индикатора_1_канал = 1 Then
                Выводимая_цифра_led = Lookup(11 , Цифры_ok)       ' Выводим пустое место в 1 - 4 разрядах
              Else
                Выводимая_цифра_led = Lookup(11 , Цифры_oa)       ' Выводим пустое место в 1 - 4 разрядах
            End If
          Case 5 To 8
            If Тип_индикатора_2_канал = 1 Then
                Выводимая_цифра_led = Lookup(11 , Цифры_ok)       ' Выводим пустое место в 5 - 8 разрядах
              Else
                Выводимая_цифра_led = Lookup(11 , Цифры_oa)       ' Выводим пустое место в 5 - 8 разрядах
            End If
        End Select
      Else
'-------------------------------------------------------------------------------
'-----------------------   Выводим дополнительные симвоы   ---------------------
'-------------------------------------------------------------------------------
        If Флаг_дополнительный_символ(счетчик_разрядов) = 1 Then
            Select Case Счетчик_разрядов
              Case 1 To 4
                If Тип_индикатора_1_канал = 1 Then
                    Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_ok)       ' Выводим дополнительный_символ в 1 - 4 разрядах
                  Else
                    Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_oa)       ' Выводим дополнительный_символ в 1 - 4 разрядах
                End If
              Case 5 To 8
                If Тип_индикатора_2_канал = 1 Then
                    Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_ok)       ' Выводим дополнительный_символ в 5 - 8 разрядах
                  Else
                    Выводимая_цифра_led = Lookup(дополнительный_символ(счетчик_разрядов) , Цифры_oa)       ' Выводим дополнительный_символ в 5 - 8 разрядах
                End If
            End Select
          Else
'-------------------------------------------------------------------------------
'-------   Если не мигаем и ничего другого не выводим, выводим основное   ------
'-------------------------------------------------------------------------------
            Выводимая_цифра_led = Цифра(счетчик_разрядов)
              Select Case Счетчик_разрядов
                Case 1 To 4
                  If Тип_индикатора_1_канал = 1 Then
                      Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_ok)       ' Если не выводим дополнительную информацию, выводим основную в 1 - 4 разрядах
                    Else
                      Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_oa)       ' Если не выводим дополнительную информацию, выводим основную в 1 - 4 разрядах
                  End If
                Case 5 To 8
                  If Тип_индикатора_2_канал = 1 Then
                      Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_ok)       ' Если не выводим дополнительную информацию, выводим основную в 5 - 8 разрядах
                    Else
                      Выводимая_цифра_led = Lookup(выводимая_цифра_led , Цифры_oa)       ' Если не выводим дополнительную информацию, выводим основную в 5 - 8 разрядах
                  End If
              End Select
        End If
'-------------------------------------------------------------------------------
'-------------   Если необходимо, выводим точку в нужном разряде   -------------
'-------------------------------------------------------------------------------
      If Флаг_точка(счетчик_разрядов) = 1 Then
          Выводимая_цифра_led = Выводимая_цифра_led Xor &H80       '&H80 или &B10000000 добавляем к выводимой цифре точку
      End If
    End If
'-------------------------------------------------------------------------------
'---------------------     Загружаем в порт код цифры     ----------------------
'-------------------------------------------------------------------------------
    I2csend Запись_сегменты_pcf8574 , Выводимая_цифра_led
'-------------------------------------------------------------------------------
'---------------   Включаем соответствующий разряд индикатора   ----------------
'-------------------------------------------------------------------------------
    Select Case Счетчик_разрядов
      Case 1 : If Тип_индикатора_1_канал = 0 Then Разряд = &B00000001 Else Разряд = &B11111110
      Case 2 : If Тип_индикатора_1_канал = 0 Then Разряд = &B00000010 Else Разряд = &B11111101
      Case 3 : If Тип_индикатора_1_канал = 0 Then Разряд = &B00000100 Else Разряд = &B11111011
      Case 4 : If Тип_индикатора_1_канал = 0 Then Разряд = &B00001000 Else Разряд = &B11110111
      Case 5 : If Тип_индикатора_2_канал = 0 Then Разряд = &B00010000 Else Разряд = &B11101111
      Case 6 : If Тип_индикатора_2_канал = 0 Then Разряд = &B00100000 Else Разряд = &B11011111
      Case 7 : If Тип_индикатора_2_канал = 0 Then Разряд = &B01000000 Else Разряд = &B10111111
      Case 8 : If Тип_индикатора_2_канал = 0 Then Разряд = &B10000000 Else Разряд = &B01111111
    End Select
'-------------------------------------------------------------------------------
'---------------------------   Загружаем в PCF8574   ---------------------------
'-------------------------------------------------------------------------------
    I2csend Запись_разряды_pcf8574 , Разряд       ' Короткий вариант записи данных в PCF8574 Выход
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
  Цифры_ok:
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'----------------------------   Можно написать так   ---------------------------
'-------------------------------------------------------------------------------
'    Data &H3F , &H06 , &H5B , &H4F , &H66 , &H6D , &H7D , &H07 , &H7F , &H6F       '0, 1, 2, 3, 4, 5, 6, 7, 8, 9
'    Data &H40 , &H00 , &H63 , &H39 , &H78 , &H5C , &H38 , &H74 , &H5E , &H77       '"-", "", "значек градуса", "С", "t", "o", "L", "h", "d", "A"
'    Data &H58 , &H31 , &H76 , &H79 , &H50 , &H71 , &H1C , &H73 , &H37 , &H80       '"c", "Г", "Н", "E", "r", "F", "U", "u", "P", "П". "."
'    Data &H54       ', &H , &H , &H , &H , &H , &H , &H , &H , &H '"n", "", "", "", "", "", "", "", "", "". ""
'-------------------------------------------------------------------------------
'-------   а можно так, выглядит нагляднее, но работать будет одинаково   ------
'-------------------------------------------------------------------------------
    Data &H3F       ' 0   "0"
    Data &H06       ' 1   "1"
    Data &H5B       ' 2   "2"
    Data &H4F       ' 3   "3"
    Data &H66       ' 4   "4"
    Data &H6D       ' 5   "5"
    Data &H7D       ' 6   "6"
    Data &H07       ' 7   "7"
    Data &H7F       ' 8   "8"
    Data &H6F       ' 9   "9"
    Data &H40       ' 10  "_"
    Data &H00       ' 11  "Пустое место"
    Data &H63       ' 12  "Значек градуса"
    Data &H39       ' 13  "С"
    Data &H78       ' 14  "t"
    Data &H5C       ' 15  "o"
    Data &H38       ' 16  "L"
    Data &H74       ' 17  "h"
    Data &H5E       ' 18  "d"
    Data &H77       ' 19  "A"
    Data &H58       ' 20  "c"
    Data &H31       ' 21  "Г"
    Data &H76       ' 22  "H"
    Data &H79       ' 23  "E"
    Data &H50       ' 24  "r"
    Data &H71       ' 25  "F"
    Data &H3E       ' 26  "U"
    Data &H1C       ' 27  "u"
    Data &H73       ' 28  "P"
    Data &H37       ' 29  "П"
    Data &H80       ' 30  "Точка"
    Data &H54       ' 31  "n"
'-------------------------------------------------------------------------------
  Цифры_oa:
'-------------------------------------------------------------------------------
'    Data &HC0 , &HF9 , &HA4 , &HB0 , &H99 , &H92 , &H82 , &HF8 , &H80 , &H90       '0,1,2,3,4,5,6,7,8,9
'    Data &HBF , &HFF , &H9C , &HC6 , &H87 , &HA3 , &HC7 , &H8B , &HA1 , &H88       '"-", "", "значек градуса", "С", "t", "o", "L", "h", "d", "A"
'    Data &HA7 , &HCE , &H89 , &H86 , &HAF , &H8E , &HC1 , &HE3 , &H8C , &HC8       '"c", "Г", "Н", "E", "r", "F", "U", "u", "P", "П"
'    Data &H7F , &HAB       ', &H , &H , &H , &H , &H , &H , &H , &H , &H ' "." , "n", "", "", "", "", "", "", "", "", "". ""
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'-------   а можно так, выглядит нагляднее, но работать будет одинаково   ------
'-------------------------------------------------------------------------------
    Data &HC0       ' 0   "0"
    Data &HF9       ' 1   "1"
    Data &HA4       ' 2   "2"
    Data &HB0       ' 3   "3"
    Data &H99       ' 4   "4"
    Data &H92       ' 5   "5"
    Data &H82       ' 6   "6"
    Data &HF8       ' 7   "7"
    Data &H80       ' 8   "8"
    Data &H90       ' 9   "9"
    Data &HBF       ' 10  "_"
    Data &HFF       ' 11  "Пустое место"
    Data &H9C       ' 12  "Значек градуса"
    Data &HC6       ' 13  "С"
    Data &H87       ' 14  "t"
    Data &HA3       ' 15  "o"
    Data &HC7       ' 16  "L"
    Data &H8B       ' 17  "h"
    Data &HA1       ' 18  "d"
    Data &H88       ' 19  "A"
    Data &HA7       ' 20  "c"
    Data &HCE       ' 21  "Г"
    Data &H89       ' 22  "H"
    Data &H86       ' 23  "E"
    Data &HAF       ' 24  "r"
    Data &H8E       ' 25  "F"
    Data &HC1       ' 26  "U"
    Data &HE3       ' 27  "u"
    Data &H8C       ' 28  "P"
    Data &HC8       ' 29  "П"
    Data &H7F       ' 30  "Точка"
    Data &HAB       ' 31  "n"
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------

http://s5.uploads.ru/t/ozwVK.jpg http://s4.uploads.ru/t/GtKD5.jpg

Видео работы в железе, выложено на файлообменник (~18 Mb) в формате МР4, поэтому кто с мобильных устройств, сделайте выводы - скачать

Видео работы эмуляции в "Протеус", выложено на файлообменник (~12 Mb) в формате МР4, поэтому кто с мобильных устройств, сделайте выводы - скачать

Схема в формате pdf - скачать

Архив со всем необходимым (эмуляция в "Протеус", исходник, схема, документация на микросхемы) - скачать

+1

11

Кнопки, коммутация чего нибудь (в данном случае бегущий огонь) и LCD20x4, через PCF8574x и 2 ножки МК.

Исходник

'*******************************************************************************
'-------------------------------------------------------------------------------
  $regfile = "m8def.dat"
  $crystal = 8000000
  $framesize = 32
  $hwstack = 40
  $swstack = 40
  $baud = 4800       '1200     '2400     '4800     '9600     '19200     '38400     '57600     '115000
'*******************************************************************************
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
'------------------------   Подключаемые библиотеки   --------------------------
'-------------------------------------------------------------------------------
  $lib "lcd_pcf8574_8.lib"
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'*****************                                       ***********************
'*****************         Конфигурация шины I2c         ***********************
'*****************        микросхема часов DS1307        ***********************
'*****************                                       ***********************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Config Sda = Portc.4       ' Конфигурация порта
  Config Scl = Portc.5       ' Конфигурация порта
  Config I2cdelay = 2       ' Задержки i2c "10 - 100кГц, 5 - 200кГц, 2 - 500кГц, 1 - 1Мгц" - для стабильной работы чем длиннее провода тем меньше частота
  I2cinit           ' Инициализация i2c
  Dim Инициализация_i2c As Byte
'-------------------------------------------------------------------------------
'------------------------------------------------------------------
'|             |  PCF8574,PCF8574N, PCF8575 |  PCF8574A, PCF8574AP |
'|-------------|----------------------------|----------------------|
'|  A0  A1  A2 |     Чтение  |   Запись     |   Чтение  |  Запись  |
'|-------------|-------------|--------------|-----------|----------|
'|  0   0   0  |      &H40   |     &H41     |    &H70   |   &H71   |
'|  1   0   0  |      &H42   |     &H43     |    &H72   |   &H73   |
'|  0   1   0  |      &H44   |     &H45     |    &H74   |   &H75   |
'|  1   1   0  |      &H46   |     &H47     |    &H76   |   &H77   |
'|  0   0   1  |      &H48   |     &H49     |    &H78   |   &H79   |
'|  1   0   1  |      &H4A   |     &H4B     |    &H7A   |   &H7B   |
'|  0   1   1  |      &H4C   |     &H4D     |    &H7C   |   &H7D   |
'|  1   1   1  |      &H4E   |     &H4F     |    &H7E   |   &H7F   |
'------------------------------------------------------------------
'-------------------------------------------------------------------------------

  Const Чтение_клавиатуры_pcf8574 = &H4E
  Const Запись_клавиатуры_pcf8574 = &H4F

  Const Чтение_клавиатуры_pcf8574a = &H70
  Const Запись_клавиатуры_pcf8574a = &H71

  Const Чтение_бегущий_огонь_pcf8574a = &H72
  Const Запись_бегущий_огонь_pcf8574a = &H73

'  Const Чтение_клавиатуры_pcf8575 = &H40
'  Const Запись_клавиатуры_pcf8575 = &H41

  Const Чтение_выхода_pcf8574 = &H40
  Const Запись_выхода_pcf8574 = &H41

'  Const Чтение_выхода_pcf8575 = &H42
'  Const Запись_выхода_pcf8575 = &H43

  Const Pcf8574_lcd = &H76       ' Адрес PCF8574A LCD

'-------------------------------------------------------------------------------
  Dim _lcd_e As Byte
  Dim _backlight As Byte
  Dim Буфер_lcd_string As String * 20

  I2cinit
  Waitms 10
'-------------------------------------------------------------------------------
'---------------------   Конфигурация выводов PCF8574x   -----------------------
'-------------------------------------------------------------------------------

  Const Pcf_rs = 0
  Const Pcf_bl = 1
  Const Pcf_e2 = 2
  Const Pcf_e1 = 3
'-------------------
  Const Pcf_d4 = 4
  Const Pcf_d5 = 5
  Const Pcf_d6 = 6
  Const Pcf_d7 = 7
'-------------------
  _lcd_e = 192      ' 64=E2 (3 & 4 stering) 128=E1 (1 & 2 string) 192=E1+E2 (all 4 strings)
  _backlight = 0    'initial Backlight state
'-------------------------------------------------------------------------------
'-----------------   Чистим индикатор   ----------------------------------------
'-------------------------------------------------------------------------------
  Initlcd
  Waitms 10
'-------------------------------------------------------------------------------
'-------------------------   Сброс выхода на PCF8574   -------------------------
'-------------------------------------------------------------------------------
'  Const Сброс = &B00000000
'  I2csend Запись_выхода_pcf8574 , Сброс
'-------------------------------------------------------------------------------
'--------------   Настройка прерывания клавиатуры на PCF8574   -----------------
'-------------------------------------------------------------------------------
  Config Pind.3 = Input       ' Настраиваем вывод на вход
  Set Portd.3
  Config Int1 = Falling       ' Прерывание срабатывает по спаду уровня   Rising ; Falling ; Low Level
  On Int1 Прерывание_клавиатуры       'Nosave       '> После прерывания идем в подпрограмму обработки прерывания с Ds1307
  Const Антидребезг = 0       ' Значение антидребезга (используется в подпрограмме "Клавиатура"
'-------------------------------------------------------------------------------
'------------------   Конфигурация выхода для светодиодика   -------------------
'-------------------------------------------------------------------------------
  Config Portc.0 = Output       ' Натраиваем порт на выход
  Светодиод Alias Portc.0       ' Присваиваем собственное имя ножке порта контроллера
'-------------------------------------------------------------------------------
'--------------------   Конфигурация выхода для пищалки   ----------------------
'-------------------------------------------------------------------------------
  Config Portb.7 = Output       ' Натраиваем порт на выход
  Пищалка Alias Portb.7       ' Присваиваем собственное имя ножке порта контроллера
  Dim Задержка_пищалки As Byte
  Задержка_пищалки = 30
'-------------------------------------------------------------------------------
'------------------------   Конфигурация переменных   --------------------------
'-------------------------------------------------------------------------------

  Defbit Вывод_выхода As Bit       ' Множественная переменная для хранения значений коммутированого выхода
  Dim Коммутация_выхода As Byte       ' Переменная для хранения значений коммутации выхода
  Dim Код_нажатой_кнопки As Byte       ' Переменная для хранения значений кода нажатой кнопки
  Dim Флаг_нажатия_кнопки As Byte       ' Переменная для хранения информации о том, что была нажата одна из кнопок клавиатуры
  Dim Счетчик_кнопка_нажата As Byte       ' Переменная для хранения информации о продолжительности нажатия кнопки
  Dim Флаг_есть_новые_данные As Byte       ' Флаг сигнализирующий о необходимости обновления LCD
  Dim Флаг_прочитать_клавиатуру As Byte       ' Флаг сигнализирующий о произошедшем нажатии кнопки клавиатуры, и появившейся возможности считать код нажатой кнопки

'-------------------------------------------------------------------------------
  Dim Бегущий_огонь_byte As Byte

  Бегущий_огонь_byte = &B00000001
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
  Enable Int1

  Enable Interrupts ' Разрешаем работу прерываний
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
  Do : Nop
'-------------------------------------------------------------------------------
  Главный_цикл:
'-------------------------------------------------------------------------------

    If Флаг_прочитать_клавиатуру = 1 Then Rcall Обработка_клавиатуры

    If Флаг_есть_новые_данные = 1 Then Rcall Вывод_на_lcd

    rcall Бегущий_огонь

Waitms 100
'-------------------------------------------------------------------------------
'-----------------   Засыпаем, ждем, когда что нибудь нажмется   ---------------
'-------------------------------------------------------------------------------
'  Idle
'-------------------------------------------------------------------------------
'--------------------------   Переходим на метку   -----------------------------
'-------------------------------------------------------------------------------
  Goto Главный_цикл
'-------------------------------------------------------------------------------
  Loop : End
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'*************   Подпрограмма чтения кода нажатой кнопки PCF8574   *************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Чтение_кода_нажатой_кнопки:
'-------------------------------------------------------------------------------
    I2creceive Чтение_клавиатуры_pcf8574 , Код_нажатой_кнопки       'Короткий вариант чтения данных с PCF8574A key

    If Код_нажатой_кнопки > 0 And Код_нажатой_кнопки < 255 Then Флаг_нажатия_кнопки = 1
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'***************   Подпрограмма чтения состояния выхода PCF8574   **************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Чтение_коммутации_выхода:
'-------------------------------------------------------------------------------
    I2creceive Чтение_выхода_pcf8574 , Коммутация_выхода       ' Короткий вариант чтения данных с PCF8574 Выход
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'**************   Подпрограмма записи состояния выхода PCF8574   ***************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Запись_коммутации_выхода:
'-------------------------------------------------------------------------------
    I2csend Запись_выхода_pcf8574 , Коммутация_выхода       ' Короткий вариант записи данных в PCF8574 Выход
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
  Обработка_клавиатуры:
'-------------------------------------------------------------------------------
   If Флаг_нажатия_кнопки = 1 Then

       Waitms Антидребезг

       rCall Чтение_кода_нажатой_кнопки

       Incr Счетчик_кнопка_нажата

       If Счетчик_кнопка_нажата > 2 And Код_нажатой_кнопки = 255 Then Флаг_нажатия_кнопки = 0

     Else

       Счетчик_кнопка_нажата = 0

      Goto Выход_обработка_клавиатуры

   End If
'------------------------------------------------
   rCall Чтение_коммутации_выхода
'------------------------------------------------
      Select Case Код_нажатой_кнопки
     '------------------------------------------------
       Case Is = 0 : Goto Выход_обработка_клавиатуры
     '------------------------------------------------
       Case Is = 255 : Goto Выход_обработка_клавиатуры
     '------------------------------------------------
       Case Is = 254 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_0 = Коммутация_выхода.0
                           Toggle Вывод_выхода_0
                           Коммутация_выхода.0 = Вывод_выхода_0

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 253 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_1 = Коммутация_выхода.1
                           Toggle Вывод_выхода_1
                           Коммутация_выхода.1 = Вывод_выхода_1

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 251 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_2 = Коммутация_выхода.2
                           Toggle Вывод_выхода_2
                           Коммутация_выхода.2 = Вывод_выхода_2

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 247 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_3 = Коммутация_выхода.3
                           Toggle Вывод_выхода_3
                           Коммутация_выхода.3 = Вывод_выхода_3

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 239 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_4 = Коммутация_выхода.4
                           Toggle Вывод_выхода_4
                           Коммутация_выхода.4 = Вывод_выхода_4

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 223 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_5 = Коммутация_выхода.5
                           Toggle Вывод_выхода_5
                           Коммутация_выхода.5 = Вывод_выхода_5

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 191 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_6 = Коммутация_выхода.6
                           Toggle Вывод_выхода_6
                           Коммутация_выхода.6 = Вывод_выхода_6

                           rCall Bip_bip
                         Else
                       End If
     '------------------------------------------------
       Case Is = 127 :
     '------------------------------------------------
                       If Счетчик_кнопка_нажата = 1 Then

                           Вывод_выхода_7 = Коммутация_выхода.7
                           Toggle Вывод_выхода_7
                           Коммутация_выхода.7 = Вывод_выхода_7

                           rCall Bip_bip
                         Else
                       End If
'------------------------------------------------
       End Select

       rcall Запись_коммутации_выхода

       Флаг_прочитать_клавиатуру = 0
'------------------------------------------------
     Выход_обработка_клавиатуры:
       Флаг_есть_новые_данные = 1
'------------------------------------------------
    Gifr = 64
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
  Bip_bip:
'-------------------------------------------------------------------------------
    Set Пищалка

    Waitms Задержка_пищалки

    Reset Пищалка
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'******************   Подпрограмма прерывания клавиатуры   *********************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Прерывание_клавиатуры:
'-------------------------------------------------------------------------------
    Флаг_нажатия_кнопки = 1

    Флаг_прочитать_клавиатуру = 1

'    Gifr = 64
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'***********************  Подпрограмма вывода на LCD  **************************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Вывод_на_lcd:
'-------------------------------------------------------------------------------
    Буфер_lcd_string = Str(код_нажатой_кнопки)

    Буфер_lcd_string = Format(буфер_lcd_string , "  0")

    Locate 1 , 1
    Lcd Буфер_lcd_string

    Флаг_есть_новые_данные = 0
'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------
'*******************************************************************************
'**********************   Подпрограмма бегущий огонь   *************************
'*******************************************************************************
'-------------------------------------------------------------------------------
  Бегущий_огонь:
'-------------------------------------------------------------------------------

    Rotate Бегущий_огонь_byte , Left

    I2csend Запись_бегущий_огонь_pcf8574a , Бегущий_огонь_byte

'-------------------------------------------------------------------------------
  Return
'-------------------------------------------------------------------------------
'*******************************************************************************
'-------------------------------------------------------------------------------

Эмуляция, исходник, библиотека (написана Сергеем Шиловым) - скачать

http://s4.uploads.ru/t/CQGmt.jpg

0

12

Mrshilov написал(а):

А если убрать Config I2cdelay = 1, или изменить на Config I2cdelay = 10?

Работает во всем диапазоне, с CONFIG и без него.

0

13

Написал Сергей Шилов:

sasha_1973 написал(а):

Работает во всем диапазоне, с CONFIG и без него.

Мой экземпляр при Config I2cdelay = 1 глючит. Написано Philips.

+1

14

Коммутация входов на выходы

Atmega328P + MCP23017

Симуляция Протеус 7.10 + исходники Bascom 2.0.7.1  -  скачать

http://sa.uploads.ru/t/urHFM.jpg

+2

15

Atmega8A + Ds1307 + LCD через PCF8574 + клавиатурная матрица через MCP23008 + все прерывания через MCP23008 + входы-выходы через 2 x MCP23008 + входы-выходы через 2 x MCP23016

Симуляция в Протеус 7.10 + библиотека русификации LCD HD44780 + исходник Bascom 2.0.7.1 + библиотека для работы с LCD HD44780 через PCF8574  -  скачать

Библиотеку для работы с LCD HD44780 через PCF8574, написал Сергей Шилов (MrShilov), тема здесь

Тестировал всё это безобразие в железе MACTEPok

Работа с устройствами по шине i2c организована через 2 подпрограммки (Чтение_i2c и Запись_i2c), так, что на самом деле, всё очень просто.

http://se.uploads.ru/t/T3U8V.jpg

+1

16

Attiny85 + Ds1307 + LCD через PCF8574 + клавиатурная матрица через MCP23008 + все прерывания через MCP23008 + входы-выходы через 2 x MCP23008 + входы-выходы через 2 x MCP23016

Симуляция в Протеус 7.10 + библиотека русификации LCD HD44780 + исходник Bascom 2.0.7.1 + библиотека для работы с LCD HD44780 через PCF8574  -  скачать

Библиотеку для работы с LCD HD44780 через PCF8574, написал Сергей Шилов (MrShilov), тема здесь

Работа с устройствами по шине i2c организована через 2 подпрограммки (Чтение_i2c и Запись_i2c), так, что на самом деле, всё очень просто.

http://se.uploads.ru/t/uQwZf.jpg

+1


Вы здесь » Программирование ATMEL в BASCOM. » Примеры применения в среде Баском » Исследование расширителей портов контроллера