找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 24219|回复: 2
打印 上一主题 下一主题
收起左侧

LED点阵显示屏工作原理及驱动程序

[复制链接]
跳转到指定楼层
楼主
ID:105323 发表于 2016-3-4 14:47 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
LED显示屏驱动程序
几年前本人得到一块双色LED显示屏,因为没有控制器,所以对显示屏的工作原理进行了一番研究,利用手头上的元件,搭了一块电路板,编写了一段程序就放置一边了,这几天有时间,把原来的89C51汇编程序改了一下,改为AT89C2051和STC11F04E单片机能用的程序,放到博客上希望有兴趣的同行可以参考一下。下面是显示效果图:
下面是接口电路板图:

下面是电路原理图:


工作原理:这块显示屏是分为上下共32行LED点阵,水平有4块16*16点阵,所以能显示16*16点阵8个汉字。工作原理是用74ls138做为行扫描,列用74ls595控制,当138扫描到某一行时,595决定哪一列该亮,就这样快速扫描,就形成了图像了。参见下图:

以单色单元板为例走线方式如下图:


各信号走向如下:
l        JP1排针16脚信号A->74HC245的第2脚(信号放大)->74HC245的第18脚->74HC138的第1脚->JP2排针16脚
l        JP1排针15脚信号B->74HC245的第3脚(信号放大)->74HC245的第17脚->74HC138的第2脚->JP2排针15脚
l        JP1排针1脚信号OE->74HC245的第4脚(信号放大)->74HC245的第16脚->74HC04D的第1脚->74HC04D的2脚->①74HC138的第5脚->②74HC04D的3脚->74HC04D的4脚->JP2排针1脚
l        JP1排针11脚信号R->74HC245的第9脚(信号放大)->74HC245的第11脚->最左上角74HC595-1的第14脚->74HC595-1的9脚->74HC595-2的14脚->74HC595-2的9脚->最右下角74HC595-16的14脚->74HC595-16的9脚->JP2排针11脚

我现在用的是双色板,JP1各端口含义如下:

ABCD是显示屏电路板上的74LS138地址译码端, 单片机寄存器R3控制行扫描,当R3从00000000到00010000增加时ABCD的变化给138译码,当R3=0FH时正好扫描16行,当进位到10时扫描结束,OE是138的片选使能端,低电平有效。G1,G2是给595送绿色数据,R1R2是给595送红色数据的,ST是595数据锁存脉冲,SC是595时钟输入端。所有11个接线端都要通过74HC244总线驱动器接入。正常工作时因为按行扫描,首先扫描第一行和第17行同时进行,依次扫描到第16行和32行结束,所以送数据时,要把“黑龙江省哈尔滨市”8个汉字分成上面4个和下面4个,首先取“黑”字的16*16点阵数据的第一行第一个字节(一个汉字32个字节)存入单片机寄存器R6中,再取“哈” 字的16*16点阵数据的第一行第一个字节存入单片机寄存器R4中,调用送字节子程序送出到595中,接下来再取“黑”字的16*16点阵数据的第一行第二个字节存入单片机寄存器R6中,接着取“哈” 字的16*16点阵数据的第一行第二个字节存入单片机寄存器R4中,调用送字节子程序送出到595中,如此共取8次,用R2控制,这样就扫描完了第一行和第17行,用R3控制ABCD共扫描16行(因为一次扫描2行)就完成一屏的数据显示。为了配合这种扫描方式,8个汉字的点阵数据要进行重新排列才行,这在后续的程序中再说。
下面是51单片机汇编语言代码,主要由显示程序和送字节数据程序2段程序组成:
    ORG 0000H
       AJMPKS        ;显示绿色黑龙江省哈尔滨市,11.0592MHZSTC11F04E单片机
       ORG 0003H
       RETI
       ORG 000BH
; LJMP 0C00H
    RETI
       ORG 001BH
       RETI
       ORG 0023H
    ;AJMPS             ;接收数据转S
       A1   EQU P1.0   ;P1.0=A         2
       B1   EQU P1.1   ;P1.1=B         4
       C1   EQU P1.2   ;P1.2=C         6
       D1   EQU P1.3  ;P1.3=D         8
       G1   EQU 0B3H    ;数据输出G1=B4
       G2   EQU 0B7H   ;数据输出 G2=B5
       STB  EQU 0B2H    ;595数据锁存脉冲=L 12
       SCK EQU 0B4H    ;595时钟输入=S   11
       R11  EQU 0B0H   ;改为81R22改为80,上下显示颠倒
       R22  EQU  0B1H
       EN   EQU 0B5H    ;138片选,行输出使NENG
       DELBUF EQU 7FH
       WDT_CONTR   EQU 0C1H
       AUX EQU   0A2H            ;

  KS:   MOVSP,#65H    ;设堆栈指针
        MOV SCon,#50h; 方式1,REN=1.SM0SM1SM2REN,TB8RB8TI,RI
        MOV TMOD,#21H;波特率发生器T1工作在模式2
        MOV TH1,#0FDH;预置初值(按照波特率9600BPS预置初值) 11.0592=9600=FD
        MOV TL1,#0FDH;
        MOV  TH0,#88H     ;8800=12t,7000=stc1t
         MOV  TL0, #00H
        ORL IE, #92H  ;EA=1ES=1;ET0=1
        SETBPS       ;串口中断优先
        SETBTR1      ;启动定时器1
        MOV WDT_CONTR ,#27H;;;;;;看门狗设置使能

Q:        MOV A,#0;FFH
            MOVR2,#64D    ;清数据区
            MOV R0,#20H
QING:  MOV@R0,A      ;清数据区
          INC R0
           DJNZ R2,QING

Q1:     SETB G1
         SETBG2         ;G1,G2送数显示绿色
         SETB R11
         SETBR22        ;R11R22送数显示红色
T1:     MOVR3,#00H     ;行扫描 R3控制行数从0000000000010000,ABCD的变化给138译码0F扫描16行,当10时扫描结束
         MOV   DPTR , #0500H    ;取数字
TZ:     MOV  R2,  #8   ;送一行8个汉字
         SETBEN         ;138片选,行输出使能
  ZJ1:    CLRA
          MOVC  A, @A+DPTR ;16*16点阵,每行显示4个汉字,32条水平线,(1个汉字占16条水平线)2行显示8个汉字,所以先取第一行的一个字节,显示半个汉字(黑)
          CPL A              ;再跳过8个字节(4个汉字)取第二行1个字节数据(哈)
          MOV R6,A
          INC DPTR
          CLR A
          MOVC  A, @A+DPTR
          CPL A
          MOV R4,A
          ACALLBIN       ;BIN2显示绿色
          INC DPTR
          DJNZ R2,ZJ1
          SETB   STB
          CALL SDELAY
          CLR    STB

          MOVA,R3                 ;138地址ABCD
          MOVP1,A                 ;P2.0-P2.3=ABCD
          INC R3
          MOV A,R3
          XRLA,#10H           ;00-08是前8行,08-10H是后8;
          JNZTZ              ;送前16
          MOV WDT_CONTR ,#17H;喂狗CLREN
          AJMP T1

BIN:   MOV  R5, #08H  ;G1G2,或R11R22中写一个字节数据
BIN1:  RLC  A
      ; MOV  R11, C  ;写上半屏红色
       MOV  G1,C    ;写上半屏红色
       MOV R4,A
       MOV A,R6
       RLC A
      ; MOV R22,C   ;下半屏红色
       MOV G2,C    ;下半屏绿色
       MOV R6,A
       MOV A,R4
       SETB  SCK
       CALL SDELAY
       CLR SCK
       DJNZ  R5,  BIN1
       RET

SDELAY:      MOV      DELBUF,    #8D
SDEL1:       NOP
             NOP
             DJNZ     DELBUF,    SDEL1
             RET
      ORG0500h      ;黑龙江省哈尔滨市
