基础外设总结+完结

时至今日重要吧zigbee基础外设写完了,来做个总结吧~

简单的延时函数写法

void Delay(unsigned int t)
{
  while(t--);
}

 

初始化系统时钟函数——时钟源为32MHZ晶振,时钟频率为32MHZ

void Init_Clock_32MHz()
{
  CLKCONCMD &= ~0x40;       //选择系统时钟源为32MHZ晶振
  while(CLKCONSTA & 0x40);  //等待晶振稳定
  CLKCONCMD &= ~0x47;       //设置系统主时钟频率为32MHZ
}

 

串口初始化函数——设置外设,32MHz的系统时钟产生9600BPS的波特率,串口属性相关的配置,清除发送和接收中断标志位,使能串口相关中断位。

 1 void Init_Uart0()
 2 {
 3   //端口相关的配置
 4   PERCFG = 0x00;        //串口0的引脚映射到位置1,即P0_2和P0_3
 5   P0SEL = 0x0C;         //将P0_2和P0_3端口设置成外设功能
 6   //波特率相关的配置
 7   U0BAUD = 59;          //32MHz的系统时钟产生9600BPS的波特率
 8   U0GCR = 8;            //16MHz---9; 32MHz---8
 9   //串口属性相关的配置
10   U0UCR |= 0x80;        //禁止流控,8位数据,清除缓冲器
11   U0CSR |= 0xC0;        //选择UART模式,使能接收器
12   //清除发送和接收中断标志位
13   UTX0IF = 0;           //清除TX发送中断标志
14   URX0IF = 0;           //清除RX接收中断标志
15   //使能串口相关中断位
16   URX0IE = 1;           //使能URAT0的接收中断
17   EA = 1;               //使能总中断
18 }

 

以及串口的接收终端响应函数

#pragma vector = URX0_VECTOR
__interrupt void UR0_RecvInt()
{
  UR0_Command = U0DBUF; //将控制命令字从缓冲区取出
}

 

还有串口的发送函数哦——需要清除终端标志

void UR0_Send_Byte(unsigned char dat)
{
  U0DBUF = dat;         //将要发送的1字节数据写入U0DBUF
  while(!UTX0IF);       //等待TX中断标志,即数据发送完成
  UTX0IF = 0;           //清除TX中断标志,准备下一次发送
}

 

下位机状态信息发送函数——下机位发送数据帧

unsigned char Send_Data[6];     //数据帧发送缓存

void UR0_Send_Staus()
{
  unsigned char i;
  Send_Data[0] = 0xbf;            //填充帧头
  Send_Data[5] = 0xfb;            //填充帧尾
  for(i = 0; i < 6 ; i++)
  {
    UR0_Send_Byte(Send_Data[i]);  //发送数据帧
  }
}

 

ADC的初始化——P0_0作为模拟I/O使用

void Init_ADC0()
{
  P0SEL |= 0x01;      //P0_0端口设置为外设功能
  P0DIR &= ~0x01;     //P0_0端口设置为输入端口
  APCFG |= 0x01;      //P0_0作为模拟I/O使用
}

 

有ADC初始化就需要采集电压~

void Get_ADC1_Data()
{
  ADCIF = 0;
  //参考电压选择AVDD5引脚,256抽取率,通道0
  ADCCON3 = (0x80 | 0x20 | 0x00);
  while(!ADCIF);          //等待ADC转换完成
  Send_Data[1] = ADCH;    //填充数据帧
  Send_Data[2] = ADCL;    //填充数据帧
  dat_ad = ADCH;          //读取ADC的高8位
}

 

采集完的电压可以附带灯光控制

unsigned char dat_ad = 0;       //ADC采样结果的高8位
unsigned char Stat_LED = 0;     //灯光状态标志

void Auto_Control_lED()
{
  if(dat_ad < 0x30)       //光照电压小于1/3的参考电压
  {
    D6 = 1;               //点亮D5灯
    Stat_LED |= 0xf0;     //更新灯光标志
  }
  else
  {
    D6 = 0;               //关闭D5灯
    Stat_LED &= 0x0f;     //更新灯光标志
  }
  Send_Data[3] = Stat_LED;
}

 

 

