久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3703|回復: 2
打印 上一主題 下一主題
收起左側

basic語言與匯編語言混合編程---電子手表

[復制鏈接]
跳轉到指定樓層
樓主
ID:342822 發(fā)表于 2020-8-22 09:50 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最后由 taotie 于 2020-8-22 10:17 編輯



這是一個外國網站的程序,在bascom avr平臺采用basic語言與匯編語言混合編程。下載回來對其進行部分改造:
去掉lcd16x4液晶改用流行的oled屏仿真。
增加中文設置提示。
注意:源程序是用Bascom-Avr-1.11.9.1編寫的,在新版Bascom-Avr須在非匯編塊中的匯編指令前增加“!”字符



$regfile = "m8def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 8000000

Config Portb.1 = Output                                     '一個引腳配置為LED輸出

'********* LCD ***************************************************
''設置LCD模塊的針腳,必要時根據您自己的連接
' Config Lcdpin = Pin , Db4 = Portc.2 , Db5 = Portc.3 , Db6 = Portc.4 , Db7 = Portc.5 , E = Portc.1 , Rs = Portc.0
'Config Lcdmode = Port
'Config Lcdbus = 4                                          '4 bit mode
' Config Lcd = 20 * 4
' Initlcd
'Cursor Off
Config Scl = Portc.5                                                           ' 用I2C引腳Scl = Portc.5 ,Sda = Portc.4
Config Sda = Portc.4
Config Twi = 400000                                                             ' i2c 的速度

I2cinit
$lib "i2c_twi.lbx"                                                                        ' 不使用模擬I2c的軟件,而是使用twi
$lib "glcdSSD1306-I2C.lib"                                                        ' 用glcdSSD1306-I2C庫替換默認庫要添加在bascom avr庫中

#if _build < 20784
Dim ___lcdrow As Byte , ___lcdcol As Byte                                ' 老版本變量格式進行編譯
#endif

Config Graphlcd = Custom , Cols = 128 , Rows = 64 , Lcdname = "SSD1306"   '配置圖形顯示器


'********* ISR Timer 2 ***************************************************
Config Clock = User      '配置用于Time$和Date$變量的計時器。

'您可以以128Hz的頻率去抖動(最大延遲4/128 = 0.031s)
Config Timer2 = Timer , Async = On , Prescale = 1         '預分頻器8->16Hz或1->128Hz
On Ovf2 _isr_t2ovf Nosave
Enable Ovf2

Enable Interrupts

Config Date = ymd , Separator = -        '配置日期格式    歐洲:dmy    美國:mdy       亞洲:ymd
_sec = 00 : _min = 15 : _hour = 14 : _day = 21 : _month = 08 : _year = 20

Dim Flagrtc_changed As Bit
Dim Tick_128hz As Byte

'********* 輸入鍵和去抖***************************************************
'將按鈕分配給引腳-它們必須全部連接到同一端口!
Const Key_plus = &B0000_1000                                '1 =按鈕輸入
Const Key_minus = &B0001_0000
Const Key_enter = &B0010_0000

Const Pinb_mask = Key_plus + Key_minus + Key_enter         '過濾輸入的掩碼
Const Pinb_mask_compl = &HFF - Pinb_mask                    'Pinb_mask compliment

'這是PortB上的按鈕
Ddrb = Ddrb And Pinb_mask_compl                             'DDRB: 0=INPUT 1=OUTPUT
Portb = Portb Or Pinb_mask                                  '1 =激活輸入的內部上拉電阻
Key_port Alias Pinb

Dim Key_state As Byte                                      '0/1按鈕的反轉狀態(tài)(1 =按下)
Dim Key_press As Byte                                     '觸發(fā)按鍵
Dim Key_rep As Byte                                        '自動重復計數器
Dim Key_ct0 As Byte , Key_ct1 As Byte                       '2 位計數器用于反跳

Const Key_repeat_start = 127                               '計時器ISR的編號-1,直到自動重復開始(大約500-1000ms)
Const Key_repeat_next = 15                                '定時器ISR的編號-1,用于自動重復重復率(大約125毫秒)

'反跳初始值
Key_ct0 = 255                                             '攔截程序從按鍵開始
Key_ct1 = 255
'Key_rep = Key_repeat_start                                 'Paranoia

'********* 一般的 ***************************************************
Dim I As Byte , J As Byte , K As Byte , L As Byte
Dim q As Byte
Dim Setdatetime_index As Byte
Setdatetime_index = 2                                       '日期數組的第一個索引為1,2 = _min

Dim Date_array(6) As Byte At _sec Overlay                   '秒/分鐘/小時/天/月/年的數組指定在內存中覆蓋變量。

'********* 主循環(huán) ***************************************************
Do