DB00H,00H,08H,40H,02H,08H,00H,00H,40H,00H,00H,80H,01H,02H,00H,00H
DB3FH,00H,0FCH,40H,02H,0CH,40H,00H,30H,40H,08H,40H,09H,01H,20H,00H
DB21H,08H,08H,0A0H,02H,08H,20H,08H,17H,2FH,0FCH,0FEH,09H,00H,10H,04H
DB31H,7CH,28H,0A0H,02H,1FH,04H,0FCH,00H,28H,40H,02H,11H,0FFH,0CH,0FEH
DB2DH,49H,38H,10H,0FFH,20H,0FEH,08H,80H,10H,40H,64H,11H,01H,24H,00H,25H
DB49H,48H,08H,02H,41H,80H,10H,60H,83H,40H,80H,20H,01H,0C0H,08H,21H,4AH
DB08H,0EH,02H,81H,88H,00H,20H,52H,40H,10H,03H,3FH,00H,0FCH,3FH,4DH,0F8H
DB0F4H,04H,01H,88H,00H,08H,13H,40H,0F8H,0CH,21H,08H,08H,01H,48H,00H,00H
DB04H,09H,90H,40H,10H,12H,40H,20H,3FH,21H,0FCH,08H,7FH,48H,0FCH,08H,04H
DB09H,0A0H,20H,20H,22H,40H,20H,0C8H,21H,08H,08H,01H,4BH,00H,0FCH,08H,11H
DB0C0H,10H,0E0H,0E2H,40H,24H,0FH,21H,0F8H,08H,0FFH,7AH,0FEH,08H,08H,11H,82H
DB18H,20H,3FH,40H,0FEH,08H,21H,08H,08H,00H,4AH,00H,08H,11H,21H,82H,08H,20H
DB20H,44H,00H,0FH,21H,0F8H,28H,28H,02H,90H,08H,16H,01H,82H,00H,2FH,23H,0FEH
DB20H,08H,21H,08H,10H,24H,03H,4CH,0F8H,20H,05H,7EH,00H,20H,22H,00H,18H,0FH
DB01H,0F8H,00H,44H,02H,44H,08H,40H,02H,00H,00H,20H,24H,00H,08H,08H,01H,08H,00H

END




获取汉字点阵数据的VB程序
新建一个vb工程,新建桌面如下图:



Form1上放置4个文本框,6个命令按钮,5个标签Label,一个下拉框ComboBox,分别把命令按钮的caption改成“获取汉字点阵信息”,“清空EEPROM”,“发送数据”,“读EEPROM”,“读时钟”,”修改时钟“。把4TextboxText清空。在“工程”菜单下,选部件,如下图:


引入串口通信控件,如下图:

然后把拉到桌面上,就可以应用vb自带的串口通信部件了。
下面把代码复制到工程代码区中:
Private Sub Combo1_Click()
On Error Resume Next
Label4.Caption = 8 ' Combo1.Text
MSComm1.CommPort = Right(Combo1.Text,1)
MSComm1.Settings = "9600,n,8,1"
If MSComm1.PortOpen = False Then MSComm1.PortOpen= True
MSComm1.InputLen = 0
MSComm1.RThreshold = 1
MSComm1.SThreshold = 0
MSComm1.InputMode = comInputModeBinary 'comInputModeText
MSComm1.InBufferSize = 2048
MSComm1.OutBufferSize = 2048
MSComm1.InBufferCount = 0
MSComm1.OutBufferCount = 0
Label4.Caption = "串口号:" &MSComm1.CommPort
End Sub


Private Sub Command1_Click()
Dim zf$, q$, w$, X, zf1, p, o,l, cc, B, s, Y
Dim m, k, j, i, c1, c2, c3, c4,c5, c6, c7, c8, c9, c10, c11, c12, c13, c14, c15, c16
Dim S11, s12, s13, s14, s15,s16, SS
Dim C(32), a(32) AsString
Dim a1 As Byte
On Error Resume Next
zf$ = Text1.Text
X = Len(zf$)
For j = 1 To X
zf1 = Hex(Asc(Mid$(zf$, j, 1)))
If zf1 <"A0" Then
q$ = "&H" & Left(zf1, 1)
w$ = "&H" & Right(zf1, 1)
q = Val(q$)
w = Val(w$)
m = (q * 16 + w) * 16
k = 16
           Open "G:\单片机\LED显示屏\汉字点阵\asc16" ForBinary As #1
Else
q$ = "&H" & Left(zf1, 2)
w$ = "&h" & Right(zf1, 2)
q = Val(q$) - 160
w = Val(w$) - 160
m = ((q - 1) * 94 + w - 1) * 32
k = 32
           Open "G:\单片机\LED显示屏\汉字点阵\hzk16" ForBinary As #1
End If

or i = 1 To k
m = m + 1
Seek #1, m
Get #1, m, a1
B = a1
  For l = 1 To 8'把一个字节的十六进制数转换二进制数
    cc =B / 2 '被2除,余数为1
    If B/ 2 = Int(B / 2) Then
    s =0 & s
   Else
    s =1 & s
    EndIf
    B =Int(cc)
  Next l
C(i) = s
'Text2.Text = Text2.Text + C(i)
If k = 32 Then
c1 = C(1) + C(2): c2 = C(3) + C(4)'16*16点阵,每个字每行2个字节相加。
c3 = C(5) + C(6): c4 = C(7) + C(8)
c5 = C(9) + C(10): c6 = C(11) + C(12)
c7 = C(13) + C(14): c8 = C(15) + C(16)
c9 = C(17) + C(18): c10 = C(19) + C(20)
c11 = C(21) + C(22): c12 = C(23) +C(24)
c13 = C(25) + C(26): c14 = C(27) +C(28)
c15 = C(29) + C(30): c16 = C(31) +C(32)
a(1) = C(1)
a(2) = C(2)
a(3) = C(3)
a(4) = C(4)
a(5) = C(5)
a(6) = C(6)
a(7) = C(7)
a(8) = C(8)
a(9) = C(9)
a(10) = C(10)
a(11) = C(11)
a(12) = C(12)
a(13) = C(13)
a(14) = C(14)
a(15) = C(15)
a(16) = C(16)
a(17) = C(17)
a(18) = C(18)
a(19) = C(19)
a(20) = C(20)
a(21) = C(21)
a(22) = C(22)
a(23) = C(23)
a(24) = C(24)
a(25) = C(25)
a(26) = C(26)
a(27) = C(27)
a(28) = C(28)
a(29) = C(29)
a(30) = C(30)
a(31) = C(31)
a(32) = C(32)
Else
c1 = C(1): c2 = C(2)
c3 = C(3): c4 = C(4)
c5 = C(5): c6 = C(6)
c7 = C(7): c8 = C(8)
c9 = C(9): c10 = C(10)
c11 = C(11): c12 = C(12)
c13 = C(13): c14 = C(14)
c15 = C(15): c16 = C(16)
'源码,没经过处理
a(1) = C(1)
a(2) = C(2)
a(3) = C(3)
a(4) = C(4)
a(5) = C(5)
a(6) = C(6)
a(7) = C(7)
a(8) = C(8)
a(9) = C(9)
a(10) = C(10)
a(11) = C(11)
a(12) = C(12)
a(13) = C(13)
a(14) = C(14)
a(15) = C(15)
a(16) = C(16)
End If
s = ""
Next i
Close
l = 0: o = 0
    Forl = 1 To k '32
       p = a(l)
           For o = 1 To 8
               Y = Mid(p, o, 1)
               Y = "&H" & Y
               Y = Val(Y) * 2 ^ (8 - o)
               cc = cc + Y
           Next o
        a(l) = Hex(cc)
          If Len(a(l)) = 1 Then a(l) = "0" & a(l)
   ' s = s +a(l) & "H,"
    s =s + a(l) & ","
           cc = 0
    Nextl   