还有前面的定时器——32MHz时钟128分频定时50ms,设置分屏系数等等

void Init_Timer1()
{
  T1CC0L = 0xd4;    //32MHz时钟128分频定时50ms
  T1CC0H = 0x30;    //设先填低8位,再填高8位
  T1CCTL0 |= 0x04;  //开启通道0的输出比较模式
  T1IE = 1;         //使能定时器1中断
  T1OVFIM = 1;      //使能定时器1溢出中断
  EA = 1;           //使能总中断
  T1CTL = 0x0e;     //分频系数是128,模模式
}

 

还有定时的中断响应函数——记得清楚中断标志哦

#pragma vector = T1_VECTOR
__interrupt void Timer1_Sevice()
{
  T1STAT &= ~0x01;      //清除定时器1通道0中断标志
  Get_ADC1_Data();      //采样ADC,更新数据
}

 

之前学的还有按键呢~——

unsigned char count_key = 0;    //按键操作次数统计变量


void Scan_Keys()
{
  if(SW1 == 0)                      //发现有SW1按键信号
  {
    Delay(100);                     //延时片刻,去抖动处理
    if(SW1 == 0)                    //确认为SW1按键信号
    {
      while(SW1 == 0);              //等待按键松开
      
      if((Stat_LED & 0x0f) == 0x0f) //如果D6灯处于点亮状态
      {
        D5 = 0;                     //关闭D6灯
        Stat_LED &= 0xf0;           //更新灯光标志
      }
      else                          //如果D6灯处于熄灭状态
      {
        D5 = 1;                     //点亮D6灯
        Stat_LED |= 0x0f;           //更新灯光标志
      }
      Send_Data[3] = Stat_LED;      //填充数据帧
      
      count_key++;                  //统计按键按下次数
      Send_Data[4] = count_key;     //填充数据帧
      
    }
  }     
}

 

哦对,忘了还有端口初始化函数——这个应该会

void Init_Port()
{
  //初始化LED灯的I/O端口
  P1SEL &= ~0x1b;   //P1_0、P1_1、P1_3和P1_4作为通用I/O端口
  P1DIR |= 0x1b;    //P1_0、P1_1、P1_3和P1_4端口输出
  //关闭所有的LED灯
  P1 &= ~0x1b;
  //初始化按键SW1的I/O端口
  P1SEL &= ~0x04;     //P1_2作为通用I/O端口
  P1DIR &= ~0x04;     //P1_2端口输入
  P1INP &= ~0x04;     //P1_2设置为上拉/下拉模式
  P2INP &= ~0x40;     //P1_2设置为上拉
}

 

组合起来的主函数~

void main()
{
  Init_Clock_32MHz();           //初始化系统时钟
  Init_Uart0();                 //初始化串口
  Init_ADC1();                  //初始化ADC
  Init_Timer1();                //初始化定时器
  Init_Port();                  //初始化通用I/O端口
  LED_Check();                  //检测LED灯的状态
  
  while(1)
  {
    Scan_Keys();                //扫描按键并执行操作
    Auto_Control_lED();         //根据光照数据控制灯光
    if(UR0_Command == 0xa3)     //判断是否收到上位机指令
    {
      UR0_Command = 0x00;       //清除当前指令状态
      D4 = 1;                   //点亮发送指示灯
      UR0_Send_Staus();         //发送下位机系统信息数据帧
      D4 = 0;                   //关闭发送指示灯
    }
  }
}

 

 

 