'  Home                                                      '光標原點
' Lcd Date$ ; "  " ; Time$                                  '顯示日期和時間
'  Locate 2 , 1
' Lcd "Set: " ; Lookupstr(setdatetime_index , Data_dateset)  'var = LOOKUPSTR(索引,標簽)從表中返回一個字符串
Setfont font8x8
Lcdat 2, 16 , Date$
Setfont font12x16
Lcdat 4, 16 ,Time$
Setfont font8x8
'Lcdat 7, 16 , "Set: " ; Lookupstr(setdatetime_index , Data_dateset)  'LOOKUPSTR(索引,標簽)從表中返回一個字符串
'為了節(jié)省電源,在ASM中編寫了128Hz環(huán)路:
Setfont font12x16
q=Lookup(setdatetime_index , Data_set)
Lcdat 7, 16 ,chr(134);chr(135);  ": " ; chr(q)

   Flagrtc_changed = 0
   Enable Interrupts                                        'Paranoia
   '進行節(jié)電循環(huán)直到((Flagrtc_changed = 1)或(Key_press> 0))

Main_1:

Config Powermode = Powersave                    '配置電源模式=省電模式  如果定時器/計數器2啟用,它將在睡眠期間保持運行
                                                                    '省電模式僅適用于8535、Mega8、Mega163。
!   lds     r16,{Key_press}                                  '按下按鈕了嗎?
  !  TST     r16
  !  BRNE    main_2
  !  lds     r16,{flagRTC_Changed}                            '再來一秒鐘?
!   sbrS    r16,bit.flagRTC_Changed
!   RJMP    Main_1

Main_2:

If Key_press > 0 Then Gosub Setdatetime_input

Loop


'---------------------------------------------------------------
'子例程:Setdatetime_input         設置日期時間輸入

'呼叫來源:main

'目的:設定日期和時鐘

'參數:鍵輸入
'---------------------------------------------------------------
Setdatetime_input:

Disable Interrupts                                         '禁用中斷
    I = Key_press                                           '讀取鍵
    Key_press = 0

    L = Lookup(setdatetime_index , Date_max)
    If Setdatetime_index = 4 Then
       L = Lookup(_month , Date_month)
       K = _year And 3
       If _month = 2 Then If K = 0 Then Incr L
    End If
    K = Lookup(setdatetime_index , Date_min)

    J = Date_array(setdatetime_index)
    If I = Key_plus Then
        If J < L Then Incr J Else J = K
    End If
    If I = Key_minus Then
        If J > K Then Decr J Else J = L
    End If
    Date_array(setdatetime_index) = J

Enable Interrupts                                          '啟用中斷

    If I = Key_enter Then
        If Setdatetime_index < 6 Then Incr Setdatetime_index Else Setdatetime_index = 1
    End If

Return


'********ISR計時器2***************************************************

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

'子程序:'u isr_t2ovf

'呼叫來源:定時器2(128Hz)

'目的:RTC,去抖動

'結果:RTC:_秒、_min、\u小時、\u天、\u月、\u年
'          '反跳:請參見下文
'---------------------------------------------------------------
$external _soft_clock
Const _sectic = 0                                          'CONFIG CLOCK = USER,GOSUB <> SECTIC的編譯器語句

_isr_t2ovf:
$asm
        push    r16
        in      r16,sreg
        push    r16                                        ' 將R16和SREG保存在堆棧中

' 防抖鍵
        push    r17                                         '現在保存所有使用的寄存器
        push    r18
        PUSH    r19
       Call Debounce_port
        POP     r19                                        '恢復寄存器
        pop     r18
        pop     r17

        lds     r16,{tick_128hz}                            '每1/128秒增加一次tick_128
        inc     r16
        sts     {tick_128hz},r16
        andi    r16,128-1                                   '如果_tick128不是128的倍數
        brne    _T2OVF_END                                  '   set_digit退出isr,否則已過去一秒鐘

'  該位變量將每隔一秒鐘設置一次
        lds     r16,{flagRTC_Changed}                       '位變量
        sbr     r16,2^bit.flagRTC_Changed
        sts     {flagRTC_Changed},r16                       '注意標志是重置標志的主要代碼責任

'  轉至內部Bascom ISR例行程序:軟時鐘
        pop     r16                                         '獲取SREG的內容
        !out    sreg,r16                                    '恢復sreg
        pop     r16
        JMP    _SOFT_CLOCK                                  '原始RETI

_t2ovf_end:
        pop     r16                                         '獲取SREG的內容
        !out    sreg,r16                                    '恢復SREG
        pop     r16

$end Asm
Return                                                      '帶著RETI離開isr