s15 = s15 + s
'Text1.Text = Text1.Text + s15
'Exit Sub
o = 0: cc = 0: p = 0: l = 0: Y = 0: s =0
Next j
k = Len(s15)
Text2.Text = s15 + "字符数=" & k& Chr(13) + Chr(10)
'下面对多字节(8)个点阵汉字进行处理,行扫描
Dim Bq() As String
Bq = Split(s15, ",") '分割为数组
l = X * 32 / 2
s1 = ""
For i = 0 To 15 ' Step 4
c1 = "H,"
For j = 0 To l - 1 Step 32
s1 = Bq(2 * i + j) + c1 + Bq(2 * i + l + j) + c1 +Bq(2 * i + j + 1) + c1 + Bq(2 * i + l + j + 1) + c1
Text3.Text = Text3.Text + s1 '加 l = X * 32 /2是把8个汉字分成一半,同时显示上面4个汉字和下面4个汉字,先取上面一个字节,再取下面一个字节,加32是取第二个汉字,加64是取地个汉字,加96是取第4个汉字,一次取完一行
Next j
For j = 0 To l - 1 Step 32
s2 = Bq(2 * i + j) + Bq(2 * i + l + j) + Bq(2 * i+ j + 1) + Bq(2 * i + l + j + 1)
Text4.Text = Text4.Text + s2
Next j
Next i
End Sub
Private Sub Command2_Click()

If MSComm1.PortOpen = False Then MSComm1.PortOpen= True

MSComm1.Output = "66"
Text3.Text = "66OK"

MSComm1.PortOpen = False
End Sub
Private Sub Command3_Click()
Dim s1, s2, s3 As String
If MSComm1.PortOpen = False Then MSComm1.PortOpen= True
zf$ = Text1.Text
X = Len(zf$)
If X = 16 Then X = "10"
If X = 24 Then X = "18"
s1 = Text4.Text
If X < 10 Then X = "0" & X
s2 = Mid$(s1, 1, 512)
MSComm1.Output = X & s2
s3 = Mid$(s1, 513, 512)
MSComm1.Output = s3
S4 = Mid$(s1, 1025, 512)
MSComm1.Output = S4
Text3.Text = X & s2 & s3 &S4
MSComm1.PortOpen = False
End Sub
Private Sub Command4_Click()
If MSComm1.PortOpen = False Then MSComm1.PortOpen= True
MSComm1.Output = "77"
End Sub
Private Sub Command5_Click()
MSComm1.Output = "99"
End Sub
Private Sub Command6_Click()
sj = Format(Now, "yyyy年mm月dd日hh时mm分ss秒")
w = Weekday(Date) - 1
xq = "0" & w
sj1 = Mid(sj, 3, 2) + Mid(sj, 6, 2) + Mid(sj, 9,2) & xq
sj2 = Mid(sj, 12, 2) + Mid(sj, 15, 2) + Mid(sj,18, 2)
Text3.Text = "88" + sj1 + sj2
MSComm1.Output = "88" + sj1 + sj2
End Sub
Private Sub Form_Load()
Text1.Text = "黑龙江省哈尔滨市"'黑龙江省哈尔滨市道里区红军街一号
MSComm1.Settings = "9600,n,8,1"
MSComm1.InputMode = comInputModeBinary
MSComm1.InputLen = 0
MSComm1.InBufferSize = 2048
MSComm1.OutBufferSize = 2048
MSComm1.RThreshold = 1 '
MSComm1.InBufferCount = 0
MSComm1.OutBufferCount = 0
MSComm1.PortOpen = True
End Sub
Private Sub MSComm1_OnComm()
Dim strBuff As String
Dim str() As Byte
Select Case MSComm1.CommEvent
Case comEvReceive
MSComm1.InputLen = 0
strBuff = MSComm1.Input
str() = strBuff
'接收数据处理为16进制
For i = 0 To UBound(str)
If Len(Hex(str(i))) = 1 Then
strData = strData & "0" &Hex(str(i))
Else
strData = strData & Hex(str(i))
End If
Next
Text3.Text = Text3.Text + strData
End Select
End Sub
点击工具栏上的启动按钮,如下图,看是否出错,能正常运行就大功告成。如果出错


可能是缺少HZK16ASC16两个文件,或文件路径不正确,需要改动路径。文件目录如下图:可到我的网盘下载。(连接在我的前面文章中)

本程序有4个功能,在最上面的文本框中输入要获取的点阵汉字,可以是8个,16个(与显示屏对应),点击“获取汉字点阵信息”按钮,获得的数据如下图:



Text2中显示的是单个汉字的点阵信息,每32个字节是一个汉字,如00,08,3F,FC,21,08,31,28,2D,38,25,48,21,08,3F,F8,01,00,7F,FC,01,00,FF,FE,00,00,28,90,24,4C,44,44是“黑”字的点阵,接下来的是“龙”字的点阵02,00,02,40,02,20,02,04,FF,FE,02,80,02,88,04,88,04,90,04,A0,08,C0,08,82,11,82,16,82,20,7E,40,00,以此类推。
Text3中显示的是按汉字字符串“黑龙江省哈尔滨市”的1/2,相隔4个汉字分离出来的点阵信息,因为我用的显示屏每块是32*128的点阵,所以上下可以显示216*16的点阵,每行可以显示416*16的汉字,单片机程序是上下2行汉字同时扫描,所以要进行1/2汉字点阵分离。如果要扩充到2块显示屏,就可以显示16个汉字,如显示“黑龙江省哈尔滨市道里区红军街一号”,就需要从19个汉字同时扫描,相应的点阵信息要从第9个开始分离,再重新组合。为了便于贴到单片机程序中,加上了“,”号和“H”符号。
Text4中显示的与TEXT3中的内容一致,只不过去掉了“,”号和“H”符号,便于和单片机通信。
点击“清空EEPROM”按钮,功能是清空单片机STC11F04EEEPROM的数据,刷新数据之前必须先清空。STC11F04E1K字节的EEPROM,有2个扇区,每隔扇区512字节,地址是“0000—01FF”是第一扇区,“0200—03FF”是第二扇区。
点击“发送数据”按钮,是把Text4中的点阵数据通过串口发送到单片机STC11F04E中到EEPROM中,串口波特率是9600,应用时注意你自己微机的串口号,默认是“com8”。在串口发送数据时,会把汉字字符串的长度信息发送到EEPROM的“0000”单元中,便于单片机自动改变扫描长度。
点击“读EEPROM”按钮是读出单片机STC11F04E中的EEPROM数据。
点击“读时钟”可以读出时钟模块的日期和时间,如”16011801143533”asii码“31363031313830313134353333”表示16年、118日、星期一、143533秒。
点击“修改时钟”,会把微机系统的时钟写入时钟模块。


STC11F04E单片机程序

;可显示绿色8个、16个、24个汉字,11.0592MHZ,9600波特率,STC11F04E单片机,可串口接收81624个汉字并显示,2016-01-12通过

          ORG0000H
          AJMPKS        
          ORG 0003H
          RETI
          ORG 000BH
;       LJMP CT
        RETI
          ORG 001BH
         RETI
       ORG 0023H
       AJMPS        ;接收数据转S
       A1   EQU P1.0   ;P1.0=A         2
       B1   EQU P1.1   ;P1.1=B         4
       C1   EQU P1.2   ;P1.2=C         6
       D1   EQU P1.3   ;P1.3=D         8
       G1   EQU 0B3H    ;数据输出G1=B4
       G2   EQU 0B7H   ;数据输出  G2=B5
       STB  EQU 0B2H    ;595数据锁存脉冲=L 12
       SCK  EQU 0B4H    ;595时钟输入=S   11
       R11  EQU 0B0H   ;改为81R22改为80,上下显示颠倒
       R22  EQU  0B1H
       EN   EQU 0B5H    ;138片选,行输出使NENG
       DELBUF EQU 7FH
       DBUF EQU 60H
       ZS EQU 61H
       HM      EQU   1EH            ;定时器毫秒存储
       WDT_CONTR   EQU 0C1H
       FLAG_1 EQU    20H.1          ;

       ;声明与IAP/ISP/EEPROM有关的特殊功能寄存器的地址
       IAP_DATA       EQU   0C2H
       IAP_ADDRH      EQU   0C3H
       IAP_ADDRL      EQU   0C4H
       IAP_CMD        EQU   0C5H
       IAP_TRIG       EQU   0C6H
       IAP_CONTR      EQU   0C7H
       ;定义ISP/IAP命令
       ISP_IAP_BYTE_READ  EQU  1H   ;字节读
       ISP_IAP_BYTE_PROGRAM  EQU   2H ;字节编程,可以将1写成0,要将1变成0,必须执行字节编程
       ISP_IAP_SECTOR_ERASE    EQU 3H ;扇区擦除,可以将0擦成1,要将0变成1,必须擦除整个扇区
       ;定义Flash 操作等待时间及允许IAP/ISP/EEPROM操作的常数
       ENABLE_IAP     EQU  84H    ;系统工作时钟<6MHz时,对IAP_CONTR寄存器设置此值
   KS:  MOVSP,#65H    ;设堆栈指针
        MOV SCon,#50h; 方式1,REN=1.SM0SM1SM2REN,TB8RB8TI,RI
        MOV TMOD,#21H;波特率发生器T1工作在模式2
        MOV TH1,#0FDH;预置初值(按照波特率9600BPS预置初值)  11.0592=9600=FD 14400=FE 7200=FC
        MOV TL1,#0FDH;预置初值(按照波特率9600BPS预置初值) 11.0592=4800=FA 2400=F4 1200=E8
        MOV  TH0,#88H     ;8800=12t,7000=stc1t
      MOV  TL0, #00H
        ORL IE, #92H  ;EA=1ES=1;ET0=1
        SETBPS       ;串口中断优先
        SETBTR1      ;启动定时器1
       MOV WDT_CONTR ,#27H;;;;;;看门狗设置使能
