这一节我们操作寄存器进行GPIO的应用
1、端口控制寄存器RCGC2
寄存器RCGC2地址为0X400FE108,其功能为:运行模式时钟选通控制
其中5-31位保留 第4位对应GPIOE 第3位对应GPIOD 第2位对应PORTC 第1位对应PORTB 第0位对应PORTA
2、方向寄存器GPIODIR
对GPIO进行操作设置其方向是免不了的
实际地址:PA口为0X40004400 ,PB口为0X40005400,PC口为0X40006400,PD口为0X40007400,PE口为0X40024400(注意)
方向寄存器GPIODIR的 31:8位 保留 0:7位控制GPIO的方向 相应的管脚写0,此管脚为输入,相应的管脚写1,此管脚为输出
3、模式寄存器GPIOAFSEL
实际地址 PA口为0X40004420 ,PB口为0X40005420,PC口为0X40006420,PD口为0X40007420,PE口为0X40024420
模式寄存器GPIOAFSEL的 31:8位 保留 0:7位进行GPIO的模式控制 相应位为0表示此位作为普通IO口,相应位为1表示此位被当做片内外设
(相信学过430的朋友会很明白)
除了5个JTAG管脚(PB7 和 PC[3:0])之外,所有GPIO管脚默认都是输入管脚 (GPIODIR=0 且 GPIOAFSEL=0)。JTAG管脚默认为JTAG功能(GPIOAFSEL=1)
4、GPIO 2-mA 驱动选择GPIODR2R(它允许对端口的每个GPIO信号进行单独配置,而不会影响其他引脚)
实际地址0X40004500 31:8位 保留 0:7位配置输出电流是否为2mA 相应位为0表示不为2mA(默认情况下为2mA,当不为2mA时则可以重新配置为4或8mA),相应位为1表示输出电流为2mA
5、GPIO 4-mA 驱动选择GPIODR4R以及GPIO 8-mA 驱动选择GPIODR8R 其配置方式同GPIODR2R(只是寄存器实际地址不同而已)
在看例程之前先了解一些芯片的锁死问题
如果JTAG管脚在设计中用作GPIO,那么一定要小心了,否则会将芯片锁死,什么叫锁死呢、为什么会锁死?
其实是这样的,正常操作时当给芯片下载程序时JTAG管脚默认为JTAG功能,此时程序可以顺利下载进去,可是当你在程序中加入把JTAG口配置为GPIO功能的语句时,当芯片上电后Flash中的程序会立即执行,这会在瞬间把JTAG口配置为GPIO功能,可想而知你的程序肯定就下载不进去了,因为占用了JTAG口,
当然解决办法是有的,我们可以通过使用一个基于外部或软件的触发器来恢复JTAG功能,就可以避免锁死情况的发生。
具体是这样的:
编写一个按键检测函数,当检测到这个按键按下时执行死循环程序,把这个按键检测函数放在主函数的最开始位置,这时即使把JTAG配置为GPIO也不担心锁住。
具体操作:先按下复位键,再按下用户定义的按键(按下的同时不要松开复位键),然后放开复位键,再放开用户按键即可。
原理:当按下复位键和用户键时程序从主函数处执行,最开始检测到用户按键的按下而进入死循环,所以下面的程序就再也没有执行了,所以就不会把JTAG配置为GPIO了(程序执行不到这一步了),所以就不会让芯片所死了。
接着看一个GPIO例程
#include
void JtagWait(void)//我们811板子上用户按键是PC4,按下按键为低电平
[
HWREG(0x400FE108)|= 0x00000004; // 以全字(32位)方式访问硬件寄存器,选通GPIOC 模块的时钟
HWREGBITW(0X40006400, 4) = 0; //PC4设置为输入(按键的输入) GPIODIR
HWREGBITW(0X40006420, 4) = 0; //PC4设置为通用IO口 GPIOAFSEL
if(HWREGBITW(0X40006000, 4)==0) //0X40006000为PCDATA的地址,读PC4的状态
while(1);//死循环,等待JTAG连接
]
void delay(int z)
[
int x;
char y;
for(x=z;x>0;x--)
for(y=120;y>0;y--);
]
int main()
[ //!!!!!!!!!!!!!!!!!!!LED连接PD0,低电平点亮
JtagWait();
HWREG(0x400FE108)|= 0x00000008; // 以全字(32位)方式访问硬件寄存器,选通GPIOD 模块的时钟(用来驱动LED)
HWREGBITW(0X40007400, 0) = 1; //PD0设置为输出 GPIODIR
HWREGBITW(0X40007420, 0) = 0; //PD0设置为通用IO口 GPIOAFSEL
while(1)
[
//注:向GPIODATA数据寄存器写入数据时其位地址一定要左移两位
//在写操作过程中,如果与数据位相关联的地址位被设为1,那么GPIODATA寄存器的值将发生变化。
//如果被清零,那么该寄存器的值将保持不变。
// ADDR[9:2] 9 8 7 6 5 4 3 2 1 0 (将0xEB的值写入地址GPIODATA+0x098处,u表示没有被写操作改变的数据。 )
// 0x098 0 0 1 0 0 1 1 0 1 0
// 0xEB 1 1 1 0 1 0 1 1
// GPIODATA u u 1 u u 0 1 u
//如果使用PD0驱动LED,则0x01<<2=0x04;如果使用PD1驱动LED,则0x02<<2=0x08;如果PD0和PD1都进行驱动,则0x03<<2=0x0c;依此规律
HWREGBITW(0X40007000+0x00000004, 0) = 1;//PD0=1,熄灭LED 0X40007000为PDDATA地址
delay(100);
HWREGBITW(0X40007000+0x00000004, 0) = 0;//PD0=0,点亮LED
delay(100);
]
]
如有不正确的地方还请指正。
0