59pic USART 232汇编程序
2017-12-06 来源:eefocus
INCLUDE
LIST P=PIC16F877
;__CONFIG _CP_OFF & _DEBUG_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC & _LVP_OFF ;PIC16F877
;__IDLOCS 0x7206
errorlevel -302
errorlevel -203
CBLOCK 20H
COUNTERH
COUNTERL
COUNTER
TEMP1
TEMP2
TEMP3
TEMP4
TEMP_A
TEMP_B
TEMP_C
DADR
CNT
EE_DADR
ENDC
#DEFINE START_KEY PORTB,1
#DEFINE BELL PORTD,0
ORG 00H
NOP
GOTO START
ORG 04H
GOTO _INT
; ORG 0100H
;********************************************
;查问题回答 1 字符表(共 25 个字符)
TABLE1
ADDWF PCL,F
DT '\n\r-My name is P16F877.\n\n\r'
;\n 换行
;\r 回车
;查问题回答 2 字符表(共 22 个字符)
TABLE2
ADDWF PCL,F
DT '\n\r-I’m 3 years old.\n\n\r'
;查问题回答 3 字符表(共 27 个字符)
TABLE3
ADDWF PCL,F
DT '\n\r-I’m born in ShangHai.\n\n\r'
;查问题回答 4 字符表(共 34 个字符)
TABLE4
ADDWF PCL,F
DT '\n\r-Yes,I like sports very much.\n\n\r'
;查问题回答 5 字符表(共 28 个字符)
TABLE5
ADDWF PCL,F
DT '\n\r-The date is 2007-2-15.\n\n\r'
;*******************************************
;初始化和提示信息字符表(共 74 个字符)
TABLE
ADDWF PCL,F
DT '\nHello!\n\r'
DT 'I’m your new friend,Nice to meet you.'
DT 'What do you want to know?\n\n\r'
;********************************************
ORG 0100H
;********************************************
;问题 5 字符表(共 22 个字符)
TAB5
ADDWF PCL,F
DT 'What’s the date today?'
;问题 4 字符表(共 19 个字符)
TAB4
ADDWF PCL,F
DT 'Do you like sports?'
;问题 3 字符表(共 20 个字符)
TAB3
ADDWF PCL,F
DT 'Where were you born?'
;问题 2 字符表(共 16 个字符)
TAB2
ADDWF PCL,F
DT 'How old are you?'
;问题 1 字符表(共 17 个字符)
TAB1
ADDWF PCL,F
DT 'What’s your name?'
;********************************************
;错误提示 1 字符表(共 64 个字符)
TABLE6
ADDWF PCL,F
DT '\n\r-Sorry.I CANnot answer the question.'
DT 'Please ask another one.\n\n\r'
;错误提示 2 字符表(共 48 个字符)
TABLE7
ADDWF PCL,F
DT '\n\r-What your enter is wrong.Please try again.\n\n\r'
;********************************************
ORG 0200H
_INT
NOP
NOP
RETFIE
START
NOP
BSF STATUS,RP0 ;定义RA口,RC口全部为输出
MOV LW 06H ;
MOV WF ADCON1 ;设置RA口全部为普通数字IO口
MOV LW B’00110000’ ;
MOV WF TRISA
MOV LW B’11011000’ ;设置SCL为输入, SDA为输入
MOV WF TRISC
MOV LW 00H
MOV WF TRISD ;
MOV LW 0FFH
MOV WF TRISB
BCF OPTION_REG,7
BCF STATUS,RP0
;********** IIC 初始化设置 ************
MOV LW 08H ;初始化SSPCON,
MOV WF SSPCON ;IIC主控模式
BCF PIR1,SSPIF
BSF STATUS,RP0
MOV LW 80H ;初始化SSPSTAT寄存器,
MOV WF SSPSTAT ;传送速率为标准模式100KHz
MOV LW 09H
MOV WF SSPADD ;设定IIC时钟频率
CLRF SSPCON2 ;初始化SSPCON2
BSF PIE1,SSPIE ;SSP中断允许
CLRF INTCON
BSF INTCON,PEIE ;开中断
BSF INTCON,GIE
BCF STATUS,RP0
BSF SSPCON,SSPEN ;SSP模块使能
;********** IIC 初始化设置结束 ************
;********** USART 初始化设置开始 ************
ST BSF STATUS,RP0
MOV LW B’00100100’
MOV WF TXSTA ;异步方式,高波特率,发送使能
MOV LW .25
MOV WF SPBRG ;设置波特率 9600,Fosc=4MHz
BCF STATUS,RP0
MOV LW B’10010000’ ;设置连续接收数据
MOV WF RCSTA
; CLRF INTCON
BSF STATUS,RP0
CLRF PIE1
BCF STATUS,RP0
;********** USART 初始化设置结束 ************
CLRF PORTA
; CLRF PORTB
CLRF PORTD
CALL CLR_RAM
BEGIN
;Read Test Counter Value from EEPROM***********************
MOV LW 20H ;read counterl counterh from eeprom
MOV WF DADR
MOV LW .2
MOV WF CNT
MOV LW 00H
MOV WF EE_DADR
CALL EE_READ
;Read Test Counter Value from EEPROM***********************
;Compare Test Counter Value is zero?************************
CLRZ
MOV F COUNTERH,F
BTFSS STATUS,Z
GOTO PRESS_START_KEY
CLRZ
MOV F COUNTERL,F
BTFSS STATUS,Z
GOTO PRESS_START_KEY
CALL _ERROR_BELL
GOTO BEGIN
;Compare Test Counter Value is zero?************************
PRESS_START_KEY
BTFSC START_KEY ;按开始键开始测试
GOTO $-1
CALL DELAY20MS
BTFSC START_KEY
GOTO $-4
BTFSS START_KEY
GOTO $-1
CALL DELAY20MS
BTFSS START_KEY
GOTO $-4
;Test Counter decrease 1****************************
MOV LW .1 ;conter decrease 1
SUBWF COUNTERL,F
BTFSS STATUS,C
DECF COUNTERH,F
CALL RAM_TO_EE ;write counterl counterh to eeprom
;Test Counter decrease 1****************************
; GOTO BEGIN
;输出问候语
CSH
MOV F COUNTER,W
; BSF PCLATH,0
CALL TABLE
; BCF PCLATH,0
CALL FASONG
CALL DELAY3
INCF COUNTER
MOV F COUNTER,W
SUBLW .74
BTFSS STATUS,Z
GOTO CSH
;********************************************
;开始检测并储存外界输入
LOOP
CLRF PIR1 ;清 RCIF
CLRF COUNTER
MOV LW 30H
MOV WF FSR
BCF PIR1,RCIF
JIESHU NOP
LRC BTFSS PIR1,RCIF
GOTO LRC
MOV F RCREG,W
SUBLW '\r' ;与 Enter 对应的 ASCII 码比较
BTFSC STATUS,Z
GOTO WTPD ;按了回车键,转判断子程序
MOV F RCREG,W
SUBLW '\b' ;与退格键 BacksPACe 对应的 ASCII 码比较
BTFSC STATUS,Z
GOTO TUIGE ;按了退格键,转退格处理
MOV F RCREG,W
CALL FASONG
MOV WF INDF
INCF FSR
GOTO LRC
;********************************************
;退格处理子程序
TUIGE
MOV F RCREG,W
CALL FASONG
DECF FSR
GOTO LRC
;********************************************
;问题判断子程序
WTPD
MOV F RCREG,W
MOV WF INDF
;********************************************
;和第一个问题进行比较
PD1
CLRF COUNTER
MOV LW 30H
MOV WF FSR
LP1
MOV F COUNTER,W
; BSF PCLATH,1
BSF PCLATH,0
CALL TAB1
BCF PCLATH,0
; BCF PCLATH,1
SUBWF INDF,W ;查表所得的数据与 INDF 的内容相减,结果送 W
BTFSS STATUS,Z
GOTO PD2 ;内容不符,转 PD2 判断
INCF FSR ;内容相符,数据存储地址加一
INCF COUNTER
MOV F COUNTER,W
SUBLW .17 ;判断是否已到第一个问题的 17 个字符数
BTFSS STATUS,Z
GOTO LP1 ;没到,继续第一个问题的判断
MOV LW '\r' ; Enter ??
SUBWF INDF,W
BTFSS STATUS,Z
GOTO CUOWU2 ;不相等,后面还有内容,转到错误提示2
CLRF COUNTER
GOTO HD1 ;转到回答1
;********************************************
;和第二个问题进行比较
PD2
CLRF COUNTER
MOV LW 30H
MOV WF FSR
LP2
MOV F COUNTER,W
; BSF PCLATH,1
BSF PCLATH,0
CALL TAB2
BCF PCLATH,0
; BCF PCLATH,1
SUBWF INDF,W ;查表所得的数据与 INDF 的内容相减,结果送 W
BTFSS STATUS,Z
GOTO PD3 ;内容不符,转 PD3 判断
INCF FSR ;内容相符,数据存储地址加一
INCF COUNTER
MOV F COUNTER,W
SUBLW .16 ;判断是否已到第一个问题的 16 个字符数
BTFSS STATUS,Z
GOTO LP2 ;没到,继续第一个问题的判断
MOV LW '\r' ; Enter ??
SUBWF INDF,W
BTFSS STATUS,Z
GOTO CUOWU2 ;不相等,后面还有内容,转到错误提示2
CLRF COUNTER
GOTO HD2 ;转到回答2
;********************************************
;和第三个问题进行比较
PD3
CLRF COUNTER
MOV LW 30H
MOV WF FSR
LP3
MOV F COUNTER,W
; BSF PCLATH,1
BSF PCLATH,0
CALL TAB3
BCF PCLATH,0
; BCF PCLATH,1
SUBWF INDF,W ;查表所得的数据与 INDF 的内容相减,结果送 W
BTFSS STATUS,Z
GOTO PD4 ;内容不符,转 PD4 判断
INCF FSR ;内容相符,数据存储地址加一
INCF COUNTER
MOV F COUNTER,W
SUBLW .20 ;判断是否已到第一个问题的 20 个字符数
BTFSS STATUS,Z
GOTO LP3 ;没到,继续第一个问题的判断
MOV LW '\r' ; Enter ??
SUBWF INDF,W
BTFSS STATUS,Z
GOTO CUOWU2 ;不相等,后面还有内容,转到错误提示2
CLRF COUNTER
GOTO HD3 ;转到回答3
;********************************************
;和第四个问题进行比较
PD4
CLRF COUNTER
MOV LW 30H
MOV WF FSR
LP4
MOV F COUNTER,W
; BSF PCLATH,1
BSF PCLATH,0
CALL TAB4
BCF PCLATH,0
; BCF PCLATH,1
SUBWF INDF,W ;查表所得的数据与 INDF 的内容相减,结果送 W
BTFSS STATUS,Z
GOTO PD5 ;内容不符,转 PD5 判断
INCF FSR ;内容相符,数据存储地址加一
INCF COUNTER
MOV F COUNTER,W
SUBLW .19 ;判断是否已到第一个问题的 19 个字符数
BTFSS STATUS,Z
GOTO LP4 ;没到,继续第一个问题的判断
MOV LW '\r' ; Enter ??
SUBWF INDF,W
BTFSS STATUS,Z
GOTO CUOWU2 ;不相等,后面还有内容,转到错误提示2
CLRF COUNTER
GOTO HD4 ;转到回答4
;********************************************
;和第五个问题进行比较
PD5
CLRF COUNTER
MOV LW 30H
MOV WF FSR
LP5
MOV F COUNTER,W
; BSF PCLATH,1
BSF PCLATH,0
CALL TAB5
BCF PCLATH,0
; BCF PCLATH,1
SUBWF INDF,W ;查表所得的数据与 INDF 的内容相减,结果送 W
BTFSS STATUS,Z
GOTO CUOWU ;内容不符,转 CUOWU 提示1
INCF FSR ;内容相符,数据存储地址加一
INCF COUNTER
MOV F COUNTER,W
SUBLW .22 ;判断是否已到第一个问题的 16 个字符数
BTFSS STATUS,Z
GOTO LP5 ;没到,继续第一个问题的判断
MOV LW '\r' ; Enter ??
SUBWF INDF,W
BTFSS STATUS,Z
GOTO CUOWU2 ;不相等,后面还有内容,转到错误提示2
CLRF COUNTER
GOTO HD5 ;转到回答2
;********************************************
;输出回答 1
HD1
MOV F COUNTER,W
; BSF PCLATH,0
CALL TABLE1
; BCF PCLATH,0
CALL FASONG
CALL DELAY3
INCF COUNTER
MOV F COUNTER,W
SUBLW .25
BTFSS STATUS,Z
GOTO HD1
GOTO LOOP ;输出完毕,转到输出检测
;输出回答 2
HD2
MOV F COUNTER,W
; BSF PCLATH,0
CALL TABLE2
; BCF PCLATH,0
CALL FASONG
CALL DELAY3
INCF COUNTER
MOV F COUNTER,W
SUBLW .22
BTFSS STATUS,Z
GOTO HD2
GOTO LOOP ;输出完毕,转到输出检测
;输出回答 3
HD3
MOV F COUNTER,W
; BSF PCLATH,0
CALL TABLE3
; BCF PCLATH,0
CALL FASONG
CALL DELAY3
INCF COUNTER
MOV F COUNTER,W
SUBLW .27
BTFSS STATUS,Z
GOTO HD3
GOTO LOOP ;输出完毕,转到输出检测
;输出回答 4
HD4
MOV F COUNTER,W
; BSF PCLATH,0
CALL TABLE4
; BCF PCLATH,0
CALL FASONG
CALL DELAY3
INCF COUNTER
MOV F COUNTER,W
SUBLW .34
BTFSS STATUS,Z
GOTO HD4
GOTO LOOP ;输出完毕,转到输出检测
;输出回答 5
HD5
MOV F COUNTER,W
; BSF PCLATH,0
CALL TABLE5
; BCF PCLATH,0
CALL FASONG
CALL DELAY3
INCF COUNTER
MOV F COUNTER,W
SUBLW .28
BTFSS STATUS,Z
GOTO HD5
; GOTO LOOP ;输出完毕,转到输出检测
CLRF COUNTER
CALL DELAY1S
CALL _PASS_BELL
GOTO BEGIN
;********************************************
;输出错误提示 1
CUOWU
CLRF COUNTER
LP6 MOV F COUNTER,W
; BSF PCLATH,1
BSF PCLATH,0
CALL TABLE6
BCF PCLATH,0
; BCF PCLATH,1
CALL FASONG
CALL DELAY3
INCF COUNTER
MOV F COUNTER,W
SUBLW .64
BTFSS STATUS,Z
GOTO LP6
GOTO LOOP
;输出错误提示 2
CUOWU2
CLRF COUNTER
LP7 MOV F COUNTER,W
; BSF PCLATH,1
BSF PCLATH,0
CALL TABLE7
BCF PCLATH,0
; BCF PCLATH,1
CALL FASONG
CALL DELAY3
INCF COUNTER
MOV F COUNTER,W
SUBLW .48
BTFSS STATUS,Z
GOTO LP7
GOTO LOOP
;********************************************
;********************************************
;USART 方式发送数据子程序
FASONG
MOV WF TXREG
BSF STATUS,RP0
BTFSS TXSTA,TRMT
GOTO $-1
BCF STATUS,RP0
RETURN
;********************************************
CLR_RAM
MOV LW 20H
MOV WF FSR
CLRF INDF
INCF FSR,F
BTFSS FSR,7
GOTO $-3
RETURN
;***********************_ERROR_BELL 子程序 **********************************
_ERROR_BELL
CALL _PASS_BELL
CALL DELAY200MS
CALL DELAY200MS
CALL _PASS_BELL
CALL DELAY200MS
CALL DELAY200MS
CALL _PASS_BELL
CALL DELAY200MS
CALL DELAY200MS
RETURN
;***********************_PASS_BELL 子程序 **********************************
_PASS_BELL
MOV LW .20
MOV WF TEMP_A
BELL2
MOV LW .190
MOV WF TEMP_B
BELL1
BSF BELL ;频率 Hz
CALL DELAY125US
BCF BELL
CALL DELAY125US
DECFSZ TEMP_B,1
GOTO BELL1
DECFSZ TEMP_A,1
GOTO BELL2
RETURN
;**********************************************************
DELAY50US
MOV lw .15 ;DELAY50US
MOV wf TEMP1
decfsz TEMP1,F
goto $-1
RETLW 0
;*********************** 250uS 延时子程序 1 **************
DELAY125US
MOV LW .42
MOV WF TEMP_C
DECFSZ TEMP_C,F
GOTO $-1
RETURN
;********************************************
DELAY1MS
MOV lw .2
MOV wf TEMP2
MOV lw .170
MOV wf TEMP1
DECFSZ TEMP1,F
goto $-1
DECFSZ TEMP2,F
GOTO $-5
RETURN
;********************************************
DELAY10MS
CALL DELAY1MS
CALL DELAY1MS
CALL DELAY1MS
CALL DELAY1MS
CALL DELAY1MS
CALL DELAY1MS
CALL DELAY1MS
CALL DELAY1MS
CALL DELAY1MS
CALL DELAY1MS
RETLW 0
;********************************************
;延时子程序,约 10MS
DELAY3
MOV LW .20
MOV WF TEMP1
LOOP1
MOV LW .166
MOV WF TEMP2
DECFSZ TEMP2
GOTO $-1
DECFSZ TEMP1
GOTO LOOP1
RETURN
;********************************************
;延时 20MS 子程序
DELAY20MS
MOV lw .40
MOV wf TEMP2
DELAY20MS_1
MOV lw .166
MOV wf TEMP1
DECFSZ TEMP1,F
goto $-1
DECFSZ TEMP2,F
GOTO DELAY20MS_1
RETURN
;********************************************
DELAY200MS
MOV lw .10
MOV wf TEMP3
DELAY200MS_2
MOV lw .40
MOV wf TEMP2
DELAY200MS_1
MOV lw .166
MOV wf TEMP1
DECFSZ TEMP1,F
goto $-1
DECFSZ TEMP2,F
GOTO DELAY200MS_1
DECFSZ TEMP3,F
GOTO DELAY200MS_2
RETURN
;********************************************
DELAY1S
MOV lw .50
MOV wf TEMP3
DELAY1S_2
MOV lw .40
MOV wf TEMP2
DELAY1S_1
MOV lw .166
MOV wf TEMP1
DECFSZ TEMP1,F
goto $-1
DECFSZ TEMP2,F
GOTO DELAY1S_1
DECFSZ TEMP3,F
GOTO DELAY1S_2
RETURN
;********************************************
RAM_TO_EE:
MOV LW 20H
MOV WF DADR
MOV LW .2
MOV WF CNT
MOV LW 00H
MOV WF EE_DADR
CALL EE_WRITE
RETURN
;*********************************EE_WRITE***********************************
;本程序实现从内部RAM传送多字节数据到内部EEPROM。
;入口参数:原操作数的地址放在DADR中,目标EEPROM的地址放在EE_DADR中,字节数在W中。
;出口参数:相关数据已写入指定EEPROM单元中。
;占用资源:W,STATUS,FSR,一重堆栈。
;**************************************************************************
EE_WRITE:
MOV F DADR,W
MOV WF FSR ;RAM 单元首地址
MOV F EE_DADR,W
BANKSEL PIE1 ;BANK1
BCF PIE1,EEIE ;关闭EE中断
BANKSEL EEADR ;BANK2
MOV WF EEADR ;将目标地址写入EEADR
EE_LOOP2:
BANKSEL PORTA ;BANK0
MOV F INDF,W
BANKSEL EEDATA ;BANK2
MOV WF EEDATA ;将源数据写入EEDATA
BANKSEL EECON1 ;BANK3
BCF EECON1,EEPGD ;指定 EEPROM 为操作对象
BSF EECON1,WREN ;写允许
BCF INTCON,GIE ;关闭中断
MOV LW 55H ;MICROChip
MOV WF EECON2 ;规
MOV LW 0XAA ;定
MOV WF EECON2 ;代码
BSF EECON1,WR ;开始写入
BCF EECON1,WREN ;写保护
BTFSC EECON1,WR ;写完了吗?
GOTO $-1
BANKSEL PORTA ;BANK0
INCF FSR,F ;写下一个数据
BANKSEL EEADR ;BANK2
INCF EEADR,F
BANKSEL PORTA ;BANK0
DECFSZ CNT,F ;所有字节的数据写完了吗?
GOTO NEXT1
BSF INTCON,GIE ;重新开总中断
RETURN
NEXT1:
GOTO EE_LOOP2
;********************************EE_READ***********************************
;本程序实现从内部连续的EEPROM单元传送多字节数据到内部RAM。
;入口参数:原操作数在EEPROM中的首地址放在EE_DADR中,目标RAM的首地址放在DADR中,
; 字节数放在CNT中。
;出口参数:相关数据已在指定的连续RAM单元中
;占用资源:W,STATUS,FSR,内部EEPROM模块,一重堆栈。
;***************************************************************************
EE_READ:
BANKSEL PORTA ;BANK0
MOV F DADR,W
MOV WF FSR ;目标RAM的地址
MOV F EE_DADR,W
BANKSEL EEADR ;BANK2
MOV WF EEADR ;地址
EE_READ1:
BANKSEL EECON1 ;BANK3
BCF EECON1,EEPGD ;指定 EEPROM 为操作对象
BSF EECON1,RD ;开始读取
BANKSEL EEDATA ;BANK2
MOV F EEDATA,W
BANKSEL PORTA ;BANK0
MOV WF INDF ;依次取出连续的数据
INCF FSR,F
BANKSEL EEADR ;BANK2
INCF EEADR,F
BANKSEL PORTA ;BANK0
DECFSZ CNT,F ;判断所有字节的数据是否取完
GOTO EE_READ1
RETURN
;***************************************************************************
ORG 0x2100
DE 00H,0AH,00H,00H,00H,00H
END
上一篇:pic单片机4x4键盘扫描程序
下一篇:PIC单片机扩展8255A并口