Q:        MOV A,#0;FFH
       MOVR2,#64D    ;清数据区
       MOV R0,#20H
QING:  MOV@R0,A     ;清数据区
       INC R0
       DJNZ R2,QING

Q1:     SETB G1
         SETBG2         ;G1,G2送数显示绿色
         SETB R11
         SETBR22        ;R11R22送数显示红色
         MOV   DPTR , #0000H    ;取汉字长度
         LCALL  Byte_Read;
         MOV   ZS, A; #8   ;送一行8个汉字
T1:     MOVR3,#00H     ;行扫描R3控制行数从0000000000010000,ABCD的变化给138译码0F扫描16行,当10时扫描结束
         MOV   DPTR , #0001H    ;取数字
TZ:     MOV A,ZS
         MOV   R2, A; #8   ;送一行8个汉字
         SETBEN         ;138片选,行输出使能
  ZJ1:   LCALL Byte_Read;16*16点阵,每行显示4个汉字,32条水平线,(1个汉字占16条水平线)2行显示8个汉字,所以先取第一行的一个字节,显示半个汉字(黑)        
          CPLA                     ;再跳过8个字节(4个汉字)取第二行1个字节数据(哈)
          MOV R6,A
          INC DPTR
          LCALL  Byte_Read;
          CPL A
          MOV R4,A
          ACALLBIN       ;BIN2显示绿色
          INCDPTR
          DJNZ R2,ZJ1
          SETB   STB
          NOP;
          CLR    STB
          MOVA,R3                 ;138地址ABCD
          MOVP1,A                 ;P2.0-P2.3=ABCD
          INC R3
          MOV A,R3
          XRLA,#10H           ;00-08是前8行,08-10H是后8;
          JNZTZ              ;送前16
          MOV WDT_CONTR ,#17H;喂狗CLR EN
          JNB FLAG_1,T1
          CALL FS1
          AJMP T1

BIN:   MOV  R5, #08H  ;G1G2,或R11R22中写一个字节数据
BIN1:  RLC  A
      ; MOV  R11, C  ;写上半屏红色
       MOV  G1,C    ;写上半屏绿色
       MOV R4,A
       MOV A,R6
       RLC A
      ; MOV R22,C   ;下半屏红色
       MOV G2,C    ;下半屏绿色
       MOV R6,A
       MOV A,R4
       SETB  SCK
       NOP;
       NOP
       NOP
       CLR SCK
       DJNZ  R5,  BIN1
       RET

;------------------------------------------------
;读一字节,调用前需打开IAP 功能,入口:DPTR= 字节地址,返回:A= 读出字节
Byte_Read:
   MOV    IAP_CONTR, #ENABLE_IAP    ;打开 IAP功能,设置Flash 操作等待时间
   MOV    IAP_CMD,   #ISP_IAP_BYTE_READ  ;设置为IAP/ISP/EEPROM字节读模式命令
   MOV    IAP_ADDRH, DPH            ;设置目标单元地址的高8位地址
   MOV    IAP_ADDRL, DPL            ;设置目标单元地址的低8位地址
   CLR    EA
   MOV    IAP_TRIG,  #5AH      ;先送5Ah,再送A5hISP/IAP触发寄存器,每次都需如此
   MOV    IAP_TRIG,  #0A5H     ;送完A5h后,ISP/IAP命令立即被触发起动
   NOP
   MOV    A,  IAP_DATA         ;读出的数据在IAP_DATA单元中,送入累加器A
   SETB   EA
   ACALL IAP_Disable ;关闭 IAP功能,清相关的特殊功能寄存器,使CPU处于安全状态,
                     ;一次连续的IAP操作完成之后建议关闭IAP功能,不需要每次都关
   RET
;------------------------------------------------
;字节编程,调用前需打开IAP 功能,入口:DPTR= 字节地址,A=须编程字节的数据
Byte_Program:
   MOV   IAP_CONTR,#ENABLE_IAP   ;打开 IAP功能,设置Flash 操作等待时间
   MOV   IAP_CMD,#ISP_IAP_BYTE_PROGRAM  ;设置为IAP/ISP/EEPROM字节编程模式命令
   MOV   IAP_ADDRH,DPH           ;设置目标单元地址的高8位地址
   MOV   IAP_ADDRL,DPL           ;设置目标单元地址的低8位地址
   MOV   IAP_DATA,A              ;要编程的数据先送进ISP_DATA寄存器
   CLR   EA
   MOV   IAP_TRIG,#5AH           ;先送5Ah,再送A5hISP/IAP触发寄存器,每次都需如此
   MOV   IAP_TRIG,#0A5H         ;送完A5h后,ISP/IAP命令立即被触发起动
   NOP
   SETB  EA
    ACALL IAP_Disable ;关闭 IAP功能,清相关的特殊功能寄存器,使CPU处于安全状态,
                      ;一次连续的IAP操作完成之后建议关闭IAP功能,不需要每次都关
   RET
;------------------------------------------------
;擦除扇区,入口:DPTR= 扇区地址
Sector_Erase:
   MOV   IAP_CONTR,#ENABLE_IAP   ;打开 IAP功能,设置Flash 操作等待时间
   MOV   IAP_CMD,#03H            ;设置为IAP/ISP/EEPROM扇区擦除模式命令
   MOV   IAP_ADDRH,DPH           ;设置目标单元地址的高8位地址
   MOV   IAP_ADDRL,DPL           ;设置目标单元地址的低8位地址
   CLR   EA
   MOV   IAP_TRIG,#5AH           ;先送5Ah,再送A5hISP/IAP触发寄存器,每次都需如此
   MOV   IAP_TRIG,#0A5H         ;送完A5h后,ISP/IAP命令立即被触发起动
   NOP
   SETB  EA
    ACALL IAP_Disable ;关闭 IAP功能,清相关的特殊功能寄存器,使CPU处于安全状态,
                      ;一次连续的IAP操作完成之后建议关闭IAP功能,不需要每次都关
   RET
;------------------------------------------------
IAP_Disable:
;关闭 IAP功能,清相关的特殊功能寄存器,使CPU处于安全状态,
;一次连续的IAP操作完成之后建议关闭IAP功能,不需要每次都关
   MOV   IAP_CONTR,#0            ;关闭 IAP功能
   MOV   IAP_CMD, #0             ;清命令寄存器,使命令寄存器无命令,此句可不用
   MOV   IAP_TRIG,#0             ;清命令触发寄存器,使命令触发寄存器无触发,此句可不用
   MOV   IAP_ADDRH,#0FFH  ;送地址高字节单元为00,指向非EEPROM
   MOV   IAP_ADDRL,#0FFH  ;送地址低字节单元为00,防止误操作
   RET

S:    PUSH ACC
      PUSH PSW
      PUSH DPH
      PUSH DPL
