NY8A050D九齐EPROM 8位MCU应用指南:GPIO初始化、高低电平、定时器中断及看门狗设置等功能详解

一、初始化GPIO

1. 设置输入输出 — IOSTB

(1)IOSTB 解释
//IOSTB 初始值0x3F 即默认全为输入模式
//1-输入	0-输出
#define C_PB0_Input 	0x01
#define C_PB1_Input 	0x02
....
#define C_PB6_Input 	0x20
//输出都是0x00
#define C_PB##_Output 	0x00	
    
#define C_PB_Input		0x3F
#define	C_PB_Output		0x00
(2)IOSTB 使用
//方式1:宏定义表示
IOSTB = C_PB4_Input | C_PB1_Input;//设置PB4和PB1为输入模式,其他则为输出模式
//方式2:使用十六或二进制表示
IOSTB = 0x1F; //设置PB0-PB4为输入模式,PB5为输出模式
IOSTB = 0x00; //设置PB0-PB5为输出模式
IOSTB	= 0B11001001;	//PB5421	输出

2. 设置高低电平 — PORTB

(1)PORTB 解释
//PORTB 初始值0x00 即默认全为低电平
//1-高电平 0-低电平
#define C_PB_Data	0x3F
#define	C_PB5_Data	0x20
#define	C_PB4_Data	0x10
#define	C_PB3_Data	0x08
#define	C_PB2_Data	0x04
#define	C_PB1_Data	0x02
#define	C_PB0_Data	0x01
(2)PORTB 使用
//方式1:宏定义表示
PORTB = C_PB5_Data | C_PB3_Data;//设置PB5和PB3为高电平
//方式2:使用十六或二进制表示
PORTB = 0x00; //全输出低电平
PORTB = 0xFF; //全输出高电平
PORTB = 0x05; //PB2,PB0输出高电平
PORTB = 0B11001001;	//PB5421低电平

3.上拉电阻 — BPHCON

(1)BPHCON 解释
//BPHCON 初始值0x3F 默认全禁用
//1-禁用上拉 0-启用上拉
#define	C_PB_PHB	0x3F
#define	C_PB5_PHB	0x20
#define	C_PB4_PHB	0x10
#define	C_PB3_PHB	0x08	
#define	C_PB2_PHB	0x04
#define	C_PB1_PHB	0x02
#define	C_PB0_PHB	0x01
(2)BPHCON 使用
//方式1:宏定义表示
BPHCON = (unsigned char)~C_PB4_PHB; //PB4上拉,其他禁用
BPHCON = (unsigned char)~(C_PB4_PHB | C_PB2_PHB); //PB42上拉,其他禁用
//方式2:使用十六或二进制表示
BPHCON = 0B00101101;//PB41上拉
BPHCON = 0x1F;//PB5上拉
BPHCON = 0x00;//PB0-PB5上拉

3.下拉电阻 — BPLCON

