Заготовка для поделок на pic16f676 + дисплей nokia 3310 + энкодер
Создано: 23-04-2012 12:08:30  Метки: pic electronic



Вот такая заготовка для всяких поделок типа вольтметров, счетчиков, датчиков и т.д. и т.п.
А вот пример кода для вольт-амперметра с программным шимом и опросом энкодера:

@device = pic16F676, intrc_osc_noclkout, wdt_on, mclr_off, protect_off
    osccal = %11111100
    enc1    var porta.5
    enc2    var porta.4
    butt    var porta.3
    
    D_C      var portc.3
    rst      var portc.2            
    SDIN     var portc.4
    SCK      var portc.5
    
    shim    var porta.2
    voltm   con 0         'an0
    ampm    con 1         'an1
    
            define adc_bits 10 
            define adc_clock 3 
            define adc_sampleus 50 
            adval var word 
            trisa=%00111011
            trisc=0
            CMCON = 7 
            ANSEL = %00000011 ' an1, AN0
            adcon0=%10000000 ' правое выравнивание, опорное - питание
            LcdReg          var  byte        
            x               var  byte
            y               var  byte
            t               var  byte
            e               var  byte
            z               var  byte
            Offset          var  byte
            Char            var  byte
            a               var  byte
            tmpshim var byte
            shcount var byte
            portc = 0
            counter var word 
            encstate var byte
            new var byte
            ioca = %00111000
          wpua = %00110100      
          tmr0 = 255
          INTCON = %10101000
          OPTION_REG = %00000000
          counter = 0
          tmpshim = 0
          shcount = 255
          
                on interrupt goto encoder 

                   DATA  @0,$3E,$51,$49,$45,$3E,_       ';// 0
                            $00,$42,$7F,$40,$00,_       ';// 1
                            $42,$61,$51,$49,$46,_       ';// 2
                            $21,$41,$45,$4B,$31,_       ';// 3
                            $18,$14,$12,$7F,$10,_       ';// 4
                            $27,$45,$45,$45,$39,_       ';// 5
                            $3C,$4A,$49,$49,$30,_       ';// 6
                            $01,$71,$09,$05,$03,_       ';// 7
                            $36,$49,$49,$49,$36,_       ';// 8
                            $06,$49,$49,$29,$1E,_       ';// 9
                            $08,$08,$3E,$08,$08,_       ';// +
                            $08,$08,$08,$08,$08,_       ';// -
                            $00,$60,$60,$00,$00,_       ';// .
                            $3F,$40,$40,$40,$3F,_       ';// U
                            $7E,$11,$11,$11,$7E,_       ';// A
                            $00,$41,$7F,$41,$00,_       ';// I
                            $1F,$20,$40,$20,$1F         ';// V
                 
                RST = 1
                            
                LcdReg  =  %00100001          'LCD Extended Commands.
                call    PrintCtrlLcd
                LcdReg  =  228          'Set LCD Vop (Contrast).
                call    PrintCtrlLcd
                LcdReg  =  %00000111          'Set Temp coefficent.
                call    PrintCtrlLcd
                LcdReg  =  %00010011          'LCD bias mode 1:48.
                call    PrintCtrlLcd
                LcdReg  =  %00100000          'LCD Standard Commands, Horizontal addressing mode.
                call    PrintCtrlLcd
                LcdReg  =  %00001100
                call    PrintCtrlLcd
               
                call CursorHome                
                Call ClearLcd
                
