;*****************************************************   
;Copyright (c) 2024, 苏州华芯微电子股份有限公司
;All rights reserved                                 
;
;文件名称: HS16P2811-GPIO
;摘    要: HS16P2811-GPIO功能演示
;
;当前版本: 1.0                                      
;作    者: LBW
;完成日期: 2024.11.14
;*****************************************************   

;***********************************************************
;files include
#include "HS16P2811.inc"



;***********************************************************
;用户IO定义

#define SCL             PORTA,7
#define SDA             PORTA,6

SDA_OUTPUT MACRO
	BSR		RP0		;转到bank1
    	BCR		TRISA6	
    	BCR		RP0		;转到bank0
ENDM

SDA_INPUT MACRO
	BSR		RP0		;转到bank1
    	BSR		TRISA6	
    	BCR		RP0		;转到bank0
ENDM  

;***********************************************************
;user general reg define
DELAY_US		EQU		040H
DELAY_MS_CNT		EQU		041H

E2_ADDR         	EQU     	042H
E2_DATA         	EQU     	043H
I2C_DATA        	EQU     	044H
I2C_COUNT       	EQU     	045H


FLAG1       		EQU     	046H
#define 	F_ACK          FLAG1,0


STATUS_BUF		EQU		07EH	;中断保护寄存器必须放 0x70-0x7F不要动！！！
ACC_BUF			EQU		07FH	;中断保护寄存器必须放 0x70-0x7F不要动！！！
;***********************************************************
;函数入口地址
	ORG	00H
	NOP
	NOP
	GOTO	MAIN_SETUP
	
;中断入口地址04H
	ORG	004H
	GOTO	INT_PRO
INT_PRO:
	MOVAR	ACC_BUF		;保存ACC
	SWAPR	STATUS,0
	MOVAR	STATUS_BUF	;保存STATUS
	
	CLRR    PIR1     ;清中断标志	
	

	
INT_BACK:	
	SWAPR	STATUS_BUF,0
	MOVAR	STATUS		;恢复STATUS
	SWAPR	ACC_BUF,1
	SWAPR	ACC_BUF,0	;恢复ACC
	RETFIE
;//中断代码结束



;==========================================================================
;主程序开始
;***********************************************************
;系统寄存器和GPIO配置
;注意寄存器所在 bank 区域
;***********************************************************
MAIN_SETUP:	
	CALL	SYSTEM_INIT
	CALL	GPIO_INIT
	CALL	CLR_RAM
	MOVIA	100
	CALL	DELAY_MS
	BCR	RP0		;转到bank0
	GOTO	MAIN_LOOP
	
;***********************************************************
SYSTEM_INIT:
	BSR		RP0		;转到bank1
	CLRR	20H		;bank1-20H地址 RAM 清0
	MOVIA	000H		;-0-- ----
	MOVAR	OPTIONR		;OPTIONR(BANK1)
			;Bit6：INTEDG：外部中断触发方式选择位（PC1）;0-falling edge, 1-rising edge
			;Bitn：无关位仿真须写0
	
	MOVIA	0A0H		;101- ----   	
	MOVAR	PCON		;PCON(BANK1)(芯片控制寄存器)
			;Bit7：WDTE: WDT（看门狗定时器）使能位	;0-DIS, 1-EN
			;Bit5：LVREN: 低电压复位使能位			;0-DIS, 1-EN
			;Bitn：无关位仿真须写0
	
	MOVIA	000H		;-0-- ---0 
	MOVAR	PIE1		;PIE1(BANK1)
			;Bit6:ADCIE ADC中断使能位
			;Bit0:T1IE 定时器T1中断使能位 
			;Bitn：无关位仿真须写0
			
	MOVIA	000H		;---- -0-0
	MOVAR	PIE2		;PIE2(BANK1)
			;Bit1:T3IE 定时器T3中断使能位
			;Bit2:T4IE 定时器T4中断使能位
			;Bit5:C1IE 比较器C1中断使能位
			;Bitn：无关位仿真须写0
			
	BCR		RP0		;转到bank0
	
	MOVIA	000H		;00-0 0-00
	MOVAR	INTCON		;INTCON(BANK0)
			;bit7:GIE-全局中断使能位
			;bit6:PEIE-外设总中断使能位
			;bit4:INTIE-外部中断使能位(PC1)
			;bit3:PAIE-PORTA输入变化中断使能位
			;bit1:INTIF-外部中断标志位
			;bit0:PAIF-PORTA输入变化中断标志位	
			;Bitn：无关位仿真须写0
			
	MOVIA	000H		;---- -0-0
	MOVAR	PIR2		;PIR2(BANK0)
			;Bit1:T3IF-定时器T3溢出标志位,软件清0
			;Bit2:T4IF-定时器T4溢出标志位,软件清0
			;Bit5:C1IF-比较器C1输出变化时被置位,软件清0
			;Bitn：无关位仿真须写0
	
	MOVIA	000H		;-0-- ---0
	MOVAR	PIR1		;PIR1(BANK0)
			;Bit6:ADCIF-ADC转换完成标志位
			;Bit0:T1IF-T1溢出标志位 
			;Bitn：无关位仿真须写0
	RETURN
	