JS0:   CLR ES
       CLR EA
       SETB  REN  ;允许接收
       LCALLPDRI     ;等待串口数据
       MOV  A,  SBUF   ;读输入缓冲区
       CLR RI
       MOV B,A
       XRLA,#66H         ;擦除EEPROM
       JNZ JS
       AJMP JS3
JS:    MOV A,B
       XRLA,#77H       ;EEPROM发送到PC
       JZ FS6
       MOV A,B
       SUBBA,#28H     ;30H="0" ,如果第一个字节是“01”表示16进制发送,如果是“30H”表示ASC码接收
       JC  JS1        ;8asc码是38h-28hc=0(01h,10h先发送2个小于28的命令字符)-28h,c=1.Js1十六进制接收,(36,37,38)-28h,c=0,ascii接收
       LCALL PDRI;等待下一个串口数据
       MOV  A,  SBUF   ;读输入缓冲区
       MOV R2,A
       CLR RI
       XRLA,#36H       ;ASC码接收时命令改成6677  ;擦除EEPROM
       JNZ JSI
       AJMP JS3
FS6:   AJMP FS0
JSI:    MOV A,B
       XRLA,#37H       ;EEPROM发送到PC
       JNZ JSA
       AJMP FS0
JSA:   MOVA,B          ;分离出汉字长度81624EEPROM0000单元
       ANL A,#0FH
       SWAP A
       MOV B,A
       MOV A,R2
       ANL A,#0FH
       ORL A,B
       MOV    DPTR,#0000H
       LCALL  Byte_Program
JSI1:   MOVR2,#00h      ;ascii码接收
       MOV R5,#04H;02h
       MOV    DPTR,#0001H
SI8:     SETBREN         ;接收第一个字节时没有清除RI,所以还得从2CH开始接收
       MOV R2,#00h
SI9: MOV R0,#2CH
       LCALL PDRI  ;PC发来的是ASCII,要读入2ASC码才能合成一个字节数据
     MOVA,   SBUF ;读输入缓冲区
       CLR RI;软件清除串口中断标记
         MOV   @R0,A   ;数据送RAM
      INC  R0            ;数据地址加1
SI10:   LCALLPDRI
     MOVA,   SBUF ;读输入缓冲区
       CLR RI;软件清除串口中断标记
         MOV   @R0,A   ;数据送RAM
      DEC  R0           ;数据地址减1,回到第一个字节
LASC: LCALL  ASC
       SWAP   A
       MOV  DBUF,  A
       INC   R0              ;数据地址加1
       LCALL  ASC
       ORL DBUF,A
       MOVA,DBUF             ;
       LCALL Byte_Program          ;字节编程写入A
       CLR RI;软件清除串口中断标记
       INC DPTR
      DJNZ R2,SI9
       DJNZ R5,SI8
       AJMP SEND1

JS1:   MOV    DPTR,#0000H
       MOV A,B
       LCALL  Byte_Program;MOV R2,#00H
JS2:   MOV    DPTR,#0001H
    SETB  REN ;允许接收
S2:    LCALL PDRI;等待下一个串口数据
       MOV  A,  SBUF   ;读输入缓冲区
       LCALL Byte_Program          ;字节编程写入A
       CLR RI;软件清除串口中断标记
       INC DPTR
       MOV A,DPH
       CJNE A,#04H ,S2
       AJMP SEND
FS0:   ;MOV R2,#00H
       MOV    DPTR,#0000H  ;EEPROM测试起始地址送DPTR数据指针
FS:   LCALL Byte_Read   ;MOVX A,@DPTR;读芯片内部扩展的EXTRAM
       MOV    SBUF,   A
       JNB    TI,    $
       CLR    TI
       INC DPTR
       MOV A,DPH
       CJNE A,#04H ,FS;DJNZ R2,FS
       AJMP SEND
JS3:   MOV    DPTR,#0000H  ;EEPROM测试起始地址送DPTR数据指针
       LCALL  Sector_Erase ;擦除整个扇区
       MOV    DPTR,#0200H  ;EEPROM测试起始地址送DPTR数据指针
       LCALL  Sector_Erase ;擦除整个扇区
       AJMP SEND
SEND1:  SETBFLAG_1
SEND:   POP DPL
      POP DPH
      POP PSW
      POP ACC
       SETB ES
       SETB EA
SD:  RETI


FS1:   PUSH ACC
      PUSH PSW
      PUSH DPH
      PUSH DPL
       MOV R5,#04H;02H
       MOV    DPTR,#0000H  ;EEPROM测试起始地址送DPTR数据指针
       CLR    ES
       MOV R0,#2CH
FS2:   MOV R2,#00H
FS3:   LCALL Byte_Read   ;
       MOV @R0,A
       CALL FSD
       INC DPTR
       DJNZ R2,FS3
       DJNZ R5,FS2
       CLR  FLAG_1
       SETB   ES
       POP DPL
      POP DPH
      POP PSW
      POP ACC
       RET


ASC:   MOV   A,   @R0
       CLR   C
       SUBB   A,   #30H
       MOV   R6,   A
       SUBB  A,   #0AH    ;0-9的数字不够减 30-39=0-9
       JC    ASCEND
       XCH   A,   R6
       SUBB  A,  #07H     ;A-F的数字再减,比如A=41H-30H-7=A, 41-47=A-F
       MOV   R6,  A
ASCEND:MOV   A,   R6
       RET
FSD:      MOV DPTR,#0FD0H
       MOV    A,   @R0
FSD1:  ANL    A,     #0F0H
       SWAP   A
       MOVC A,@A+DPTR
       MOV    SBUF,   A
       JNB    TI,    $
       CLR    TI
       MOV    A,   @R0
       ANL    A,     #0FH
       MOVCA,@A+DPTR
       MOV    SBUF,   A
       JNB    TI,    $
       CLR    TI
       ;INC    R0
       RET

PDRI:          SETB REN;占用R4/R5/R1
              MOV R1,#100;20;300毫秒超时退出!
PBZ:          MOV R4,#25;50;100;67
DY2:          MOV R5,#2;4;8
DY1:          JB RI,KKQ;检测到RI1就退出
              DJNZ R5,DY1;25微秒检测一次
              JB RI,KKQ;检测到RI1就退出
              SETB C;程序正常时C=1
              DJNZ R4,DY2;内循环50毫秒
              DJNZ R1,PBZ;超时退出
              CLR C;对串口接收超时退出C=0
              CLRRI;清除有串口数据标志
KKQ:          RET

END




LED显示屏显示时钟

首先在原电路基础上添加一个时钟模块DS20001,如下图:


然后把单片机显示程序改变如下:
T1:     MOVR3,#00H     ;行扫描 R3控制行数从0000000000010000,ABCD的变化给138译码0F扫描16行,当10时扫描结束
         MOV   DPTR , #TABSZ   ;取数字
         MOV R2,#160
         SETBEN         ;138片选,行输出使能

  ZJ1:   ACALLMON          ;取月数据首址
         ACALL HOU          ;取时数据首址 调显示

         MOVA,MONTH        ;取月数据首址+1,第二位
         ANL A,#0FH
         ACALL MON1

          MOVA,HOUR        ;取时数据首址
          ANL A,#0FH
          ACALLHOU1        ;2         调显示

          MOV A,R2;#160
          ACALLYUE        ;取“月”字数据首址

          MOVA,R2       ;"-"字数据首址
          ADD A,#64
          ACALLSHI        ;3            调显示

          MOVA,R2       ;取“月”字数据首址+1
          ADD A,#01H
          ACALL YUE

          MOVA,MINUTE     ;取分数据首址
          LCALLHOU0       ;4           调显示

          MOVA,DAY        ;取日数据首址
          ACALLMON0       ;5

          MOVA,MINUTE     ;""数据首址+1
          ANL A,#0FH
          ACALLHOU1       ;6           调显示

          MOVA,DAY        ;取日数据首址+1
          ANL A,#0FH
          ACALL MON1

          MOVA,R2       ;"-"字数据首址
          ADD A,#64
          ACALLSHI        ;7          调显示

          MOVA,#32       ;取日字的汉字点阵首址
          ADD A,R2
          ACALLYUE

          MOVA,SECOND       ;取秒数据首址
          ACALLHOU0         ; 调显示

          MOVA,#33      ;取日字的汉字点阵首址+1
          ADD A,R2
          ACALL YUE

          MOVA,SECOND       ;取秒数据首址+1
          ANL A,#0FH
          ACALLHOU1       ;8      调显示

          INC R2
          ;DEC DPH
          INC DPTR

          SETB   STB
          NOP
          CLR    STB

          MOVA,R3                 ;138地址ABCD
          MOVP1,A                 ;P2.0-P2.3=ABCD
          INC R3
          MOV A,R3
          XRLA,#10H           ;00-08是前8行,08-10H是后8;
          JNZZJ1             ;送前16
          MOV WDT_CONTR ,#17H;喂狗CLR EN
          JNB FLAG_1,TZ0
          CALLFS1