注:

  • 上拉和下拉的默认状态都是全部禁用,但是具体初始值不同
  • 以 NY8A050D 为例,具备上拉功能的引脚有PB0-PB5,但具备下拉功能的引脚只有PB0-PB3,具体需要查看芯片文档
  • (1)BPLCON 解释
    //BPLCON 初始值0xF0 默认全禁用
    //1-禁用下拉 0-启用下拉
    #define	 C_PB_PLB	0xF0
    #define	 C_PB3_PLB	0x80
    #define	 C_PB2_PLB	0x40
    #define	 C_PB1_PLB	0x20 	
    #define	 C_PB0_PLB	0x10
    
    (2)BPHCON 使用
    //方式1:宏定义表示
    BPLCON = (unsigned char)~C_PB1_PLB; //PB1下拉,其他禁用
    BPHCON = (unsigned char)~(C_PB2_PLB | C_PB1_PLB); //PB21x下拉,其他禁用
    //方式2:使用十六或二进制表示
    BPLCON = 0B01111111;	//PB3下拉
    BPLCON = 0xF0;	//全部禁用下拉
    BPLCON = 0x00;  //全部启用下拉
    

    4.开漏输出 — BODCON

    (1)BODCON 解释
    //BODCON 初始值0x00 默认全禁用
    //1-开启 0-禁用
    #define	C_PB_OD		0x3F
    #define	C_PB5_OD	0x20
    #define	C_PB4_OD	0x10	
    #define	C_PB2_OD	0x04
    #define	C_PB1_OD	0x02
    #define	C_PB0_OD	0x01
    
    (2)BODCON 使用
    //方式1:宏定义表示
    BODCON = C_PB0_OD;				//设置PB0为开漏输出
    BODCON = C_PB5_OD | C_PB1_OD;	//设置PB51为开漏输出
    //方式2:使用十六或二进制表示
    BODCON = 0x3F;					//PB0-5设置为开漏输出
    BODCON = 0B00100010;			//设置PB51为开漏输出
    

    ## 二、修改GPIO的高低电平

    1.源码

    typedef struct __PORTBbits_t
    {
        unsigned PB0    : 1;
        unsigned PB1    : 1;
        unsigned PB2    : 1;
        unsigned PB3    : 1;
        unsigned PB4    : 1;
        unsigned PB5    : 1;
        unsigned GP6    : 1; //!< General purpose read/write register bit
        unsigned GP7    : 1; //!< General purpose read/write register bit
    } __PORTBbits_t;
    
    //! PortB (PortB Data Register)
    extern __at(0x0006) __sfr PORTB;
    extern __at(0x0006) volatile __PORTBbits_t PORTBbits; //!< PortB Data Register
    __sbit PB0 = PORTB : 0;
    __sbit PB1 = PORTB : 1;
    __sbit PB2 = PORTB : 2;
    __sbit PB3 = PORTB : 3;
    __sbit PB4 = PORTB : 4;
    __sbit PB5 = PORTB : 5;
    

    2.使用方式

    根据源码,有两种方式可以修改PB引脚的高低电平

    //1.使用位变量
    PB1 = 0;
    PB2 = 1;
    //2.使用结构体成员
    PORTBbits.PB3 = 0;
    PORTBbits.PB4 = 1;
    

    三、中断

    1.定时器中断

    #include <ny8.h>
    #include "ny8_constant.h"
    
    /*
    * 晶振频率:8MHz,时钟周期数:4T
    * 该示例实现的功能:
    *	每次进入中断使变量system_tick,单位毫秒
    *	当system_tick达到5ms和100ms的时候,while循环执行代码
    */
    #define SYSTEM_5MS		0x01
    #define SYSTEM_100MS	0x02
    
    volatile unsigned char system_tick = 0;//系统计时变量
    
    /**
    *	中断,本代码中每约5ms进入一次中断
    */
    void isr() __interrupt(0)
    {
        static unsigned char tick_100ms = 0;		//100ms计时变量
    	
        if(T0IF)//Timer0溢出中断标志
        {
            T0IF = 0;//清除中断标志
            TMR0 = 100;//Timer0寄存器重新从100开始计数
            system_tick |= SYSTEM_5MS;
            //每5ms进入中断,计数20次就是100ms
            if(++tick_100ms >= 20)
            {
               	tick_100ms = 0;
    			system_tick |= SYSTEM_100MS;
            }
        }
    }
    
    /**
    *	初始化定时器函数
    */
    void timer_init(void)
    {
        DISI();				//关闭中断
        PCON1 = C_TMR0_Dis;	//关闭时钟
        TMR0 = 100;			//Timer0寄存器计数从100开始计算
        T0MD = C_PS0_TMR0;	//将预分频器0分配给Timer0
        T0MD |= C_PS0_Div64;//预分频器64分频,时钟源为指令时钟
        INTE = C_INT_TMR0;	//使能Timer0溢出中断
        INTF = 0;			//清除所有中断标志
        PCON1 = C_TMR0_En;	//使能时钟
        PCON = C_WDT_En | C_LVR_En;	//看门狗使能,低压复位使能
        ENI();				//开启中断
    }
    
    void do_something(){}
    
    void main()
    {
        timer_init();//初始化定时器
    	while(1)
    	{
            //系统计时5ms
    		if(system_tick & SYSTEM_5MS)
    		{
                CLRWDT();//清理看门狗
                system_tick &= ~SYSTEM_5MS;//清零系统计时
    			do_something();//执行某些任务
    		}
            //系统计时100ms
    		if(system_tick & SYSTEM_100MS)
    		{
                CLRWDT();//清理看门狗
                system_tick &= ~SYSTEM_100MS;//清零系统计时
    			do_something();//执行某些任务
    		}
    	}
    }
    

    对于 Timer0 的时间计算,首先要知道以下4个参数:

    晶振频率、时钟周期数、预分频数、计数器值

    请添加图片描述
    请添加图片描述

    这4个参数都是可以自己设置的,如上图我设置了晶振频率4MHz,时钟周期数4T,预分频64,计数从0开始(8位单片机最大计数值为256-1=255)

    接下来就是计算公式:

  • 机器周期 T1 = 1÷(晶振频率 ÷ 时钟周期数) = 1 ÷ (4 ÷ 4) = 1 us
  • 预分频后定时器时钟周期 T2 = T1 x 预分频数 = 1 x 64 = 64 us
  • 计数值溢出后总的定时时间 T = 计数器值 x T2 = 255 x 64 = 16320 us = 16.32 ms
  • 最终计算结果位16.32ms

    我计算了一个比较好用的计算值,也就是前面代码的设置:

    晶振频率:8MHz

    时钟周期数:4T

    预分频数:64

    计数器值:100

    定时结果:5ms(4.96ms)

    四、看门狗

    WDT(WatchDog Timer)看门狗

    对其的通俗解释就是它是你家的二哈,你每天都要及时给它吃东西,否则你家就要被拆了

    WDT 就是这么一个定时器电路,一般有个输入端(叫喂狗),一个输出到MCU的RST端(复位);每过一段时间,你需要及时的输出一个信号到输入端,给WDT清零,否则超过规定时间不喂狗,它就会发送复位信号到MCU进行复位(也就是狗把家拆了),放置MCU发生死机。

    WDT 的作用就是放置程序发生死循环,或者说程序跑飞

    看门狗属于定时器电路,所以就理所当然的涉及到了定时器和中断了,使能代码如下:

    PCON |= C_WDT_En;	//使能看门狗
    PCON |= C_LVR_En;	//低压复位使能
    

    另外,定时喂狗使用的代码如下:

    CLRWDT();			//清理看门狗
    

    具体的使用在定时器中断也有使用

    作者:Alysop

    物联沃分享整理
    物联沃-IOTWORD物联网 » NY8A050D九齐EPROM 8位MCU应用指南:GPIO初始化、高低电平、定时器中断及看门狗设置等功能详解

    发表回复