;***********************************************************
GPIO_INIT:	
	BSR		RP0		;转到bank1
	
	MOVIA	0x33			;0000 0000 
	MOVAR	TRISA		;TRISA(BANK1)
			;PORTA输入输出配置寄存器 (0-OUT;1-IN) 
				
	MOVIA	00H			;--00 1100 
	MOVAR	TRISC		;TRISC(BANK1)
			;PORTC输入输出配置寄存器 (0-OUT;1-IN) 
				
	MOVIA	00H			;0000 0000 
	MOVAR	PAODCON		;PAODCON(BANK1)
			;开漏配置:1-EN;0-DIS
	
	MOVIA	03FH		;1111 1111
	MOVAR	PAHCON		;PAHCON(BANK1)
			;内部上拉配置:1-DIS;0-EN
			
	MOVIA	0FFH		;1111 1111
	MOVAR	PADCON		;PADCON(BANK1)
			;内部下拉配置:1-DIS;0-EN
			
	MOVIA	00H			;0000 0000 
	MOVAR	WUACON		;WUACON(BANK1)
			;端口唤醒配置:1-EN;0=DIS

	BCR	RP0		;转到bank0

	CLRR	PORTA		;0000 0000	//端口输出赋值
	CLRR	PORTC		;--00 0000	//端口输出赋值
	
	MOVIA	0FFH		;--11 0111
	MOVAR	PCDCON		;PCDCON(BANK0)
				;内部下拉配置:1-DIS;0-EN
			
	MOVIA	0FFH		;--11 1011
	MOVAR	PCHCON		;PCHCON(BANK0)
				;内部上拉配置:1-DIS;0-EN
	
	RETURN
;***********************************************************
;函数名：清所有ram
;IRP:FSR7：00-BANK0 区间接寻址;01 = BANK1 区间接寻址
;***********************************************************
CLR_RAM:
	BCR		IRP
	MOVIA	0x5F  	;个数
	MOVAR	0x20  	;个数存放地址 
	MOVIA 	0x7F  	;REG从后往前 清理 
	MOVAR	FSR	
RAM_CLR_LOOP:	
	BSR		FSR,7	;bank1
	CLRR	INDF
	
	BCR		FSR,7	;bank0
	CLRR	INDF
	DECR	FSR,1
	DECRSZ	20H,1
	GOTO	RAM_CLR_LOOP	
	RETURN
	
;***********************************************************
;main
;***********************************************************
MAIN_LOOP:	
	CLRWDT	  		;清看门狗
	MOVIA	100
	CALL	DELAY_MS

	MOVIA	0X10
	MOVAR	E2_ADDR
	MOVIA	0X5A
	MOVAR	E2_DATA
	CALL	WRITE_E2

	CLRR	E2_DATA
	MOVIA	0X10
	MOVAR	E2_ADDR
	CALL	READ_E2

	MOVIA	0X5A
	XORAR	E2_DATA,A 
	BTRSS	Z 
	GOTO	MAIN_LOOP

	MOVIA	0X01 
	XORAR	PORTC,R 
	
	GOTO	MAIN_LOOP		;主函数循环	 
	
	
	
;***********************************************************
;函数名：DELAY
;传参：循环体调用次数
;返回值：
;功能：延时4个指令周期  Fcpu=4M时候延时1us，延时有误差
;引脚：
;备注：
;***********************************************************
DELAY:					
	MOVAR	DELAY_US	
DELAY_LOOP:	
	CLRWDT				;1;/清看门狗
	DECRSZ	DELAY_US,1	;1/(2)
	GOTO	DELAY_LOOP	;2	
	RETURN				;2	



;==================================================
;I2C开始
;==================================================
I2C_START:
        SDA_OUTPUT
        CALL    DELAY_2US
        BSR     SDA 
        CALL    DELAY_2US
        BSR     SCL
        CALL    DELAY_2US
        BCR     SDA
        CALL    DELAY_2US
        BCR     SCL
        CALL    DELAY_2US
        RETURN 
;==================================================
;I2C写字节
;==================================================
I2C_WRITEBYTE:
        MOVIA   8
        MOVAR   I2C_COUNT
I2C_WRITEBYTE_ON:
        RLR     I2C_DATA,R
        BTRSS   C
        GOTO    WRITE_BIT0
WRITE_BIT1:
        BSR     SDA
        GOTO    SET_BIT_END