TZ0:      AJMP T1


MON:      MOV A,MONTH
MON0:     ANL A,#0F0H
          SWAP A
MON1:     MOV B,#10H
          MULAB       ;B放结果高8位,A放结果低8
          MOVC  A, @A+DPTR ;16*16点阵,每行显示4个汉字,32条水平线,(1个汉字占16条水平线)2行显示8个汉字,所以先取第一行的一个字节,显示半个汉字(牡)
          CPLA                     ;再跳过8个字节(4个汉字)取第二行1个字节数据(校)
          MOV R6,A
          RET
HOU:      MOV A,HOUR
HOU0:     ANL A,#0F0H
          SWAP A
HOU1:     MOV B,#10H
          MUL AB
          MOVC  A, @A+DPTR ;16*16点阵,每行显示4个汉字,32条水平线,(1个汉字占16条水平线)2行显示8个汉字,所以先取第一行的一个字节,显示半个汉字(牡)
          CPLA                     ;再跳过8个字节(4个汉字)取第二行1个字节数据(校)
          MOV R4,A
          ACALLBIN       ;BIN2显示绿色
          RET

YUE:      ;MOV A,R2
          MOVC  A, @A+DPTR ;
          CPL A
          MOV R6,A
          RET
SHI:      MOVC  A, @A+DPTR ;
          CPL A
          MOV R4,A
          ACALLBIN       ;BIN2显示绿色
          RET
显示效果如下图:


显示程序改变如下:
T1:     MOVR3,#00H     ;行扫描 R3控制行数从0000000000010000,ABCD的变化给138译码0F扫描16行,当10时扫描结束
         MOV   DPTR , #TABSZ   ;取数字
         MOV R2,#160
         SETBEN         ;138片选,行输出使能

  ZJ1:   ACALL MON
         ACALLHOU         ;1

         MOV A,MONTH
         ANL A,#0FH
         ACALL MON1

          MOV A,HOUR
          ANL A,#0FH
          ACALLHOU1        ;2

          MOV A,R2;#160
          ACALLYUE        ;取“月”字数据首址

          MOVA,R2       ;""字数据首址
          ADD A,#64
          ACALLSHI        ;3

          MOVA,R2       ;取“月”字数据首址
          ADD A,#01H
          ACALL YUE

          MOVA,R2       ;""字数据首址
          ADD A,#65
          ACALL SHI        ;4

          MOV A,DAY
          ACALLMON0       ;5

          MOV A,MINUTE
          ACALL HOU0

          MOV A,DAY
          ANL A,#0FH
          ACALL MON1

          MOV A,MINUTE
          ANL A,#0FH
          ACALLHOU1       ;6

          MOVA,#32       ;取日字的汉字点阵首址
          ADD A,R2
          ACALL YUE

          MOVA,R2     ;""字数据首址
          ADD A,#96
          INC DPH
          ACALL SHI

          DECDPH        ;7
          MOVA,#33      ;取日字的汉字点阵首址+1
          ADDA,R2
          ACALL YUE

          INC DPH
          MOVA,R2       ;""字数据首址+1
          ADD A,#97
          ACALLSHI        ;8

          INC R2
          DEC DPH
          INC DPTR

          SETB   STB
          NOP
          CLR    STB

          MOVA,R3                 ;138地址ABCD
          MOVP1,A                 ;P2.0-P2.3=ABCD
          INC R3
          MOV A,R3
          XRLA,#10H           ;00-08是前8行,08-10H是后8;
          JNZZJ1             ;送前16
          MOV WDT_CONTR ,#17H;喂狗CLR EN
          JNB FLAG_1,TZ0
          CALL FS1
TZ0:      AJMP T1


MON:      MOV A,MONTH
MON0:     ANL A,#0F0H
          SWAP A
MON1:     MOV B,#10H
          MULAB       ;B放结果高8位,A放结果低8
          MOVC  A, @A+DPTR ;16*16点阵,每行显示4个汉字,32条水平线,(1个汉字占16条水平线)2行显示8个汉字,所以先取第一行的一个字节,显示半个汉字(牡)
          CPLA                     ;再跳过8个字节(4个汉字)取第二行1个字节数据(校)
          MOV R6,A
          RET
HOU:      MOV A,HOUR
HOU0:     ANL A,#0F0H
          SWAP A
HOU1:     MOV B,#10H
          MUL AB
          MOVC  A, @A+DPTR ;16*16点阵,每行显示4个汉字,32条水平线,(1个汉字占16条水平线)2行显示8个汉字,所以先取第一行的一个字节,显示半个汉字(牡)
          CPLA                     ;再跳过8个字节(4个汉字)取第二行1个字节数据(校)
          MOV R4,A
          ACALLBIN       ;BIN2显示绿色
          RET

YUE:      ;MOV A,R2
          MOVC  A, @A+DPTR ;
          CPL A
          MOV R6,A
          RET
SHI:      MOVC  A, @A+DPTR ;
          CPL A
          MOV R4,A
          ACALLBIN       ;BIN2显示绿色
          RET

显示效果如下图:


通过串口发送命令:“8816011801123045”可修改时间和日期,含义是16年一月18日星期一123045秒。
还可以通过串口发送命令“99”,读取时钟模块的日期和时间。

完整程序请在我的网盘下载。


采用STC12C5A60S2单片机的LED显示屏驱动程序
一、原理图如下,由于LED显示屏上的驱动集成电路使用了74HC245集成电路(前面的例子是使用74HC244),使能端并取消了74LS04,所以驱动电路有所变化,相应的程序也有所改变。原来74LS138使能端经74LS04反相是低电平,现在取消了74LS04就变为高电平了

二、显示效果如下:2个画面交替显示。
三、STC12C5A60S2单片机简介
STC12C5A60S2是STC生产的单时钟/机器周期(1T)的单片机,是高速、低功耗、超强抗干扰的新一代8051单片机,指令代码完全兼容传统8051,但速度快8-12倍。内部集成MAX810专用复位电路,2路PWM,8路高速10位A/D转换,针对电机控制,强干扰场合。
1、增强型8051CPU,单时钟/机器周期,stc12c5a60s2的运行速度比at89s52要快12
2、工作电压 5.5-3.5V
360K字节ROM1280字节数据RAM
4、通用I/O口,复位后为:准双向口/弱上拉
可设置成四种模式:准双向口/弱上拉,强推挽/强上拉,仅为输入/高阻,开漏
每个I/O口驱动能力均可达到20mA,但整个芯片最大不要超过120mA
5、有1K字节的EEPROM,擦写次数在10万次以上
6、看门狗
7、内部集成MAX810专用复位电路
8、外部掉电检测电路
9、时钟源:外部高精度晶体/时钟,内部R/C振荡器
常温下内部R/C振荡器频率为:5.0V单片机为:11~17MHz3.3V单片机为:8~12MHz
10416位定时器,两个与传统8051兼容的定时器/计数器,16位定时器T0T1
113个时钟输出口,可由T0的溢出在P3.4/T0输出时钟,可由T1的溢出在P3.5/T1输出时钟,独立波特率发生器可以在P1.0口输出时钟
12、外部中断I/O7路,传统的下降沿中断或电平触发中断,并新增支持上升沿中断的PCA模块,PowerDown模式可由外部中断唤醒,INT0/P3.2INT1/P3.3T0/P3.4T1/P3.5RxD/P3.0CCP0/P1.3CCP0/P1.3
132PWM
14A/D转换,10位精度ADC,共8路,转换速度可达250K/S
15、通用全双工异步串行口(UART)
16、双串口,RxD2/P1.2TxD2/P1.3
17、工作范围:-40~85
18、封装:LQFP-48LQFP-44PDIP-40PLCC
四、温度测量原理:采用NTC热敏电阻器与一个固定电阻分压,如下图随着温度的变化,分压值也会变化,用STC12C5A60S2单片机的A/D转换器采集这个分压值,在单片机中设置一个电压与温度的对应表(这个表通过实验获得),根据采集的电压值获取对应的温度值,显示出来并保存在单片机内存中。


