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();			//清理看门狗

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

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值