This is a program from a foreign website, which is programmed in a mixed language of basic and assembly language on the bascom avr platform. I downloaded it and made some modifications to it:
I removed the lcd16x4 and used the popular oled screen emulation instead.
I added Chinese setting prompts.
Note: The source program is written using Bascom-Avr-1.11.9.1. In the new version of Bascom-Avr, you need to add "!" before the assembly instructions in the non-assembly block.
$regfile = "m8def.dat"
$framesize = 32
$swstack = 32
$hwstack = 32
$crystal = 8000000
Config Portb.1 = Output 'A pin is configured as LED output
'******** LCD ******************************************************
''Set the pins of the LCD module according to your own connection if necessary
' 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 ' Use I2C pins Scl = Portc.5, Sda = Portc.4
Config Sda = Portc.4
Config Twi = 400000 ' I2c speed
I2cinit
$lib "i2c_twi.lbx" ' Do not use software to simulate I2c, but use twi
$lib "glcdSSD1306-I2C.lib" ' Replace the default library with the glcdSSD1306-I2C library to be added to the bascom avr library
#if _build < 20784
Dim ___lcdrow As Byte , ___lcdcol As Byte ' Compile with the old version variable format
#endif
Config Graphlcd = Custom , Cols = 128 , Rows = 64 , Lcdname = "SSD1306" 'Configure the graphics display
'********* ISR Timer 2 ******************************************************
Config Clock = User 'Configure the timer for the Time$ and Date$ variables.
' You can debounce at 128Hz (max delay 4/128 = 0.031s)
Config Timer2 = Timer , Async = On , Prescale = 1 ' Prescaler 8->16Hz or 1->128Hz
On Ovf2 _isr_t2ovf Nosave
Enable Ovf2
Enable Interrupts
Config Date = ymd , Separator = - ' Configure date format Europe: dmy USA: mdy Asia: ymd
_sec = 00 : _min = 15 : _hour = 14 : _day = 21 : _month = 08 : _year = 20
Dim Flagrtc_changed As Bit
Dim Tick_128hz As Byte
'******** Enter Key and Debounce************************************************
' Assign buttons to pins - they must all be connected to the same port!
Const Key_plus = &B0000_1000 '1 = button inputConst
Key_minus = &B0001_0000
Const Key_enter = &B0010_0000
Const Pinb_mask = Key_plus + Key_minus + Key_enter 'Mask to filter inputConst
Pinb_mask_compl = &HFF - Pinb_mask 'Pinb_mask compliment
'This is a button on PortB
Ddrb = Ddrb And Pinb_mask_compl 'DDRB:0=INPUT 1=OUTPUT
Portb = Portb Or Pinb_mask '1 = Activate internal pull-up resistor for input
Key_port Alias Pinb
Dim Key_state As Byte '0/1 Inverted state of the button (1 = pressed)
Dim Key_press As Byte 'Trigger key press
Dim Key_rep As Byte 'Auto repeat counter
Dim Key_ct0 As Byte , Key_ct1 As Byte '2 bit counter for debounce
Const Key_repeat_start = 127 'Number -1 of timer ISR until auto repeat starts (approx. 500-1000ms)
Const Key_repeat_next = 15 'Number -1 of timer ISR for auto repeat repeat rate (approx. 125ms)
'Debounce initial value
Key_ct0 = 255 'Intercept routine to start from key press
Key_ct1 = 255
'Key_rep = Key_repeat_start 'Paranoia
'************ General *****************************************************
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 'The first index of the date array is 1, 2 = _min
Dim Date_array(6) As Byte At _sec Overlay 'The array of seconds/minutes/hours/days/months/years specifies the overlay variable in memory.
'********* Main loop***************************************************
Do
' Home 'Cursor origin
' Lcd Date$ ; " " ; Time$ 'Display date and time
' Locate 2 , 1
' Lcd "Set: " ; Lookupstr(setdatetime_index , Data_dateset) 'var = LOOKUPSTR (index, label) returns a string from the table
Setfont font8x8
Lcdat 2, 16 , Date$
Setfont font12x16
Lcdat 4, 16 ,Time$
Setfont font8x8
'Lcdat 7, 16 , "Set: " ; Lookupstr(setdatetime_index , Data_dateset) 'LOOKUPSTR (index, label) returns a string from the table
'In order to save power, a 128Hz loop was written in ASM:
Setfont font12x16
q=Lookup(setdatetime_index , Data_set)
Lcdat 7, 16 ,chr(134);chr(135); ": " ; chr(q)
Flagrtc_changed = 0
Enable Interrupts 'Paranoia
'Do power save cycle until ((Flagrtc_changed = 1) or (Key_press > 0))
Main_1:
Config Powermode = Powersave 'Configure power mode = power save mode If Timer/Counter 2 is enabled, it will keep running during sleep
'Power save mode only applies to 8535, Mega8, Mega163.
! lds r16,{Key_press} 'Did the button get pressed?
! TST r16
! BRNE main_2
! lds r16,{flagRTC_Changed} 'Another second?
! sbrS r16,bit.flagRTC_Changed
! RJMP Main_1
Main_2:
If Key_press > 0 Then Gosub Setdatetime_input
Loop
'---------------------------------------------------------------
'Subroutine: Setdatetime_input Set datetime input
'Call from: main
'Purpose: Set date and clock
'Parameters: Key input
'---------------------------------------------------------------
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 'Get contents of SREG
!out sreg,r16 'Restore sreg
pop r16
JMP _SOFT_CLOCK 'Original RETI
_t2ovf_end:
pop r16 'Get contents of SREG
!out sreg,r16 'Restore SREG
pop r16
$end Asm
Return 'Leave isr with RETI
'********Debounce******************************************************
'------------------------------------------------- --------------
'Subroutine: Debounce_port
''Detects up to 8 keys simultaneously, with debounce and auto-repeat capabilities
'Each key is scanned 3 times to change state
'Registers used: R16, R17, R18, R19
'Variables: Key_state state for key 0/1
'Key_rep repeat counter for auto-repeat
'Key_ct0 / Key_ct1 2-bit counter for debounce
'Result: Key_press: pin bit goes to 1 when key press is detected
'After reading it out, reset the state of Key_press in Main!
'Thanks to Peter Dannegger
'---------------------------------------------------------------
Debounce_port: 'About 108 bytes
$asm
in R18, key_port
com R18 'Pin active low
ANDI R18, Pinb_mask 'Filter pins with Pinb_mask
LDS R19, {Key_state}
eor R18, R19 'Detect level change at pin input
LDS R16, {Key_ct0} '8 channel 2-bit counter
LDS R17, {Key_ct1}
and R16, R18 'Reset 2-bit counter in R17: R16
and R17, R18
com R16 'Decrement R17: R16
eor R17, R16
STS {Key_ct0} , R16 'Save counter
STS {Key_ct1} , R17
and R18, R16 'IF counter=&B11 Set digital input blanking
and R18, R17
eor R19, R18 '0<->1 switch state
STS {Key_state} , R19
LDS R16, {key_press}
and R18, R19
or R16, R18 'Detected "0->1 key press
LDS R17, {Key_rep}
tst R19 'Key_state: Is any key pressed?
breq Key_isr_rep
dec R17
brpl Key_isr_finish 'IF Key_rep <0 set_digit wait time expires
mov R16, R19 'Auto repeat key_press = key_state
ldi R17,key_repeat_next 'Set up auto-reply repeat timer
rjmp Key_isr_finish
Key_isr_rep:
ldi R17, key_repeat_start 'Reset auto reply start
timerKey_isr_finish:
STS {Key_rep} , R17 'Save auto reply timerSTS
{key_press} , R16 'Save debounce key
$end Asm
Return
'******** RTC *******************************************************
'The following empty routine if you want to use
'time/date bascom functions. , 31 , 28 , 31 , 30 , 31 , 30 , 31 , 30 , 31 , 30 , 31 '12 month end mark
Data_dateset : Data " " , " Sec " , "Min " , "Hour" , "Day " , "Month " , "Year" minimum mark Date_max: Data 0 , 59 , 59 , 23 , 31 , 12 , 99 ''Second " , "Min " , "Hour" , "Day " , "Month " , "Year" maximum mark Date_month: Data 0 , 31 , 28 , 31 , 30 , 31 , 30 , 31 , 30 , 31 , 30 , 31 '12 month end mark Data_dateset: Data " " , "Sec " , "Min " , "Hour" , "Day " , "Mon " , "Year" 'Seconds", "Minutes", "Hours", "Day", "Month", "Year" Data_set: Data 0 , 128, 129 , 130 , 131 , 132, 133 'Seconds", "Minutes", "Hours", "Day", "Month", "Year" $include "../font8x8.font" $include "../font12x16.font"
Previous article:Bascom-avr program that can display temperature and time (and set alarm time)
Next article:BASCOM-AVR driver digital tube simple code
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Apple faces class action lawsuit from 40 million UK iCloud users, faces $27.6 billion in claims
- Apple faces class action lawsuit from 40 million UK iCloud users, faces $27.6 billion in claims
- The US asked TSMC to restrict the export of high-end chips, and the Ministry of Commerce responded
- The US asked TSMC to restrict the export of high-end chips, and the Ministry of Commerce responded
- ASML predicts that its revenue in 2030 will exceed 457 billion yuan! Gross profit margin 56-60%
- Detailed explanation of intelligent car body perception system
- How to solve the problem that the servo drive is not enabled
- Why does the servo drive not power on?
- What point should I connect to when the servo is turned on?
- How to turn on the internal enable of Panasonic servo drive?
- Please explain the principle of this boost circuit
- Career Options
- How to choose an analog-to-digital converter?
- [Project source code] FPGA-based asynchronous FIFO show-ahead mode
- [Construction Monitoring and Security System] XIV. Realization of the core functions of the project
- Is the Linux interrupt handling process global or local interrupts?
- Commonly used surge suppression devices
- Or is it a buck-boost problem? Please ask the teachers
- RSL10-002GEVB power management node design
- How to measure current ranging from 1uA to 1.5A