五、显示程序
          ORG 0000H
       AJMPKS        ;显示xxxx 室温xx度,11.0592MHZSTC12C5A60S2单片机 ,带时钟,可交替显示温度。88命令修改时间日期,99命令查询日期时间2016-01-27 通过
      ORG0003H       ;XXXXXXXX-X
      RETI
       ORG 000BH
        LJMP CT
        RETI
       ORG 001BH
       RETI

       ORG 0023H
       AJMPS        ;接收数据转S
       A1  EQU P0.0   ;P1.0=A         2
       B1   EQU P0.1   ;P1.1=B         4
       C1   EQU P0.2   ;P1.2=C         6
       D1   EQU P0.3   ;P1.3=D         8
       G1   EQU P2.6   ;数据输出G1=B4
       G2   EQU P2.7  ;数据输出  G2=B5
       STB  EQU P2.5    ;595数据锁存脉冲=L12
       SCK  EQU P2.4    ;595时钟输入=S   11
       R11  EQU P2.3   ;改为81R22改为80,上下显示颠倒
       R22  EQU  P2.2
       EN   EQU P2.1    ;138片选,行输出使NENG
       ADC_Channel_1_Result EQU 2FH
       DBUF EQU 60H
       ZS EQU 61H
       HM      EQU   1EH            ;定时器毫秒存储
       WDT_CONTR   EQU 0C1H
       AUX1     EQU   0A2H           ;AUXR1寄存器的ADRJ位是A/D转换结果寄存器(ADC_RES,ADC_RESL)的数据格式调整控制位.
;ADRJ=0时,..............................................10A/D转换结果的高8位存放在ADC_RES中,低2位存放在ADC_RESL的低2位中.
       ;AUR EQU 8EH; Internal/External RAM access 内部/外部RAM存取= 0:内部扩展的EXT_RAM可以存取.
       FLAG_1 EQU    20H.1          ;
       FLAG_2 EQU    20H.1          ;
       FLAG_3 EQU    20H.1          ;
       YEAR   EQU    28H            ;
       MONTH  EQU    29H            ;
       DAY    EQU    2AH            ;
       WEEK   EQU    2BH            ;星期
       HOUR   EQU    2CH            ;小时
       MINUTE EQU    2DH            ;分钟
       SECOND EQU    2EH            ;
       FLAG   EQU    27H            ;通用标志寄存器
                                       ;BIT0=1, ACK ERR
                                       ;BIT0=0,ACK OK
                                       ;BIT1=1,TEST MODE
                                       ;BIT1=0,NORMAL MODE
       P1M0 DATA 92H
       P1M1 DATA 91H
       P0M0 DATA 94H
       P0M1 DATA 93H
       P2M0 DATA 96H
       P2M1 DATA 95H
       TIMETEMP       EQU    27H    ;时间数据缓存器
       TIMETX         EQU    59H    ;时间数据发送寄存器
       TIMERX         EQU    5AH    ;时间数据接收寄存器
       SDA            EQU    0b5h   ;IICSDA口线 15
       SCL            EQU    0b7h   ;IICSCL口线 13
       LED            EQU    0B6H
       ;声明与IAP/ISP/EEPROM有关的特殊功能寄存器的地址
       IAP_DATA       EQU   0C2H
       IAP_ADDRH      EQU   0C3H
       IAP_ADDRL      EQU   0C4H
       IAP_CMD        EQU   0C5H
       IAP_TRIG       EQU   0C6H
       IAP_CONTR      EQU   0C7H
       ;定义ISP/IAP命令
       ISP_IAP_BYTE_READ  EQU  1H   ;字节读
       ISP_IAP_BYTE_PROGRAM  EQU   2H ;字节编程,可以将1写成0,要将1变成0,必须执行字节编程
       ISP_IAP_SECTOR_ERASE    EQU 3H ;扇区擦除,可以将0擦成1,要将0变成1,必须擦除整个扇区
       ;定义Flash 操作等待时间及允许IAP/ISP/EEPROM操作的常数
       ENABLE_IAP     EQU  84H    ;系统工作时钟<6MHz时,对IAP_CONTR寄存器设置此值
       ;AD转换设置
       ADC_CONTR EQU 0BCH ;ADC control register
      ; SFR name Address bit B7  B6     B5    B4      B3      B2  B1   B0
   ;ADC_CONTR BCH name ADC_POWER SPEED1 SPEED0 ADC_FLAG ADC_START CHS2CHS1 CHS0
       ADC_RES EQU 0BDH ;ADC high 8-bit result register
       ADC_LOW2 EQU 0BEH ;ADC low 8-bit result register
       P1ASF EQU 09DH ;P1 secondary function control register
       ADC_FLAG EQU 10H ;ADC complete flag
       ADC_Power_On_Speed_Channel_1EQU 11100000B   ;;B7=power,B6B5=speed,B4=flag,B3=start;B2B1B0=ch0-ch7001P1.1作为A/D输入,000P1.0输入

  KS:   MOVSP,#65H   ;设堆栈指针
        MOV SCon,#50h; 方式1,REN=1.SM0SM1SM2REN,TB8RB8TI,RI
        MOV TMOD,#21H;波特率发生器T1工作在模式2
MOVTH1,#0FDH;预置初值(按照波特率9600BPS预置初值)11.0592=9600=FD         MOV TL1,#0FDH;
        MOV  TH0,#0DCH;88H     ;8800=12t,7000=stc1t
      MOV  TL0, #00H
        ORL IE, #92H  ;EA=1ES=1;ET0=1
        SETBPS       ;串口中断优先
        SETBTR1      ;启动定时器1
        SETB EN
        MOVP0M0,#00000000b     ; P1M0=0 P1M1=0双向口   P1M0=1 P1M1=0输入口   P1M0=0 P1M1=1推挽输出20ma
        MOV P0M1,#00000000b
        MOVP2M0,#00000000b     ; P1M0=0 P1M1=0双向口   P1M0=1 P1M1=0输入口   P1M0=0 P1M1=1推挽输出20ma
        MOVP2M1,#00000000b
        MOV   ADC_CONTR,#ADC_Power_On_Speed_Channel_1;AD转换设置
        ;ANL AUX1,#11111011B   ;ADRJ =0
        LCALL INIT_ADC
        MOV WDT_CONTR ,#27H;;;;;;看门狗设置使能
Q:      MOV A,#0;FFH
       MOVR2,#64D    ;清数据区
       MOV R0,#20H
  QING:  MOV@R0,A     ;清数据区
       INC R0
       DJNZ R2,QING
        LCALL  TIMESTATUS_INT12       ;24小时制
        LCALL READ_TIME   ;
        MOV WDT_CONTR ,#17H;喂狗CLR EN
         SETBTR0          ;启动定时器0
Q1:     SETB G1
         SETBG2         ;G1,G2送数显示绿色
         SETBR11
         SETBR22        ;R11R22送数显示红色
         CLR LED