'*********防抖******************************************* ************
'------------------------------------------------- --------------
'子程序:Debounce_port
''同時檢測最大 8個按鍵,具有反跳和自動重復功能
'每個鍵被掃描3次以更改狀態(tài)
'使用的寄存器:R16,R17,R18,R19
'變量:鍵0/1的Key_state狀態(tài)
'Key_rep自動重復的重復計數器
'Key_ct0 / Key_ct1 2位計數器,用于反跳
'結果:Key_press:檢測到按下鍵時,引腳位變?yōu)?
'讀出后在Main中重置Key_press的狀態(tài)!
'感謝彼得·丹納格(Peter Dannegger)
'---------------------------------------------------------------
Debounce_port:                                              '大約108個字節(jié)
  $asm
    in R18, key_port
    com R18                                                 '引腳低電平有效
    ANDI R18, Pinb_mask                                     '帶Pinb_mask的過濾器引腳
    LDS R19, {Key_state}
    eor R18, R19                                           '在引腳輸入處檢測電平變化

    LDS R16, {Key_ct0}                                     '8通道2位計數器
    LDS R17, {Key_ct1}
    and R16, R18                                           '重置R17中的2位計數器:R16
    and R17, R18
    com R16                                                 '遞減R17:R16
    eor R17, R16
    STS {Key_ct0} , R16                                    '保存計數器
    STS {Key_ct1} , R17

    and R18, R16                                          'IF counter=&B11設置數字輸入消隱
    and R18, R17
    eor R19, R18                                            '0<->1切換狀態(tài)
    STS {Key_state} , R19

    LDS R16, {key_press}
    and R18, R19
    or R16, R18                                            '檢測到“0->1按鍵

    LDS R17, {Key_rep}
    tst R19                                              'Key_state:是否按下任何鍵?
    breq Key_isr_rep
    dec R17
    brpl Key_isr_finish                                    'IF Key_rep <0 set_digit等待時間到期
    mov R16, R19                                            '自動重復key_press = key_state
    ldi R17, key_repeat_next                              '設置自動回復重復計時器
    rjmp Key_isr_finish

Key_isr_rep:
    ldi R17, key_repeat_start                             '重置自動回復開始計時器

Key_isr_finish:
    STS {Key_rep} , R17                                     '保存自動回復計時器
    STS {key_press} , R16                                  '保存去抖鍵
  $end Asm
Return


'********* RTC ***************************************************
'如果要使用以下空例程
'時間/日期bascom功能。 您可以根據需要填充它們
Getdatetime:
    Return
Settime:
    Return
Setdate:
    Return
End

'******** 選擇日期和時間 ************************************
Date_min:
Data 0 , 0 , 0 , 0 , 1 , 1 , 0        '‘秒”,“分鐘”,“小時”,“日”,“月”,“年”最小標志
Date_max:
Data 0 , 59 , 59 , 23 , 31 , 12 , 99  '‘秒”,“分鐘”,“小時”,“日”,“月”,“年”最大標志
Date_month:
Data 0 , 31 , 28 , 31 , 30 , 31 , 30 , 31 , 31 , 30 , 31 , 30 , 31 '12個月月末標志
Data_dateset:
Data " " , "Sec " , "Min " , "Hour" , "Day " , "Mon " , "Year"  '秒”,“分鐘”,“小時”,“日”,“月”,“年”
Data_set:
Data 0 , 128, 129 , 130 , 131 , 132, 133  '秒”,“分鐘”,“小時”,“日”,“月”,“年”
$include "../font8x8.font"
$include "../font12x16.font"  

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

沙發(fā)
ID:595904 發(fā)表于 2020-12-30 01:56 | 只看該作者
受益了 !
回復

使用道具 舉報

板凳
ID:595904 發(fā)表于 2020-12-30 02:01 | 只看該作者
正在為老版本的程序不能在新版本中運行傷腦筋,樓主的這篇文章為我解惑了。非常感謝!
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 99久久国产免费 | 国产福利资源 | 久久午夜电影 | 亚洲欧美在线视频 | 国产精品九九 | 中文字幕亚洲欧美日韩在线不卡 | 91热爆在线观看 | 中文字幕国产视频 | 欧美一区二区三区的 | 91久久久久久久久久久久久 | 天天射影院 | 中文字幕久久久 | 午夜一区二区三区视频 | 日韩精品在线播放 | av免费网站在线观看 | 99精品免费久久久久久日本 | jdav视频在线观看免费 | 久久久久久综合 | 中文字幕成人av | 日韩高清www | 天堂综合网久久 | 亚洲高清久久 | 午夜影院在线免费观看视频 | 国产日韩欧美二区 | 老牛嫩草一区二区三区av | 国产欧美精品一区二区 | 免费的色网站 | a a毛片 | 狠狠干美女 | 91精品久久久久久久久久 | 日韩一区二区不卡 | 欧美亚洲激情 | 欧美日韩在线视频一区二区 | 免费在线观看一区二区 | h视频在线观看免费 | 国产高清在线视频 | 日本淫视频 | 天堂资源视频 | 日韩欧美国产精品一区 | 91精品国产欧美一区二区 | 日本一区二区三区视频在线 |