【CC2530入门教程-02】CC2530的通用I/O端口输入和输出控制

[复制链接]
6343|31
 楼主| ohy3686 发表于 2017-6-22 12:35 | 显示全部楼层 |阅读模式
本帖最后由 ohy3686 于 2017-6-22 12:48 编辑

【CC2530入门教程-02】CC2530的通用I/O端口输入和输出控制

一、CC2530的引脚概述
    CC2530微控制器采用QFN40封装,有40 个引脚。其中,有21个数字I/O端口,其中P0和P1是8 位端口,P2仅有5位可以使用。这21个端口均可以通过编程进行配置
    在微控制器内部,有一些特殊功能的存储单元,这些单元用来存放控制微控制器内部器件的命令、数据或运行过程中的一些状态信息,这些寄存器统称为“特殊功能寄存器(SFR)”。操作微控制器的本质,就是对这些特殊功能寄存器进行读写操作,并且某些特殊功能寄存器可以位寻址
    每一个特殊功能寄存器本质上就是一个内存单元,而标识每个内存单元的是内存地址,不容易**。为了便于使用,每个特殊功能寄存器都会起一个名字,在程序设计时,只要引入头文件“ioCC2530.h”,就可以直接使用寄存器的名称访问内存地址了。
    CC2530的通用I/O端口相关的常用寄存器有下面4个:
    <1> PxSEL:端口功能选择,设置端口是通用I/O还是外设功能
    <2> PxDIR:作为通用I/O时,用来设置数据的传输方向。
    <3> PxINP:作为通用输入端口时,选择输入模式是上拉下拉还是三态
    <4> Px:数据端口,用来控制端口的输出或获取端口的输入。

二、设置寄存器中某些位的方法
    <1> 对寄存器的某些位清0而不影响其他位。
    例如:寄存器P1TM的当前值是0x6c,现需要将该寄存器的第1位、第3 位和第5位设置为0,同时不能影响该寄存器其他位的值,那么,在C语言中应该怎么编写代码呢?
    使用“&=”将寄存器指定位清0,同时不影响其他位的值。
    正确写法:P1TM &= ~0x2A;
    因为:逻辑“与”操作的特点是,该位有0结果就为0,若为1则保存原来值不变。
    首先将字节 0000 0000 中要操作的位设置为1,即0010 1010,在将该数值取反,即1101 0101,也就是~0x2A。再将该值与寄存器P1TM“相与”,那么有0的位,即1、3、5位将被清0,其余的位会保持原来的值不变。
    所以:P1TM的当前值为0x6c,即0110 1100,
    0110 1100 && 1101 0101 = 0100 0100,即1、3、5位清0,其他位不变。
   <注意>:该方法只能操作多位同时清0,或者某一位清0的情况,如果要将寄存器的某两位设置为01,则不能采用这种写法。(其中原因自己思考一下)
    在不少嵌入式应用的源码程序中,对于某一位n的清0操作也可以写成:寄存器 &= ~(0x01<<(n));其道理是一样的。
    <2> 对寄存器的某些位置1而不影响其他位。
    例如:寄存器P1TM的当前值是0x6c,现需要将该寄存器的第1位、第4位和第5位设置为1,同时不能影响该寄存器其他位的值,那么,在C语言中应该怎么编写代码呢?
    使用“|=”将寄存器指定位置1,同时不影响其他位的值。
    正确写法:P1TM |= 0x32;
    因为:逻辑“或”操作的特点是,该位有1结果就为1,若为0则保存原来值不变。
    首先将字节 0000 0000 中要操作的位设置为1,即0011 0010,也就是0x32。 再将该值与寄存器P1TM“相或”,那个有1的位,即1、4、5位将被设置为1,其余的位会保持原来的值不变。
    所以:P1TM的当前值为0x6c,即0110 1100,
    0110 1100 || 0011 0010 = 0111 1110,即1、4、5位置1,其他位不变。
    同样要注意:该方法只能操作多位同时置1,或者某一位置1的情况。

三、实训案例:按键输入控制灯光输出状态
【1】准备工作
引入CC2530必要的头文件,定义相关变量等。
【2】端口功能选择
    微控制器的大部分I/O端口都是功能复用的,在使用的时候需要通过功能选择寄存器来配置端口的功能。 CC2530的特殊功能寄存器PxSEL是端口功能选择寄存器。