T1:     MOVR3,#00H     ;行扫描R3控制行数从0000000000010000,ABCD的变化给138译码0F扫描16行,当10时扫描结束
         MOV   DPTR , #TABSZ   ;取数字
         MOV R2,#160
         CLREN               ;138片选,行输出使能
         MOV A,SECOND;根据秒数据交替显示
         ANL A,#0FH
         SUBB A,#5
         JNC ZJ1
         AJMP ZJ2
  ZJ1:    MOVA,R2       ;取“温“字数据首址+1
          ADD A,#96
          INC DPH
          ACALL YUE
          DEC DPH
          ACALLHOU          ;取时数据首址 1调显示

          MOVA,R2       ;取“温“字数据首址+1
          ADD A,#97
          INC DPH
          ACALL YUE
          DEC DPH

          MOVA,HOUR        ;取时数据首址低字节
          ANL A,#0FH
          ACALLHOU1        ;2         调显示

          MOVA,R2       ;""字数据首址
          ADD A,#128
          INC DPH
          ACALL YUE
          DEC DPH

          MOVA,MINUTE     ;取分数据首址
          ACALLHOU2        ;3调显示

          MOVA,R2       ;""字数据首址+1
          ADD A,#129
          INC DPH
          ACALL YUE
          DEC DPH
          MOVA,MINUTE     ;""数据首址+1
          ANL A,#0FH
          ACALLHOU3      ;4调显示

          MOV A,ADC_Channel_1_Result
          MOVR5,A         ;A/D结果送R5
          LCALL HEX2BCD  ;影响单元:R0,R1,R6 R1A/D结果转换成BCD的十位和个位
          ACALL MON0

          MOVA,SECOND       ;取秒数据首址
          ACALLHOU0         ; 5调显示

          MOV A,ADC_Channel_1_Result
          MOVR5,A         ;A/D结果送R5
          LCALL HEX2BCD  ;影响单元:R0,R1,R6 R1A/D结果转换成BCD的十位和个位
          ANL A,#0FH
          ACALLMON1       ;

          MOVA,SECOND       ;取秒数据首址+1
          ANL A,#0FH
          ACALLHOU1       ;6      调显示

          MOVA,R2       ;""字数据首址+1
          ADD A,#128
          INC DPH
          ACALL YUE
          DEC DPH

          MOVA,R2       ;"-"字数据首址
          ADD A,#64
          ACALLSHI        ;7          调显示

          MOVA,R2       ;""字数据首址+1
          ADD A,#129
          INC DPH
          ACALL YUE
          DEC DPH

          MOVA,WEEK      ;取星期数据首址+1
          ANL A,#0FH
          ACALLHOU3      ;8      调显示

          INC R2
          INC DPTR

          SETB   STB
          NOP
          CLR    STB

          MOV A,R3                 ;138地址ABCD
          MOVP0,A                 ;P2.0-P2.3=ABCD
          INC R3
          MOV A,R3
          XRLA,#10H           ;00-08是前8行,08-10H是后8;
          JNZZJ1             ;送前16
          MOV WDT_CONTR ,#17H;喂狗CLR EN
          JNB FLAG_1,TZ0
          CALL FS1
TZ0:      AJMP T1

  ZJ2:   ACALLMON          ;取月数据首址
         ACALLHOU          ;取时数据首址 调显示

         MOVA,MONTH        ;取月数据首址+1,第二位
         ANL A,#0FH
         ACALL MON1

          MOV A,HOUR        ;取时数据首址+1
          ANL A,#0FH
          ACALLHOU1        ;2         调显示

          MOV A,R2;#160
          ACALLYUE        ;取“月”字数据首址

          MOVA,MINUTE     ;取分数据首址
          ACALLHOU2;0        ;调显示

          MOVA,R2       ;取“月”字数据首址+1
          ADD A,#01H
          ACALL YUE

          MOVA,MINUTE     ;""数据首址+1
          ANL A,#0FH
          ACALLHOU3;1       ;6           调显示

          MOVA,DAY        ;取日数据首址
          ACALLMON0       ;5

          MOVA,SECOND       ;取秒数据首址
          ACALLHOU0         ; 调显示

          MOVA,DAY        ;取日数据首址+1
          ANL A,#0FH
          ACALL MON1

          MOVA,SECOND       ;取秒数据首址+1
          ANL A,#0FH
          ACALLHOU1       ;8      调显示

          MOVA,#32       ;取日字的汉字点阵首址
          ADD A,R2
          ACALL YUE

         ; MOVA,WEEK       ;取星期数据首址
          ;ACALLHOU2;0        ; 调显示
          MOVA,R2       ;"-"字数据首址
          ADD A,#64
          ACALLSHI        ;7          调显示

          MOVA,#33      ;取日字的汉字点阵首址+1
          ADD A,R2
          ACALL YUE

          MOVA,WEEK      ;取星期数据首址+1
          ANL A,#0FH
          ACALL HOU3;1      ;8      调显示

          INC R2
          ;DEC DPH
          INC DPTR

          SETB   STB
          NOP
          CLR    STB

          MOVA,R3                 ;138地址ABCD
          MOVP0,A                 ;P2.0-P2.3=ABCD
          INC R3
          MOV A,R3
          XRLA,#10H           ;00-08是前8行,08-10H是后8;
          JNZZJ2             ;送前16
          MOV WDT_CONTR ,#17H;喂狗CLR EN
          JNB FLAG_1,TZ3
          CALL FS1

TZ3:      AJMP T1
MON:      MOV A,MONTH
MON0:     ANL A,#0F0H
          SWAP A
MON1:     MOV B,#10H
          MULAB       ;B放结果高8位,A放结果低8
          MOVC  A, @A+DPTR ;16*16点阵,每行显示4个汉字,32条水平线,(1个汉字占16条水平线)2行显示8个汉字,所以先取第一行的一个字节,显示半个汉字(牡)
          CPLA                     ;再跳过8个字节(4个汉字)取第二行1个字节数据(校)
          MOV R6,A
          RET
HOU:      MOV A,HOUR
HOU0:     ANL A,#0F0H
          SWAP A
HOU1:     MOV B,#10H
          MUL AB
          MOVC  A, @A+DPTR ;16*16点阵,每行显示4个汉字,32条水平线,(1个汉字占16条水平线)2行显示8个汉字,所以先取第一行的一个字节,显示半个汉字(牡)
          CPLA                     ;再跳过8个字节(4个汉字)取第二行1个字节数据(校)
          MOV R4,A
          ACALLBIN       ;BIN2显示绿色
          RET

HOU2:     ANL A,#0F0H
          SWAP A
HOU3:     MOV B,#10H
          MUL AB
SHI:      MOVC  A, @A+DPTR ;16*16点阵,每行显示4个汉字,32条水平线,(1个汉字占16条水平线)2行显示8个汉字,所以先取第一行的一个字节,显示半个汉字(牡)
          CPLA                     ;再跳过8个字节(4个汉字)取第二行1个字节数据(校)
          MOV R4,A
          ACALLBIN2       ;BIN2显示绿色
          RET
YUE:      ;MOV A,R2
          MOVC  A, @A+DPTR ;
          CPL A
          MOV R6,A
          RET

BIN:   MOV  R5, #08H  ;G1G2,或R11R22中写一个字节数据
BIN1:  RLC  A
      ; MOV  R11, C  ;写上半屏红色
       MOV  G1,C    ;写上半屏红色
       MOV R4,A
       MOV A,R6
       RLC A
      ; MOV R22,C   ;下半屏红色
       MOV R22,C    ;下半屏绿色
       MOV R6,A
       MOV A,R4
       SETB  SCK
       NOP;CALL SDELAY
       NOP
       NOP
       CLR SCK
       DJNZ  R5,  BIN1
       RET
BIN2:  MOV  R5, #08H  ;G1G2,或R11R22中写一个字节数据
BIN3:  RLC  A
       MOV  G1,C     ;G1
       MOV R4,A
       MOV A,R6
       RLC A
       MOV R22,C   ;下半屏红色G1 R22 红色的日
       MOV R6,A
       MOV A,R4
       SETB  SCK
       NOP
       NOP
       CLR SCK
       DJNZ  R5,  BIN3

       RET



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏2 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:83069 发表于 2018-4-17 11:51 | 只看该作者
好文章,就是汇编不懂,能发个c的不?
回复

使用道具 举报

板凳
ID:279667 发表于 2018-5-31 08:58 | 只看该作者
不懂汇编...看着挺费劲的...有C版本的么?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表