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;
}
原文地址:https://blog.csdn.net/qq_45796666/article/details/131014468
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。