• 基础外设总结+完结


    时至今日重要吧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 }
    最终代码~
  • 相关阅读:
    【转】我该 不该学习VULKAN
    游戏开发内功秘籍记录
    VS 配置外部DLL的引用路径【可执行文件的环境路径】
    OpenGL3.x,4.x中使用FreeImage显示图片的BUG-黑色,或颜色分量顺序错乱
    C++风格与C风格文件读写效率测试-vs2015,vs2017
    【转】矩阵的几何解释
    android 线程间通信
    android 网络
    安卓 碎片 如何实现类似 活动 栈的 进栈 出栈
    安卓 内容提供者 观察者 解析器
  • 原文地址:https://www.cnblogs.com/yuling520/p/12728323.html
Copyright © 2020-2023  润新知