综合以上代码就是这样啦

  1 #include "ioCC2530.h"
  2 
  3 #define D3  P1_0
  4 #define D4  P1_1
  5 #define D5  P1_3
  6 #define D6  P1_4
  7 #define SW1 P1_2
  8 
  9 unsigned char Stat_LED = 0;     //灯光状态标志
 10 unsigned char UR0_Command;      //上位机命令控制字
 11 unsigned char Send_Data[6];     //数据帧发送缓存
 12 unsigned char count_key = 0;    //按键操作次数统计变量
 13 unsigned char dat_ad = 0;       //ADC采样结果的高8位
 14 
 15 /*=======================简单的延时函数========================*/
 16 void Delay(unsigned int t)
 17 {
 18   while(t--);
 19 }
 20 
 21 /*====================初始化系统时钟函数======================*/
 22 void Init_Clock_32MHz()
 23 {
 24   CLKCONCMD &= ~0x40;       //选择系统时钟源为32MHZ晶振
 25   while(CLKCONSTA & 0x40);  //等待晶振稳定
 26   CLKCONCMD &= ~0x47;       //设置系统主时钟频率为32MHZ
 27 }
 28 
 29 /*======================初始化串口0函数=======================*/
 30 void Init_Uart0()
 31 {
 32   //端口相关的配置
 33   PERCFG = 0x00;        //串口0的引脚映射到位置1,即P0_2和P0_3
 34   P0SEL = 0x0C;         //将P0_2和P0_3端口设置成外设功能
 35   //波特率相关的配置
 36   U0BAUD = 59;          //32MHz的系统时钟产生9600BPS的波特率
 37   U0GCR = 8;            //16MHz---9; 32MHz---8
 38   //串口属性相关的配置
 39   U0UCR |= 0x80;        //禁止流控,8位数据,清除缓冲器
 40   U0CSR |= 0xC0;        //选择UART模式,使能接收器
 41   //清除发送和接收中断标志位
 42   UTX0IF = 0;           //清除TX发送中断标志
 43   URX0IF = 0;           //清除RX接收中断标志
 44   //使能串口相关中断位
 45   URX0IE = 1;           //使能URAT0的接收中断
 46   EA = 1;               //使能总中断
 47 }
 48 
 49 /*===================串口0接收中断服务函数=====================*/
 50 #pragma vector = URX0_VECTOR
 51 __interrupt void UR0_RecvInt()
 52 {
 53   UR0_Command = U0DBUF; //将控制命令字从缓冲区取出
 54 }
 55 
 56 /*=====================串口0单字节发送函数=====================*/
 57 void UR0_Send_Byte(unsigned char dat)
 58 {
 59   U0DBUF = dat;         //将要发送的1字节数据写入U0DBUF
 60   while(!UTX0IF);       //等待TX中断标志,即数据发送完成
 61   UTX0IF = 0;           //清除TX中断标志,准备下一次发送
 62 }
 63 
 64 /*====================下位机状态信息发送函数====================*/
 65 void UR0_Send_Staus()
 66 {
 67   unsigned char i;
 68   Send_Data[0] = 0xbf;            //填充帧头
 69   Send_Data[5] = 0xfb;            //填充帧尾
 70   for(i = 0; i < 6 ; i++)
 71   {
 72     UR0_Send_Byte(Send_Data[i]);  //发送数据帧
 73   }
 74 }
 75 
 76 /*=======================ADC初始化函数========================*/
 77 void Init_ADC1()
 78 {
 79   APCFG |= 0x01;      //P0_0作为模拟I/O使用
 80 }
 81 
 82 /*====================ADC电压采样函数========================*/
 83 void Get_ADC1_Data()
 84 {
 85   ADCIF = 0;
 86   //参考电压选择AVDD5引脚,256抽取率,通道0
 87   ADCCON3 = (0x80 | 0x20 | 0x00);
 88   while(!ADCIF);          //等待ADC转换完成
 89   Send_Data[1] = ADCH;    //填充数据帧
 90   Send_Data[2] = ADCL;    //填充数据帧
 91   dat_ad = ADCH;          //读取ADC的高8位
 92 }
 93 
 94 /*====================灯光自动控制函数========================*/
 95 void Auto_Control_lED()
 96 {
 97   if(dat_ad < 0x30)       //光照电压小于1/3的参考电压
 98   {
 99     D6 = 1;               //点亮D5灯
100     Stat_LED |= 0xf0;     //更新灯光标志
101   }
102   else
103   {
104     D6 = 0;               //关闭D5灯
105     Stat_LED &= 0x0f;     //更新灯光标志
106   }
107   Send_Data[3] = Stat_LED;
108 }
109 
110 /*=====================定时器1初始化函数======================*/
111 void Init_Timer1()
112 {
113   T1CC0L = 0xd4;    //32MHz时钟128分频定时50ms
114   T1CC0H = 0x30;    //设先填低8位,再填高8位
115   T1CCTL0 |= 0x04;  //开启通道0的输出比较模式
116   T1IE = 1;         //使能定时器1中断
117   T1OVFIM = 1;      //使能定时器1溢出中断
118   EA = 1;           //使能总中断
119   T1CTL = 0x0e;     //分频系数是128,模模式
120 }
121 
122 /*====================定时器1中断服务函数=====================*/
123 #pragma vector = T1_VECTOR
124 __interrupt void Timer1_Sevice()
125 {
126   T1STAT &= ~0x01;      //清除定时器1通道0中断标志
127   Get_ADC1_Data();      //采样ADC,更新数据
128 }
129 
130 /*======================端口初始化函数========================*/
131 void Init_Port()
132 {
133   //初始化LED灯的I/O端口
134   P1SEL &= ~0x1b;   //P1_0、P1_1、P1_3和P1_4作为通用I/O端口
135   P1DIR |= 0x1b;    //P1_0、P1_1、P1_3和P1_4端口输出
136   //关闭所有的LED灯
137   P1 &= ~0x1b;
138   //初始化按键SW1的I/O端口
139   P1SEL &= ~0x04;     //P1_2作为通用I/O端口
140   P1DIR &= ~0x04;     //P1_2端口输入
141   P1INP &= ~0x04;     //P1_2设置为上拉/下拉模式
142   P2INP &= ~0x40;     //P1_2设置为上拉
143 }
144 
145 /*=======================灯光检测函数========================*/
146 void LED_Check()
147 {
148   D4 = 1;
149   Delay(60000);
150   D3 = 1; 
151   Delay(60000);
152   D6 = 1; 
153   Delay(60000);
154   D5 = 1;
155   Delay(60000);
156   D5 = 0;
157   Delay(60000);
158   D6 = 0; 
159   Delay(60000);
160   D3 = 0; 
161   Delay(60000);
162   D4 = 0;
163 }
164 
165 /*=======================按键扫描函数=========================*/
166 void Scan_Keys()
167 {
168   if(SW1 == 0)                      //发现有SW1按键信号
169   {
170     Delay(100);                     //延时片刻,去抖动处理
171     if(SW1 == 0)                    //确认为SW1按键信号
172     {
173       while(SW1 == 0);              //等待按键松开
174       
175       if((Stat_LED & 0x0f) == 0x0f) //如果D6灯处于点亮状态
176       {
177         D5 = 0;                     //关闭D6灯
178         Stat_LED &= 0xf0;           //更新灯光标志
179       }
180       else                          //如果D6灯处于熄灭状态
181       {
182         D5 = 1;                     //点亮D6灯
183         Stat_LED |= 0x0f;           //更新灯光标志
184       }
185       Send_Data[3] = Stat_LED;      //填充数据帧
186       
187       count_key++;                  //统计按键按下次数
188       Send_Data[4] = count_key;     //填充数据帧
189       
190     }
191   }     
192 }
193 
194 /*==========================主函数============================*/
195 void main()
196 {
197   Init_Clock_32MHz();           //初始化系统时钟
198   Init_Uart0();                 //初始化串口
199   Init_ADC1();                  //初始化ADC
200   Init_Timer1();                //初始化定时器
201   Init_Port();                  //初始化通用I/O端口
202   LED_Check();                  //检测LED灯的状态
203   
204   while(1)
205   {
206     Scan_Keys();                //扫描按键并执行操作
207     Auto_Control_lED();         //根据光照数据控制灯光
208     if(UR0_Command == 0xa3)     //判断是否收到上位机指令
209     {
210       UR0_Command = 0x00;       //清除当前指令状态
211       D4 = 1;                   //点亮发送指示灯
212       UR0_Send_Staus();         //发送下位机系统信息数据帧
213       D4 = 0;                   //关闭发送指示灯
214     }
215   }
216 }
最终代码~

 

posted @ 2020-04-18 21:42  彡灬小宇  阅读(338)  评论(0编辑  收藏  举报