Main:           y = 1
                x = 0
                Char = 13                    ' "U"
                call    PrintWChar     
                x = 24
                adcin voltm, adval
                adval = adval*3
                Char = (adval dig 3)    ' десятые
                call    PrintWChar     
                Char = (adval dig 2)    ' единицы
                call    PrintWChar     
                Char = 12               ' точка
                call    PrintWChar     
                Char = (adval dig 1)    ' десятые
                call    PrintWChar     
                Char = (adval dig 0)    ' сотые
                call    PrintWChar     
                x = 0
                y = 3
                Char = 15                    ' "I"
                call    PrintWChar     
                x = 24
                adcin ampm, adval
                adval = adval*3
                Char = (adval dig 3)    ' единицы
                call    PrintWChar     
                Char = 12               ' точка
                call    PrintWChar     
                Char = (adval dig 2)    ' десятые
                call    PrintWChar     
                Char = (adval dig 1)    ' сотые
                call    PrintWChar     
                Char = (adval dig 0)    ' тысячн
                call    PrintWChar     
                y = 5
                x = 0
                Char = (counter dig 4)    ' десятые
                call    PrintChar     
                Char = (counter dig 3)    ' десятые
                call    PrintChar     
                Char = (counter dig 2)    ' точка
                call    PrintChar     
                Char = (counter dig 1)    ' десятые
                call    PrintChar     
                Char = (counter dig 0)    ' сотые
                call    PrintChar
                'PAUSE 500
                Goto main
    disable
encoder:     if intcon.0 = 1 then
                intcon.0 = 0
               new = enc1 + enc2 * 2
                if encstate = 2 then
                    if new = 3 then counter = counter + 1
                    if new = 0 then counter = counter - 1
                endif         
                if encstate = 0 then
                    if new = 2 then counter = counter + 1
                    if new = 1 then counter = counter - 1
                endif         
                if encstate = 1 then
                    if new = 0 then counter = counter + 1
                    if new = 3 then counter = counter - 1
                endif         
                if encstate = 3 then
                    if new = 1 then counter = counter + 1
                    if new = 2 then counter = counter - 1
                endif
                encstate = new
                counter = counter & %0000001111111111
             endif
             if intcon.2 = 1 then
                intcon.2 = 0
                tmr0 = 255
                 shcount = shcount - 1
                if shcount = 0 then tmpshim = counter >> 2
                if tmpshim > 0 then
                 shim = 1
                 tmpshim = tmpshim - 1
                else
                 shim = 0
                endif
            endif         
    resume
    enable
  
               
                	
' Перевод курсора x=0..83 y=0..5	
CursorHome:     x = 0
                y = 0
SetCursor:      LcdReg  = %10000000 + x       ' cursor  X
                call    PrintCtrlLcd
                LcdReg  =  %01000000 + y        ' cursor  Y
                call    PrintCtrlLcd
                return

PrintChar:   offset = Char * 5 
                call SetCursor         
                for a = 1 to 5                
                    read offset, LcdReg
                    call  PrintDataLcd
                    offset = offset + 1
                next a
                x = x + 6
                return

' печать символа удвоенного размера
PrintWChar:   offset = Char * 5          
                for a = 1 to 5                
                    read offset, z
                    t = (z & 1)*3
                    t = t|((z & 2)*6)
                    t = t|((z & 4)*12)
                    t = t|((z & 8)*24)
                    call SetCursor
                    LcdReg = t
                    call  PrintDataLcd
                    LcdReg = t
                    call  PrintDataLcd
                    z = z >> 4
                    t = (z & 1)*3
                    t = t|((z & 2)*6)
                    t = t|((z & 4)*12)
                    t = t|((z & 8)*24)
                    y = y + 1
                    call SetCursor
                    LcdReg = t
                    call  PrintDataLcd
                    LcdReg = t
                    call  PrintDataLcd
                    offset = offset + 1
                    x = x + 2
                    y = y - 1                    
                next a
                x = x + 2
                return

' очистка китайца (708 нулевых байта)
ClearLcd: 
        D_C = 1
        LcdReg = 0
        for t = 0 to 235
            for a = 0 to 2
            call PrintDataLcd
            next a
        next t
        Return         

' отправка данных/команд на lcd
PrintCtrlLcd:   D_C = 0                             
PrintDataLcd:   for e = 1 to 8
                    SDIN = LcdReg.7              
                    LcdReg = LcdReg << 1
                    SCK = 1
                    SCK = 0
                next e               
                D_C = 1
                return
                
end 

вольтметр висит на AN0, амперметр на AN1, вывод шима с RA2. частотой програмный шим не блещет, поэтому фильтр я на него вешал из 2 резисторов на 4.7к и 2 емкостей 10 мкФ...
2599 просмотров комментировать