WRITE_BIT0:
        BCR     SDA
SET_BIT_END:        
        CALL    DELAY_2US
        BSR     SCL
        CALL    DELAY_2US
        BCR     SCL
        DECRSZ  I2C_COUNT,R           
        GOTO    I2C_WRITEBYTE_ON              
;==================================================
;I2C测试应答
;==================================================
I2C_TESTACK:
        SDA_INPUT	;SDA作输入		   
        BSR     SCL
        CALL    DELAY_2US
        BCR     F_ACK
        BTRSS   SDA
        BSR     F_ACK        ;SDA为低电平 表示有应答，置应答标志位F_ACK
        BCR     SCL
        CALL    DELAY_2US
        SDA_OUTPUT
        RETURN

;==================================================
;I2C读字节
;==================================================
I2C_READBYTE:
        SDA_INPUT
        MOVIA   8
        MOVAR   I2C_COUNT
        CLRR    I2C_DATA

I2C_READBYTE_LOOP:
        RLR     I2C_DATA,R
        BCR     I2C_DATA,0
I2C_BITIN:
        BSR     SDA
        BSR     SCL
        CALL    DELAY_2US
I2C_BIT1:   
        BCR     C
        BTRSC   SDA
        BSR     C     
        BCR     SCL
        CALL    DELAY_2US
        BTRSC   C
        BSR     I2C_DATA,0
        DECRSZ  I2C_COUNT,R
        GOTO    I2C_READBYTE_LOOP
SET_SDA_OUTPUT:
        SDA_OUTPUT                
        RETURN
;==================================================
;I2C无应答
;==================================================
I2C_NOACK:
        BSR     SDA
        CALL    DELAY_2US
        BSR     SCL
        CALL    DELAY_2US
        BCR     SCL
        CALL    DELAY_2US
        RETURN 

;==================================================
;I2C结束
;==================================================
I2C_STOP:
        SDA_OUTPUT               
        BCR     SDA
        CALL    DELAY_2US
        BSR     SCL
        CALL    DELAY_2US
        BSR     SDA
        CALL    DELAY_2US
        RETURN                          

       
;==================================================
;页写 
;==================================================
WRITE_E2:
        CALL    I2C_START
        MOVIA   0A0H
        MOVAR   I2C_DATA
        CALL    I2C_WRITEBYTE
        BTRSS   F_ACK
        GOTO    WRITE_E2_PAGE_END 

        MOVR    E2_ADDR,A               ;起始地址
        MOVAR   I2C_DATA
        CALL    I2C_WRITEBYTE        
        BTRSS   F_ACK
        GOTO    WRITE_E2_PAGE_END 

        MOVR    E2_DATA,A 
        MOVAR   I2C_DATA
        CALL    I2C_WRITEBYTE        
        BTRSS   F_ACK
        GOTO    WRITE_E2_PAGE_END 

WRITE_E2_PAGE_END:
        CALL    I2C_STOP
        MOVIA   6
        CALL    DELAY_MS
        RETURN


;==================================================
;页读
;==================================================
READ_E2:  
        CALL    I2C_START
        
        MOVIA   0A0H
        MOVAR   I2C_DATA
        CALL    I2C_WRITEBYTE
        BTRSS   F_ACK
        GOTO    READ_E2_PAGE_END

        MOVR    E2_ADDR,A
        MOVAR   I2C_DATA
        CALL    I2C_WRITEBYTE
        BTRSS   F_ACK
        GOTO    READ_E2_PAGE_END

        CALL    I2C_START
        MOVIA   0A1H
        MOVAR   I2C_DATA
        CALL    I2C_WRITEBYTE
        BTRSS   F_ACK
        GOTO    READ_E2_PAGE_END

        CALL    I2C_READBYTE
        MOVR    I2C_DATA,A              
        MOVAR   E2_DATA  

 ;第九个同步时钟 给24C02应答
CLOCK_SYN:
        SDA_OUTPUT                           
        BCR     SDA
        CALL    DELAY_2US
        BSR     SCL             
        CALL    DELAY_2US                     
        BCR     SCL             

READ_E2_PAGE_END:
        CALL    I2C_STOP
        RETURN	
	
	
;***********************************************************
;函数名：DELAY_MS
;传参：1-255ms
;返回值：
;功能：ms级延时
;引脚：
;备注：
;***********************************************************
DELAY_MS:					
	MOVAR	DELAY_MS_CNT		
DELAY_LOOP1:
	MOVIA	250
	CALL	DELAY
	CALL	DELAY
	CALL	DELAY
	CALL	DELAY
	DECRSZ	DELAY_MS_CNT,1	;1/(2)
	GOTO	DELAY_LOOP1	;2	
DELAY_2US:       
        CLRWDT        
	RETURN				;2	
;***********************************************************
 
