PIC单片机学习第一天----GPIO

PIC单片机学习第一天

第一天入职,本公司使用的芯片为PIC16的,是一种8位的单片机,网上的资料近乎绝迹,公司给的手册也是全英文的,对于我这种英语小白死在是太难了。

这款芯片由于硬件的约束,并没有标准库这些东西,只能面向寄存器进行编写代码;同时使用的人不多造成的资料不多,学习起来也很费劲。

对于任何单片机首先要学的肯定是I/O口了,对于STM32单片机的GPIO的配置大家肯定都不陌生,标准库的一套流程,结构体定义,引脚端口,输入或者输出模式,还有速度,然后初始化;但是对于PIC这款单片机不太一样,下面说一下所使用到的几个寄存器:

1、TRISx ——— 数据方向寄存器

主要用来控制 I/O 引脚的方向,即用来控制PORTx 是输入还是输出。这个就有带你类似STM32单片机的GPIO_InitStructure.GPIO_Mode = 这个东西;

TRISx(数据方向控制寄存器):0=输出模式(Out),1=输入模式(In);

2、PORTx ——— 端口寄存器

用来锁存输出数据。当读PORTx 时,器件直接读 I/O 引脚电平(而不是锁存值)。

3、LATx ——— 输出数据锁存器

写端口就是写该锁存器(LATx)。数据锁存器也可以直接读写。如果外设没有使用该引脚,并且TRISx位配置该引脚为输出,则将锁存器内的数据输出到引脚。

上面三个标准工作寄存器每个端口都有;

有的端口可能话剧有下面一个或多个寄存器:

1、ANSELx————模拟选择寄存器

ANSELx(模拟选择寄存器):0 = 数字I/O口,1 = 模拟输入口;

2、WPUx---————弱上拉寄存器

配置步骤如下:

第一步:首先配置ANSELx寄存器,将IO口定义为数字IO,还是模拟输入IO;

第二步:配置TRISx,将IO口定义为输入,还是输出;

第三步:若定义IO口为输入,要得到IO端口的实际电平,则直接读取PORTx寄存器,若将IO口定义为输出,则通过写LATx来达到对IO口置高低电平操作。

注意:若直接写PORTx寄存器,实际上会写入到LATx中,所以一般不写入PORTx寄存器。若直接读取LATx寄存器,读取到的是锁存在GPIO Latch中的数据,而不是真正的IO端口数据,所以一般不读取LATx寄存器。

当某个引脚配置成模拟IO时候,必须将其相应的TRISx配置成输入,这样才能读取到引脚上外部电压。

PORT与LAT寄存器区别:

rd port指令脉冲来的时候,管脚端平锁存到port中,也就是说要想获得正确的管脚状态,只有读取port寄存器,而如果去读lat寄存器,读到的输出锁存器的值,比如说你一开始设置管脚成输出,通过lat输出了一个0x55,然后你设置管脚成输出,这个时候管脚电平再外部电路的驱动下发生了变化编程了0x66,这个时候你读port才能读到0x66,而如果你去读lat则读到的是你上一次输出值,不是当前时刻管脚电平状态。这也就是lat和port的不同之所在。所以在做pic18的时候我们应该养成写则写lat,读则读port的好习惯

LAT是作为缓存使用的,PORT读的是I/O状态,所以,读I/O时用PORT,写I/O时用LAT。

总结一下:

1、I/O作为写输出时使用锁存器LAT;

2、I/O作为读输入时使用端口PORT;

3、若定义IO口为输入,要得到IO端口的实际电平,则直接读取PORTx寄存器,若将IO口定义为输出,则通过写LATx来达到对IO口置高低电平操作。

4、当某个引脚配置成模拟IO时候,必须将其相应的TRISx配置成输入,这样才能读取到引脚上外部电压。

最后参考一下配置代码:

void Pin_manager_initialization(void)            //???????
{
                                                    //输出数据锁存寄存器
    LATA = 0x00;                                    //??A??0 
    LATB = 0x00;                                    //??B??0 
    LATC = 0x00;                                    //??C??0 
    
                                                    //方向控制寄存器
    TRISA = 0x00;                                   //??A?????0输出1输入
    TRISB = 0x00;                                   //??B?????
    TRISC = 0x00;                                   //??C?????
 
                                                    //模/数控制寄存器
    ANSELA = 0x00;                                  //??A???????0数字I/O口1模拟输入口
    ANSELB = 0x00;                                  //??B??????? 
    ANSELC = 0x00;                                  //??C??????? 
                                                    

                  //弱上拉寄存器--这个寄存器不是所有端口都有的,所以可有可无
    WPUA = 0x00;                                    //??A????0失能1使·1能
    WPUB = 0x00;                                    //??B????
    

                                                     //选择寄存器
    OPTION_REGbits.nWPUEN = 0x00;                    //?WPUx???????这个可有可无
}

还有一种写法:大家看到代码的时候可能都有这个疑惑,下面解答一下;上面是按字节进行配置I/O,比较迅速;下面是按位进行配置,比较一对一;我刚开始见到这种也是很懵逼,怎么还有俩配置方式,后来进行学习才明白的。

void Pin_manager_initialization(void)            //???????
{
                                                    
        LATAbits.LATA0 = 0 ;
        LATAbits.LATA1 = 0 ;
        LATBbits.LATB4 = 0 ;

        TRISAbits.TRISA1 = 0;
 
}

相关文章

文章浏览阅读552次。com.mongodb.MongoQueryException: Quer...
文章浏览阅读635次,点赞9次,收藏8次。MongoDB 是一种 NoSQ...
文章浏览阅读2.1k次。和。_mongodb 日期类型
文章浏览阅读1.7k次。Scalestack等客户期待使用MongoDB Atla...
文章浏览阅读970次。SpringBoot整合中间件mongodb、ES_sprin...
文章浏览阅读673次。MongoDB 简介_尚医通sql