CC2530通用IO口的輸入輸出


一、引腳概述

CC2530有40 個引腳。其中,有21個數字I/O端口,其中P0和P1是8 位端口P2僅有5位可以使用。P2端口的5個引腳中,有2個需要用作仿真,有2個需要用作晶振。所以可供我們使用的就只有17個引腳了。

 

 

操作微控制器的本質,就是對這些特殊功能寄存器(SFR)進行讀寫操作,並且某些特殊功能寄存器可以位尋址

 

每一個特殊功能寄存器本質上就是一個內存單元,為了便於使用,每個特殊功能寄存器都會起一個名字,在程序設計時,只要引入頭文件“ioCC2530.h”,就可以直接使用寄存器的名稱訪問內存地址了。

 

 

 CC2530的通用I/O端口相關的常用寄存器有下面4個:

        <1> PxSEL:端口功能選擇,設置端口是通用I/O還是外設功能

        <2> PxDIR:作為通用I/O時,用來設置數據的傳輸方向。

        <3> PxINP:作為通用輸入端口時,選擇輸入模式是上拉下拉還是三態

        <4> Px:數據端口,用來控制端口的輸出或獲取端口的輸入。

具體的寄存器功能和應用下面會說到。

 

二、設置寄存器的方法

 <1> 對寄存器的某些位清0而不影響其他位。

使用“&=”將寄存器指定位清0,同時不影響其他位的值。 

 

因為:邏輯“與”操作的特點是,該位有0結果就為0,若為1則保存原來值不變。

 

Tip:該方法只能操作多位同時清0,或者某一位清0的情況,如果要將寄存器的位既要清0又要置1,則不能采用這種寫法。

 

對於寄存器的第n位的清0操作也可以寫成:寄存器 &= ~(0x01<<(n))

 

<2> 對寄存器的某些位置1而不影響其他位。

使用“|=”將寄存器指定位置1,同時不影響其他位的值。

 

因為:邏輯“或”操作的特點是,該位有1結果就為1,若為0則保存原來值不變。

 

 對於寄存器的第n位的清0操作也可以寫成:寄存器 |= (0x01<<(n));

 

題目:實現2個按鍵分別控制2個LED燈開關的功能,即SW1按下后松開,LED5亮,SW1再次按下后松開, LED5滅。SW2以同樣的方式控制LED6。本題中的引腳圖

 

 

 

涉及到的寄存器

端口功能選擇寄存器。

 

 

端口傳輸方向設置寄存器。

 

 

輸入端口需要設置其輸入方式的寄存器

端口能夠提供“上拉”、“下拉”和“三態”三種輸入模式

 

 

 

 

例子:將P1_2端口為按鍵輸入,設置為輸入上拉模式。

1 P1INP &=~0x04  //0000 0100->1111 1011  首先需要將P1_2設置為上/下拉模式
2 P2INP &=~0x40  //0100 0000 ->1011 1111 在將P1_2確定為上拉模式

 

通用I/O端口寄存器配置的基本思路。

 

 

設計思路:

1.設計一個端口初始化函數,對端口的功能進行配置,LED相關的端口設置為輸出,按鍵相關的端口設置為輸入,並且配置成上拉模式。

 

設計端口初始化函數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設置為上拉模式,也可以不設置。

void InitPort()
{
  P1SEL &= ~0x18;         //將P1_3和P1_4設置為通用I/O端口功能
  P1DIR |= 0x18;          //將P1_3和P1_4的端口傳輸方式設置為輸出
  P1SEL &= ~0x04;         //將P1_2設置為通用I/O端口功能
  P1DIR &= ~0x04;         //將P1_2的端口傳輸方式設置為輸入
  P0SEL &= ~0x02;         //將P0_1設置為通用I/O端口功能
  P0DIR &= ~0x02;         //將P0_1的端口傳輸方式設置為輸入
  P0INP &= ~0x02;         //將P0_1的端口輸入方式設置為:上拉/下拉
  P1INP &= ~0x04;         //將P1_2的端口輸入方式設置為:上拉/下拉
  P2INP &= ~0x60;         //將P0端口和P1端口引腳設置為:上拉
  LED5 = 0;               //上電的時候,LED5不亮
  LED6 = 0;               //上電的時候,LED6不亮
}

 

 

 

2.主函數中掃描按鍵端口的變化,默認是高電平。當按鍵按下的時候,為低電平。當出現低電平的時候,需要進行去抖的處理。

  <1>沒有按鍵下時,端口的輸入為高電平,當發現該端口有低電平產生時,則有可能會是按鍵按下,需要經過去抖動處理,如果該端口還是低電平,則確認為按鍵按下。

        <2>在進行按鍵處理時,先等待按鍵松開,然后再將相關的LED進行開關狀態的取反控制。

 

void main()
{
  InitPort();
  while(1)
  {
    ScanKeys();
  }
}

 

 

最終代碼展示

 

 1 #include "ioCC2530.h"
 2 
 3 #define LED5 P1_3
 4 #define LED6 P1_4
 5 #define SW1 P1_2
 6 #define SW2 P0_1
 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端口功能  0001 1000->1110 0111 將P1_3和P1_4設置普通IO口
16   P1DIR |= 0x18;          //將P1_3和P1_4的端口傳輸方式設置為輸出   0001 1000 將P1_3和P1_4設置為輸出模式
17   P1SEL &= ~0x04;         //將P1_2設置為通用I/O端口功能   0000 0100->1111 1011 將P1_2設置為普通IO口
18   P1DIR &= ~0x04;         //將P1_2的端口傳輸方式設置為輸入  1111 1011 將P1_2的設置為輸入模式。還會有P1INP與P2INP寄存器設置
19   P0SEL &= ~0x02;         //將P0_1設置為通用I/O端口功能   0000 0010 ->1111 1101 將P0_1設置為普通IO口
20   P0DIR &= ~0x02;         //將P0_1的端口傳輸方式設置為輸入   1111 1101  將P0_1設置為輸入
21   P0INP &= ~0x02;         //將P0_1的端口輸入方式設置為:上拉/下拉  0000 0010->1111 1101  先設置上拉或者下拉模式 P0_1設置為、
22   P1INP &= ~0x04;         //將P1_2的端口輸入方式設置為:上拉/下拉  1111 1011  P1_2設置上拉或者下拉模式
23   P2INP &= ~0x60;         //將P0端口和P1端口引腳設置為:上拉  0110 0000 -> 1001 1111  可看寄存器 5與6對應的P0和P1  0為上拉模式
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       //將LED5的燈光開關狀態取反
37       LED5 = ~LED5;
38   }
39   if(SW2 == 0)
40   {                       //發現SW2有低電平信號
41     Delay(100);           //按鍵去抖動
42     if(SW2 == 0)
43     {                     //確實是有按鍵動作
44       while(SW2 == 0);    //等待按鍵2松開
45       LED6 = ~LED6;
46     }
47   }
48 }
49 /*=====================主函數=========================*/
50 void main()
51 {
52   InitPort();
53   while(1)
54   {
55     ScanKeys();  //按鍵掃描函數里面包含了點燈
56   }
57 }
View Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM