基础外设总结+完结
时至今日重要吧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 }