【3】端口传输方向设置
【4】对于输入的端口要设置其输入方式
    输入方式用来从外界器件获取输入的电信号,当CC2530的引脚为输入端口时,该端口能够提供“上拉”、“下拉”和“三态”三种输入模式,可以通过编程进行设置。在本次实训中,实际上不需要对P0_1和P1_2引脚进行输入方式的设置,因为CC2530复位后,各个I/O端口默认使用的就是上拉模式
【5】设计端口初始化函数InitPort()。
    <1>设置P1SEL寄存器,将P1_2、P1_3和P1_4设置为通用I/O端口。
    <2>设置P1DIR寄存器,将P1_3和P1_4设置为输出,将P1_2设置为输入。
    <3>设置P0SEL寄存器,将P0_1设置为通用I/O端口。
    <4>设置P0DIR寄存器,将P0_1设置为输入。
    <5>设置PxINP寄存器,将P0_1和P1_2设置为上拉模式,也可以不设置。
【6】设计键盘扫描函数ScanKeys()。
    <1>没有按键下时,端口的输入为高电平,当发现该端口有低电平产生时,则有可能会是按键按下,需要经过去抖动处理,如果该端口还是低电平,则确认为按键按下。
    <2>在进行按键处理时,先等待按键松开,然后根据灯光状态标志Stat_key进行开灯或关灯动作。
    Stat_key为灯光状态标志字节,其第0位第1位分别标志着LED5和LED6的当前状态。
    该字节的第0位为1时,LED5当前已亮。
    该字节的第0位为0时,LED5当前熄灭。
    该字节的第1位为1时,LED6当前已亮。
    该字节的第1位为0时,LED6当前熄灭。
【7】主函数的实现。
    至此,大功搞成,连接仿真器,进行编译调试。

【附件】:本实训源代码。
  1. #include "ioCC2530.h"

  2. #define LED5 P1_3
  3. #define LED6 P1_4
  4. #define SW1 P1_2
  5. #define SW2 P0_1
  6. unsigned char Stat_key = 0;   //按键状态全局变量
  7. /*===================延时函数=========================*/
  8. void Delay(unsigned int t)
  9. {
  10.   while(t--);
  11. }
  12. /*================端口初始化函数======================*/
  13. void InitPort()
  14. {
  15.   P1SEL &= ~0x18;         //将P1_3和P1_4设置为通用I/O端口功能
  16.   P1DIR |= 0x18;          //将P1_3和P1_4的端口传输方式设置为输出
  17.   P1SEL &= ~0x04;         //将P1_2设置为通用I/O端口功能
  18.   P1DIR &= ~0x04;         //将P1_2的端口传输方式设置为输入
  19.   P0SEL &= ~0x02;         //将P0_1设置为通用I/O端口功能
  20.   P0DIR &= ~0x02;         //将P0_1的端口传输方式设置为输入
  21.   P0INP &= ~0x02;         //将P0_1的端口输入方式设置为:上拉/下拉
  22.   P1INP &= ~0x04;         //将P1_2的端口输入方式设置为:上拉/下拉
  23.   P2INP &= ~0x60;         //将P0端口和P1端口引脚设置为:上拉
  24.   LED5 = 0;               //上电的时候,LED5不亮
  25.   LED6 = 0;               //上电的时候,LED6不亮
  26. }
  27. /*=================按键扫描函数=======================*/
  28. void ScanKeys()
  29. {
  30.   if(SW1 == 0)
  31.   {                       //发现SW1有低电平信号
  32.     Delay(100);           //按键去抖动
  33.     if(SW1 == 0)
  34.     {                      //确实是有按键动作
  35.       while(SW1 == 0);    //等待按键1松开
  36.       //判断按键1按下之前,LED灯是打开还是关闭的?
  37.       if((Stat_key & 0x01) == 0x01)
  38.       {
  39.         Stat_key &= ~0x01;  
  40.         LED5 = 0;
  41.       }
  42.       else{
  43.         Stat_key |= 0x01;
  44.         LED5 = 1;
  45.       }
  46.     }
  47.   }
  48.   if(SW2 == 0)
  49.   {                       //发现SW2有低电平信号
  50.     Delay(100);           //按键去抖动
  51.     if(SW2 == 0)
  52.     {                     //确实是有按键动作
  53.       while(SW2 == 0);    //等待按键2松开
  54.       if((Stat_key & 0x02) == 0x02)
  55.       {
  56.         Stat_key &= ~0x02;
  57.         LED6 = 0;
  58.       }
  59.       else{
  60.         Stat_key |= 0x02;
  61.         LED6 = 1;
  62.       }
  63.     }
  64.   }
  65. }
  66. /*=====================主函数=========================*/
  67. void main()
  68. {
  69.   InitPort();
  70.   while(1)
  71.   {
  72.     ScanKeys();
  73.   }
  74. }


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
10299823 发表于 2017-6-24 17:23 | 显示全部楼层
确实不错,IO操作是入门基础。
10299823 发表于 2017-6-24 17:31 | 显示全部楼层
 楼主| ohy3686 发表于 2017-6-27 18:34 | 显示全部楼层
10299823 发表于 2017-6-24 17:23
确实不错,IO操作是入门基础。

只有熟练掌握I/O操作和中断之后,才有可能做其他的功能。
 楼主| ohy3686 发表于 2017-7-2 15:34 | 显示全部楼层
系列教材完成。
泰山神泉 发表于 2018-2-8 14:50 | 显示全部楼层
现在,正在学习嵌入式.不错的学习资料.千里之行,始于足下!!!感谢,楼主的分享
youtome 发表于 2018-2-10 21:52 | 显示全部楼层
很基础入门的学习材料。
cemaj 发表于 2018-2-10 21:52 | 显示全部楼层
mcu主要还是寄存器的操作
youtome 发表于 2018-2-10 21:53 | 显示全部楼层
CC2530的功耗怎么样
cemaj 发表于 2018-2-10 21:53 | 显示全部楼层
CC2530的IO资源还是非常丰富的。
aspoke 发表于 2018-2-22 21:54 | 显示全部楼层
楼主最近没有出新的设计了。
232321122 发表于 2018-2-22 21:54 | 显示全部楼层
这个的无线是怎么设计的
aspoke 发表于 2018-2-22 21:59 | 显示全部楼层
后面设计的板子怎么样了
232321122 发表于 2018-2-22 22:00 | 显示全部楼层
RF的IO是怎么使用的
 楼主| ohy3686 发表于 2018-2-23 09:30 | 显示全部楼层
aspoke 发表于 2018-2-22 21:59
后面设计的板子怎么样了

样板已经做出来了。
https://bbs.21ic.com/icview-2406092-1-1.html
 楼主| ohy3686 发表于 2018-2-23 09:31 | 显示全部楼层
cemaj 发表于 2018-2-10 21:52
mcu主要还是寄存器的操作

大部分在操作寄存器和处理中断。
 楼主| ohy3686 发表于 2018-2-23 09:32 | 显示全部楼层
youtome 发表于 2018-2-10 21:53
CC2530的功耗怎么样

还可以,低功耗要通过编程来体现。
 楼主| ohy3686 发表于 2018-2-23 09:32 | 显示全部楼层
cemaj 发表于 2018-2-10 21:53
CC2530的IO资源还是非常丰富的。

还不错。
 楼主| ohy3686 发表于 2018-2-23 09:32 | 显示全部楼层
aspoke 发表于 2018-2-22 21:54
楼主最近没有出新的设计了。

最近在做“蓝桥杯”单片机设计与开发的教程。
做了一个二合一的开发板:
https://bbs.21ic.com/icview-2406092-1-1.html
 楼主| ohy3686 发表于 2018-2-23 09:33 | 显示全部楼层
232321122 发表于 2018-2-22 21:54
这个的无线是怎么设计的

我自己没有设计这一部分,
用的是现成的CC2530核心模块。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:广东职业技术学院 欧浩源(ohy3686@foxmail.com)    [Zigbee技术&物联网应用] 群:168225322    [技术交流微信]:gzyohy (暗号:宝塔镇河妖)

322

主题

899

帖子

3548

粉丝
快速回复 在线客服 返回列表 返回顶部